/* * Copyright (C) by Argonne National Laboratory * See COPYRIGHT in top-level directory */ #include "mpi.h" #include #include #include /* 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; }