summaryrefslogtreecommitdiffstats
path: root/testpar
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
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')
-rw-r--r--testpar/t_coll_chunk.c2
-rw-r--r--testpar/t_dset.c2
-rw-r--r--testpar/t_select_io_dset.c417
-rw-r--r--testpar/t_vfd.c1805
4 files changed, 2139 insertions, 87 deletions
diff --git a/testpar/t_coll_chunk.c b/testpar/t_coll_chunk.c
index fd77988..1ff7a8e 100644
--- a/testpar/t_coll_chunk.c
+++ b/testpar/t_coll_chunk.c
@@ -782,7 +782,7 @@ coll_chunktest(const char *filename, int chunk_factor, int select_factor, int ap
status = H5Pget_selection_io(xfer_plist, &selection_io_mode);
VRFY((status >= 0), "testing property list get succeeded");
- if (facc_type == FACC_MPIO && (selection_io_mode != H5D_SELECTION_IO_MODE_ON)) {
+ if (facc_type == FACC_MPIO && (selection_io_mode == H5D_SELECTION_IO_MODE_OFF)) {
switch (api_option) {
case API_LINK_HARD:
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, &prop_value);
diff --git a/testpar/t_dset.c b/testpar/t_dset.c
index e401cd5..b75b6ae 100644
--- a/testpar/t_dset.c
+++ b/testpar/t_dset.c
@@ -3356,7 +3356,7 @@ actual_io_mode_tests(void)
ret = H5Pclose(dxpl_id);
VRFY((ret >= 0), "H5Pclose succeeded");
- if (selection_io_mode != H5D_SELECTION_IO_MODE_ON) {
+ if (selection_io_mode == H5D_SELECTION_IO_MODE_OFF) {
test_actual_io_mode(TEST_ACTUAL_IO_NO_COLLECTIVE);
/*
diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c
index eb64bfe..daeacf0 100644
--- a/testpar/t_select_io_dset.c
+++ b/testpar/t_select_io_dset.c
@@ -128,6 +128,11 @@ typedef enum {
#define TEST_TCONV_BUF_TOO_SMALL 0x008
#define TEST_IN_PLACE_TCONV 0x010
+/* Definitions used by test_bug_optimized_bufs() and test_bug_api_library() */
+#define DIMS 10000
+#define BIG_X_FACTOR 1048576
+#define BIG_Y_FACTOR 32
+
/*
* Helper routine to set dxpl
* --selection I/O mode
@@ -2960,6 +2965,8 @@ test_multi_dsets_all(int niter, hid_t fid, unsigned chunked, unsigned mwbuf)
const void *wbufs[MULTI_NUM_DSETS];
void *rbufs[MULTI_NUM_DSETS];
+ curr_nerrors = nerrors;
+
/* for n niter to ensure that all randomized dset_types with multi_dset_type_t will be covered */
for (n = 0; n < niter; n++) {
@@ -3434,6 +3441,19 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_
/* Datatype conversion */
if (test_mode & TEST_DATATYPE_CONVERSION) {
+
+ /* With one exception, all will land at H5FD__mpio_read/write_selection().
+ * As the xfer mode is H5FD_MPIO_INDEPENDENT, this will call
+ * H5FD__read/write_from_selection() triggering H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB.
+ */
+ no_selection_io_cause_read_expected |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB;
+
+ /* Exception case: This will turn off selection I/O landing at H5FD__mpio_write() */
+ if ((test_mode & TEST_TCONV_BUF_TOO_SMALL) && !(test_mode & TEST_IN_PLACE_TCONV))
+ no_selection_io_cause_write_expected |= H5D_SEL_IO_TCONV_BUF_TOO_SMALL;
+ else
+ no_selection_io_cause_write_expected |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB;
+
if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0)
P_TEST_ERROR;
tid = H5T_NATIVE_UINT;
@@ -3443,18 +3463,12 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_
if (H5Pset_buffer(dxpl, sizeof(int), NULL, NULL) < 0)
P_TEST_ERROR;
- /* If we're using in-place type conversion sel io will succeed */
if (test_mode & TEST_IN_PLACE_TCONV) {
if (H5Pset_modify_write_buf(dxpl, TRUE) < 0)
P_TEST_ERROR;
}
- else
- no_selection_io_cause_write_expected |= H5D_SEL_IO_TCONV_BUF_TOO_SMALL;
-
/* In-place type conversion for read doesn't require modify_write_buf */
}
-
- /* If the tconv buf is largge enough sel io will succeed */
}
/* Create 1d data space */
@@ -3521,6 +3535,31 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_
static void
test_get_no_selection_io_cause(const char *filename, hid_t fapl)
{
+ hid_t dxpl = H5I_INVALID_HID;
+ H5D_selection_io_mode_t selection_io_mode;
+
+ if (MAINPROCESS) {
+ printf("\n");
+ TESTING("for H5Pget_no_selection_io_cause()");
+ }
+
+ curr_nerrors = nerrors;
+
+ if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0)
+ P_TEST_ERROR;
+ if (H5Pget_selection_io(dxpl, &selection_io_mode) < 0)
+ P_TEST_ERROR;
+ if (H5Pclose(dxpl) < 0)
+ P_TEST_ERROR;
+
+ /* The following tests are based on H5D_SELECTION_IO_MODE_DEFAULT as the
+ * default setting in the library; skip the tests if that is not true */
+ if (selection_io_mode != H5D_SELECTION_IO_MODE_DEFAULT) {
+ if (MAINPROCESS)
+ SKIPPED();
+ return;
+ }
+
test_no_selection_io_cause_mode(filename, fapl, TEST_DISABLE_BY_API);
test_no_selection_io_cause_mode(filename, fapl, TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET);
test_no_selection_io_cause_mode(filename, fapl, TEST_DATATYPE_CONVERSION);
@@ -3533,6 +3572,366 @@ test_get_no_selection_io_cause(const char *filename, hid_t fapl)
return;
} /* test_get_no_selection_io_cause() */
+/*
+ * This bug is exposed when running testpar/t_coll_md.c via testphdf5.
+ *
+ * Optimized bufs (bufs[1] is NULL) is used when passing as a parameter to the mpio driver
+ * for selection I/O. When computing mpi_bufs_base in that routine, it is not accounted
+ * for and therefore causing segmentation fault when running the test.
+ *
+ * Fix:
+ * Check for optimized bufs when computing mpi_bufs_base.
+ */
+static void
+test_bug_optimized_bufs(const char *filename, hid_t fapl)
+{
+ hid_t dxpl = H5I_INVALID_HID;
+ hid_t dcpl = H5I_INVALID_HID;
+ hid_t fid = H5I_INVALID_HID;
+ hid_t did = H5I_INVALID_HID;
+ hid_t fspace_id = H5I_INVALID_HID;
+ hid_t mspace_id = H5I_INVALID_HID;
+ hsize_t dims[1];
+ hsize_t cdims[1];
+ hsize_t start[1];
+ hsize_t stride[1];
+ hsize_t count[1];
+ hsize_t block[1];
+ int *wbuf;
+
+ if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ P_TEST_ERROR;
+
+ if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
+ P_TEST_ERROR;
+
+ dims[0] = (hsize_t)mpi_size * (hsize_t)DIMS;
+
+ fspace_id = H5Screate_simple(1, dims, NULL);
+
+ cdims[0] = (hsize_t)mpi_size;
+
+ if (H5Pset_chunk(dcpl, 1, cdims) < 0)
+ P_TEST_ERROR;
+
+ if ((did = H5Dcreate2(fid, "bug_optimized_bufs", H5T_NATIVE_INT, fspace_id, H5P_DEFAULT, dcpl,
+ H5P_DEFAULT)) < 0)
+ P_TEST_ERROR;
+
+ start[0] = (hsize_t)mpi_rank;
+ stride[0] = (hsize_t)mpi_size;
+ count[0] = DIMS;
+ block[0] = 1;
+
+ if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0)
+ P_TEST_ERROR;
+
+ if ((mspace_id = H5Screate_simple(1, count, NULL)) < 0)
+ P_TEST_ERROR;
+
+ if ((wbuf = calloc(1, count[0] * sizeof(int))) == NULL)
+ P_TEST_ERROR;
+
+ if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0)
+ P_TEST_ERROR;
+
+ /* Enable collection transfer mode */
+ if (H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE) < 0)
+ P_TEST_ERROR;
+
+ /* Enable selection I/O */
+ if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0)
+ P_TEST_ERROR;
+
+ if (H5Dwrite(did, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl, wbuf) < 0)
+ P_TEST_ERROR;
+
+ if (H5Dclose(did) < 0)
+ P_TEST_ERROR;
+
+ if (H5Pclose(dcpl) < 0)
+ P_TEST_ERROR;
+
+ if (H5Pclose(dxpl) < 0)
+ P_TEST_ERROR;
+
+ if (H5Sclose(fspace_id) < 0)
+ P_TEST_ERROR;
+
+ if (H5Sclose(mspace_id) < 0)
+ P_TEST_ERROR;
+
+ if (H5Fclose(fid) < 0)
+ P_TEST_ERROR;
+
+ return;
+
+} /* test_bug_optimized_bufs() */
+
+/*
+ * The bug is exposed when running testpar/t_pread.c.
+ *
+ * The file is created with userblock. Before passing down to the mpio driver for
+ * selection I/O, the parameter offsets[] is added by base_addr (size of the uesrblock).
+ * For the independent case in the mpio driver for selection I/O,
+ * the intermediate routine for the API H5FDread/write_vector_from_selection() is called.
+ * The parameter offsets[] is passed as is to the intermediate routine which will
+ * be added again by base_addr causing incorrect data retrieval.
+ *
+ * Fix:
+ * The parameter offsets[] needs to be adjusted by the base_addr addition before calling
+ * the intermediate routine.
+ */
+static void
+test_bug_base_addr(const char *filename, hid_t fapl)
+{
+ hid_t dxpl = H5I_INVALID_HID;
+ hid_t dxpl_read = H5I_INVALID_HID;
+ hid_t fid = H5I_INVALID_HID;
+ hid_t did = H5I_INVALID_HID;
+ hid_t sid = H5I_INVALID_HID;
+ hid_t fcpl = H5I_INVALID_HID;
+ hsize_t dims[1];
+ hid_t tid = H5T_NATIVE_INT;
+ int wbuf[DSET_SELECT_DIM];
+ int rbuf[DSET_SELECT_DIM];
+ int i;
+
+ /* Create user block */
+ if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
+ P_TEST_ERROR;
+
+ if (H5Pset_userblock(fcpl, 512) < 0)
+ P_TEST_ERROR;
+
+ if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0)
+ P_TEST_ERROR;
+
+ /* Create the file with userblock */
+ if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
+ P_TEST_ERROR;
+
+ /* Create 1d data space */
+ dims[0] = DSET_SELECT_DIM;
+
+ if ((sid = H5Screate_simple(1, dims, NULL)) < 0)
+ P_TEST_ERROR;
+
+ if ((did = H5Dcreate2(fid, "bug_base_addr", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) <
+ 0)
+ P_TEST_ERROR;
+
+ /* Initialize data */
+ for (i = 0; i < DSET_SELECT_DIM; i++)
+ wbuf[i] = i;
+
+ if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0)
+ P_TEST_ERROR;
+
+ /* Enable selection I/O */
+ if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0)
+ P_TEST_ERROR;
+
+ /* Independent by default and with selection I/O ON for reading */
+ if ((dxpl_read = H5Pcopy(dxpl)) < 0)
+ P_TEST_ERROR;
+
+ /* Enable collective and with selection I/O ON for writing */
+ if (H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE) < 0)
+ P_TEST_ERROR;
+
+ if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, dxpl, wbuf) < 0)
+ P_TEST_ERROR;
+
+ if (H5Dread(did, tid, H5S_ALL, H5S_ALL, dxpl_read, rbuf) < 0)
+ P_TEST_ERROR;
+
+ if (H5Dclose(did) < 0)
+ P_TEST_ERROR;
+
+ if (H5Pclose(dxpl) < 0)
+ P_TEST_ERROR;
+
+ if (H5Pclose(dxpl_read) < 0)
+ P_TEST_ERROR;
+
+ if (H5Sclose(sid) < 0)
+ P_TEST_ERROR;
+
+ if (H5Pclose(fcpl) < 0)
+ P_TEST_ERROR;
+
+ if (H5Fclose(fid) < 0)
+ P_TEST_ERROR;
+ return;
+
+} /* test_bug_base_addr() */
+
+/*
+ * This bug is exposed when running testpar/t_2Gio.c with at least 2 processes.
+ *
+ * The root problem is from calling an API function from within the library i.e.
+ * calling H5FDread/write_vector_from_selection() for independent access in the
+ * mpio driver for selection I/O.
+ *
+ * The test scenario is described below with the test writing to a dataset
+ * via H5Dwrite():
+ * --running with 2 processes
+ * --with selection I/O on
+ * --with COLLECTIVE xfer mode
+ *
+ * For process 1:
+ * The library internal calls H5D__write():
+ * --io_info.use_select_io is ON
+ * --io_info.use_select_io is OFF after calling H5D__typeinfo_init_phase2()
+ * due to H5D_SEL_IO_TCONV_BUF_TOO_SMALL
+ * --H5D__mpio_opt_possible() returns 0 so xfer mode is set to
+ * H5FD_MPIO_INDEPENDENT
+ * The library eventually calls H5FD__mpio_write() performing scalar calls for the writes
+ *
+ * For process 0:
+ * The library internal calls H5D__write():
+ * --io_info.use_select_io is ON
+ * --H5D__mpio_opt_possible() returns 0 so xfer mode is set to
+ * H5FD_MPIO_INDEPENDENT
+ * The library eventually calls H5FD__mpio_write_selection():
+ * --since the xfer mode is INDEPENDENT it calls the API
+ * H5FDwrite_vector_from_selection(), which eventually calls
+ * H5FD__mpio_write_vector(). This routine obtains the
+ * xfer mode via API context which returns COLLECTIVE.
+ * Then the test hangs when trying to do MPI_File_set_view().
+ *
+ * Fix:
+ * Create wrapper functions for the API H5FDread/write_vector_from_selection() and
+ * they will be called by H5FD__mpio_read/write_selection() for independent access.
+ *
+ */
+static void
+test_bug_api_library(const char *filename, hid_t fapl)
+{
+ hid_t dxpl = H5I_INVALID_HID;
+ hid_t fid = H5I_INVALID_HID;
+ hid_t did = H5I_INVALID_HID;
+ hid_t sid = H5I_INVALID_HID;
+ hid_t fspace_id = H5I_INVALID_HID;
+ hid_t mspace_id = H5I_INVALID_HID;
+ hsize_t dims[2];
+ hsize_t start[2];
+ hsize_t stride[2];
+ hsize_t count[2];
+ hsize_t block[2];
+ int *wbuf;
+ hsize_t i, j;
+
+ if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ P_TEST_ERROR;
+
+ dims[0] = (hsize_t)BIG_X_FACTOR;
+ dims[1] = (hsize_t)BIG_Y_FACTOR;
+
+ if ((sid = H5Screate_simple(2, dims, NULL)) < 0)
+ P_TEST_ERROR;
+
+ if ((did = H5Dcreate2(fid, "bug_coll_to_ind", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT,
+ H5P_DEFAULT)) < 0)
+ P_TEST_ERROR;
+
+ if ((wbuf = malloc((size_t)dims[0] * (size_t)dims[1] * sizeof(int))) == NULL)
+ P_TEST_ERROR;
+
+ /* Each process takes a slabs of rows. */
+ block[0] = (hsize_t)dims[0] / (hsize_t)mpi_size;
+ block[1] = (hsize_t)dims[1];
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = (hsize_t)mpi_rank * block[0];
+ start[1] = 0;
+
+ if ((fspace_id = H5Dget_space(did)) < 0)
+ P_TEST_ERROR;
+ if (MAINPROCESS) {
+ if (H5Sselect_none(fspace_id) < 0)
+ P_TEST_ERROR;
+ } /* end if */
+ else {
+ if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0)
+ P_TEST_ERROR;
+ } /* end else */
+
+ if ((mspace_id = H5Screate_simple(2, block, NULL)) < 0)
+ P_TEST_ERROR;
+ if (MAINPROCESS) {
+ if (H5Sselect_none(mspace_id) < 0)
+ P_TEST_ERROR;
+ } /* end if */
+
+ if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0)
+ P_TEST_ERROR;
+
+ /* Enable collective transfer */
+ if (H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE) < 0)
+ P_TEST_ERROR;
+
+ /* Enable selection I/O */
+ if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0)
+ P_TEST_ERROR;
+
+ /* Put some trivial data in wbuf */
+ for (i = 0; i < block[0]; i++) {
+ for (j = 0; j < block[1]; j++) {
+ *wbuf = (int)((i + start[0]) * 100 + (j + start[1] + 1));
+ wbuf++;
+ }
+ }
+
+ /* With datatype conversion */
+ if (H5Dwrite(did, H5T_NATIVE_UCHAR, mspace_id, fspace_id, dxpl, wbuf) < 0)
+ P_TEST_ERROR;
+
+ if (H5Dclose(did) < 0)
+ P_TEST_ERROR;
+
+ if (H5Pclose(dxpl) < 0)
+ P_TEST_ERROR;
+
+ if (H5Sclose(fspace_id) < 0)
+ P_TEST_ERROR;
+
+ if (H5Sclose(mspace_id) < 0)
+ P_TEST_ERROR;
+
+ if (H5Fclose(fid) < 0)
+ P_TEST_ERROR;
+
+ return;
+
+} /* test_bug_api_library() */
+
+/*
+ * Verify bugs exposed when H5D_SELECTION_IO_MODE_ON is set as the
+ * default in the library.
+ */
+static void
+test_bugs_select_on(const char *filename, hid_t fapl)
+{
+ if (MAINPROCESS) {
+ printf("\n");
+ TESTING("to verify bugs exposed when H5D_SELECTION_IO_MODE_ON is set as library default");
+ }
+
+ curr_nerrors = nerrors;
+
+ test_bug_optimized_bufs(filename, fapl);
+ test_bug_base_addr(filename, fapl);
+ test_bug_api_library(filename, fapl);
+
+ CHECK_PASSED();
+ return;
+
+} /* test_bugs_select_on() */
+
/*-------------------------------------------------------------------------
* Function: main
*
@@ -3740,12 +4139,10 @@ main(int argc, char *argv[])
if (H5Fclose(fid) < 0)
P_TEST_ERROR;
- if (MAINPROCESS) {
- printf("\n");
- TESTING("Testing for H5Pget_no_selection_io_cause()");
- }
test_get_no_selection_io_cause(FILENAME, fapl);
+ test_bugs_select_on(FILENAME, fapl);
+
/* Barrier to make sure all ranks are done before deleting the file, and
* also to clean up output (make sure PASSED is printed before any of the
* following messages) */
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() */