diff options
Diffstat (limited to 'testpar/t_vfd.c')
-rw-r--r-- | testpar/t_vfd.c | 1805 |
1 files changed, 1730 insertions, 75 deletions
diff --git a/testpar/t_vfd.c b/testpar/t_vfd.c index 827faf4..5e9070d 100644 --- a/testpar/t_vfd.c +++ b/testpar/t_vfd.c @@ -100,6 +100,100 @@ static unsigned vector_write_test_6(int file_name_id, int mpi_rank, int mpi_size H5FD_mpio_collective_opt_t coll_opt_mode, const char *vfd_name); static unsigned vector_write_test_7(int file_name_id, int mpi_rank, int mpi_size, H5FD_mpio_xfer_t xfer_mode, H5FD_mpio_collective_opt_t coll_opt_mode, const char *vfd_name); +/* + * Tests for selection I/O: + * They are derived from test_selection_io() in test/vfd.c and modified for parallel testing. + */ + +/* + * Global declarations for selection I/O tests` + */ + +/* Number of errors */ +int nerrors = 0; +int curr_nerrors = 0; + +/* Test file name */ +#define SELECT_FNAME "mpio_select_test_file" + +/* Dimemsion sizes */ +#define SEL_IO_DIM0 4 +#define SEL_IO_DIM1 8 +int sel_dim0 = SEL_IO_DIM0; +int sel_dim1 = SEL_IO_DIM1; + +/* Write buffers */ +int *wbuf1 = NULL; +int *wbuf2 = NULL; +int *wbufs[2] = {NULL, NULL}; + +/* File buffers */ +int *fbuf1 = NULL; +int *fbuf2 = NULL; +int *fbufs[2] = {NULL, NULL}; /* Array of file buffers */ + +/* Expected read buffers */ +int *erbuf1 = NULL; +int *erbuf2 = NULL; +int *erbufs[2] = {NULL, NULL}; /* Array of expected read buffers */ + +/* iotypes for testing: + H5FD_MPIO_INDEPENDENT + H5FD_MPIO_COLLECTIVE + --H5FD_MPIO_COLLECTIVE_IO + --H5FD_MPIO_INDIVIDUAL_IO +*/ +#define iotypes 3 + +#define P_TEST_ERROR \ + do { \ + nerrors++; \ + H5_FAILED(); \ + AT(); \ + } while (0) + +#define CHECK_PASSED() \ + do { \ + int err_result = (nerrors > curr_nerrors); \ + \ + MPI_Allreduce(MPI_IN_PLACE, &err_result, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); \ + \ + if (MAINPROCESS) { \ + if (err_result == 0) \ + PASSED(); \ + else \ + HDputs(" ***TEST FAILED***"); \ + } \ + } while (0) + +/* Utility functions for selection I/O */ +static herr_t test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t block[], + H5FD_t *lf, H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], + hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[], + uint32_t rbufcount, int *erb[], hbool_t shorten_rbufs); + +static herr_t test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, + hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], + size_t element_sizes[], int *wb[]); + +/* Test functions for selection I/O */ +static void test_selection_io(int mpi_rank, int mpi_size); +static void test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl); +static void test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims1[]); +static void test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims2[]); +static void test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims1[], hsize_t dims2[]); +static void test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], + hid_t mem_spaces[], hid_t file_spaces[], hsize_t dims1[], + hsize_t dims2[]); + +/****************************************************************************/ /****************************************************************************/ /***************************** Utility Functions ****************************/ @@ -4065,86 +4159,22 @@ vector_write_test_7(int file_name_id, int mpi_rank, int mpi_size, H5FD_mpio_xfer } /* vector_write_test_7() */ -/*------------------------------------------------------------------------- - * Function: main - * - * Purpose: Run parallel VFD tests. - * - * Return: Success: 0 - * - * Failure: 1 - * - *------------------------------------------------------------------------- - */ - -int -main(int argc, char **argv) +static void +test_vector_io(int mpi_rank, int mpi_size) { unsigned nerrs = 0; -#ifdef H5_HAVE_SUBFILING_VFD - int required = MPI_THREAD_MULTIPLE; - int provided = 0; -#endif - int mpi_size; - int mpi_rank = 0; - -#ifdef H5_HAVE_SUBFILING_VFD - if (MPI_SUCCESS != MPI_Init_thread(&argc, &argv, required, &provided)) { - printf(" MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE. Exiting\n"); - goto finish; - } - - if (provided != required) { - printf(" MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE. Exiting\n"); - goto finish; - } -#else - if (MPI_SUCCESS != MPI_Init(&argc, &argv)) { - printf(" MPI_Init failed. Exiting\n"); - goto finish; - } -#endif - - MPI_Comm_size(comm, &mpi_size); - MPI_Comm_rank(comm, &mpi_rank); - /* Attempt to turn off atexit post processing so that in case errors - * occur during the test and the process is aborted, it will not hang - * in the atexit post processing. If it does, it may try to make MPI - * calls which may not work. - */ - if (H5dont_atexit() < 0) - printf("%d:Failed to turn off atexit processing. Continue.\n", mpi_rank); - - H5open(); - - if (mpi_rank == 0) { - printf("=========================================\n"); - printf("Parallel virtual file driver (VFD) tests\n"); - printf(" mpi_size = %d\n", mpi_size); - printf("=========================================\n"); - } - - if (mpi_size < 2) { - if (mpi_rank == 0) - printf(" Need at least 2 processes. Exiting.\n"); - goto finish; - } - - alloc_and_init_file_images(mpi_size); + nerrs += alloc_and_init_file_images(mpi_size); if (!pass) { printf("\nAllocation and initialize of file image buffers failed. Test aborted.\n"); + nerrors += (int)nerrs; + return; } MPI_Barrier(comm); - if (mpi_rank == 0) { - - printf("\n\n --- TESTING MPIO VFD --- \n\n"); - } - nerrs += vector_read_test_1(0, mpi_rank, mpi_size, H5FD_MPIO_INDEPENDENT, H5FD_MPIO_INDIVIDUAL_IO, "mpio"); nerrs += vector_read_test_1(0, mpi_rank, mpi_size, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_INDIVIDUAL_IO, "mpio"); @@ -4312,18 +4342,1643 @@ main(int argc, char **argv) H5FD_SUBFILING_NAME); #endif + nerrors += (int)nerrs; + + /* return(nerrs);*/ + +} /* test_vector_io() */ + +/* + * Utility routine to perform the actual selection I/O read + */ +static herr_t +test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t block[], H5FD_t *lf, + H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], hid_t file_spaces[], + haddr_t offsets[], size_t element_sizes[], uint32_t rbufcount, int *erb[], + hbool_t shorten_rbufs) +{ + int *rbuf1 = NULL; + int *rbuf2 = NULL; + int *rbufs[2] = {NULL, NULL}; + size_t bufsize; + int i; + int j; + + bufsize = (hsize_t)(sel_dim0 * sel_dim1) * sizeof(int); + if ((rbuf1 = malloc(bufsize)) == NULL) + goto error; + if ((rbuf2 = malloc(bufsize)) == NULL) + goto error; + rbufs[0] = rbuf1; + rbufs[1] = rbuf2; + + /* Initialize read buffer */ + for (i = 0; i < (int)rbufcount; i++) + for (j = 0; j < sel_dim0 * sel_dim1; j++) + rbufs[i][j] = -1; + + /* Handle elements in count that are not part of rbufcount */ + for (i = (int)rbufcount; i < (int)count; i++) + if (shorten_rbufs) + rbufs[i] = NULL; + else + rbufs[i] = rbufs[rbufcount - 1]; + + /* Issue read call */ + if (H5FDread_selection(lf, type, dxpl, count, mem_spaces, file_spaces, offsets, element_sizes, + (void **)rbufs) < 0) + goto error; + + /* Verify result */ + for (i = 0; i < (int)rbufcount; i++) { + hsize_t endblock = MIN((start[i] + block[i]), (hsize_t)(sel_dim0 * sel_dim1)); + for (j = (int)start[i]; j < (int)endblock; j++) + if (rbufs[i][j] != erb[i][j]) { + H5_FAILED(); + AT(); + printf( + "data read from file does not match expected values at mapping array location %d: %d\n", + i, mpi_rank); + printf("expected data: \n"); + for (j = 0; j < sel_dim0 * sel_dim1; j++) { + printf("%6d", erb[i][j]); + if (!((j + 1) % sel_dim1)) + printf("\n"); + } + printf("read data: \n"); + for (j = 0; j < (sel_dim0 * sel_dim1); j++) { + printf("%6d", rbufs[i][j]); + if (!((j + 1) % sel_dim1)) + printf("\n"); + } + goto error; + } + } + + if (rbuf1) + free(rbuf1); + if (rbuf2) + free(rbuf2); + return 0; + +error: + if (rbuf1) + free(rbuf1); + if (rbuf2) + free(rbuf2); + return -1; + +} /* end test_selection_io_read_verify() */ + +/* + * Utility routine to perform the actual selection I/O write + */ +static herr_t +test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], + hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[], int *wb[]) +{ + const void **bufs = NULL; /* Avoids cast/const warnings */ + int i; + int j; + + if (NULL == (bufs = calloc(count, sizeof(void *)))) + goto error; + + /* Update write buffer */ + for (i = 0; i < (int)count; i++) { + if (wb[i] && (i == 0 || wb[i] != wb[i - 1])) + for (j = 0; j < (sel_dim0 * sel_dim1); j++) + wb[i][j] += 2 * (sel_dim0 * sel_dim1); + bufs[i] = wb[i]; + } + + /* Issue write call */ + if (H5FDwrite_selection(lf, type, dxpl, count, mem_spaces, file_spaces, offsets, element_sizes, bufs) < 0) + goto error; + + if (bufs) + free(bufs); + + return 0; + +error: + if (bufs) + free(bufs); + return -1; + +} /* end test_selection_io_write() */ + +/* + * Perform the following tests that use shortened arrays for wbuf and element sizes + * --Test 1: Strided <> Strided 1D and 2D I/O for both file and memory spaces + * --Reset selections + * --Test 2: Strided <> Strided 2D I/O, 2 different selections in the same memory buffer + * --Reset selections + */ +static void +test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims1[], hsize_t dims2[]) +{ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ + hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ + hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ + int i; + int j; + int i2; + int j2; + + int shorten_element_sizes; /* Whether to shorten the element sizes array */ + + for (shorten_element_sizes = 0; shorten_element_sizes <= 1; shorten_element_sizes++) { + /* + * Test 1: Strided <> Strided 1D and 2D I/O + */ + /* sel_dim1 must be even */ + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Strided selection in memory (1D) */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + stride[0] = 2; + start[0] = (hsize_t)mpi_rank * stride[0] * count[0]; + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + verify_start[0] = start[0]; + verify_block[0] = (count[0] * stride[0]); + + /* Strided selection in file (1D) */ + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 1) in file (2D) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 0) in memory (2D) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + stride[0] = 2; + stride[1] = 1; + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + start[1] = 0; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + verify_start[1] = start[0] * count[1]; + verify_block[1] = (count[0] * count[1] * stride[0]); + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, + (int **)wbufs) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file bufs */ + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + fbuf1[(2 * i) + 1] = wbuf1[2 * i]; + for (i = 1, i2 = 0, j2 = 1; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) { + assert(i2 < sel_dim0); + fbuf2[i2 * sel_dim1 + j2] = wbuf2[i * sel_dim1 + j]; + j2 += 2; + if (j2 >= sel_dim1) { + i2++; + j2 = 1; + } + } + + /* Update expected read bufs */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + erbuf1[2 * i] = wbuf1[2 * i]; + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[i * sel_dim1 + j] = -1; + for (i = 1; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) + erbuf2[i * sel_dim1 + j] = wbuf2[i * sel_dim1 + j]; + + /* Read and verify */ + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 2, mem_spaces, + file_spaces, addrs, element_sizes, 2, (int **)erbufs, FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + verify_start[0] = start[0]; + verify_block[0] = block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + verify_start[1] = start[0] * block[1]; + verify_block[1] = (block[0] * block[1]); + + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 2, mem_spaces, + file_spaces, addrs, element_sizes, 2, (int **)fbufs, FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 2: Strided <> Strided 2D I/O, 2 different selections in the same memory buffer + */ + /* Switch mem and file spaces to both be 2D */ + if (H5Sset_extent_simple(mem_spaces[0], 2, dims2, NULL) < 0) + P_TEST_ERROR; + if (H5Sset_extent_simple(file_spaces[0], 2, dims2, NULL) < 0) + P_TEST_ERROR; + + /* Strided selection in memory (1st) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + stride[0] = 2; + stride[1] = 1; + start[0] = (hsize_t)mpi_rank * count[0] * stride[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + verify_start[0] = start[0] * count[1]; + verify_block[0] = (count[0] * count[1] * stride[0]); + + /* Strided selection (across dim 0) in memory (2nd) */ + start[0] = 1 + ((hsize_t)mpi_rank * count[0] * stride[0]); + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + verify_start[1] = start[0] * count[1]; + verify_block[1] = (count[0] * count[1] * stride[0]); + + /* Strided selection in file (1st) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 0; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 1) in file (2nd) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Use the same memory buffer for both selections */ + wbufs[0] = wbuf2; + + /* Shorten wbuf array */ + if (shorten_element_sizes) + wbufs[1] = NULL; + else + wbufs[1] = wbufs[0]; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, + (int **)wbufs) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file bufs - need to reuse 1D array so data stays consistent, so use math to + * find 1D index into 2D array */ + for (i = 0, i2 = 0, j2 = 0; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) { + assert(i2 < sel_dim0); + fbuf1[(i2 * sel_dim1) + j2] = wbuf2[i * sel_dim1 + j]; + j2 += 2; + if (j2 >= sel_dim1) { + i2++; + j2 = 0; + } + } + for (i = 1, i2 = 0, j2 = 1; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) { + assert(i2 < sel_dim0); + fbuf2[i2 * sel_dim1 + j2] = wbuf2[i * sel_dim1 + j]; + j2 += 2; + if (j2 >= sel_dim1) { + i2++; + j2 = 1; + } + } + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[i * sel_dim1 + j] = -1; + for (i = 0; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) + erbuf2[i * sel_dim1 + j] = wbuf2[i * sel_dim1 + j]; + for (i = 1; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) + erbuf2[i * sel_dim1 + j] = wbuf2[i * sel_dim1 + j]; + + /* Read and verify */ + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 2, mem_spaces, + file_spaces, addrs, element_sizes, 1, (int **)&erbufs[1], + shorten_element_sizes ? TRUE : FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + verify_start[1] = start[0] * block[1]; + verify_block[1] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 2, mem_spaces, + file_spaces, addrs, element_sizes, 2, (int **)fbufs, FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Reset first spaces to 1D */ + if (H5Sset_extent_simple(mem_spaces[0], 1, dims1, NULL) < 0) + P_TEST_ERROR; + if (H5Sset_extent_simple(file_spaces[0], 1, dims1, NULL) < 0) + P_TEST_ERROR; + + /* Reset write buffer array */ + wbufs[0] = wbuf1; + wbufs[1] = wbuf2; + + /* Change to shortened element sizes array */ + element_sizes[1] = 0; + + MPI_Barrier(comm); + } + + /* Reset element sizes array */ + element_sizes[1] = element_sizes[0]; + + return; + +} /* test_selection_io_types_shorten() */ + +/* + * Perform the following tests for 1 & 2 dimensional spaces: + * --Test 1: Strided 1D (memory) <> Strided 2D (file) I/O + * --Reset selections + * --Test 2: Strided 2D (memory) <> Strided 1D (file) I/O + * --Reset selections + */ +static void +test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims1[], hsize_t dims2[]) +{ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ + hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ + hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ + int i; + int j; + int i2; + int j2; + + /* + * Test 1: Strided 1D (memory) <> Strided 2D (file) I/O + */ + /* Strided selection (across dim 1) in file */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection in memory */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + stride[0] = 2; + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 1, i2 = 0, j2 = 1; i < (sel_dim0 * sel_dim1); i += 2) { + assert(i2 < sel_dim0); + fbuf2[(i2 * sel_dim1) + j2] = wbuf1[i]; + j2 += 2; + if (j2 >= sel_dim1) { + i2++; + j2 = 1; + } + } + + /* Update expected read buf */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 1; i < (sel_dim0 * sel_dim1); i += 2) + erbuf1[i] = wbuf1[i]; + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = (count[0] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&erbufs[0], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 2: Strided 2D (memory) <> Strided 1D (file) I/O + */ + /* Strided selection in file */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + stride[0] = 2; + start[0] = (hsize_t)mpi_rank * stride[0] * count[0]; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 0) in memory */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + stride[0] = 2; + stride[1] = 1; + start[0] = (hsize_t)mpi_rank * count[0] * stride[0]; + start[1] = 0; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0, i2 = 0; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) { + assert(i2 < (sel_dim0 * sel_dim1)); + fbuf1[i2] = wbuf2[i * sel_dim1 + j]; + i2 += 2; + } + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[(i * sel_dim1) + j] = -1; + for (i = 0; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) + erbuf2[(i * sel_dim1) + j] = wbuf2[i * sel_dim1 + j]; + + /* Read and verify */ + verify_start[0] = start[0] * count[1]; + verify_block[0] = (count[0] * count[1] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&erbufs[1], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + return; + +} /* test_selection_io_types_1d_2d() */ + +/* + * Perform the following tests for 2 dimensional spaces: + * --Test 1: Simple 2D contiguous I/O for both file and memory spaces + * --Test 2: Strided (memory) <> Contiguous(file) 2D I/O + * --Reset selections + * --Test 3: Contiguous (memory) <> Strided (file) 2D I/O + * --Reset selections + * --Test 4: Strided (memory) <> Strided (file) 2D I/O + * --Reset selections + */ +static void +test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], + hsize_t dims2[]) +{ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ + hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ + hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ + int i; + int j; + int i2; + int j2; + + /* + * Test 1: Simple 2D contiguous I/O + */ + + /* Contiguous selection in file and memory */ + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + fbuf2[(i * sel_dim1) + j] = wbuf2[(i * sel_dim1) + j]; + + /* Read and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 2: Strided (memory) <> Contiguous(file) 2D I/O + */ + /* Contiguous selection in file */ + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + start[0] = 1 + ((hsize_t)mpi_rank * count[0]); + start[1] = 0; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + P_TEST_ERROR; + + /* Strided selection in memory */ + block[0] = 1; + block[1] = 1; + stride[0] = 2; + stride[1] = 1; + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + start[1] = 0; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < sel_dim0 / 2; i++) + for (j = 0; j < sel_dim1; j++) { + fbuf2[((i + 1) * sel_dim1) + j] = wbuf2[(((2 * i) + 1) * sel_dim1) + j]; + } + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[(i * sel_dim1) + j] = -1; + for (i = 0; i < sel_dim0 / 2; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[(((2 * i) + 1) * sel_dim1) + j] = wbuf2[(((2 * i) + 1) * sel_dim1) + j]; + + /* Read and verify */ + verify_start[0] = start[0] * count[1]; + verify_block[0] = (count[0] * count[1] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&erbufs[1], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 3: Contiguous (memory) <> Strided (file) 2D I/O + */ + + /* Strided selection in file */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Contiguous selection in memory */ + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1 / 2; j++) + fbuf2[i * sel_dim1 + (2 * j) + 1] = wbuf2[i * sel_dim1 + (j + 1)]; + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[i * sel_dim1 + j] = -1; + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1 / 2; j++) + erbuf2[i * sel_dim1 + (j + 1)] = wbuf2[i * sel_dim1 + (j + 1)]; + + /* Read and verify */ + verify_start[0] = start[0] * count[1] * stride[1]; + verify_block[0] = (count[0] * count[1] * stride[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&erbufs[1], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 4: Strided (memory) <> Strided (file) 2D I/O + */ + /* sel_dim0 and sel_dim1 must be even */ + assert(sel_dim0 / 2 == (sel_dim0 + 1) / 2); + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Strided selection (across dim 0) in file */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + stride[0] = 2; + stride[1] = 1; + start[0] = 1 + ((hsize_t)mpi_rank * count[0] * stride[0]); + start[1] = 0; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 1) in memory */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0, i2 = 1, j2 = 0; i < sel_dim0; i++) + for (j = 1; j < sel_dim1; j += 2) { + assert(i2 < sel_dim0); + fbuf2[i2 * sel_dim1 + j2] = wbuf2[i * sel_dim1 + j]; + if (++j2 == sel_dim1) { + i2 += 2; + j2 = 0; + } + } + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[i * sel_dim1 + j] = -1; + for (i = 0; i < sel_dim0; i++) + for (j = 1; j < sel_dim1; j += 2) + erbuf2[i * sel_dim1 + j] = wbuf2[i * sel_dim1 + j]; + /* Read and verify */ + verify_start[0] = start[0] * count[1] * stride[1]; + verify_block[0] = (count[0] * count[1] * stride[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&erbufs[1], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + return; + +} /* test_selection_io_types_2d() */ + +/* + * Perform the following tests for 1 dimensional spaces: + * --Test 1: Simple 1D contiguous I/O in both file and memory spaces + * --Test 2: Strided (memory) <> Contiguous (file) 1D I/O + * --Reset selections + * --Test 3: Contiguous (memory) <> Strided (file) 1D I/O + * --Reset selections + * --Test 4: Strided (memory) <> Strided 1D (file) I/O + * --Reset selections + */ +static void +test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], + hsize_t dims1[]) +{ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ + hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ + hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ + int i; + + /* + * Test 1: Simple 1D contiguous I/O + */ + + /* Contiguous selection in file and memory */ + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < sel_dim0 * sel_dim1; i++) + fbuf1[i] = wbuf1[i]; + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 2: Strided (memory) <> Contiguous (file) 1D I/O + */ + /* sel_dim1 must be even */ + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Contiguous selection in file */ + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + start[0] = 1 + ((hsize_t)mpi_rank * count[0]); + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + P_TEST_ERROR; + + /* Strided selection in memory */ + block[0] = 1; + stride[0] = 2; + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + fbuf1[i + 1] = wbuf1[(2 * i) + 1]; + + /* Update expected read buf */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + erbuf1[(2 * i) + 1] = wbuf1[(2 * i) + 1]; + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = (count[0] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&erbufs[0], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 3: Contiguous (memory) <> Strided (file) 1D I/O + */ + /* sel_dim1 must be even */ + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Strided selection in file */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); /* count is this value from twice above */ + stride[0] = 2; /* stride is this value from twice above */ + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Contiguous selection in memory */ + start[0] = 1 + ((hsize_t)mpi_rank * count[0]); + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + fbuf1[(2 * i) + 1] = wbuf1[i + 1]; + + /* Update expected read buf */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + erbuf1[i + 1] = wbuf1[i + 1]; + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = count[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&erbufs[0], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 4: Strided (memory) <> Strided 1D (file) I/O + */ + /* sel_dim1 must be even */ + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Strided selection in file */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + stride[0] = 2; + start[0] = 0 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection in memory */ + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + fbuf1[2 * i] = wbuf1[(2 * i) + 1]; + + /* Update expected read buf */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + erbuf1[(2 * i) + 1] = wbuf1[(2 * i) + 1]; + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = (count[0] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&erbufs[0], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + return; + +} /* test_selection_io_types_1d() */ + +/* + * Perform the following tests for selection I/O: + * + * test_selection_io_types_1d(): + * ---Selection I/O tests for 1 dimensional spaces + * test_selection_io_types_2d() + * ---Selection I/O tests for 2 dimensional spaces + * test_selection_io_types_1d_2d() + * ---Selection I/O tests for 1 & 2 dimensional spaces + * test_selection_io_types_shorten() + * --Selection I/O tests that use shortened arrays for wbuf and element sizes + */ +static void +test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) +{ + hid_t mem_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* memory dataspaces vector */ + hid_t file_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* file dataspaces vector */ + hsize_t dims1[1]; /* 1d dimension sizes */ + hsize_t dims2[2]; /* 2d dimension sizes */ + + H5FD_mem_t type; /* File type */ + haddr_t addrs[2]; /* File allocation address */ + size_t element_sizes[2] = {sizeof(int), sizeof(int)}; /* Element size */ + size_t bufsize; /* Buffer size */ + int i; + int j; + + curr_nerrors = nerrors; + + /* + * Default dimension sizes for mpi_size 1 or 2: + * int sel_dim0 = SELECT_IO_DIM0; + * int sel_dim1 = SELECT_IO_DIM1; + */ + if (mpi_size >= 3) { + sel_dim0 = mpi_size * 2; + sel_dim1 = mpi_size * 4; + } + + dims1[0] = (hsize_t)(sel_dim0 * sel_dim1); + dims2[0] = (hsize_t)sel_dim0, dims2[1] = (hsize_t)sel_dim1; + + /* Create dataspaces - location 0 will be 1D and location 1 will be 2D */ + if ((mem_spaces[0] = H5Screate_simple(1, dims1, NULL)) < 0) + P_TEST_ERROR; + if ((mem_spaces[1] = H5Screate_simple(2, dims2, NULL)) < 0) + P_TEST_ERROR; + if ((file_spaces[0] = H5Screate_simple(1, dims1, NULL)) < 0) + P_TEST_ERROR; + if ((file_spaces[1] = H5Screate_simple(2, dims2, NULL)) < 0) + P_TEST_ERROR; + + /* Initialize global buffers: + * --wbuf1, wbuf2: write buffers + * --fbuf1, fbuf1: expected file buffers + * --erbuf1, erbuf2: expected read buffers + */ + bufsize = (size_t)(sel_dim0 * sel_dim1) * sizeof(int); + + if ((wbuf1 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + if ((wbuf2 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + wbufs[0] = wbuf1; + wbufs[1] = wbuf2; + + if ((fbuf1 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + if ((fbuf2 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + fbufs[0] = fbuf1; + fbufs[1] = fbuf2; + + if ((erbuf1 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + if ((erbuf2 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + erbufs[0] = erbuf1; + erbufs[1] = erbuf2; + + /* Initialize data */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) { + wbuf1[(i * sel_dim1) + j] = (i * sel_dim1) + j; + wbuf2[(i * sel_dim1) + j] = (i * sel_dim1) + j + (sel_dim0 * sel_dim1); + } + + /* Loop over memory types */ + for (type = 1; type < H5FD_MEM_NTYPES; type++) { + + addrs[0] = H5FDalloc(lf, type, H5P_DEFAULT, (sizeof(int) * (hsize_t)sel_dim0 * (hsize_t)sel_dim1)); + addrs[1] = H5FDalloc(lf, type, H5P_DEFAULT, (sizeof(int) * (hsize_t)sel_dim0 * (hsize_t)sel_dim1)); + + test_selection_io_types_1d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, + file_spaces, dims1); + test_selection_io_types_2d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, + file_spaces, dims2); + test_selection_io_types_1d_2d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, + file_spaces, dims1, dims2); + test_selection_io_types_shorten(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, + file_spaces, dims1, dims2); + + } /* end for */ + + /* Close dataspaces */ + for (i = 0; i < 2; i++) { + if (H5Sclose(mem_spaces[i]) < 0) + P_TEST_ERROR; + if (H5Sclose(file_spaces[i]) < 0) + P_TEST_ERROR; + } + + /* Free the buffers */ + if (wbuf1) + free(wbuf1); + if (wbuf2) + free(wbuf2); + if (fbuf1) + free(fbuf1); + if (fbuf2) + free(fbuf2); + if (erbuf1) + free(erbuf1); + if (erbuf2) + free(erbuf2); + + CHECK_PASSED(); + + return; + +} /* test_selection_io_real() */ + +/* + * These tests for selection I/O are derived from test_selection_io() in + * test/vfd.c and modified for parallel testing. + */ +static void +test_selection_io(int mpi_rank, int mpi_size) +{ + H5FD_t *lf = NULL; /* VFD struct ptr */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + char filename[1024]; /* Test file name */ + unsigned flags = 0; /* File access flags */ + + unsigned collective; /* Types of I/O for testing */ + hid_t dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ + hid_t def_dxpl = H5I_INVALID_HID; /* dxpl: independent access */ + hid_t col_xfer_dxpl = H5I_INVALID_HID; /* dxpl: collective access with collective I/O */ + hid_t ind_io_dxpl = H5I_INVALID_HID; /* dxpl: collective access with individual I/O */ + + /* If I use fapl in this call, I got an environment printout */ + h5_fixname(SELECT_FNAME, H5P_DEFAULT, filename, sizeof(filename)); + + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + P_TEST_ERROR; + + if (H5Pset_fapl_mpio(fapl, comm, info) < 0) + P_TEST_ERROR; + + /* Create file */ + flags = H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC; + + if (NULL == (lf = H5FDopen(filename, flags, fapl, HADDR_UNDEF))) + P_TEST_ERROR; + + /* Default dxpl which will be H5FD_MPIO_INDEPENDENT by default */ + def_dxpl = H5Pcreate(H5P_DATASET_XFER); + + /* Set dxpl for collective access which will have H5FD_MPIO_COLLECTIVE_IO as default */ + if ((col_xfer_dxpl = H5Pcopy(def_dxpl)) < 0) + P_TEST_ERROR; + if (H5Pset_dxpl_mpio(col_xfer_dxpl, H5FD_MPIO_COLLECTIVE) < 0) + P_TEST_ERROR; + + /* Set dxpl for H5FD_MPIO_INDIVIDUAL_IO */ + if ((ind_io_dxpl = H5Pcopy(col_xfer_dxpl)) < 0) + P_TEST_ERROR; + if (H5Pset_dxpl_mpio_collective_opt(ind_io_dxpl, H5FD_MPIO_INDIVIDUAL_IO) < 0) + P_TEST_ERROR; + + for (collective = 0; collective < iotypes; collective++) { + // for (collective = 0; collective < 1; collective++) { + if (collective) + dxpl = collective == 1 ? col_xfer_dxpl : ind_io_dxpl; + else + dxpl = def_dxpl; + + if (MAINPROCESS) { + if (collective) { + if (collective == 1) + printf(" Testing with Collective access: collective I/O "); + else + printf(" Testing with Collective_access: Individual I/O "); + } + else + printf(" Testing with Independent access "); + } + + /* Perform the actual tests */ + test_selection_io_real(mpi_rank, mpi_size, lf, dxpl); + } + + /* Close file */ + if (H5FDclose(lf) < 0) + P_TEST_ERROR; + + /* Close the fapl */ + if (H5Pclose(fapl) < 0) + P_TEST_ERROR; + + if (H5Pclose(def_dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(col_xfer_dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(ind_io_dxpl) < 0) + P_TEST_ERROR; + + // if (MAINPROCESS && HDremove(filename) < 0) + // P_TEST_ERROR; + +} /* test_selection_io() */ + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Run parallel VFD tests. + * + * Return: Success: 0 + * + * Failure: 1 + * + *------------------------------------------------------------------------- + */ + +int +main(int argc, char **argv) +{ + +#ifdef H5_HAVE_SUBFILING_VFD + int required = MPI_THREAD_MULTIPLE; + int provided = 0; +#endif + int mpi_size; + int mpi_rank; + int ret; + +#ifdef H5_HAVE_SUBFILING_VFD + if (MPI_SUCCESS != MPI_Init_thread(&argc, &argv, required, &provided)) { + printf(" MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE. Exiting\n"); + goto finish; + } + + if (provided != required) { + printf(" MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE. Exiting\n"); + goto finish; + } +#else + if (MPI_SUCCESS != MPI_Init(&argc, &argv)) { + printf(" MPI_Init failed. Exiting\n"); + goto finish; + } +#endif + + MPI_Comm_size(comm, &mpi_size); + MPI_Comm_rank(comm, &mpi_rank); + + /* Attempt to turn off atexit post processing so that in case errors + * occur during the test and the process is aborted, it will not hang + * in the atexit post processing. If it does, it may try to make MPI + * calls which may not work. + */ + if (H5dont_atexit() < 0) + printf("%d:Failed to turn off atexit processing. Continue.\n", mpi_rank); + + H5open(); + + if (mpi_rank == 0) { + printf("=========================================\n"); + printf("Parallel virtual file driver (VFD) tests\n"); + printf(" mpi_size = %d\n", mpi_size); + printf("=========================================\n"); + } + + MPI_Barrier(comm); + + if (mpi_rank == 0) + printf("\n --- TESTING MPIO VFD: selection I/O --- \n"); + + test_selection_io(mpi_rank, mpi_size); + + if (mpi_rank == 0) + printf("\n --- TESTING MPIO VFD: vector I/O --- \n"); + + if (mpi_size < 2) { + if (mpi_rank == 0) { + printf(" Need at least 2 processes to run tests for vector I/O."); + SKIPPED(); + } + printf("\n"); + goto finish; + } + + test_vector_io(mpi_rank, mpi_size); + finish: /* make sure all processes are finished before final report, cleanup * and exit. */ MPI_Barrier(comm); - if (mpi_rank == 0) { /* only process 0 reports */ - printf("===================================\n"); - if (nerrs > 0) - printf("***vfd tests detected %d failures***\n", nerrs); + /* Gather errors from all processes */ + MPI_Allreduce(&nerrors, &ret, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); + nerrors = ret; + + if (MAINPROCESS) { + printf("\n===================================\n"); + if (nerrors) + printf("***Parallel vfd tests detected %d errors***\n", nerrors); else - printf("vfd tests finished with no failures\n"); + printf("Parallel vfd tests finished with no errors\n"); printf("===================================\n"); } @@ -4337,6 +5992,6 @@ finish: MPI_Finalize(); /* cannot just return (nerrs) because exit code is limited to 1byte */ - return (nerrs > 0); + return (nerrors != 0); } /* main() */ |