/* ///////////////////////////////////////////////////////////////////// */ /*! \file \brief Writing of a 1D buffer in parallel. Write a 1D buffer in parallel using 4 different versions. For a contiguous data type, use: VERSION == 1 employs shared file pointer VERSION == 2 employs individual file pointer with offset computed by the MPI_File_seek() VERSION == 3 defines a file view with offset depending on the process rank VERSION == 4 similar to VERSION == 3, but using a contiguous MPI datatype A non-contiguous version is handled with VERSION == 5, which defines a MPI vector datatype and a file view. \author A. Mignone (mignone@to.infn.it) \date March 1, 2020 */ /* ///////////////////////////////////////////////////////////////////// */ #include #include #include #include #define NELEM 3 #define VERSION 5 int main(int argc, char **argv) { int i, rank, size; double buf[NELEM]; char fname[] = "arr1D.bin"; MPI_File fh; MPI_Offset disp; /* -------------------------------------------------------- 0. Initialize the MPI execution environment -------------------------------------------------------- */ MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &rank); MPI_Comm_size (MPI_COMM_WORLD, &size); /* -------------------------------------------------------- 1. Initialize array -------------------------------------------------------- */ for (i = 0; i < NELEM; i++) buf[i] = rank; /* -------------------------------------------------------- 2. Delete, re-open file and write -------------------------------------------------------- */ MPI_File_delete(fname, MPI_INFO_NULL); MPI_File_open( MPI_COMM_WORLD, fname, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh ); #if VERSION == 1 // Contiguous data, shared file pointer MPI_File_write_ordered(fh, buf, NELEM, MPI_DOUBLE, MPI_STATUS_IGNORE); #elif VERSION == 2 // Contiguous data, individual file pointer disp = rank*NELEM*sizeof(double); // In bytes MPI_File_seek(fh, disp, MPI_SEEK_SET); MPI_File_write(fh, buf, NELEM, MPI_DOUBLE, MPI_STATUS_IGNORE); #elif VERSION == 3 // Contiguous data, file view disp = rank*NELEM*sizeof(double); MPI_File_set_view(fh, disp, MPI_DOUBLE, MPI_DOUBLE, "native", MPI_INFO_NULL); MPI_File_write(fh, buf, NELEM, MPI_DOUBLE, MPI_STATUS_IGNORE); #elif VERSION == 4 // Contiguous data, file view with MPI datatype MPI_Datatype cntg_type; MPI_Type_contiguous(NELEM, MPI_DOUBLE, &cntg_type); MPI_Type_commit(&cntg_type); disp = rank*NELEM*sizeof(double); MPI_File_set_view(fh, disp, MPI_BYTE, cntg_type, "native", MPI_INFO_NULL); MPI_File_write(fh, buf, 1, cntg_type, MPI_STATUS_IGNORE); MPI_Type_free(&cntg_type); #elif VERSION == 5 // Non-contiguous data, file view, vector type MPI_Datatype vec_type; for (i = 0; i < NELEM; i++) buf[i] = rank + 0.1*i; MPI_Type_vector(NELEM, 1, size, MPI_DOUBLE, &vec_type); MPI_Type_commit(&vec_type); disp = rank*sizeof(double); MPI_File_set_view(fh, disp, MPI_DOUBLE, vec_type, "native", MPI_INFO_NULL); MPI_File_write(fh, buf, NELEM, MPI_DOUBLE, MPI_STATUS_IGNORE); MPI_Type_free(&vec_type); #endif MPI_File_close(&fh); MPI_Finalize(); return 0; }