/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2019, Northwestern University * Copyright (C) 2019, Northwestern University * See COPYRIGHT notice in top-level directory. * See COPYRIGHT notice in top-level directory. * * * This program shows an example of calling MPI_File_set_view(), which sets * This program shows an example of calling MPI_File_set_view(), which sets * a visible file region to the calling MPI process. With such fileview set, * a visible file region to the calling MPI process. With such fileview set, * all successive MPI read and write function calls will read and write only * all successive MPI read and write function calls will read and write only * the visible region. In this example program, the visible region to process * the visible region. In this example program, the visible region to process * rank i starts from file offset (rank * 10 * sizeof(int)). * rank i starts from file offset (rank * 10 * sizeof(int)). * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #define CHECK_ERR(func) { \ #define CHECK_ERR(func) { \ if (err != MPI_SUCCESS) { \ if (err != MPI_SUCCESS) { \ int errorStringLen; \ int errorStringLen; \ char errorString[MPI_MAX_ERROR_STRING]; \ char errorString[MPI_MAX_ERROR_STRING]; \ MPI_Error_string(err, errorString, &errorStringLen); \ MPI_Error_string(err, errorString, &errorStringLen); \ printf("Error at line %d: calling %s (%s)\n",__LINE__, #func, errorSt printf("Error at line %d: calling %s (%s)\n",__LINE__, #func, errorSt } \ } \ } } /*----< main() >------------------------------------------------------------* /*----< main() >------------------------------------------------------------* int main(int argc, char **argv) { int main(int argc, char **argv) { char *filename; char *filename; int i, err, cmode, rank, buf[10]; int i, err, cmode, rank, buf[10]; MPI_Offset offset; MPI_Offset offset; MPI_File fh; MPI_File fh; > MPI_Info info; MPI_Status status; MPI_Status status; MPI_Init(&argc, &argv); MPI_Init(&argc, &argv); err = MPI_Comm_rank(MPI_COMM_WORLD, &rank); err = MPI_Comm_rank(MPI_COMM_WORLD, &rank); CHECK_ERR(MPI_Comm_rank); CHECK_ERR(MPI_Comm_rank); filename = "testfile.out"; filename = "testfile.out"; if (argc > 1) filename = argv[1]; if (argc > 1) filename = argv[1]; /* open a file (create if the file does not exist) */ /* open a file (create if the file does not exist) */ cmode = MPI_MODE_CREATE | MPI_MODE_RDWR; cmode = MPI_MODE_CREATE | MPI_MODE_RDWR; err = MPI_File_open(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &fh); err = MPI_File_open(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &fh); CHECK_ERR(MPI_File_open); CHECK_ERR(MPI_File_open); /* initialize write buffer contents */ /* initialize write buffer contents */ for (i=0; i<10; i++) buf[i] = 100 * rank + i; for (i=0; i<10; i++) buf[i] = 100 * rank + i; /* set file offset for this calling process */ /* set file offset for this calling process */ offset = (MPI_Offset)rank * 10 * sizeof(int); offset = (MPI_Offset)rank * 10 * sizeof(int); > /* Set "view is local" info key for MPI_File_set_view() call */ > MPI_Info_create(&info); > MPI_Info_set(info, "view_is_local", "true"); > /* MPI_File_set_view() sets the file visible region to this process start /* MPI_File_set_view() sets the file visible region to this process start * at offset. Setting etype argument to MPI_INT means this file will be * at offset. Setting etype argument to MPI_INT means this file will be * accessed in the units of integer size. Setting filetype argument to * accessed in the units of integer size. Setting filetype argument to * MPI_INT means a contiguous 4-byte region (assuming integer size if 4 * MPI_INT means a contiguous 4-byte region (assuming integer size if 4 * bytes) is recursively applied to the file to form the visible region t * bytes) is recursively applied to the file to form the visible region t * the calling process, starting from its "offset" set in the offset * the calling process, starting from its "offset" set in the offset * argument. In this example, the "file view" of a process is the entire * argument. In this example, the "file view" of a process is the entire * file starting from its offset. * file starting from its offset. */ */ err = MPI_File_set_view(fh, offset, MPI_INT, MPI_INT, "native", MPI_INFO_ | err = MPI_File_set_view(fh, offset, MPI_INT, MPI_INT, "native", info); CHECK_ERR(MPI_File_set_view); CHECK_ERR(MPI_File_set_view); /* Each process writes 3 integers to the file region visible to it. /* Each process writes 3 integers to the file region visible to it. * Note the file pointer will advance 3x4 bytes after this call. * Note the file pointer will advance 3x4 bytes after this call. */ */ err = MPI_File_write_all(fh, &buf[0], 3, MPI_INT, &status); | err = MPI_File_write(fh, &buf[0], 3, MPI_INT, &status); CHECK_ERR(MPI_File_set_view); CHECK_ERR(MPI_File_set_view); /* Each process continues to write next 7 integers to the file region /* Each process continues to write next 7 integers to the file region * visible to it, starting from the file pointer updated from the previou * visible to it, starting from the file pointer updated from the previou * write call. * write call. */ */ err = MPI_File_write_all(fh, &buf[3], 7, MPI_INT, &status); err = MPI_File_write_all(fh, &buf[3], 7, MPI_INT, &status); CHECK_ERR(MPI_File_set_view); CHECK_ERR(MPI_File_set_view); /* close the file collectively */ /* close the file collectively */ err = MPI_File_close(&fh); err = MPI_File_close(&fh); CHECK_ERR(MPI_File_set_view); CHECK_ERR(MPI_File_set_view); MPI_Finalize(); MPI_Finalize(); return 0; return 0; } }