summaryrefslogtreecommitdiffstats
path: root/testpar/t_vfd.c
diff options
context:
space:
mode:
authorLarry Knox <lrknox@hdfgroup.org>2023-08-08 16:06:05 (GMT)
committerGitHub <noreply@github.com>2023-08-08 16:06:05 (GMT)
commitf43d301f633b5e2cd9cde160ddb2c13578f9231f (patch)
tree3c05bb6a52a5cb19869721dab02e4931f6e48e39 /testpar/t_vfd.c
parent8ceb226bae916152510387da6f7f9710903882a8 (diff)
downloadhdf5-f43d301f633b5e2cd9cde160ddb2c13578f9231f.zip
hdf5-f43d301f633b5e2cd9cde160ddb2c13578f9231f.tar.gz
hdf5-f43d301f633b5e2cd9cde160ddb2c13578f9231f.tar.bz2
Merge Implementation of the mpio driver with selection I/O. (#3360)
Diffstat (limited to 'testpar/t_vfd.c')
-rw-r--r--testpar/t_vfd.c1805
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() */