int MPIU_read_external32_conversion_fn(void *userbuf, MPI_Datatype datatype, int count, void *filebuf) { int position_i = 0; MPI_Aint position = 0; MPI_Aint bytes = 0; int mpi_errno = MPI_SUCCESS; int is_contig = 0; ADIOI_Datatype_iscontig(datatype, &is_contig); mpi_errno = MPI_Pack_external_size("external32", count, datatype, &bytes); if (mpi_errno != MPI_SUCCESS) goto fn_exit; if (is_contig) { mpi_errno = MPI_Unpack_external("external32", filebuf, bytes, &position, userbuf, count, datatype); if (mpi_errno != MPI_SUCCESS) goto fn_exit; } else { void *tmp_buf = NULL; tmp_buf = ADIOI_Malloc(bytes); if (!tmp_buf) { mpi_errno = MPI_ERR_NO_MEM; goto fn_exit; } mpi_errno = MPI_Pack(filebuf, count, datatype, tmp_buf, bytes, &position_i, MPI_COMM_WORLD); if (mpi_errno != MPI_SUCCESS) { ADIOI_Free(tmp_buf); goto fn_exit; } mpi_errno = MPI_Unpack_external("external32", tmp_buf, bytes, &position, userbuf, count, datatype); if (mpi_errno != MPI_SUCCESS) { ADIOI_Free(tmp_buf); goto fn_exit; } ADIOI_Free(tmp_buf); } fn_exit: return mpi_errno; }
int main(int argc, char *argv[]) { /* Variable declarations */ MPI_Datatype oneslice, twoslice, threeslice; int errs = 0; MPI_Aint sizeofint, bufsize, position; void *buffer; int i, j, k; /* Initialize a to some known values. */ for (i = 0; i < 100; i++) { for (j = 0; j < 100; j++) { for (k = 0; k < 100; k++) { a[i][j][k] = i * 1000000 + j * 1000 + k; } } } /* Initialize MPI */ MPI_Init(&argc, &argv); MPI_Type_extent(MPI_INT, &sizeofint); parse_args(argc, argv); /* Create data types. */ /* NOTE: This differs from the way that it's done on the sheet. */ /* On the sheet, the slice is a[0, 2, 4, ..., 16][2-10][1-9]. */ /* Below, the slice is a[0-8][2-10][1, 3, 5, ..., 17]. */ MPI_Type_vector(9, 1, 2, MPI_INT, &oneslice); MPI_Type_hvector(9, 1, 100 * sizeofint, oneslice, &twoslice); MPI_Type_hvector(9, 1, 100 * 100 * sizeofint, twoslice, &threeslice); MPI_Type_commit(&threeslice); /* Pack it into a buffer. */ position = 0; /* MPI_Pack_size(1, threeslice, MPI_COMM_WORLD, &bufsize); */ MPI_Pack_external_size((char *) "external32", 1, threeslice, &bufsize); if (bufsize != 2916) { fprintf(stderr, " Error on pack size! Got %d; expecting %d\n", (int) bufsize, 2916); } buffer = (void *) malloc((unsigned) bufsize); /* -1 to indices on sheet to compensate for Fortran --> C */ MPI_Pack_external((char *) "external32", &(a[0][2][1]), 1, threeslice, buffer, bufsize, &position); /* Unpack the buffer into e. */ position = 0; MPI_Unpack_external((char *) "external32", buffer, bufsize, &position, e, 9 * 9 * 9, MPI_INT); /* Display errors, if any. */ for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { for (k = 0; k < 9; k++) { /* The truncation in integer division makes this safe. */ if (e[i][j][k] != a[i][j + 2][k * 2 + 1]) { errs++; if (verbose) { printf("Error in location %d x %d x %d: %d, should be %d.\n", i, j, k, e[i][j][k], a[i][j + 2][k * 2 + 1]); } } } } } /* Release memory. */ free(buffer); if (errs) { fprintf(stderr, "Found %d errors\n", errs); } else { printf(" No Errors\n"); } MPI_Type_free(&oneslice); MPI_Type_free(&twoslice); MPI_Type_free(&threeslice); MPI_Finalize(); return 0; }