/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* (C) 2001 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
#include "mpi.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* writes a file of size 4 Gbytes and reads it back.
should be run on one process only*/
/* The file name is taken as a command-line argument. */
/* Can be used only on file systems on which ROMIO supports large files,
i.e., any file system created after 1999 */
#define SIZE 1048576*4 /* no. of long longs in each write/read */
#define NTIMES 128 /* no. of writes/reads */
static void handle_error(int errcode, const char *str)
{
char msg[MPI_MAX_ERROR_STRING];
int resultlen;
MPI_Error_string(errcode, msg, &resultlen);
fprintf(stderr, "%s: %s\n", str, msg);
MPI_Abort(MPI_COMM_WORLD, 1);
}
#define MPI_CHECK(fn) { int errcode; errcode = (fn); if (errcode != MPI_SUCCESS) handle_error(errcode, #fn); }
int main(int argc, char **argv)
{
MPI_File fh;
MPI_Status status;
MPI_Offset size;
long long *buf, i;
char *filename;
int j, mynod, nprocs, len, flag, err;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
if (nprocs != 1) {
fprintf(stderr, "Run this program on one process only\n");
MPI_Abort(MPI_COMM_WORLD, 1);
}
i = 1;
while ((i < argc) && strcmp("-fname", *argv)) {
i++;
argv++;
}
if (i >= argc) {
fprintf(stderr, "\n*# Usage: large -fname filename\n\n");
MPI_Abort(MPI_COMM_WORLD, 1);
}
argv++;
len = strlen(*argv);
filename = (char *) malloc(len + 1);
strcpy(filename, *argv);
fprintf(stderr,
"This program creates an 4 Gbyte file. Don't run it if you don't have that much disk space!\n");
buf = (long long *) malloc(SIZE * sizeof(long long));
if (!buf) {
fprintf(stderr, "not enough memory to allocate buffer\n");
MPI_Abort(MPI_COMM_WORLD, 1);
}
MPI_CHECK(MPI_File_open(MPI_COMM_SELF, filename,
MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh));
for (i = 0; i < NTIMES; i++) {
for (j = 0; j < SIZE; j++)
buf[j] = i * SIZE + j;
err = MPI_File_write(fh, buf, SIZE, MPI_DOUBLE, &status);
/* MPI_DOUBLE because not all MPI implementations define
* MPI_LONG_LONG_INT, even though the C compiler supports long long. */
if (err != MPI_SUCCESS) {
fprintf(stderr, "MPI_File_write returned error\n");
MPI_Abort(MPI_COMM_WORLD, 1);
}
}
MPI_CHECK(MPI_File_get_size(fh, &size));
fprintf(stderr, "file size = %@LL@ bytes\n", size);
MPI_CHECK(MPI_File_seek(fh, 0, MPI_SEEK_SET));
for (j = 0; j < SIZE; j++)
buf[j] = -1;
flag = 0;
for (i = 0; i < NTIMES; i++) {
err = MPI_File_read(fh, buf, SIZE, MPI_DOUBLE, &status);
/* MPI_DOUBLE because not all MPI implementations define
* MPI_LONG_LONG_INT, even though the C compiler supports long long. */
if (err != MPI_SUCCESS) {
fprintf(stderr, "MPI_File_write returned error\n");
MPI_Abort(MPI_COMM_WORLD, 1);
}
for (j = 0; j < SIZE; j++)
if (buf[j] != i * SIZE + j) {
fprintf(stderr, "error: buf %d is %@LL@, should be %@LL@ \n", j, buf[j],
i * SIZE + j);
flag = 1;
}
}
if (!flag)
fprintf(stderr, "Data read back is correct\n");
MPI_CHECK(MPI_File_close(&fh));
free(buf);
free(filename);
MPI_Finalize();
return 0;
}