diff options
author | Neil Fortner <fortnern@gmail.com> | 2023-04-28 23:58:25 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-28 23:58:25 (GMT) |
commit | 3236fb79cedcbe8fed2f421db1ae15f630b5b90f (patch) | |
tree | b4751d6d020d057f4a43f3c89186418cdd1ac0cf /testpar | |
parent | 4497feb5756d76479fb36fef999692c0909f8340 (diff) | |
download | hdf5-3236fb79cedcbe8fed2f421db1ae15f630b5b90f.zip hdf5-3236fb79cedcbe8fed2f421db1ae15f630b5b90f.tar.gz hdf5-3236fb79cedcbe8fed2f421db1ae15f630b5b90f.tar.bz2 |
Implement selection I/O with type conversion (#2823)
Initial implementation of selection I/O with type conversion. Allows
Parallel collective I/O with type conversion, as long as selection I/O
is enabled.
Diffstat (limited to 'testpar')
-rw-r--r-- | testpar/CMakeLists.txt | 2 | ||||
-rw-r--r-- | testpar/Makefile.am | 2 | ||||
-rw-r--r-- | testpar/t_2Gio.c | 77 | ||||
-rw-r--r-- | testpar/t_coll_chunk.c | 9 | ||||
-rw-r--r-- | testpar/t_dset.c | 90 | ||||
-rw-r--r-- | testpar/t_select_io_dset.c | 3786 | ||||
-rw-r--r-- | testpar/t_subfiling_vfd.c | 68 |
7 files changed, 3994 insertions, 40 deletions
diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt index d876a21..fb66e76 100644 --- a/testpar/CMakeLists.txt +++ b/testpar/CMakeLists.txt @@ -8,6 +8,7 @@ project (HDF5_TEST_PAR C) set (testphdf5_SOURCES ${HDF5_TEST_PAR_SOURCE_DIR}/testphdf5.c ${HDF5_TEST_PAR_SOURCE_DIR}/t_dset.c + ${HDF5_TEST_PAR_SOURCE_DIR}/t_select_io_dset.c ${HDF5_TEST_PAR_SOURCE_DIR}/t_file.c ${HDF5_TEST_PAR_SOURCE_DIR}/t_file_image.c ${HDF5_TEST_PAR_SOURCE_DIR}/t_mdset.c @@ -96,6 +97,7 @@ set (H5P_TESTS t_prestart t_init_term t_pmulti_dset + t_select_io_dset t_shapesame t_filters_parallel t_subfiling_vfd diff --git a/testpar/Makefile.am b/testpar/Makefile.am index 539750a..59d47e1 100644 --- a/testpar/Makefile.am +++ b/testpar/Makefile.am @@ -33,7 +33,7 @@ check_SCRIPTS = $(TEST_SCRIPT_PARA) # Test programs. These are our main targets. # -TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pread t_pshutdown t_prestart t_init_term t_pmulti_dset t_shapesame t_filters_parallel t_2Gio t_vfd +TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pread t_pshutdown t_prestart t_init_term t_pmulti_dset t_select_io_dset t_shapesame t_filters_parallel t_2Gio t_vfd if SUBFILING_VFD_CONDITIONAL TEST_PROG_PARA += t_subfiling_vfd diff --git a/testpar/t_2Gio.c b/testpar/t_2Gio.c index d62fb55..8b67dd9 100644 --- a/testpar/t_2Gio.c +++ b/testpar/t_2Gio.c @@ -3868,6 +3868,10 @@ test_no_collective_cause_mode(int selection_mode) uint32_t no_collective_cause_global_expected = 0; // hsize_t coord[NELM][MAX_RANK]; + uint32_t no_selection_io_cause_write = 0; + uint32_t no_selection_io_cause_read = 0; + uint32_t no_selection_io_cause_expected = 0; + const char *filename; const char *test_name; hbool_t is_chunked = 1; @@ -3968,27 +3972,50 @@ test_no_collective_cause_mode(int selection_mode) dataset = H5Dcreate2(fid, "nocolcause", data_type, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); VRFY((dataset >= 0), "H5Dcreate2() dataset succeeded"); + /* Set up the dxpl for the write */ + dxpl_write = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_write >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded"); + /* * Set expected causes and some tweaks based on the type of test */ if (selection_mode & TEST_DATATYPE_CONVERSION) { test_name = "Broken Collective I/O - Datatype Conversion"; - no_collective_cause_local_expected |= H5D_MPIO_DATATYPE_CONVERSION; - no_collective_cause_global_expected |= H5D_MPIO_DATATYPE_CONVERSION; + /* set different sign to trigger type conversion */ data_type = H5T_NATIVE_UINT; + + /* Disable selection I/O since datatype conversion is supported in collective with selection I/O */ + ret = H5Pset_selection_io(dxpl_write, H5D_SELECTION_IO_MODE_OFF); + VRFY((ret >= 0), "H5Pset_selection_io succeeded"); + + no_collective_cause_local_expected |= H5D_MPIO_DATATYPE_CONVERSION | H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected |= H5D_MPIO_DATATYPE_CONVERSION | H5D_MPIO_NO_SELECTION_IO; + no_selection_io_cause_expected |= H5D_SEL_IO_DISABLE_BY_API; } if (selection_mode & TEST_DATA_TRANSFORMS) { test_name = "Broken Collective I/O - DATA Transforms"; - no_collective_cause_local_expected |= H5D_MPIO_DATA_TRANSFORMS; - no_collective_cause_global_expected |= H5D_MPIO_DATA_TRANSFORMS; + + /* Set transform */ + ret = H5Pset_data_transform(dxpl_write, "x+1"); + VRFY((ret >= 0), "H5Pset_data_transform succeeded"); + + /* Disable selection I/O since data transforms are supported in collective with selection I/O */ + ret = H5Pset_selection_io(dxpl_write, H5D_SELECTION_IO_MODE_OFF); + VRFY((ret >= 0), "H5Pset_selection_io succeeded"); + + no_collective_cause_local_expected |= H5D_MPIO_DATA_TRANSFORMS | H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected |= H5D_MPIO_DATA_TRANSFORMS | H5D_MPIO_NO_SELECTION_IO; + no_selection_io_cause_expected |= H5D_SEL_IO_DISABLE_BY_API; } if (selection_mode & TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES) { test_name = "Broken Collective I/O - No Simple or Scalar DataSpace"; no_collective_cause_local_expected |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES; no_collective_cause_global_expected |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES; + no_collective_cause_local_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; } if (selection_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT || @@ -3996,6 +4023,8 @@ test_no_collective_cause_mode(int selection_mode) test_name = "Broken Collective I/O - No CONTI or CHUNKED Dataset"; no_collective_cause_local_expected |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET; no_collective_cause_global_expected |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET; + no_collective_cause_local_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; } if (selection_mode & TEST_COLLECTIVE) { @@ -4008,6 +4037,8 @@ test_no_collective_cause_mode(int selection_mode) test_name = "Broken Collective I/O - Independent"; no_collective_cause_local_expected = H5D_MPIO_SET_INDEPENDENT; no_collective_cause_global_expected = H5D_MPIO_SET_INDEPENDENT; + no_collective_cause_local_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; /* switch to independent io */ is_independent = 1; } @@ -4037,10 +4068,6 @@ test_no_collective_cause_mode(int selection_mode) for (i = 0; i < length; i++) buffer[i] = i; - /* Set up the dxpl for the write */ - dxpl_write = H5Pcreate(H5P_DATASET_XFER); - VRFY((dxpl_write >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded"); - if (is_independent) { /* Set Independent I/O */ ret = H5Pset_dxpl_mpio(dxpl_write, H5FD_MPIO_INDEPENDENT); @@ -4052,11 +4079,6 @@ test_no_collective_cause_mode(int selection_mode) VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded"); } - if (selection_mode & TEST_DATA_TRANSFORMS) { - ret = H5Pset_data_transform(dxpl_write, "x+1"); - VRFY((ret >= 0), "H5Pset_data_transform succeeded"); - } - /*--------------------- * Test Write access *---------------------*/ @@ -4072,6 +4094,20 @@ test_no_collective_cause_mode(int selection_mode) &no_collective_cause_global_write); VRFY((ret >= 0), "retrieving no collective cause succeeded"); + ret = H5Pget_no_selection_io_cause(dxpl_write, &no_selection_io_cause_write); + VRFY((ret >= 0), "retrieving no selection io cause succeeded"); + + if (no_collective_cause_local_write & H5D_MPIO_NO_SELECTION_IO) { + VRFY((no_selection_io_cause_write == no_selection_io_cause_expected), + "H5D_MPIO_NO_SELECTION_IO for write is as expected"); + } + + if (no_collective_cause_global_write & H5D_MPIO_NO_SELECTION_IO) { + + VRFY((no_selection_io_cause_write == no_selection_io_cause_expected), + "H5D_MPIO_NO_SELECTION_IO for write is as expected"); + } + /*--------------------- * Test Read access *---------------------*/ @@ -4092,6 +4128,21 @@ test_no_collective_cause_mode(int selection_mode) &no_collective_cause_global_read); VRFY((ret >= 0), "retrieving no collective cause succeeded"); + ret = H5Pget_no_selection_io_cause(dxpl_read, &no_selection_io_cause_read); + VRFY((ret >= 0), "retrieving no selection io cause succeeded"); + + if (no_collective_cause_local_read & H5D_MPIO_NO_SELECTION_IO) { + + VRFY((no_selection_io_cause_read == no_selection_io_cause_expected), + "H5D_MPIO_NO_SELECTION_IO for read is as expected"); + } + + if (no_collective_cause_global_read & H5D_MPIO_NO_SELECTION_IO) { + + VRFY((no_selection_io_cause_read == no_selection_io_cause_expected), + "H5D_MPIO_NO_SELECTION_IO for read is as expected"); + } + /* Check write vs read */ VRFY((no_collective_cause_local_read == no_collective_cause_local_write), "reading and writing are the same for local cause of Broken Collective I/O"); diff --git a/testpar/t_coll_chunk.c b/testpar/t_coll_chunk.c index 5f853e3..6636ffa 100644 --- a/testpar/t_coll_chunk.c +++ b/testpar/t_coll_chunk.c @@ -566,7 +566,8 @@ coll_chunktest(const char *filename, int chunk_factor, int select_factor, int ap hsize_t start[RANK], count[RANK], stride[RANK], block[RANK]; #ifdef H5_HAVE_INSTRUMENTED_LIBRARY - unsigned prop_value; + unsigned prop_value; + H5D_selection_io_mode_t selection_io_mode; #endif /* H5_HAVE_INSTRUMENTED_LIBRARY */ int mpi_size, mpi_rank; @@ -804,7 +805,11 @@ coll_chunktest(const char *filename, int chunk_factor, int select_factor, int ap /* Only check chunk optimization mode if selection I/O is not being used - * selection I/O bypasses this IO mode decision - it's effectively always * multi chunk currently */ - if (facc_type == FACC_MPIO && !H5_use_selection_io_g) { + + 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)) { 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 34c4d97..d144235 100644 --- a/testpar/t_dset.c +++ b/testpar/t_dset.c @@ -3348,13 +3348,27 @@ test_actual_io_mode(int selection_mode) void actual_io_mode_tests(void) { - int mpi_size = -1; + H5D_selection_io_mode_t selection_io_mode; + hid_t dxpl_id = H5I_INVALID_HID; + herr_t ret; + int mpi_size = -1; + int mpi_rank = -1; + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); /* Only run these tests if selection I/O is not being used - selection I/O * bypasses this IO mode decision - it's effectively always multi chunk * currently */ - if (!H5_use_selection_io_g) { + + dxpl_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_id >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded"); + ret = H5Pget_selection_io(dxpl_id, &selection_io_mode); + VRFY((ret >= 0), "retrieving selection io mode succeeded"); + ret = H5Pclose(dxpl_id); + VRFY((ret >= 0), "H5Pclose succeeded"); + + if (selection_io_mode != H5D_SELECTION_IO_MODE_ON) { test_actual_io_mode(TEST_ACTUAL_IO_NO_COLLECTIVE); /* @@ -3438,6 +3452,10 @@ test_no_collective_cause_mode(int selection_mode) uint32_t no_collective_cause_global_read = 0; uint32_t no_collective_cause_global_expected = 0; + uint32_t no_selection_io_cause_write = 0; + uint32_t no_selection_io_cause_read = 0; + uint32_t no_selection_io_cause_expected = 0; + const char *filename; const char *test_name; hbool_t is_chunked = 1; @@ -3538,27 +3556,50 @@ test_no_collective_cause_mode(int selection_mode) dataset = H5Dcreate2(fid, "nocolcause", data_type, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); VRFY((dataset >= 0), "H5Dcreate2() dataset succeeded"); + /* Set up the dxpl for the write */ + dxpl_write = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_write >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded"); + /* * Set expected causes and some tweaks based on the type of test */ if (selection_mode & TEST_DATATYPE_CONVERSION) { test_name = "Broken Collective I/O - Datatype Conversion"; - no_collective_cause_local_expected |= H5D_MPIO_DATATYPE_CONVERSION; - no_collective_cause_global_expected |= H5D_MPIO_DATATYPE_CONVERSION; + /* set different sign to trigger type conversion */ data_type = H5T_NATIVE_UINT; + + /* Disable selection I/O since datatype conversion is supported in collective with selection I/O */ + ret = H5Pset_selection_io(dxpl_write, H5D_SELECTION_IO_MODE_OFF); + VRFY((ret >= 0), "H5Pset_selection_io succeeded"); + + no_collective_cause_local_expected |= H5D_MPIO_DATATYPE_CONVERSION | H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected |= H5D_MPIO_DATATYPE_CONVERSION | H5D_MPIO_NO_SELECTION_IO; + no_selection_io_cause_expected |= H5D_SEL_IO_DISABLE_BY_API; } if (selection_mode & TEST_DATA_TRANSFORMS) { test_name = "Broken Collective I/O - DATA Transforms"; - no_collective_cause_local_expected |= H5D_MPIO_DATA_TRANSFORMS; - no_collective_cause_global_expected |= H5D_MPIO_DATA_TRANSFORMS; + + /* Set transform */ + ret = H5Pset_data_transform(dxpl_write, "x+1"); + VRFY((ret >= 0), "H5Pset_data_transform succeeded"); + + /* Disable selection I/O since data transforms are supported in collective with selection I/O */ + ret = H5Pset_selection_io(dxpl_write, H5D_SELECTION_IO_MODE_OFF); + VRFY((ret >= 0), "H5Pset_selection_io succeeded"); + + no_collective_cause_local_expected |= H5D_MPIO_DATA_TRANSFORMS | H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected |= H5D_MPIO_DATA_TRANSFORMS | H5D_MPIO_NO_SELECTION_IO; + no_selection_io_cause_expected |= H5D_SEL_IO_DISABLE_BY_API; } if (selection_mode & TEST_NOT_SIMPLE_OR_SCALAR_DATASPACES) { test_name = "Broken Collective I/O - No Simple or Scalar DataSpace"; no_collective_cause_local_expected |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES; no_collective_cause_global_expected |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES; + no_collective_cause_local_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; } if (selection_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET_COMPACT || @@ -3566,6 +3607,8 @@ test_no_collective_cause_mode(int selection_mode) test_name = "Broken Collective I/O - No CONTI or CHUNKED Dataset"; no_collective_cause_local_expected |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET; no_collective_cause_global_expected |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET; + no_collective_cause_local_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; } if (selection_mode & TEST_COLLECTIVE) { @@ -3578,6 +3621,8 @@ test_no_collective_cause_mode(int selection_mode) test_name = "Broken Collective I/O - Independent"; no_collective_cause_local_expected = H5D_MPIO_SET_INDEPENDENT; no_collective_cause_global_expected = H5D_MPIO_SET_INDEPENDENT; + no_collective_cause_local_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; + no_collective_cause_global_expected &= ~(unsigned)H5D_MPIO_NO_SELECTION_IO; /* switch to independent io */ is_independent = 1; } @@ -3607,10 +3652,6 @@ test_no_collective_cause_mode(int selection_mode) for (i = 0; i < length; i++) buffer[i] = i; - /* Set up the dxpl for the write */ - dxpl_write = H5Pcreate(H5P_DATASET_XFER); - VRFY((dxpl_write >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded"); - if (is_independent) { /* Set Independent I/O */ ret = H5Pset_dxpl_mpio(dxpl_write, H5FD_MPIO_INDEPENDENT); @@ -3642,6 +3683,20 @@ test_no_collective_cause_mode(int selection_mode) &no_collective_cause_global_write); VRFY((ret >= 0), "retrieving no collective cause succeeded"); + ret = H5Pget_no_selection_io_cause(dxpl_write, &no_selection_io_cause_write); + VRFY((ret >= 0), "retrieving no selection io cause succeeded"); + + if (no_collective_cause_local_write & H5D_MPIO_NO_SELECTION_IO) { + VRFY((no_selection_io_cause_write == no_selection_io_cause_expected), + "H5D_MPIO_NO_SELECTION_IO for write is as expected"); + } + + if (no_collective_cause_global_write & H5D_MPIO_NO_SELECTION_IO) { + + VRFY((no_selection_io_cause_write == no_selection_io_cause_expected), + "H5D_MPIO_NO_SELECTION_IO for write is as expected"); + } + /*--------------------- * Test Read access *---------------------*/ @@ -3662,6 +3717,21 @@ test_no_collective_cause_mode(int selection_mode) &no_collective_cause_global_read); VRFY((ret >= 0), "retrieving no collective cause succeeded"); + ret = H5Pget_no_selection_io_cause(dxpl_read, &no_selection_io_cause_read); + VRFY((ret >= 0), "retrieving no selection io cause succeeded"); + + if (no_collective_cause_local_read & H5D_MPIO_NO_SELECTION_IO) { + + VRFY((no_selection_io_cause_read == no_selection_io_cause_expected), + "H5D_MPIO_NO_SELECTION_IO for read is as expected"); + } + + if (no_collective_cause_global_read & H5D_MPIO_NO_SELECTION_IO) { + + VRFY((no_selection_io_cause_read == no_selection_io_cause_expected), + "H5D_MPIO_NO_SELECTION_IO for read is as expected"); + } + /* Check write vs read */ VRFY((no_collective_cause_local_read == no_collective_cause_local_write), "reading and writing are the same for local cause of Broken Collective I/O"); diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c new file mode 100644 index 0000000..10b29e4 --- /dev/null +++ b/testpar/t_select_io_dset.c @@ -0,0 +1,3786 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * + * Purpose: Test selection I/O + */ + +#include "h5test.h" +#include "testpar.h" + +#define FILENAME "pselect_io.h5" + +/* MPI variables */ +int mpi_size; +int mpi_rank; + +/* Number of errors */ +int nerrors = 0; +int curr_nerrors = 0; + +#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) + +/* + * Test configurations + */ +typedef enum { + TEST_NO_TYPE_CONV, /* no type conversion (null case) */ + TEST_NO_SIZE_CHANGE_NO_BKG, /* no size change, no bkg buffer */ + TEST_LARGER_MEM_NO_BKG, /* larger memory type, no bkg buffer */ + TEST_SMALLER_MEM_NO_BKG, /* smaller memory type, no bkg buffer */ + TEST_CMPD_WITH_BKG, /* compound types with bkg buffer */ + TEST_TYPE_CONV_SEL_EMPTY, /* some processes have null/empty selections and with type conversion */ + TEST_MULTI_CONV_NO_BKG, /* multi dataset test 1 */ + TEST_MULTI_CONV_BKG, /* multi dataset test 2 */ + TEST_MULTI_CONV_SIZE_CHANGE, /* multi dataset test 3 */ + TEST_MULTI_CONV_SEL_EMPTY, /* multi dataset test 4 */ + TEST_MULTI_ALL, /* multi dataset test 5 */ + TEST_SELECT_NTESTS +} test_select_config_t; + +#define DSET_SELECT_DIM 100 +#define DSET_SELECT_CHUNK_DIM 10 + +#define MULTI_NUM_DSETS 3 +#define MULTI_MIN_DSETS 3 +#define DSET_NAME_LEN 64 + +/* Compound type */ +typedef struct s1_t { + int a; + int b; + int c; + int d; +} s1_t; + +/* + * Variation of s1 with: + * --no conversion for 2 member types + * --1 larger mem type, + * --1 smaller mem type + */ +typedef struct s2_t { + int a; + long long b; + int c; + short d; +} s2_t; + +/* Variation of s1: reverse of s1_t */ +typedef struct s3_t { + int d; + int c; + int b; + int a; +} s3_t; + +/* Variations of s1: only 2 members in s1_t */ +typedef struct s4_t { + unsigned int b; + unsigned int d; +} s4_t; + +/* Defines for test_multi_dsets_all() */ +typedef enum { + DSET_WITH_NO_CONV, /* Dataset with no type conversion */ + DSET_WITH_CONV_AND_NO_BKG, /* Dataset with type conversion but no background buffer */ + DSET_WITH_CONV_AND_BKG, /* Dataset with type conversion and background buffer */ + DSET_NTTYPES +} multi_dset_type_t; + +/* Test setting A and B */ +#define SETTING_A 1 +#define SETTING_B 2 + +/* Definitions of the test modes for test_get_no_selection_io_cause() */ +#define TEST_DISABLE_BY_API 0x001 +#define TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET 0x002 +#define TEST_DATATYPE_CONVERSION 0x004 +#define TEST_TCONV_BUF_TOO_SMALL 0x008 +#define TEST_IN_PLACE_TCONV 0x010 + +/* + * Helper routine to set dxpl + * --selection I/O mode + * --type of I/O + * --type of collective I/O + */ +static void +set_dxpl(hid_t dxpl, H5D_selection_io_mode_t select_io_mode, H5FD_mpio_xfer_t mpio_type, + H5FD_mpio_collective_opt_t mpio_coll_opt, unsigned mwbuf) +{ + if (H5Pset_selection_io(dxpl, select_io_mode) < 0) + P_TEST_ERROR; + + if (H5Pset_dxpl_mpio(dxpl, mpio_type) < 0) + P_TEST_ERROR; + + if (H5Pset_dxpl_mpio_collective_opt(dxpl, mpio_coll_opt) < 0) + P_TEST_ERROR; + + if (mwbuf) + if (H5Pset_modify_write_buf(dxpl, TRUE) < 0) + P_TEST_ERROR; + +} /* set_dxpl() */ + +/* + * Helper routine to check actual I/O mode on a dxpl + */ +static void +check_io_mode(hid_t dxpl, unsigned chunked) +{ + H5D_mpio_actual_io_mode_t actual_io_mode = H5D_MPIO_NO_COLLECTIVE; + + if (H5Pget_mpio_actual_io_mode(dxpl, &actual_io_mode) < 0) + P_TEST_ERROR; + + if (chunked) { + if (actual_io_mode != H5D_MPIO_CHUNK_COLLECTIVE) { + nerrors++; + if (MAINPROCESS) + HDprintf("\n Failed: Incorrect I/O mode (expected chunked, returned %u)", + (unsigned)actual_io_mode); + } + } + else if (actual_io_mode != H5D_MPIO_CONTIGUOUS_COLLECTIVE) { + nerrors++; + if (MAINPROCESS) + HDprintf("\n Failed: Incorrect I/O mode (expected contiguous, returned %u)", + (unsigned)actual_io_mode); + } + +} /* check_io_mode() */ + +/* + * Case 1: single dataset read/write, no type conversion (null case) + */ +static void +test_no_type_conv(hid_t fid, unsigned chunked, unsigned dtrans, unsigned mwbuf) +{ + int i; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t ntrans_dxpl = 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], stride[1], count[1], block[1]; + int wbuf[DSET_SELECT_DIM]; + int wbuf_bak[DSET_SELECT_DIM]; + int trans_wbuf[DSET_SELECT_DIM]; + int rbuf[DSET_SELECT_DIM]; + char dset_name[DSET_NAME_LEN]; + const char *expr = "2*x"; + + curr_nerrors = nerrors; + + /* Create 1d data space */ + dims[0] = DSET_SELECT_DIM; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Generate dataset name */ + HDsnprintf(dset_name, sizeof(dset_name), "no_tconv_%s_%s_%s", chunked ? "chunked" : "contig", + dtrans ? "xform" : "noxform", mwbuf ? "mwbuf" : "nomwbuf"); + + /* Create dataset */ + if ((did = H5Dcreate2(fid, dset_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + /* Initialize data */ + for (i = 0; i < (int)block[0]; i++) { + wbuf[i] = i + (int)start[0]; + trans_wbuf[i] = 2 * wbuf[i]; + } + + /* Create a memory dataspace */ + if ((mspace_id = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + /* Create a file dataspace */ + if ((fspace_id = H5Dget_space(did)) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + if ((ntrans_dxpl = H5Pcopy(dxpl)) < 0) + P_TEST_ERROR; + + /* Set data transform */ + if (dtrans) + if (H5Pset_data_transform(dxpl, expr) < 0) + P_TEST_ERROR; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(wbuf_bak, wbuf, sizeof(wbuf)); + + /* Write data to the dataset with/without data transform */ + if (H5Dwrite(did, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl, wbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(wbuf, wbuf_bak, sizeof(wbuf)); + + check_io_mode(dxpl, chunked); + + /* Read data from the dataset (if dtrans, without data transform set in dxpl) */ + if (H5Dread(did, H5T_NATIVE_INT, mspace_id, fspace_id, ntrans_dxpl, rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read (if dtrans, verify data is transformed) */ + for (i = 0; i < (int)block[0]; i++) + if (rbuf[i] != (dtrans ? trans_wbuf[i] : wbuf[i])) { + nerrors++; + HDprintf("\n Error in first data verification:\n"); + HDprintf(" At index %d: %d, %d\n", i + (int)start[0], dtrans ? trans_wbuf[i] : wbuf[i], + rbuf[i]); + break; + } + + if (dtrans) { + + /* Read the data from the dataset with data transform set in dxpl */ + if (H5Dread(did, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl, rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read is transformed a second time */ + for (i = 0; i < (int)block[0]; i++) + if (rbuf[i] != (2 * trans_wbuf[i])) { + nerrors++; + HDprintf("\n Error in second data verification:.\n"); + HDprintf(" At index %d: %d, %d\n", i + (int)start[0], 2 * trans_wbuf[i], rbuf[i]); + break; + } + } + + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + + if (H5Sclose(sid) < 0) + P_TEST_ERROR; + if (H5Dclose(did) < 0) + P_TEST_ERROR; + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(ntrans_dxpl) < 0) + P_TEST_ERROR; + + CHECK_PASSED(); + + return; +} /* test_no_type_conv() */ + +/* + * Case 2: single dataset read/write, no size change, no background buffer + */ +static void +test_no_size_change_no_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) +{ + int i; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = 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], stride[1], count[1], block[1]; + char *wbuf = NULL; + char *wbuf_bak = NULL; + char *rbuf = NULL; + char dset_name[DSET_NAME_LEN]; + + curr_nerrors = nerrors; + + if ((wbuf = (char *)HDmalloc((size_t)(4 * DSET_SELECT_DIM))) == NULL) + P_TEST_ERROR; + if (mwbuf && (wbuf_bak = (char *)HDmalloc((size_t)(4 * DSET_SELECT_DIM))) == NULL) + P_TEST_ERROR; + if ((rbuf = (char *)HDmalloc((size_t)(4 * DSET_SELECT_DIM))) == NULL) + P_TEST_ERROR; + + /* Create 1d data space */ + dims[0] = DSET_SELECT_DIM; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Generate dataset name */ + HDsnprintf(dset_name, sizeof(dset_name), "no_size_change_%s_%s", chunked ? "chunked" : "contig", + mwbuf ? "mwbuf" : "nomwbuf"); + + /* Create 1d dataset */ + if ((did = H5Dcreate2(fid, dset_name, H5T_STD_I32BE, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + /* Initialize data */ + for (i = 0; i < (int)block[0]; i++) { + wbuf[i * 4 + 3] = 0x1; + wbuf[i * 4 + 2] = 0x2; + wbuf[i * 4 + 1] = 0x3; + wbuf[i * 4 + 0] = 0x4; + } + + /* Create a memory dataspace independently */ + if ((mspace_id = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + /* Create a file dataspace independently */ + if ((fspace_id = H5Dget_space(did)) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(wbuf_bak, wbuf, (size_t)(4 * DSET_SELECT_DIM)); + + /* Write the data to the dataset with little endian */ + if (H5Dwrite(did, H5T_STD_I32LE, mspace_id, fspace_id, dxpl, wbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(wbuf, wbuf_bak, (size_t)(4 * DSET_SELECT_DIM)); + + check_io_mode(dxpl, chunked); + + /* Read the data from the dataset with little endian */ + if (H5Dread(did, H5T_STD_I32LE, mspace_id, fspace_id, dxpl, rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read */ + for (i = 0; i < (int)block[0]; i++) { + if (rbuf[4 * i + 0] != wbuf[4 * i + 0] || rbuf[4 * i + 1] != wbuf[4 * i + 1] || + rbuf[4 * i + 2] != wbuf[4 * i + 2] || rbuf[4 * i + 3] != wbuf[4 * i + 3]) { + nerrors++; + HDprintf("\n Error in data verification:\n"); + HDprintf("\n Error in data verification at index %d\n", i + (int)start[0]); + break; + } + } + + /* Read the data from the dataset with big endian */ + if (H5Dread(did, H5T_STD_I32BE, mspace_id, fspace_id, dxpl, rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read */ + for (i = 0; i < (int)block[0]; i++) { + if (rbuf[4 * i + 0] != wbuf[4 * i + 3] || rbuf[4 * i + 1] != wbuf[4 * i + 2] || + rbuf[4 * i + 2] != wbuf[4 * i + 1] || rbuf[4 * i + 3] != wbuf[4 * i + 0]) { + nerrors++; + HDprintf("\n Error in data verification at index %d\n", i + (int)start[0]); + break; + } + } + + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + + if (H5Sclose(sid) < 0) + P_TEST_ERROR; + if (H5Dclose(did) < 0) + P_TEST_ERROR; + + if (wbuf) + HDfree(wbuf); + + if (wbuf_bak) + HDfree(wbuf_bak); + + if (rbuf) + HDfree(rbuf); + + CHECK_PASSED(); + + return; +} /* test_no_size_change_no_bkg() */ + +/* + * Case 3: single dataset read/write, larger mem type, no background buffer + */ +static void +test_larger_mem_type_no_bkg(hid_t fid, unsigned chunked, unsigned dtrans, unsigned mwbuf) +{ + int i; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t ntrans_dxpl = 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], stride[1], count[1], block[1]; + long wbuf[DSET_SELECT_DIM]; + long wbuf_bak[DSET_SELECT_DIM]; + long trans_wbuf[DSET_SELECT_DIM]; + long long rbuf[DSET_SELECT_DIM]; + char dset_name[DSET_NAME_LEN]; + const char *expr = "100 - x"; + + curr_nerrors = nerrors; + + /* Create 1d data space */ + dims[0] = DSET_SELECT_DIM; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Generate dataset name */ + HDsnprintf(dset_name, sizeof(dset_name), "larger_no_bkg_%s_%s_%s", chunked ? "chunked" : "contig", + dtrans ? "xform" : "noxform", mwbuf ? "mwbuf" : "nomwbuf"); + + /* Create 1d chunked dataset with/without data transform */ + if ((did = H5Dcreate2(fid, dset_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + /* Initialize data */ + for (i = 0; i < (int)block[0]; i++) { + wbuf[i] = i + (int)start[0]; + trans_wbuf[i] = 100 - wbuf[i]; + } + + /* Create a memory dataspace */ + if ((mspace_id = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + /* Create a file dataspace */ + if ((fspace_id = H5Dget_space(did)) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + if ((ntrans_dxpl = H5Pcopy(dxpl)) < 0) + P_TEST_ERROR; + + /* Set data transform */ + if (dtrans) + if (H5Pset_data_transform(dxpl, expr) < 0) + P_TEST_ERROR; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(wbuf_bak, wbuf, sizeof(wbuf)); + + /* Write data to the dataset with/without data transform set in dxpl */ + if (H5Dwrite(did, H5T_NATIVE_LONG, mspace_id, fspace_id, dxpl, wbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(wbuf, wbuf_bak, sizeof(wbuf)); + + check_io_mode(dxpl, chunked); + + /* Read data from the dataset (if dtrans, without data transform set in dxpl) */ + if (H5Dread(did, H5T_NATIVE_LLONG, mspace_id, fspace_id, ntrans_dxpl, rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read (if dtrans, verify data is transformed) */ + for (i = 0; i < (int)block[0]; i++) + if (rbuf[i] != (long long)(dtrans ? trans_wbuf[i] : wbuf[i])) { + nerrors++; + HDprintf("\n Error in first data verification:\n"); + HDprintf(" At index %d: %lld, %lld\n", i + (int)start[0], + (long long)(dtrans ? trans_wbuf[i] : wbuf[i]), rbuf[i]); + break; + } + + if (dtrans) { + + /* Read data from the dataset with data transform set in dxpl */ + if (H5Dread(did, H5T_NATIVE_LLONG, mspace_id, fspace_id, dxpl, rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read is transformed a second time */ + for (i = 0; i < (int)block[0]; i++) + if (rbuf[i] != (long long)(100 - trans_wbuf[i])) { + nerrors++; + HDprintf("\n Error in second data verification:.\n"); + HDprintf(" At index %d: %lld, %lld\n", i + (int)start[0], + (long long)(100 - trans_wbuf[i]), rbuf[i]); + break; + } + } + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + if (H5Sclose(sid) < 0) + P_TEST_ERROR; + if (H5Dclose(did) < 0) + P_TEST_ERROR; + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(ntrans_dxpl) < 0) + P_TEST_ERROR; + + CHECK_PASSED(); + + return; + +} /* test_larger_mem_type_no_bkg() */ + +/* + * Case 4: single dataset reader/write, smaller mem type, no background buffer + */ +static void +test_smaller_mem_type_no_bkg(hid_t fid, unsigned chunked, unsigned dtrans, unsigned mwbuf) +{ + int i; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t ntrans_dxpl = 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], stride[1], count[1], block[1]; + short wbuf[DSET_SELECT_DIM]; + int wbuf_bak[DSET_SELECT_DIM]; + short trans_wbuf[DSET_SELECT_DIM]; + short rbuf[DSET_SELECT_DIM]; + char dset_name[DSET_NAME_LEN]; + const char *expr = "2 * (10 + x)"; + + curr_nerrors = nerrors; + + /* Create 1d data space */ + dims[0] = DSET_SELECT_DIM; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Generate dataset name */ + HDsnprintf(dset_name, sizeof(dset_name), "smaller_no_bkg_%s_%s_%s", chunked ? "chunked" : "contig", + dtrans ? "xform" : "noxform", mwbuf ? "mwbuf" : "nomwbuf"); + + /* Create 1d chunked dataset with/without data transform */ + if ((did = H5Dcreate2(fid, dset_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + /* Initialize data */ + for (i = 0; i < (int)block[0]; i++) { + wbuf[i] = (short)(i + (int)start[0]); + trans_wbuf[i] = (short)(2 * (10 + wbuf[i])); + } + + /* Create a memory dataspace */ + if ((mspace_id = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + /* Create a file dataspace */ + if ((fspace_id = H5Dget_space(did)) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + if ((ntrans_dxpl = H5Pcopy(dxpl)) < 0) + P_TEST_ERROR; + + /* Set data transform */ + if (dtrans) { + if (H5Pset_data_transform(dxpl, expr) < 0) + P_TEST_ERROR; + } + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(wbuf_bak, wbuf, sizeof(wbuf)); + + /* Write data to the dataset with/without data transform in dxpl */ + if (H5Dwrite(did, H5T_NATIVE_SHORT, mspace_id, fspace_id, dxpl, wbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(wbuf, wbuf_bak, sizeof(wbuf)); + + check_io_mode(dxpl, chunked); + + /* Read data from the dataset (if dtrans, without data transform set in dxpl) */ + if (H5Dread(did, H5T_NATIVE_SHORT, mspace_id, fspace_id, ntrans_dxpl, rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read (if dtrans, verify data is transformed) */ + for (i = 0; i < (int)block[0]; i++) + if (rbuf[i] != (dtrans ? trans_wbuf[i] : wbuf[i])) { + nerrors++; + HDprintf("\n Error in first data verification:\n"); + HDprintf(" At index %d: %d, %d\n", i + (int)start[0], wbuf[i], rbuf[i]); + break; + } + + if (dtrans) { + + /* Read data from the dataset with data transform set in dxpl */ + if (H5Dread(did, H5T_NATIVE_SHORT, mspace_id, fspace_id, dxpl, rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read is transformed a second time */ + for (i = 0; i < (int)block[0]; i++) + if (rbuf[i] != (2 * (10 + trans_wbuf[i]))) { + nerrors++; + HDprintf("\n Error in second data verification:.\n"); + HDprintf(" At index %d: %d, %d\n", i + (int)start[0], (2 * (10 - trans_wbuf[i])), + rbuf[i]); + break; + } + } + + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + + if (H5Sclose(sid) < 0) + P_TEST_ERROR; + if (H5Dclose(did) < 0) + P_TEST_ERROR; + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(ntrans_dxpl) < 0) + P_TEST_ERROR; + + CHECK_PASSED(); + + return; + +} /* test_smaller_mem_type_no_bkg() */ + +/* + * Case 5: single dataset reade/write, compound types with background buffer + * + * (a) Initialize compound buffer in memory with unique values + * Write all compound fields to disk + * Verify values read + * (b) Update all fields of the compound type in memory write buffer with new unique values + * Write some but not all all compound fields to disk + * Read the entire compound type + * Verify the fields have the correct (old or new) values + * (c) Update all fields of the compound type in memory read buffer with new unique values + * Read some but not all the compound fields to memory + * Verify the fields have the correct (old, middle or new) values + * (d) Set up a different compound type which has: + * --no conversion for member types + * --a field with larger mem type + * --a field with smaller mem type + * Write this compound type to disk + * Read the entire compound type + * Verify the values read + */ +static void +test_cmpd_with_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) +{ + int i; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t s1_tid = H5I_INVALID_HID; + hid_t s2_tid = H5I_INVALID_HID; + hid_t ss_ac_tid = H5I_INVALID_HID; + hid_t ss_bc_tid = 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], stride[1], count[1], block[1]; + s1_t *s1_wbuf = NULL; + s1_t *s1_wbuf_bak = NULL; + s1_t *s1_rbuf = NULL; + s2_t *s2_wbuf = NULL; + s2_t *s2_wbuf_bak = NULL; + s2_t *s2_rbuf = NULL; + char dset_name[DSET_NAME_LEN]; + + curr_nerrors = nerrors; + + /* Allocate buffers for datasets */ + if (NULL == (s1_wbuf = (s1_t *)HDmalloc(sizeof(s1_t) * DSET_SELECT_DIM))) + P_TEST_ERROR; + if (mwbuf && NULL == (s1_wbuf_bak = (s1_t *)HDmalloc(sizeof(s1_t) * DSET_SELECT_DIM))) + P_TEST_ERROR; + if (NULL == (s1_rbuf = (s1_t *)HDmalloc(sizeof(s1_t) * DSET_SELECT_DIM))) + P_TEST_ERROR; + if (NULL == (s2_wbuf = (s2_t *)HDmalloc(sizeof(s2_t) * DSET_SELECT_DIM))) + P_TEST_ERROR; + if (mwbuf && NULL == (s2_wbuf_bak = (s2_t *)HDmalloc(sizeof(s2_t) * DSET_SELECT_DIM))) + P_TEST_ERROR; + if (NULL == (s2_rbuf = (s2_t *)HDmalloc(sizeof(s2_t) * DSET_SELECT_DIM))) + P_TEST_ERROR; + + /* Create the memory data type */ + if ((s1_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t))) < 0) + P_TEST_ERROR; + + if (H5Tinsert(s1_tid, "a", HOFFSET(s1_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "b", HOFFSET(s1_t, b), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "c", HOFFSET(s1_t, c), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "d", HOFFSET(s1_t, d), H5T_NATIVE_INT) < 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 ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Case 5(a) */ + + /* Generate dataset name */ + HDsnprintf(dset_name, sizeof(dset_name), "cmpd_with_bkg_%s_%s", chunked ? "chunked" : "contig", + mwbuf ? "mwbuf" : "nomwbuf"); + + /* Create 1d dataset */ + if ((did = H5Dcreate2(fid, dset_name, s1_tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + /* Initialize data */ + for (i = 0; i < (int)block[0]; i++) { + s1_wbuf[i].a = 4 * (i + (int)start[0]); + s1_wbuf[i].b = 4 * (i + (int)start[0]) + 1; + s1_wbuf[i].c = 4 * (i + (int)start[0]) + 2; + s1_wbuf[i].d = 4 * (i + (int)start[0]) + 3; + } + + /* Create a memory dataspace */ + if ((mspace_id = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + /* Create a file dataspace */ + if ((fspace_id = H5Dget_space(did)) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(s1_wbuf_bak, s1_wbuf, sizeof(s1_t) * DSET_SELECT_DIM); + + /* Write all the data to the dataset */ + if (H5Dwrite(did, s1_tid, mspace_id, fspace_id, dxpl, s1_wbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(s1_wbuf, s1_wbuf_bak, sizeof(s1_t) * DSET_SELECT_DIM); + + check_io_mode(dxpl, chunked); + + /* Read all the data from the dataset */ + HDmemset(s1_rbuf, 0, sizeof(s1_t) * DSET_SELECT_DIM); + if (H5Dread(did, s1_tid, mspace_id, fspace_id, dxpl, s1_rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read */ + for (i = 0; i < (int)block[0]; i++) + if (s1_wbuf[i].a != s1_rbuf[i].a || s1_wbuf[i].b != s1_rbuf[i].b || s1_wbuf[i].c != s1_rbuf[i].c || + s1_wbuf[i].d != s1_rbuf[i].d) { + nerrors++; + HDprintf("\n Error in 1st data verification:\n"); + HDprintf(" At index %d: %d/%d, %d/%d, %d/%d, %d/%d\n", i + (int)start[0], s1_wbuf[i].a, + s1_rbuf[i].a, s1_wbuf[i].b, s1_rbuf[i].b, s1_wbuf[i].c, s1_rbuf[i].c, s1_wbuf[i].d, + s1_rbuf[i].d); + break; + } + + /* Case 5(b) */ + + /* Update s1_wbuf with unique values */ + for (i = 0; i < (int)block[0]; i++) { + s1_wbuf[i].a = 4 * (i + (int)start[0]) + DSET_SELECT_DIM; + s1_wbuf[i].b = 4 * (i + (int)start[0]) + DSET_SELECT_DIM + 1; + s1_wbuf[i].c = 4 * (i + (int)start[0]) + DSET_SELECT_DIM + 2; + s1_wbuf[i].d = 4 * (i + (int)start[0]) + DSET_SELECT_DIM + 3; + } + + /* Create a compound type same size as s1_t */ + if ((ss_ac_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t))) < 0) + P_TEST_ERROR; + + /* but contains only subset members of s1_t */ + if (H5Tinsert(ss_ac_tid, "a", HOFFSET(s1_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(ss_ac_tid, "c", HOFFSET(s1_t, c), H5T_NATIVE_INT) < 0) + P_TEST_ERROR; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(s1_wbuf_bak, s1_wbuf, sizeof(s1_t) * DSET_SELECT_DIM); + + /* Write s1_wbuf to the dataset but with only subset members in ss_tid */ + if (H5Dwrite(did, ss_ac_tid, mspace_id, fspace_id, dxpl, s1_wbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(s1_wbuf, s1_wbuf_bak, sizeof(s1_t) * DSET_SELECT_DIM); + + /* Read the whole compound back */ + HDmemset(s1_rbuf, 0, sizeof(s1_t) * DSET_SELECT_DIM); + if (H5Dread(did, s1_tid, mspace_id, fspace_id, dxpl, s1_rbuf) < 0) + P_TEST_ERROR; + + /* Verify the compound fields have the correct (old or new) values */ + for (i = 0; i < (int)block[0]; i++) + if (s1_rbuf[i].a != s1_wbuf[i].a || s1_rbuf[i].b != (4 * (i + (int)start[0]) + 1) || + s1_rbuf[i].c != s1_wbuf[i].c || s1_rbuf[i].d != (4 * (i + (int)start[0]) + 3)) { + nerrors++; + HDprintf("\n Error in 2nd data verification:\n"); + HDprintf(" At index %d: %d/%d, %d/%d, %d/%d, %d/%d\n", i + (int)start[0], s1_wbuf[i].a, + s1_rbuf[i].a, (4 * (i + (int)start[0]) + 1), s1_rbuf[i].b, s1_wbuf[i].c, s1_rbuf[i].c, + (4 * (i + (int)start[0]) + 3), s1_rbuf[i].d); + break; + } + + /* Case 5(c) */ + + /* Update s1_rbuf with new unique values */ + for (i = 0; i < (int)block[0]; i++) { + s1_rbuf[i].a = (4 * (i + (int)start[0])) + (2 * DSET_SELECT_DIM); + s1_rbuf[i].b = (4 * (i + (int)start[0])) + (2 * DSET_SELECT_DIM) + 1; + s1_rbuf[i].c = (4 * (i + (int)start[0])) + (2 * DSET_SELECT_DIM) + 2; + s1_rbuf[i].d = (4 * (i + (int)start[0])) + (2 * DSET_SELECT_DIM) + 3; + } + + /* Create a compound type same size as s1_t */ + if ((ss_bc_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t))) < 0) + P_TEST_ERROR; + + /* but contains only subset members of s1_t */ + if (H5Tinsert(ss_bc_tid, "b", HOFFSET(s1_t, b), H5T_NATIVE_INT) < 0 || + H5Tinsert(ss_bc_tid, "c", HOFFSET(s1_t, c), H5T_NATIVE_INT) < 0) + P_TEST_ERROR; + + /* Read the dataset: will read only what is set in ss_bc_tid */ + if (H5Dread(did, ss_bc_tid, mspace_id, fspace_id, dxpl, s1_rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read */ + for (i = 0; i < (int)block[0]; i++) + if (s1_rbuf[i].a != ((4 * (i + (int)start[0])) + (2 * DSET_SELECT_DIM)) || + s1_rbuf[i].b != (4 * (i + (int)start[0]) + 1) || + s1_rbuf[i].c != (4 * (i + (int)start[0]) + DSET_SELECT_DIM + 2) || + s1_rbuf[i].d != ((4 * (i + (int)start[0])) + (2 * DSET_SELECT_DIM) + 3)) { + nerrors++; + HDprintf("\n Error in 3rd data verification:\n"); + HDprintf(" At index %d: %d/%d, %d/%d, %d/%d, %d/%d\n", i + (int)start[0], + ((4 * (i + (int)start[0])) + (2 * DSET_SELECT_DIM)), s1_rbuf[i].a, + (4 * (i + (int)start[0]) + 1), s1_rbuf[i].b, + (4 * (i + (int)start[0]) + DSET_SELECT_DIM + 2), s1_rbuf[i].c, + ((4 * (i + (int)start[0])) + (2 * DSET_SELECT_DIM) + 3), s1_rbuf[i].d); + break; + } + + /* Case 5(d) */ + + /* Create s2_t compound type with: + * --no conversion for 2 member types, + * --1 larger mem type + * --1 smaller mem type + */ + if ((s2_tid = H5Tcreate(H5T_COMPOUND, sizeof(s2_t))) < 0) + P_TEST_ERROR; + + if (H5Tinsert(s2_tid, "a", HOFFSET(s2_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(s2_tid, "b", HOFFSET(s2_t, b), H5T_NATIVE_LLONG) < 0 || + H5Tinsert(s2_tid, "c", HOFFSET(s2_t, c), H5T_NATIVE_INT) < 0 || + H5Tinsert(s2_tid, "d", HOFFSET(s2_t, d), H5T_NATIVE_SHORT) < 0) + P_TEST_ERROR; + + /* Update s2_wbuf with unique values */ + for (i = 0; i < (int)block[0]; i++) { + s2_wbuf[i].a = (8 * (i + (int)start[0])); + s2_wbuf[i].b = (long long)(8 * (i + (int)start[0]) + 1); + s2_wbuf[i].c = (8 * (i + (int)start[0]) + 2); + s2_wbuf[i].d = (short)(8 * (i + (int)start[0]) + 3); + } + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(s2_wbuf_bak, s2_wbuf, sizeof(s2_t) * DSET_SELECT_DIM); + + if (H5Dwrite(did, s2_tid, mspace_id, fspace_id, dxpl, s2_wbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(s2_wbuf, s2_wbuf_bak, sizeof(s2_t) * DSET_SELECT_DIM); + + /* Read it back */ + HDmemset(s2_rbuf, 0, sizeof(s2_t) * DSET_SELECT_DIM); + if (H5Dread(did, s2_tid, mspace_id, fspace_id, dxpl, s2_rbuf) < 0) + P_TEST_ERROR; + + /* Verify data read */ + for (i = 0; i < (int)block[0]; i++) + if (s2_wbuf[i].a != s2_rbuf[i].a || s2_wbuf[i].b != s2_rbuf[i].b || s2_wbuf[i].c != s2_rbuf[i].c || + s2_wbuf[i].d != s2_rbuf[i].d) { + nerrors++; + HDprintf("\n Error in 4th data verification:\n"); + HDprintf(" At index %d: %d/%d, %lld/%lld, %d/%d, %d/%d\n", i + (int)start[0], s2_wbuf[i].a, + s2_rbuf[i].a, s2_wbuf[i].b, s2_rbuf[i].b, s2_wbuf[i].c, s2_rbuf[i].c, s2_wbuf[i].d, + s2_rbuf[i].d); + break; + } + + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + + if (H5Sclose(sid) < 0) + P_TEST_ERROR; + if (H5Tclose(s1_tid) < 0) + P_TEST_ERROR; + if (H5Tclose(s2_tid) < 0) + P_TEST_ERROR; + if (H5Tclose(ss_ac_tid) < 0) + P_TEST_ERROR; + if (H5Tclose(ss_bc_tid) < 0) + P_TEST_ERROR; + if (H5Dclose(did) < 0) + P_TEST_ERROR; + + /* Release buffers */ + HDfree(s1_wbuf); + HDfree(s1_wbuf_bak); + HDfree(s1_rbuf); + HDfree(s2_wbuf); + HDfree(s2_wbuf_bak); + HDfree(s2_rbuf); + + CHECK_PASSED(); + + return; + +} /* test_cmpd_with_bkg() */ + +/* + * Case 6: Type conversions + some processes have null/empty selections in datasets + */ +static void +test_type_conv_sel_empty(hid_t fid, unsigned chunked, unsigned dtrans, unsigned mwbuf) +{ + int i; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t ntrans_dxpl = 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], stride[1], count[1], block[1]; + + long lwbuf[DSET_SELECT_DIM]; + long lwbuf_bak[DSET_SELECT_DIM]; + long trans_lwbuf[DSET_SELECT_DIM]; + long lrbuf[DSET_SELECT_DIM]; + short srbuf[DSET_SELECT_DIM]; + short swbuf[DSET_SELECT_DIM]; + short swbuf_bak[DSET_SELECT_DIM]; + short trans_swbuf[DSET_SELECT_DIM]; + long long llrbuf[DSET_SELECT_DIM]; + char dset_name[DSET_NAME_LEN]; + + const char *expr = "2*x"; + + curr_nerrors = nerrors; + + /* Create 1d data space */ + dims[0] = DSET_SELECT_DIM; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Generate dataset name */ + HDsnprintf(dset_name, sizeof(dset_name), "tconv_sel_empty_%s_%s_%s", chunked ? "chunked" : "contig", + dtrans ? "xform" : "noxform", mwbuf ? "mwbuf" : "nomwbuf"); + + /* Create dataset */ + if ((did = H5Dcreate2(fid, dset_name, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + if ((ntrans_dxpl = H5Pcopy(dxpl)) < 0) + P_TEST_ERROR; + + /* Set data transform */ + if (dtrans) { + if (H5Pset_data_transform(dxpl, expr) < 0) + P_TEST_ERROR; + } + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + /* Initialize data */ + for (i = 0; i < (int)block[0]; i++) { + lwbuf[i] = i + (int)start[0]; + trans_lwbuf[i] = 2 * lwbuf[i]; + } + + /* Case 6(a) process 0: hyperslab; other processes: select none */ + + /* Create a file dataspace */ + if ((fspace_id = H5Dget_space(did)) < 0) + P_TEST_ERROR; + if (MAINPROCESS) { + if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + } + else { + if (H5Sselect_none(fspace_id) < 0) + P_TEST_ERROR; + } + + /* Create a memory dataspace */ + if ((mspace_id = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + if (mpi_rank) { + if (H5Sselect_none(mspace_id) < 0) + P_TEST_ERROR; + } + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(lwbuf_bak, lwbuf, sizeof(lwbuf)); + + /* Write data to the dataset with/without data transform in dxpl */ + if (H5Dwrite(did, H5T_NATIVE_LONG, mspace_id, fspace_id, dxpl, lwbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(lwbuf, lwbuf_bak, sizeof(lwbuf)); + + check_io_mode(dxpl, chunked); + + /* Read the data from the dataset: type conversion int-->long */ + /* If dtrans, without data transform set in dxpl */ + if (H5Dread(did, H5T_NATIVE_LONG, mspace_id, fspace_id, ntrans_dxpl, lrbuf) < 0) + P_TEST_ERROR; + + if (MAINPROCESS) { + for (i = 0; i < (int)block[0]; i++) + if (lrbuf[i] != (dtrans ? trans_lwbuf[i] : lwbuf[i])) { + nerrors++; + HDprintf("\n Error in first data verification:\n"); + HDprintf(" At index %d: %ld, %ld\n", i + (int)start[0], + dtrans ? trans_lwbuf[i] : lwbuf[i], lrbuf[i]); + break; + } + } + + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + + /* Case 6(b) process 0: get 0 row; other processes: hyperslab */ + + block[0] = mpi_rank ? (dims[0] / (hsize_t)mpi_size) : 0; + stride[0] = mpi_rank ? block[0] : 1; + count[0] = 1; + start[0] = mpi_rank ? ((hsize_t)mpi_rank * block[0]) : 0; + + /* Create a file dataspace */ + if ((fspace_id = H5Dget_space(did)) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Create a memory dataspace */ + if ((mspace_id = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + /* need to make memory space to match for process 0 */ + if (MAINPROCESS) { + if (H5Sselect_hyperslab(mspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + } + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(lwbuf_bak, lwbuf, sizeof(lwbuf)); + + /* Write data to the dataset with/without data transform */ + if (H5Dwrite(did, H5T_NATIVE_LONG, mspace_id, fspace_id, dxpl, lwbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(lwbuf, lwbuf_bak, sizeof(lwbuf)); + + /* Read the data from the dataset: type conversion int-->short */ + /* If dtrans, without data transform set in dxpl */ + if (H5Dread(did, H5T_NATIVE_SHORT, mspace_id, fspace_id, ntrans_dxpl, srbuf) < 0) + P_TEST_ERROR; + + if (mpi_rank) { + for (i = 0; i < (int)block[0]; i++) + if (srbuf[i] != (short)(dtrans ? trans_lwbuf[i] : lwbuf[i])) { + HDprintf("\n Error in second data verification:\n"); + HDprintf(" At index %d: %d, %d\n", i + (int)start[0], + (short)(dtrans ? trans_lwbuf[i] : lwbuf[i]), srbuf[i]); + break; + } + } + + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + + /* Case 6(c) process 0: select none; other processes: select all */ + + /* Initialize data */ + block[0] = DSET_SELECT_DIM; + for (i = 0; i < (int)block[0]; i++) { + swbuf[i] = (short)(i + DSET_SELECT_DIM); + trans_swbuf[i] = (short)(2 * swbuf[i]); + } + + /* Create a file dataspace */ + if ((fspace_id = H5Dget_space(did)) < 0) + P_TEST_ERROR; + if (MAINPROCESS) { + if (H5Sselect_none(fspace_id) < 0) + P_TEST_ERROR; + } + else { + if (H5Sselect_all(fspace_id) < 0) + P_TEST_ERROR; + } + + /* Create a memory dataspace */ + if ((mspace_id = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + if (MAINPROCESS) { + if (H5Sselect_none(mspace_id) < 0) + P_TEST_ERROR; + } + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(swbuf_bak, swbuf, sizeof(swbuf)); + + /* Write data to the dataset with/without data transform */ + if (H5Dwrite(did, H5T_NATIVE_SHORT, mspace_id, fspace_id, dxpl, swbuf) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(swbuf, swbuf_bak, sizeof(swbuf)); + + /* Read the data from the dataset: type conversion int-->llong */ + /* If dtrans, without data transform set in dxpl */ + if (H5Dread(did, H5T_NATIVE_LLONG, mspace_id, fspace_id, ntrans_dxpl, llrbuf) < 0) + P_TEST_ERROR; + + if (mpi_rank) { + for (i = 0; i < (int)block[0]; i++) + if (llrbuf[i] != (long long)(dtrans ? trans_swbuf[i] : swbuf[i])) { + HDprintf("\n Error in third data verification:\n"); + HDprintf(" At index %d: %lld, %lld\n", i + (int)start[0], + (long long)(dtrans ? trans_swbuf[i] : swbuf[i]), llrbuf[i]); + break; + } + } + + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + + if (H5Sclose(sid) < 0) + P_TEST_ERROR; + if (H5Dclose(did) < 0) + P_TEST_ERROR; + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(ntrans_dxpl) < 0) + P_TEST_ERROR; + + CHECK_PASSED(); + + return; + +} /* test_type_conv_sel_empty() */ + +/* + * Test 1 for multi-dataset: + * --Datasets with/without type conversion+smaller/larger mem type+no background buffer + * + * Create datasets: randomized H5T_NATIVE_INT or H5T_NATIVE_LONG + * + * Case a--setting for multi write/read to ndsets: + * Datatype for all datasets: H5T_NATIVE_INT + * + * Case b--setting for multi write/read to ndsets: + * Datatype for all datasets: H5T_NATIVE_LONG + */ +static void +test_multi_dsets_no_bkg(hid_t fid, unsigned chunked, unsigned dtrans, unsigned mwbuf) +{ + size_t ndsets; + int i, j; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t ntrans_dxpl = H5I_INVALID_HID; + hsize_t dims[1]; + hsize_t cdims[1]; + hsize_t start[1], stride[1], count[1], block[1]; + + hid_t file_sids[MULTI_NUM_DSETS]; + hid_t mem_sids[MULTI_NUM_DSETS]; + hid_t mem_tids[MULTI_NUM_DSETS]; + + char dset_names[MULTI_NUM_DSETS][DSET_NAME_LEN]; + hid_t dset_dids[MULTI_NUM_DSETS]; + + size_t buf_size; + + int *total_wbuf = NULL; + int *total_wbuf_bak = NULL; + int *total_trans_wbuf = NULL; + int *total_rbuf = NULL; + + long *total_lwbuf = NULL; + long *total_lwbuf_bak = NULL; + long *total_trans_lwbuf = NULL; + long *total_lrbuf = NULL; + + int *wbufi[MULTI_NUM_DSETS]; + int *trans_wbufi[MULTI_NUM_DSETS]; + int *rbufi[MULTI_NUM_DSETS]; + + long *lwbufi[MULTI_NUM_DSETS]; + long *trans_lwbufi[MULTI_NUM_DSETS]; + long *lrbufi[MULTI_NUM_DSETS]; + + const void *wbufs[MULTI_NUM_DSETS]; + void *rbufs[MULTI_NUM_DSETS]; + const char *expr = "2*x"; + + curr_nerrors = nerrors; + + ndsets = MAX(MULTI_MIN_DSETS, MULTI_NUM_DSETS); + + dims[0] = DSET_SELECT_DIM; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + if ((ntrans_dxpl = H5Pcopy(dxpl)) < 0) + P_TEST_ERROR; + + /* Set data transform */ + if (dtrans) + if (H5Pset_data_transform(dxpl, expr) < 0) + P_TEST_ERROR; + + /* Set up file space ids and dataset ids */ + for (i = 0; i < (int)ndsets; i++) { + if ((file_sids[i] = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + + /* Generate dataset name */ + HDsnprintf(dset_names[i], sizeof(dset_names[i]), "multi_dset%d_%s_%s_%s", i, + chunked ? "chunked" : "contig", dtrans ? "xform" : "noxform", mwbuf ? "mwbuf" : "nomwbuf"); + + /* Create ith dataset */ + if ((dset_dids[i] = + H5Dcreate2(fid, dset_names[i], ((HDrandom() % 2) ? H5T_NATIVE_LONG : H5T_NATIVE_INT), + file_sids[i], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + } + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + for (i = 0; i < (int)ndsets; i++) { + if ((mem_sids[i] = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(file_sids[i], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + } + + buf_size = ndsets * DSET_SELECT_DIM * sizeof(int); + + /* Allocate buffers for all datasets */ + if (NULL == (total_wbuf = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (mwbuf && NULL == (total_wbuf_bak = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_trans_wbuf = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_rbuf = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + + buf_size = ndsets * DSET_SELECT_DIM * sizeof(long); + + if (NULL == (total_lwbuf = (long *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (mwbuf && NULL == (total_lwbuf_bak = (long *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_trans_lwbuf = (long *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_lrbuf = (long *)HDmalloc(buf_size))) + P_TEST_ERROR; + + /* Initialize buffer indices */ + for (i = 0; i < (int)ndsets; i++) { + wbufi[i] = total_wbuf + (i * DSET_SELECT_DIM); + rbufi[i] = total_rbuf + (i * DSET_SELECT_DIM); + trans_wbufi[i] = total_trans_wbuf + (i * DSET_SELECT_DIM); + + wbufs[i] = wbufi[i]; + rbufs[i] = rbufi[i]; + } + + /* Case a */ + + /* Initialize the buffer data */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) { + wbufi[i][j] = j + (int)start[0]; + trans_wbufi[i][j] = 2 * wbufi[i][j]; + } + + /* Datatype setting for multi write/read */ + for (i = 0; i < (int)ndsets; i++) + mem_tids[i] = H5T_NATIVE_INT; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(total_wbuf_bak, total_wbuf, ndsets * DSET_SELECT_DIM * sizeof(int)); + + /* Write data to the dataset with/without data transform */ + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(total_wbuf, total_wbuf_bak, ndsets * DSET_SELECT_DIM * sizeof(int)); + + check_io_mode(dxpl, chunked); + + /* Read data from the dataset (if dtrans, without data transform set in dxpl) */ + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, ntrans_dxpl, rbufs) < 0) + P_TEST_ERROR; + + /* Verify */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) + if (rbufi[i][j] != (dtrans ? trans_wbufi[i][j] : wbufi[i][j])) { + nerrors++; + HDprintf("\n Error in 1st data verification for dset %d:\n", i); + HDprintf(" At index %d: %d, %d\n", j + (int)start[0], + dtrans ? trans_wbufi[i][j] : wbufi[i][j], rbufi[i][j]); + break; + } + + if (dtrans) { + + /* Read the data from the dataset with data transform set in dxpl */ + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + /* Verify */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) + if (rbufi[i][j] != (2 * trans_wbufi[i][j])) { + nerrors++; + HDprintf("\n Error in 1st (with dtrans) data verification for dset %d:\n", i); + HDprintf(" At index %d: %d, %d\n", j + (int)start[0], 2 * trans_wbufi[i][j], + rbufi[i][j]); + break; + } + } + + /* Case b */ + + /* Initialize buffer indices */ + for (i = 0; i < (int)ndsets; i++) { + lwbufi[i] = total_lwbuf + (i * DSET_SELECT_DIM); + trans_lwbufi[i] = total_trans_lwbuf + (i * DSET_SELECT_DIM); + lrbufi[i] = total_lrbuf + (i * DSET_SELECT_DIM); + wbufs[i] = lwbufi[i]; + rbufs[i] = lrbufi[i]; + } + + /* Initialize the buffer data */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) { + lwbufi[i][j] = j + (int)start[0] + DSET_SELECT_DIM; + trans_lwbufi[i][j] = 2 * lwbufi[i][j]; + } + + /* Datatype setting for multi write/read */ + for (i = 0; i < (int)ndsets; i++) + mem_tids[i] = H5T_NATIVE_LONG; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(total_lwbuf_bak, total_lwbuf, ndsets * DSET_SELECT_DIM * sizeof(long)); + + /* Write data to the dataset with/without data transform */ + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(total_lwbuf, total_lwbuf_bak, ndsets * DSET_SELECT_DIM * sizeof(long)); + + /* Read data from the dataset (if dtrans, with data transform again in dxpl */ + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + for (i = 0; i < (int)ndsets; i++) { + for (j = 0; j < (int)block[0]; j++) { + if (lrbufi[i][j] != (dtrans ? (2 * trans_lwbufi[i][j]) : lwbufi[i][j])) { + nerrors++; + HDprintf("\n Error in 2nd data verification for dset %d:\n", i); + HDprintf(" At index %d: %ld/%ld\n", j + (int)start[0], + (dtrans ? (2 * trans_lwbufi[i][j]) : lwbufi[i][j]), lrbufi[i][j]); + break; + } + } + } + + if (H5Pclose(dcpl) < 0) + P_TEST_ERROR; + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(ntrans_dxpl) < 0) + P_TEST_ERROR; + + for (i = 0; i < (int)ndsets; i++) { + if (H5Sclose(file_sids[i]) < 0) + P_TEST_ERROR; + if (H5Sclose(mem_sids[i]) < 0) + P_TEST_ERROR; + if (H5Dclose(dset_dids[i]) < 0) + P_TEST_ERROR; + } + + HDfree(total_wbuf); + HDfree(total_wbuf_bak); + HDfree(total_rbuf); + HDfree(total_trans_wbuf); + HDfree(total_lwbuf); + HDfree(total_lwbuf_bak); + HDfree(total_trans_lwbuf); + HDfree(total_lrbuf); + + CHECK_PASSED(); + + return; + +} /* test_multi_dsets_no_bkg() */ + +/* + * Test 2 for multi-dataset: + * Datasets with compound types+background buffer + * + * Create datasets with the same compound type + * Case (a) Initialize compound buffer in memory with unique values + * All datasets: + * --Write all compound fields to disk + * --Read the entire compound type for all datasets + * --Verify values read + * Case (b) Update all fields of the compound type in memory write buffer with new unique values + * dset0: + * --Write some but not all all compound fields to disk + * --Read and verify the fields have the correct (old(a) or new) values + * Remaining datasets: + * --Untouched + * --Read and verify the fields have the correct old(a) values + * Case (c) Update all fields of the compound type in memory read buffer with new unique values + * Randomized <mm> dataset: + * --Read some but not all the compound fields to memory + * --Verify the fields have the correct (old(a) or new) values + * dset0: + * --Untouched + * --Read and verify the fields have the correct (old(a) or middle(b)) values + * Remaining datasets: + * --Untouched + * --Read and verify the fields have the correct old(a) values + * Case (d) Set up a different compound type which has: + * --no type conversion for 2 member types + * --a field with larger mem type + * --a field with smaller mem type + * All datasets: + * --Write the compound fields to disk + * --Read the entire compound type + * --Verify values read + */ +static void +test_multi_dsets_cmpd_with_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) +{ + size_t ndsets; + int i, j, mm; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hsize_t dims[1]; + hsize_t cdims[1]; + hsize_t start[1], stride[1], count[1], block[1]; + + hid_t file_sids[MULTI_NUM_DSETS]; + hid_t mem_sids[MULTI_NUM_DSETS]; + hid_t mem_tids[MULTI_NUM_DSETS]; + + hid_t s1_tid = H5I_INVALID_HID; + hid_t ss_ac_tid = H5I_INVALID_HID; + hid_t ss_bc_tid = H5I_INVALID_HID; + hid_t s2_tid = H5I_INVALID_HID; + + char dset_names[MULTI_NUM_DSETS][DSET_NAME_LEN]; + hid_t dset_dids[MULTI_NUM_DSETS]; + + size_t buf_size; + size_t s2_buf_size; + + s1_t *total_wbuf = NULL; + s1_t *total_wbuf_bak = NULL; + s1_t *total_rbuf = NULL; + + s2_t *s2_total_wbuf = NULL; + s2_t *s2_total_wbuf_bak = NULL; + s2_t *s2_total_rbuf = NULL; + + s1_t *wbufi[MULTI_NUM_DSETS]; + s1_t *rbufi[MULTI_NUM_DSETS]; + + s2_t *s2_wbufi[MULTI_NUM_DSETS]; + s2_t *s2_rbufi[MULTI_NUM_DSETS]; + + const void *wbufs[MULTI_NUM_DSETS]; + void *rbufs[MULTI_NUM_DSETS]; + + curr_nerrors = nerrors; + + ndsets = MAX(MULTI_MIN_DSETS, MULTI_NUM_DSETS); + + dims[0] = DSET_SELECT_DIM; + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + /* Create the memory data type */ + if ((s1_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t))) < 0) + P_TEST_ERROR; + + if (H5Tinsert(s1_tid, "a", HOFFSET(s1_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "b", HOFFSET(s1_t, b), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "c", HOFFSET(s1_t, c), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "d", HOFFSET(s1_t, d), H5T_NATIVE_INT) < 0) + P_TEST_ERROR; + + for (i = 0; i < (int)ndsets; i++) { + if ((file_sids[i] = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + if ((mem_sids[i] = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + /* Generate dataset name */ + HDsnprintf(dset_names[i], sizeof(dset_names[i]), "multi_cmpd_dset%d_%s_%s", i, + chunked ? "chunked" : "contig", mwbuf ? "mwbuf" : "nomwbuf"); + + /* Create ith dataset */ + if ((dset_dids[i] = + H5Dcreate2(fid, dset_names[i], s1_tid, file_sids[i], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(file_sids[i], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + } + + buf_size = ndsets * DSET_SELECT_DIM * sizeof(s1_t); + s2_buf_size = ndsets * DSET_SELECT_DIM * sizeof(s2_t); + + /* Allocate buffers for all datasets */ + if (NULL == (total_wbuf = (s1_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (mwbuf && NULL == (total_wbuf_bak = (s1_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_rbuf = (s1_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + + if (NULL == (s2_total_wbuf = (s2_t *)HDmalloc(s2_buf_size))) + P_TEST_ERROR; + if (mwbuf && NULL == (s2_total_wbuf_bak = (s2_t *)HDmalloc(s2_buf_size))) + P_TEST_ERROR; + if (NULL == (s2_total_rbuf = (s2_t *)HDmalloc(s2_buf_size))) + P_TEST_ERROR; + + /* Initialize buffer indices */ + for (i = 0; i < (int)ndsets; i++) { + wbufi[i] = total_wbuf + (i * DSET_SELECT_DIM); + rbufi[i] = total_rbuf + (i * DSET_SELECT_DIM); + + wbufs[i] = wbufi[i]; + rbufs[i] = rbufi[i]; + } + + /* Case a */ + + /* Initialize the buffer data for all the datasets */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) { + wbufi[i][j].a = 4 * (j + (int)start[0]); + wbufi[i][j].b = 4 * (j + (int)start[0]) + 1; + wbufi[i][j].c = 4 * (j + (int)start[0]) + 2; + wbufi[i][j].d = 4 * (j + (int)start[0]) + 3; + } + + /* Datatype setting for multi write */ + for (i = 0; i < (int)ndsets; i++) + mem_tids[i] = s1_tid; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(total_wbuf_bak, total_wbuf, buf_size); + + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(total_wbuf, total_wbuf_bak, buf_size); + + check_io_mode(dxpl, chunked); + + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + /* Verify data read */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) { + if (wbufi[i][j].a != rbufi[i][j].a || wbufi[i][j].b != rbufi[i][j].b || + wbufi[i][j].c != rbufi[i][j].c || wbufi[i][j].d != rbufi[i][j].d) { + nerrors++; + HDprintf("\n Error in 1st data verification for dset %d:\n", i); + HDprintf(" At index %d: %d/%d, %d/%d, %d/%d, %d/%d\n", j + (int)start[0], wbufi[i][j].a, + rbufi[i][j].a, wbufi[i][j].b, rbufi[i][j].b, wbufi[i][j].c, rbufi[i][j].c, + wbufi[i][j].d, rbufi[i][j].d); + + break; + } + } + + /* Case b */ + + /* Update data in wbufi for dset0 with unique values */ + for (j = 0; j < (int)block[0]; j++) { + wbufi[0][j].a = (4 * (j + (int)start[0])) + DSET_SELECT_DIM; + wbufi[0][j].b = (4 * (j + (int)start[0])) + DSET_SELECT_DIM + 1; + wbufi[0][j].c = (4 * (j + (int)start[0])) + DSET_SELECT_DIM + 2; + wbufi[0][j].d = (4 * (j + (int)start[0])) + DSET_SELECT_DIM + 3; + } + + /* Create a compound type same size as s1_t */ + if ((ss_ac_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t))) < 0) + P_TEST_ERROR; + + /* but contains only subset members of s1_t */ + if (H5Tinsert(ss_ac_tid, "a", HOFFSET(s1_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(ss_ac_tid, "c", HOFFSET(s1_t, c), H5T_NATIVE_INT) < 0) + P_TEST_ERROR; + + /* Datatype setting for write to dset0 */ + mem_tids[0] = ss_ac_tid; + + /* Untouched memory and file spaces for other datasets */ + for (i = 0; i < (int)ndsets; i++) { + if (i == 0) + continue; + + if (H5Sselect_none(mem_sids[i]) < 0) + P_TEST_ERROR; + if (H5Sselect_none(file_sids[i]) < 0) + P_TEST_ERROR; + } + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(total_wbuf_bak, total_wbuf, buf_size); + + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(total_wbuf, total_wbuf_bak, buf_size); + + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + /* Verify data read */ + for (i = 0; i < (int)ndsets; i++) + if (i == 0) { /* dset0 */ + for (j = 0; j < (int)block[0]; j++) + if (wbufi[i][j].a != rbufi[i][j].a || (4 * (j + (int)start[0]) + 1) != rbufi[i][j].b || + wbufi[i][j].c != rbufi[i][j].c || (4 * (j + (int)start[0]) + 3) != rbufi[i][j].d) { + nerrors++; + HDprintf("\n Error in 2nd data verification for dset %d:\n", i); + HDprintf(" At index %d: %d/%d, %d/%d, %d/%d, %d/%d\n", j + (int)start[0], + wbufi[i][j].a, rbufi[i][j].a, (4 * (j + (int)start[0]) + 1), rbufi[i][j].b, + wbufi[i][j].c, rbufi[i][j].c, (4 * (j + (int)start[0]) + 3), rbufi[i][j].d); + break; + } + } + else { /* other datasets */ + for (j = 0; j < (int)block[0]; j++) + if ((4 * (j + (int)start[0])) != rbufi[i][j].a || + (4 * (j + (int)start[0]) + 1) != rbufi[i][j].b || + (4 * (j + (int)start[0]) + 2) != rbufi[i][j].c || + (4 * (j + (int)start[0]) + 3) != rbufi[i][j].d) { + nerrors++; + HDprintf("\n Error in 2nd data verification for dset %d:\n", i); + HDprintf(" At index %d: %d/%d, %d/%d, %d/%d, %d/%d\n", j + (int)start[0], + (4 * (j + (int)start[0])), rbufi[i][j].a, (4 * (j + (int)start[0]) + 1), + rbufi[i][j].b, (4 * (j + (int)start[0]) + 2), rbufi[i][j].c, + (4 * (j + (int)start[0]) + 3), rbufi[i][j].d); + break; + } + } + + /* Case c */ + mm = HDrandom() % (int)ndsets; + if (!mm) + mm++; + + /* Update data in rbufi for <mm> dset with new unique values */ + for (j = 0; j < (int)block[0]; j++) { + rbufi[mm][j].a = (4 * (j + (int)start[0])) + (2 * DSET_SELECT_DIM); + rbufi[mm][j].b = (4 * (j + (int)start[0])) + (2 * DSET_SELECT_DIM) + 1; + rbufi[mm][j].c = (4 * (j + (int)start[0])) + (2 * DSET_SELECT_DIM) + 2; + rbufi[mm][j].d = (4 * (j + (int)start[0])) + (2 * DSET_SELECT_DIM) + 3; + } + + /* Create a compound type same size as s1_t */ + if ((ss_bc_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t))) < 0) + P_TEST_ERROR; + + /* but contains only subset members of s1_t */ + if (H5Tinsert(ss_bc_tid, "b", HOFFSET(s1_t, b), H5T_NATIVE_INT) < 0 || + H5Tinsert(ss_bc_tid, "c", HOFFSET(s1_t, c), H5T_NATIVE_INT) < 0) + P_TEST_ERROR; + + /* Reset memory and file spaces for <mm> dset */ + if (H5Sselect_all(mem_sids[mm]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_sids[mm]) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_sids[mm], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Untouched memory and file space for other datasets */ + for (i = 0; i < (int)ndsets; i++) { + if (i == 0 || i == mm) + continue; + if (H5Sselect_none(mem_sids[i]) < 0) + P_TEST_ERROR; + if (H5Sselect_none(file_sids[i]) < 0) + P_TEST_ERROR; + } + + /* Datatype setting for read from <mm> dataset */ + mem_tids[mm] = ss_bc_tid; + + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + /* Verify data read */ + /* dset0 */ + for (j = 0; j < (int)block[0]; j++) + if (wbufi[0][j].a != rbufi[0][j].a || ((4 * (j + (int)start[0])) + 1) != rbufi[0][j].b || + wbufi[0][j].c != rbufi[0][j].c || ((4 * (j + (int)start[0])) + 3) != rbufi[0][j].d) { + nerrors++; + HDprintf("\n Error in 3rd data verification for dset0:\n"); + HDprintf(" At index %d: %d/%d, %d/%d, %d/%d, %d/%d\n", j + (int)start[0], wbufi[0][j].a, + rbufi[0][j].a, (4 * (j + (int)start[0]) + 1), rbufi[0][j].b, wbufi[0][j].c, + rbufi[0][j].c, (4 * (j + (int)start[0]) + 3), rbufi[0][j].d); + break; + } + + /* <mm> dset */ + for (j = 0; j < (int)block[0]; j++) + if (rbufi[mm][j].a != ((4 * (j + (int)start[0])) + (2 * DSET_SELECT_DIM)) || + rbufi[mm][j].b != ((4 * (j + (int)start[0])) + 1) || + rbufi[mm][j].c != ((4 * (j + (int)start[0])) + 2) || + rbufi[mm][j].d != ((4 * (j + (int)start[0])) + (2 * DSET_SELECT_DIM) + 3)) { + nerrors++; + HDprintf("\n Error in 3rd data verification for dset %d:\n", mm); + HDprintf(" At index %d: %d/%d, %d/%d, %d/%d, %d/%d\n", j + (int)start[0], + ((4 * (j + (int)start[0])) + (2 * DSET_SELECT_DIM)), rbufi[mm][j].a, + ((4 * (j + (int)start[0])) + 1), rbufi[mm][j].b, ((4 * (j + (int)start[0])) + 2), + rbufi[mm][j].c, ((4 * (j + (int)start[0])) + (2 * DSET_SELECT_DIM) + 3), rbufi[mm][j].d); + break; + } + + /* other datasets */ + for (i = 0; i < (int)ndsets; i++) { + if (i == 0 || i == mm) + continue; + + for (j = 0; j < (int)block[0]; j++) + if (rbufi[i][j].a != ((4 * (j + (int)start[0]))) || + rbufi[i][j].b != ((4 * (j + (int)start[0])) + 1) || + rbufi[i][j].c != ((4 * (j + (int)start[0])) + 2) || + rbufi[i][j].d != ((4 * (j + (int)start[0])) + 3)) { + nerrors++; + HDprintf("\n Error in 3rd data verification for dset %d:\n", i); + HDprintf(" At index %d: %d/%d, %d/%d, %d/%d, %d/%d\n", j + (int)start[0], + ((4 * (j + (int)start[0]))), rbufi[i][j].a, ((4 * (j + (int)start[0])) + 1), + rbufi[i][j].b, ((4 * (j + (int)start[0])) + 2), rbufi[i][j].c, + ((4 * (j + (int)start[0])) + 3), rbufi[i][j].d); + break; + } + } + + /* Case d */ + + /* Create s2_t compound type with: + * --no conversion for 2 member types, + * --1 larger mem type + * --1 smaller mem type + */ + if ((s2_tid = H5Tcreate(H5T_COMPOUND, sizeof(s2_t))) < 0) + P_TEST_ERROR; + + if (H5Tinsert(s2_tid, "a", HOFFSET(s2_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(s2_tid, "b", HOFFSET(s2_t, b), H5T_NATIVE_LLONG) < 0 || + H5Tinsert(s2_tid, "c", HOFFSET(s2_t, c), H5T_NATIVE_INT) < 0 || + H5Tinsert(s2_tid, "d", HOFFSET(s2_t, d), H5T_NATIVE_SHORT) < 0) + P_TEST_ERROR; + + for (i = 0; i < (int)ndsets; i++) { + s2_wbufi[i] = s2_total_wbuf + (i * DSET_SELECT_DIM); + s2_rbufi[i] = s2_total_rbuf + (i * DSET_SELECT_DIM); + + wbufs[i] = s2_wbufi[i]; + rbufs[i] = s2_rbufi[i]; + + mem_tids[i] = s2_tid; + + if (H5Sselect_all(mem_sids[i]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_sids[i]) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_sids[i], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + } + + /* Initialize the buffer data for all the datasets */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) { + s2_wbufi[i][j].a = 8 * (j + (int)start[0]); + s2_wbufi[i][j].b = (long long)((8 * (j + (int)start[0])) + 1); + s2_wbufi[i][j].c = (8 * (j + (int)start[0])) + 2; + s2_wbufi[i][j].d = (short)((8 * (j + (int)start[0])) + 3); + } + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(s2_total_wbuf_bak, s2_total_wbuf, s2_buf_size); + + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(s2_total_wbuf, s2_total_wbuf_bak, s2_buf_size); + + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + for (i = 0; i < (int)ndsets; i++) { + for (j = 0; j < (int)block[0]; j++) + if (s2_rbufi[i][j].a != s2_wbufi[i][j].a || s2_rbufi[i][j].b != s2_wbufi[i][j].b || + s2_rbufi[i][j].c != s2_wbufi[i][j].c || s2_rbufi[i][j].d != s2_wbufi[i][j].d) { + nerrors++; + HDprintf("\n Error in 3rd data verification for dset %d:\n", i); + HDprintf(" At index %d: %d/%d, %lld/%lld, %d/%d, %d/%d\n", j + (int)start[0], + s2_wbufi[i][j].a, s2_rbufi[i][j].a, s2_wbufi[i][j].b, s2_rbufi[i][j].b, + s2_wbufi[i][j].c, s2_rbufi[i][j].c, s2_wbufi[i][j].d, s2_rbufi[i][j].d); + break; + } + } + + if (H5Pclose(dcpl) < 0) + P_TEST_ERROR; + + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + + for (i = 0; i < (int)ndsets; i++) { + if (H5Sclose(file_sids[i]) < 0) + P_TEST_ERROR; + if (H5Sclose(mem_sids[i]) < 0) + P_TEST_ERROR; + if (H5Dclose(dset_dids[i]) < 0) + P_TEST_ERROR; + } + + HDfree(total_wbuf); + HDfree(total_wbuf_bak); + HDfree(total_rbuf); + HDfree(s2_total_wbuf); + HDfree(s2_total_wbuf_bak); + HDfree(s2_total_rbuf); + + CHECK_PASSED(); + + return; + +} /* test_multi_dsets_cmpd_with_bkg() */ + +/* + * Test 3 for multi-dataset: + * --Datasets with/without type conv+size change+no background buffer + * + * Create dset0: H5T_STD_I32BE + * Create other dateasets: randomized H5T_STD_I64LE or H5T_STD_I16LE + * + * Case a--setting for multi write/read to ndsets: + * Datatype for all datasets: H5T_STD_I32BE + * + * Case b--setting for multi write/read to ndsets + * Datatype for all datasets: H5T_STD_I64BE + * + * Case c--setting for multi write/read to ndsets + * Datatype for all datasets: H5T_STD_I16BE + */ +static void +test_multi_dsets_size_change_no_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) +{ + size_t ndsets; + int i, j; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hsize_t dims[1]; + hsize_t cdims[1]; + hsize_t start[1], stride[1], count[1], block[1]; + + hid_t file_sids[MULTI_NUM_DSETS]; + hid_t mem_sids[MULTI_NUM_DSETS]; + hid_t mem_tids[MULTI_NUM_DSETS]; + + char dset_names[MULTI_NUM_DSETS][DSET_NAME_LEN]; + hid_t dset_dids[MULTI_NUM_DSETS]; + + size_t buf_size, ss; + uint8_t *total_wbuf = NULL; + uint8_t *total_wbuf_bak = NULL; + uint8_t *total_rbuf = NULL; + uint8_t *total_lwbuf = NULL; + uint8_t *total_lwbuf_bak = NULL; + uint8_t *total_lrbuf = NULL; + uint8_t *total_swbuf = NULL; + uint8_t *total_swbuf_bak = NULL; + uint8_t *total_srbuf = NULL; + + uint8_t *wbufi[MULTI_NUM_DSETS]; + uint8_t *rbufi[MULTI_NUM_DSETS]; + uint8_t *lwbufi[MULTI_NUM_DSETS]; + uint8_t *lrbufi[MULTI_NUM_DSETS]; + uint8_t *swbufi[MULTI_NUM_DSETS]; + uint8_t *srbufi[MULTI_NUM_DSETS]; + + const void *wbufs[MULTI_NUM_DSETS]; + void *rbufs[MULTI_NUM_DSETS]; + + curr_nerrors = nerrors; + + ndsets = MAX(MULTI_MIN_DSETS, MULTI_NUM_DSETS); + + dims[0] = DSET_SELECT_DIM; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + /* Set up file space ids, mem space ids, and dataset ids */ + for (i = 0; i < (int)ndsets; i++) { + if ((file_sids[i] = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + + /* Generate dataset name */ + HDsnprintf(dset_names[i], sizeof(dset_names[i]), "multi_size_dset%d_%s_%s", i, + chunked ? "chunked" : "contig", mwbuf ? "mwbuf" : "nomwbuf"); + + /* Create ith dataset */ + if ((dset_dids[i] = H5Dcreate2(fid, dset_names[i], H5T_STD_I32BE, file_sids[i], H5P_DEFAULT, dcpl, + H5P_DEFAULT)) < 0) + P_TEST_ERROR; + } + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + for (i = 0; i < (int)ndsets; i++) { + if ((mem_sids[i] = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(file_sids[i], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + } + + /* Case a */ + + ss = H5Tget_size(H5T_STD_I32BE); + buf_size = ndsets * ss * DSET_SELECT_DIM; + + /* Allocate buffers for all datasets */ + if (NULL == (total_wbuf = (uint8_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_wbuf_bak = (uint8_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_rbuf = (uint8_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + + /* Initialize buffer indices */ + for (i = 0; i < (int)ndsets; i++) { + wbufi[i] = total_wbuf + (i * (int)ss * DSET_SELECT_DIM); + rbufi[i] = total_rbuf + (i * (int)ss * DSET_SELECT_DIM); + + wbufs[i] = wbufi[i]; + rbufs[i] = rbufi[i]; + } + + /* Initialize the buffer data: big endian */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) { + wbufi[i][j * (int)ss + 0] = 0x1; + wbufi[i][j * (int)ss + 1] = 0x2; + wbufi[i][j * (int)ss + 2] = 0x3; + wbufi[i][j * (int)ss + 3] = (uint8_t)(0x4 + j + (int)start[0]); + } + + /* Datatype setting for multi write/read */ + for (i = 0; i < (int)ndsets; i++) + mem_tids[i] = H5T_STD_I32BE; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(total_wbuf_bak, total_wbuf, buf_size); + + /* Write data to the dataset */ + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(total_wbuf, total_wbuf_bak, buf_size); + + check_io_mode(dxpl, chunked); + + /* Read data from the dataset */ + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + /* Verify */ + for (i = 0; i < (int)ndsets; i++) + /* Only compare when it's at least the size of H5T_STD_I32BE */ + if (H5Tget_size(H5Dget_type(dset_dids[i])) >= ss) { + for (j = 0; j < (int)block[0]; j++) + if (rbufi[i][(int)ss * j + 0] != wbufi[i][(int)ss * j + 0] || + rbufi[i][(int)ss * j + 1] != wbufi[i][(int)ss * j + 1] || + rbufi[i][(int)ss * j + 2] != wbufi[i][(int)ss * j + 2] || + rbufi[i][(int)ss * j + 3] != wbufi[i][(int)ss * j + 3]) { + H5_FAILED(); + HDprintf(" Read different values than written.\n"); + HDprintf(" For dset %d at index %d\n", i, j + (int)start[0]); + P_TEST_ERROR; + } + } + + /* Case b */ + + ss = H5Tget_size(H5T_STD_I64BE); + buf_size = ndsets * (ss * DSET_SELECT_DIM); + + /* Allocate buffers for all datasets */ + if (NULL == (total_lwbuf = (uint8_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_lwbuf_bak = (uint8_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_lrbuf = (uint8_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + + /* Initialize buffer indices */ + for (i = 0; i < (int)ndsets; i++) { + lwbufi[i] = total_lwbuf + (i * (int)ss * DSET_SELECT_DIM); + lrbufi[i] = total_lrbuf + (i * (int)ss * DSET_SELECT_DIM); + + wbufs[i] = lwbufi[i]; + rbufs[i] = lrbufi[i]; + } + + /* Initialize the buffer data: big endian */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) { + lwbufi[i][j * (int)ss + 0] = 0x1; + lwbufi[i][j * (int)ss + 1] = 0x2; + lwbufi[i][j * (int)ss + 2] = 0x3; + lwbufi[i][j * (int)ss + 3] = 0x4; + lwbufi[i][j * (int)ss + 4] = 0x5; + lwbufi[i][j * (int)ss + 5] = 0x6; + lwbufi[i][j * (int)ss + 6] = 0x7; + lwbufi[i][j * (int)ss + 7] = (uint8_t)(0x8 + j + (int)start[0]); + } + + /* Datatype setting for multi write/read */ + for (i = 0; i < (int)ndsets; i++) + mem_tids[i] = H5T_STD_I64BE; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(total_lwbuf_bak, total_lwbuf, buf_size); + + /* Write data to the dataset */ + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(total_lwbuf, total_lwbuf_bak, buf_size); + + /* Read data from the dataset */ + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + /* Verify */ + for (i = 0; i < (int)ndsets; i++) + /* Only compare when it's the size of H5T_STD_I64BE */ + if (H5Tget_size(H5Dget_type(dset_dids[i])) >= ss) { + for (j = 0; j < (int)block[0]; j++) + if (lrbufi[i][(int)ss * j + 0] != lwbufi[i][(int)ss * j + 0] || + lrbufi[i][(int)ss * j + 1] != lwbufi[i][(int)ss * j + 1] || + lrbufi[i][(int)ss * j + 2] != lwbufi[i][(int)ss * j + 2] || + lrbufi[i][(int)ss * j + 3] != lwbufi[i][(int)ss * j + 3] || + lrbufi[i][(int)ss * j + 4] != lwbufi[i][(int)ss * j + 4] || + lrbufi[i][(int)ss * j + 5] != lwbufi[i][(int)ss * j + 5] || + lrbufi[i][(int)ss * j + 6] != lwbufi[i][(int)ss * j + 6] || + lrbufi[i][(int)ss * j + 7] != lwbufi[i][(int)ss * j + 7]) { + H5_FAILED(); + HDprintf(" Read different values than written.\n"); + HDprintf(" For dset %d at index %d\n", i, j + (int)start[0]); + P_TEST_ERROR; + } + } + + /* Case c */ + + ss = H5Tget_size(H5T_STD_I16BE); + buf_size = ndsets * (ss * DSET_SELECT_DIM); + + /* Allocate buffers for all datasets */ + if (NULL == (total_swbuf = (uint8_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_swbuf_bak = (uint8_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_srbuf = (uint8_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + + /* Initialize buffer indices */ + for (i = 0; i < (int)ndsets; i++) { + swbufi[i] = total_swbuf + (i * (int)ss * DSET_SELECT_DIM); + srbufi[i] = total_srbuf + (i * (int)ss * DSET_SELECT_DIM); + + wbufs[i] = swbufi[i]; + rbufs[i] = srbufi[i]; + } + + /* Initialize the buffer data: big endian */ + for (i = 0; i < (int)ndsets; i++) + for (j = 0; j < (int)block[0]; j++) { + swbufi[i][j * (int)ss + 0] = 0x1; + swbufi[i][j * (int)ss + 1] = (uint8_t)(0x2 + j + (int)start[0]); + } + + /* Datatype setting for multi write/read */ + for (i = 0; i < (int)ndsets; i++) + mem_tids[i] = H5T_STD_I16BE; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(total_swbuf_bak, total_swbuf, buf_size); + + /* Write data to the dataset */ + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(total_swbuf, total_swbuf_bak, buf_size); + + /* Read data from the dataset */ + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + /* Verify */ + for (i = 0; i < (int)ndsets; i++) + /* Can compare for all cases */ + for (j = 0; j < (int)block[0]; j++) + if (srbufi[i][(int)ss * j + 0] != swbufi[i][(int)ss * j + 0] || + srbufi[i][(int)ss * j + 1] != swbufi[i][(int)ss * j + 1]) { + H5_FAILED(); + HDprintf(" Read different values than written.\n"); + HDprintf(" For dset %d at index %d\n", i, j + (int)start[0]); + P_TEST_ERROR; + } + + if (H5Pclose(dcpl) < 0) + P_TEST_ERROR; + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + + for (i = 0; i < (int)ndsets; i++) { + if (H5Sclose(file_sids[i]) < 0) + P_TEST_ERROR; + if (H5Sclose(mem_sids[i]) < 0) + P_TEST_ERROR; + if (H5Dclose(dset_dids[i]) < 0) + P_TEST_ERROR; + } + + HDfree(total_wbuf); + HDfree(total_wbuf_bak); + HDfree(total_rbuf); + HDfree(total_lwbuf); + HDfree(total_lwbuf_bak); + HDfree(total_lrbuf); + HDfree(total_swbuf); + HDfree(total_swbuf_bak); + HDfree(total_srbuf); + + CHECK_PASSED(); + + return; + +} /* test_multi_dsets_size_change_no_bkg() */ + +/* + * Test 4 for multi-dataset: + * Datasets with type conversions+some processes have null/empty selections + * + * Create dset0: H5T_NATIVE_INT + * Create other datasets: randomized H5T_NATIVE_LLONG or H5T_NATIVE_SHORT + * Type conversions + some processes have null/empty selections in datasets + * + * Case (a): dset0 + * process 0: hyperslab; other processes: select none + * Case (b): randomized dset <mm> + * process 0: get 0 row; other processes: hyperslab + * Case (c): randomized dset <ll> + * process 0: select none; other processes: select all + * + * Memory datatype for multi write to all datasets: H5T_NATIVE_INT + * --this will not trigger type conversion for case (a) but + * type conversion for cases (b) & (c) + * Memory datatype for multi read to all datasets: H5T_NATIVE_LONG + * --this will trigger type conversion for (a), (b) & (c) + */ +static void +test_multi_dsets_conv_sel_empty(hid_t fid, unsigned chunked, unsigned dtrans, unsigned mwbuf) +{ + size_t ndsets; + int i, j; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t ntrans_dxpl = H5I_INVALID_HID; + + hsize_t dims[1]; + hsize_t cdims[1]; + hsize_t start[1], stride[1], count[1], block[1]; + + hid_t file_sids[MULTI_NUM_DSETS]; + hid_t mem_sids[MULTI_NUM_DSETS]; + hid_t mem_tids[MULTI_NUM_DSETS]; + + char dset_names[MULTI_NUM_DSETS][DSET_NAME_LEN]; + hid_t dset_dids[MULTI_NUM_DSETS]; + + size_t buf_size; + int *total_wbuf = NULL; + int *total_wbuf_bak = NULL; + int *total_trans_wbuf = NULL; + long *total_lrbuf = NULL; + + int *wbufi[MULTI_NUM_DSETS]; + int *trans_wbufi[MULTI_NUM_DSETS]; + long *l_rbufi[MULTI_NUM_DSETS]; + + const void *wbufs[MULTI_NUM_DSETS]; + void *rbufs[MULTI_NUM_DSETS]; + + int save_block0; + int mm, ll; + + const char *expr = "2*x"; + + curr_nerrors = nerrors; + + ndsets = MAX(MULTI_MIN_DSETS, MULTI_NUM_DSETS); + + /* Create 1d data space */ + dims[0] = DSET_SELECT_DIM; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + if ((ntrans_dxpl = H5Pcopy(dxpl)) < 0) + P_TEST_ERROR; + + /* Set data transform */ + if (dtrans) + if (H5Pset_data_transform(dxpl, expr) < 0) + P_TEST_ERROR; + + /* Set up file space ids and dataset ids */ + for (i = 0; i < (int)ndsets; i++) { + if ((file_sids[i] = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + + /* Generate dataset name */ + HDsnprintf(dset_names[i], sizeof(dset_names[i]), "multi_sel_dset%d_%s_%s_%s", i, + chunked ? "chunked" : "contig", dtrans ? "xform" : "noxform", mwbuf ? "mwbuf" : "nomwbuf"); + + if (i == 0) { + if ((dset_dids[i] = H5Dcreate2(fid, dset_names[i], H5T_NATIVE_INT, file_sids[i], H5P_DEFAULT, + dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + } + else { + if ((dset_dids[i] = + H5Dcreate2(fid, dset_names[i], ((HDrandom() % 2) ? H5T_NATIVE_LLONG : H5T_NATIVE_SHORT), + file_sids[i], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + } + } + + buf_size = ndsets * DSET_SELECT_DIM * sizeof(int); + + /* Allocate buffers for all datasets */ + if (NULL == (total_wbuf = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_wbuf_bak = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_trans_wbuf = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_lrbuf = (long *)HDmalloc(ndsets * DSET_SELECT_DIM * sizeof(long)))) + P_TEST_ERROR; + + /* Initialize buffer indices */ + for (i = 0; i < (int)ndsets; i++) { + wbufi[i] = total_wbuf + (i * DSET_SELECT_DIM); + trans_wbufi[i] = total_trans_wbuf + (i * DSET_SELECT_DIM); + + wbufs[i] = wbufi[i]; + } + + /* + * Case (a): dset0 + * process 0: hyperslab; other processes: select none + */ + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + save_block0 = (int)block[0]; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + /* Get file dataspace */ + if ((file_sids[0] = H5Dget_space(dset_dids[0])) < 0) + P_TEST_ERROR; + + if (MAINPROCESS) { + if (H5Sselect_hyperslab(file_sids[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + } + else { + if (H5Sselect_none(file_sids[0]) < 0) + P_TEST_ERROR; + } + + /* Create memory dataspace */ + if ((mem_sids[0] = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + if (mpi_rank) { + if (H5Sselect_none(mem_sids[0]) < 0) + P_TEST_ERROR; + } + + /* Initialize data for wbufi[0] */ + for (j = 0; j < (int)block[0]; j++) { + wbufi[0][j] = j + (int)start[0]; + trans_wbufi[0][j] = 2 * wbufi[0][j]; + } + + /* + * Case (b): choose a dataset -- dset <mm> + * process 0: get 0 row; other processes: hyperslab + */ + + mm = HDrandom() % (int)ndsets; + if (mm == 0) + mm++; + + block[0] = mpi_rank ? (dims[0] / (hsize_t)mpi_size) : 0; + stride[0] = mpi_rank ? block[0] : 1; + count[0] = 1; + start[0] = mpi_rank ? ((hsize_t)mpi_rank * block[0]) : 0; + + /* Get file dataspace */ + if ((file_sids[mm] = H5Dget_space(dset_dids[mm])) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(file_sids[mm], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Create a memory dataspace */ + if ((mem_sids[mm] = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + /* need to make memory space to match for process 0 */ + if (MAINPROCESS) { + if (H5Sselect_hyperslab(mem_sids[mm], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + } + else { + if (H5Sselect_all(mem_sids[mm]) < 0) + P_TEST_ERROR; + } + + /* Initialize data for wbufi[1] */ + for (j = 0; j < (int)block[0]; j++) { + wbufi[mm][j] = j + (int)start[0]; + trans_wbufi[mm][j] = 2 * wbufi[mm][j]; + } + + /* + * Case (c): choose a dataset -- dset <ll> + * process 0: select none; other processes: select all + */ + + ll = mm + 1; + if ((ll % (int)ndsets) == 0) + ll = 1; + + /* Get file dataspace */ + if ((file_sids[ll] = H5Dget_space(dset_dids[ll])) < 0) + P_TEST_ERROR; + if (MAINPROCESS) { + if (H5Sselect_none(file_sids[ll]) < 0) + P_TEST_ERROR; + } + else { + if (H5Sselect_all(file_sids[ll]) < 0) + P_TEST_ERROR; + } + + /* Create a memory dataspace */ + if ((mem_sids[ll] = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + if (MAINPROCESS) { + if (H5Sselect_none(mem_sids[ll]) < 0) + P_TEST_ERROR; + } + else if (H5Sselect_all(mem_sids[ll]) < 0) + P_TEST_ERROR; + + /* Initialize data for wbufi[ll] */ + for (j = 0; j < (int)dims[0]; j++) { + wbufi[ll][j] = (int)j + DSET_SELECT_DIM; + trans_wbufi[ll][j] = 2 * wbufi[ll][j]; + } + + /* Set up remaining dsets */ + for (i = 0; i < (int)ndsets; i++) { + if (i == 0 || i == mm || i == ll) + continue; + /* Get file dataspace */ + if ((file_sids[i] = H5Dget_space(dset_dids[i])) < 0) + P_TEST_ERROR; + if (H5Sselect_none(file_sids[i]) < 0) + P_TEST_ERROR; + + if ((mem_sids[i] = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + if (H5Sselect_none(mem_sids[i]) < 0) + P_TEST_ERROR; + } + + /* Set up mem_tids[] for multi write */ + for (i = 0; i < (int)ndsets; i++) + mem_tids[i] = H5T_NATIVE_INT; + + /* Copy wbuf if the library will be modifying it */ + if (mwbuf) + HDmemcpy(total_wbuf_bak, total_wbuf, buf_size); + + /* Write data to the dataset with/without data transform */ + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbuf from backup if the library modified it */ + if (mwbuf) + HDmemcpy(total_wbuf, total_wbuf_bak, buf_size); + + check_io_mode(dxpl, chunked); + + /* Initialize buffer indices */ + for (i = 0; i < (int)ndsets; i++) { + l_rbufi[i] = total_lrbuf + (i * DSET_SELECT_DIM); + rbufs[i] = l_rbufi[i]; + } + + /* Set up mem_tids[] for multi read */ + for (i = 0; i < (int)ndsets; i++) + mem_tids[i] = H5T_NATIVE_LONG; + + if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, ntrans_dxpl, rbufs) < 0) + P_TEST_ERROR; + + if (MAINPROCESS) { + /* Case a: verify dset0 */ + for (j = 0; j < save_block0; j++) + if (l_rbufi[0][j] != (dtrans ? (long)trans_wbufi[0][j] : (long)wbufi[0][j])) { + nerrors++; + HDprintf(" Verify dset0 at index %d: %ld, %ld\n", j + (int)start[0], + dtrans ? (long)trans_wbufi[0][j] : (long)wbufi[0][j], l_rbufi[0][j]); + break; + } + } + + if (mpi_rank) { + /* Case b: verify dset <mm> */ + for (j = 0; j < (int)block[0]; j++) + if (l_rbufi[mm][j] != (long)(dtrans ? trans_wbufi[mm][j] : wbufi[mm][j])) { + nerrors++; + HDprintf(" Verify dset %d at index %d: %ld, %ld\n", mm, j + (int)start[0], + (long)(dtrans ? trans_wbufi[mm][j] : wbufi[mm][j]), l_rbufi[mm][j]); + break; + } + + /* Case c: verify dset <ll> */ + for (j = 0; j < (int)dims[0]; j++) + if (l_rbufi[ll][j] != (long)(dtrans ? trans_wbufi[ll][j] : wbufi[ll][j])) { + nerrors++; + HDprintf(" Verify dset %d at index %d: %ld, %ld\n", ll, j, + (long)(dtrans ? trans_wbufi[ll][j] : wbufi[ll][j]), l_rbufi[ll][j]); + break; + } + } + + if (H5Pclose(dcpl) < 0) + P_TEST_ERROR; + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(ntrans_dxpl) < 0) + P_TEST_ERROR; + + for (i = 0; i < (int)ndsets; i++) { + if (H5Sclose(file_sids[i]) < 0) + P_TEST_ERROR; + if (H5Sclose(mem_sids[i]) < 0) + P_TEST_ERROR; + if (H5Dclose(dset_dids[i]) < 0) + P_TEST_ERROR; + } + + HDfree(total_wbuf); + HDfree(total_wbuf_bak); + HDfree(total_trans_wbuf); + HDfree(total_lrbuf); + + CHECK_PASSED(); + + return; + +} /* test_multi_dsets_conv_sel_empty() */ + +/* + * Test 5 for multi-dataset: + * + * Repeat the following test for niter times to ensure the + * random combinations of all dataset types are hit. + * + * Create randomized contiguous or chunked datasets with: + * --DSET_WITH_NO_CONV: + * --with no type conversion + * --dataset with H5T_NATIVE_INT + * --DSET_WITH_CONV_AND_NO_BKG: + * --type conversion without background buffer + * --dataset with H5T_NATIVE_LONG + * --DSET_WITH_CONV_AND_BKG: + * --type conversion with background buffer + * --dataset with compound type s1_t + * + * Do H5Dwrite_multi() and H5Dread_multi() for the above randomized + * datasets with the settings below: + * Setting A: + * --DSET_WITH_NO_CONV: + * --write: mem_tids[] = H5T_NATIVE_INT + * --read: r_mem_tids[] = H5T_NATIVE_INT + * --DSET_WITH_CONV_AND_NO_BKG: + * --write: mem_tids[] = H5T_NATIVE_ULONG + * --read: r_mem_tids[] = H5T_NATIVE_LONG + * --DSET_WITH_CONV_AND_BKG: + * --write: mem_tids[] = s1_tid; + * --read: r_mem_tids[i] = s3_tid; + * + * Setting B: + * --DSET_WITH_NO_CONV: + * --write: mem_tids[] = H5T_NATIVE_INT + * --read: r_mem_tids[] = H5T_NATIVE_INT + * --DSET_WITH_CONV_AND_NO_BKG: + * --write: mem_tids[] = H5T_NATIVE_LONG; + * --read: r_mem_tids[] = H5T_NATIVE_SHORT; + * --DSET_WITH_CONV_AND_BKG: + * --write: mem_tids[] = s4_tid; + * --read: r_mem_tids[i] = s1_tid; + * + * Verify the result read as below: + * Setting A: + * --DSET_WITH_NO_CONV: + * --verify data read in rbufi1[i][j] is same as wbufi1[i][j] + * --DSET_WITH_CONV_AND_NO_BKG: + * --verify data read in l_rbufi2[i][j] is all LONG_MAX + * --DSET_WITH_CONV_AND_BKG: + * --verify all fields read in s3_rbufi3[i][j] is the + * reverse of s1_wbufi3[i][j] + * Setting B: + * --DSET_WITH_NO_CONV: + * --verify data read in rbufi1[i][j] is same as wbufi1[i][j] + * --DSET_WITH_CONV_AND_NO_BKG: + * --verify data read in s_rbufi2[i][j] is all SHRT_MAX + * --DSET_WITH_CONV_AND_BKG: + * --verify fields read in s1_rbufi3[i][j] is as follows: + * --fields 'a' and 'c' are as s1_wbufi3[i][j].a and s1_wbufi3[i][j].c + * --fields 'b' and 'd' are (DSET_SELECT_DIM + j + start[0]) + */ +static void +test_multi_dsets_all(int niter, hid_t fid, unsigned chunked, unsigned mwbuf) +{ + size_t ndsets; + int i, j, mm; + int s, n; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + + hsize_t dims[1]; + hsize_t cdims[1]; + hsize_t start[1], stride[1], count[1], block[1]; + + hid_t file_sids[MULTI_NUM_DSETS]; + hid_t mem_sids[MULTI_NUM_DSETS]; + hid_t mem_tids[MULTI_NUM_DSETS]; + hid_t r_mem_tids[MULTI_NUM_DSETS]; + + multi_dset_type_t dset_types[MULTI_NUM_DSETS]; + + hid_t s1_tid = H5I_INVALID_HID; + hid_t s3_tid = H5I_INVALID_HID; + hid_t s4_tid = H5I_INVALID_HID; + + char dset_names[MULTI_NUM_DSETS][DSET_NAME_LEN]; + hid_t dset_dids[MULTI_NUM_DSETS]; + + size_t buf_size; + + int *total_wbuf1 = NULL; + int *total_wbuf1_bak = NULL; + int *total_rbuf1 = NULL; + + int *wbufi1[MULTI_NUM_DSETS]; + int *rbufi1[MULTI_NUM_DSETS]; + + unsigned long *ul_total_wbuf2 = NULL; + unsigned long *ul_total_wbuf2_bak = NULL; + long *l_total_rbuf2 = NULL; + unsigned long *ul_wbufi2[MULTI_NUM_DSETS]; + long *l_rbufi2[MULTI_NUM_DSETS]; + + long *l_total_wbuf2 = NULL; + long *l_total_wbuf2_bak = NULL; + short *s_total_rbuf2 = NULL; + long *l_wbufi2[MULTI_NUM_DSETS]; + short *s_rbufi2[MULTI_NUM_DSETS]; + + s1_t *s1_total_wbuf3 = NULL; + s1_t *s1_total_wbuf3_bak = NULL; + s3_t *s3_total_rbuf3 = NULL; + s1_t *s1_wbufi3[MULTI_NUM_DSETS]; + s3_t *s3_rbufi3[MULTI_NUM_DSETS]; + + s4_t *s4_total_wbuf3 = NULL; + s4_t *s4_total_wbuf3_bak = NULL; + s1_t *s1_total_rbuf3 = NULL; + s4_t *s4_wbufi3[MULTI_NUM_DSETS]; + s1_t *s1_rbufi3[MULTI_NUM_DSETS]; + + const void *wbufs[MULTI_NUM_DSETS]; + void *rbufs[MULTI_NUM_DSETS]; + + /* for n niter to ensure that all randomized dset_types with multi_dset_type_t will be covered */ + for (n = 0; n < niter; n++) { + + /* Set up the number of datasets for testing */ + ndsets = MAX(MULTI_MIN_DSETS, MULTI_NUM_DSETS); + + /* Create dataset transfer property list */ + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Set selection I/O mode, type of I/O and type of collective I/O */ + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, mwbuf); + + /* Set dataset layout: contiguous or chunked */ + dims[0] = DSET_SELECT_DIM; + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + if (chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + /* Each process takes x number of elements */ + block[0] = dims[0] / (hsize_t)mpi_size; + stride[0] = block[0]; + count[0] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + + /* Create compound data type: s1_t */ + if ((s1_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1_t))) < 0) + P_TEST_ERROR; + + if (H5Tinsert(s1_tid, "a", HOFFSET(s1_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "b", HOFFSET(s1_t, b), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "c", HOFFSET(s1_t, c), H5T_NATIVE_INT) < 0 || + H5Tinsert(s1_tid, "d", HOFFSET(s1_t, d), H5T_NATIVE_INT) < 0) + P_TEST_ERROR; + + /* Create compound data type: s3_t */ + if ((s3_tid = H5Tcreate(H5T_COMPOUND, sizeof(s3_t))) < 0) + P_TEST_ERROR; + + if (H5Tinsert(s3_tid, "a", HOFFSET(s3_t, a), H5T_NATIVE_INT) < 0 || + H5Tinsert(s3_tid, "b", HOFFSET(s3_t, b), H5T_NATIVE_INT) < 0 || + H5Tinsert(s3_tid, "c", HOFFSET(s3_t, c), H5T_NATIVE_INT) < 0 || + H5Tinsert(s3_tid, "d", HOFFSET(s3_t, d), H5T_NATIVE_INT) < 0) + P_TEST_ERROR; + + /* Create compound data type: s4_t */ + if ((s4_tid = H5Tcreate(H5T_COMPOUND, sizeof(s4_t))) < 0) + P_TEST_ERROR; + + if (H5Tinsert(s4_tid, "b", HOFFSET(s4_t, b), H5T_NATIVE_UINT) < 0 || + H5Tinsert(s4_tid, "d", HOFFSET(s4_t, d), H5T_NATIVE_UINT) < 0) + P_TEST_ERROR; + + /* Create dataset for i ndsets */ + for (i = 0; i < (int)ndsets; i++) { + + /* File space ids */ + if ((file_sids[i] = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + + /* Memory space ids */ + if ((mem_sids[i] = H5Screate_simple(1, block, NULL)) < 0) + P_TEST_ERROR; + + mm = HDrandom() % (int)ndsets; + if (mm == 0) { + dset_types[i] = DSET_WITH_NO_CONV; + HDsnprintf(dset_names[i], sizeof(dset_names[i]), "multi_all_nconv_dset%d_%s_%s", i, + chunked ? "chunked" : "contig", mwbuf ? "mwbuf" : "nomwbuf"); + if ((dset_dids[i] = H5Dcreate2(fid, dset_names[i], H5T_NATIVE_INT, file_sids[i], H5P_DEFAULT, + dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + } + else if (mm == 1) { + dset_types[i] = DSET_WITH_CONV_AND_NO_BKG; + HDsnprintf(dset_names[i], sizeof(dset_names[i]), "multi_all_conv_nbkg_dset%d_%s_%s", i, + chunked ? "chunked" : "contig", mwbuf ? "mwbuf" : "nomwbuf"); + if ((dset_dids[i] = H5Dcreate2(fid, dset_names[i], H5T_NATIVE_LONG, file_sids[i], H5P_DEFAULT, + dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + } + else { + dset_types[i] = DSET_WITH_CONV_AND_BKG; + HDsnprintf(dset_names[i], sizeof(dset_names[i]), "multi_all_conv_bkg_dset%d_%s_%s", i, + chunked ? "chunked" : "contig", mwbuf ? "mwbuf" : "nomwbuf"); + if ((dset_dids[i] = H5Dcreate2(fid, dset_names[i], s1_tid, file_sids[i], H5P_DEFAULT, dcpl, + H5P_DEFAULT)) < 0) + P_TEST_ERROR; + } + + if (H5Sselect_hyperslab(file_sids[i], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + } /* end for i ndsets */ + + /* Allocate buffers for all datasets */ + + /* DSET_WITH_NO_CONV */ + buf_size = ndsets * DSET_SELECT_DIM * sizeof(int); + if (NULL == (total_wbuf1 = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (mwbuf && NULL == (total_wbuf1_bak = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (NULL == (total_rbuf1 = (int *)HDmalloc(buf_size))) + P_TEST_ERROR; + + /* DSET_WITH_CONV_AND_NO_BKG */ + buf_size = ndsets * DSET_SELECT_DIM * sizeof(unsigned long); + if (NULL == (ul_total_wbuf2 = (unsigned long *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (mwbuf && NULL == (ul_total_wbuf2_bak = (unsigned long *)HDmalloc(buf_size))) + P_TEST_ERROR; + buf_size = ndsets * DSET_SELECT_DIM * sizeof(long); + if (NULL == (l_total_rbuf2 = (long *)HDmalloc(buf_size))) + P_TEST_ERROR; + + buf_size = ndsets * DSET_SELECT_DIM * sizeof(long); + if (NULL == (l_total_wbuf2 = (long *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (mwbuf && NULL == (l_total_wbuf2_bak = (long *)HDmalloc(buf_size))) + P_TEST_ERROR; + buf_size = ndsets * DSET_SELECT_DIM * sizeof(short); + if (NULL == (s_total_rbuf2 = (short *)HDmalloc(buf_size))) + P_TEST_ERROR; + + /* DSET_WITH_CONV_AND_BKG */ + buf_size = ndsets * DSET_SELECT_DIM * sizeof(s1_t); + if (NULL == (s1_total_wbuf3 = (s1_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (mwbuf && NULL == (s1_total_wbuf3_bak = (s1_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + buf_size = ndsets * DSET_SELECT_DIM * sizeof(s3_t); + if (NULL == (s3_total_rbuf3 = (s3_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + + buf_size = ndsets * DSET_SELECT_DIM * sizeof(s4_t); + if (NULL == (s4_total_wbuf3 = (s4_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + if (mwbuf && NULL == (s4_total_wbuf3_bak = (s4_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + buf_size = ndsets * DSET_SELECT_DIM * sizeof(s1_t); + if (NULL == (s1_total_rbuf3 = (s1_t *)HDmalloc(buf_size))) + P_TEST_ERROR; + + /* Test with s settings for ndsets */ + for (s = SETTING_A; s <= SETTING_B; s++) { + + /* for i ndsets */ + for (i = 0; i < (int)ndsets; i++) { + + switch (dset_types[i]) { + + case DSET_WITH_NO_CONV: + /* Initialize buffer indices */ + wbufi1[i] = total_wbuf1 + (i * DSET_SELECT_DIM); + rbufi1[i] = total_rbuf1 + (i * DSET_SELECT_DIM); + + wbufs[i] = wbufi1[i]; + rbufs[i] = rbufi1[i]; + + /* Initialize the buffer data */ + for (j = 0; j < (int)block[0]; j++) + wbufi1[i][j] = j + (int)start[0]; + + /* Same for all cases */ + mem_tids[i] = H5T_NATIVE_INT; + r_mem_tids[i] = H5T_NATIVE_INT; + + break; + + case DSET_WITH_CONV_AND_NO_BKG: + if (s == SETTING_A) { + /* Initialize buffer indices */ + ul_wbufi2[i] = ul_total_wbuf2 + (i * DSET_SELECT_DIM); + l_rbufi2[i] = l_total_rbuf2 + (i * DSET_SELECT_DIM); + + wbufs[i] = ul_wbufi2[i]; + rbufs[i] = l_rbufi2[i]; + + for (j = 0; j < (int)block[0]; j++) + ul_wbufi2[i][j] = ULONG_MAX - (unsigned long)(j + (int)start[0]); + + mem_tids[i] = H5T_NATIVE_ULONG; + r_mem_tids[i] = H5T_NATIVE_LONG; + } + else if (s == SETTING_B) { + /* Initialize buffer indices */ + l_wbufi2[i] = l_total_wbuf2 + (i * DSET_SELECT_DIM); + s_rbufi2[i] = s_total_rbuf2 + (i * DSET_SELECT_DIM); + + wbufs[i] = l_wbufi2[i]; + rbufs[i] = s_rbufi2[i]; + + /* Initialize the buffer data */ + for (j = 0; j < (int)block[0]; j++) + l_wbufi2[i][j] = LONG_MAX - (long)(j + (int)start[0]); + + mem_tids[i] = H5T_NATIVE_LONG; + r_mem_tids[i] = H5T_NATIVE_SHORT; + } + + break; + + case DSET_WITH_CONV_AND_BKG: + + if (s == SETTING_A) { + /* Initialize buffer indices */ + s1_wbufi3[i] = s1_total_wbuf3 + (i * DSET_SELECT_DIM); + s3_rbufi3[i] = s3_total_rbuf3 + (i * DSET_SELECT_DIM); + + wbufs[i] = s1_wbufi3[i]; + rbufs[i] = s3_rbufi3[i]; + + /* Initialize buffer data for s1_t */ + for (j = 0; j < (int)block[0]; j++) { + s1_wbufi3[i][j].a = (4 * j + (int)start[0]); + s1_wbufi3[i][j].b = (4 * j + (int)start[0]) + 1; + s1_wbufi3[i][j].c = (4 * j + (int)start[0]) + 2; + s1_wbufi3[i][j].d = (4 * j + (int)start[0]) + 3; + } + mem_tids[i] = s1_tid; + r_mem_tids[i] = s3_tid; + } + else if (s == SETTING_B) { + /* Initialize buffer indices */ + s4_wbufi3[i] = s4_total_wbuf3 + (i * DSET_SELECT_DIM); + s1_rbufi3[i] = s1_total_rbuf3 + (i * DSET_SELECT_DIM); + + wbufs[i] = s4_wbufi3[i]; + rbufs[i] = s1_rbufi3[i]; + + /* Initialize buffer data for s4_t */ + for (j = 0; j < (int)block[0]; j++) { + s4_wbufi3[i][j].b = DSET_SELECT_DIM + (unsigned int)(j + (int)start[0]); + s4_wbufi3[i][j].d = DSET_SELECT_DIM + (unsigned int)(j + (int)start[0]); + } + mem_tids[i] = s4_tid; + r_mem_tids[i] = s1_tid; + } + + break; + + case DSET_NTTYPES: + default: + P_TEST_ERROR; + + } /* end switch dset_types */ + + } /* end for i ndsets */ + + /* Copy wbufs if the library will be modifying them */ + if (mwbuf) { + HDmemcpy(total_wbuf1_bak, total_wbuf1, ndsets * DSET_SELECT_DIM * sizeof(int)); + HDmemcpy(ul_total_wbuf2_bak, ul_total_wbuf2, + ndsets * DSET_SELECT_DIM * sizeof(unsigned long)); + HDmemcpy(l_total_wbuf2_bak, l_total_wbuf2, ndsets * DSET_SELECT_DIM * sizeof(long)); + HDmemcpy(s1_total_wbuf3_bak, s1_total_wbuf3, ndsets * DSET_SELECT_DIM * sizeof(s1_t)); + HDmemcpy(s4_total_wbuf3_bak, s4_total_wbuf3, ndsets * DSET_SELECT_DIM * sizeof(s4_t)); + } + + if (H5Dwrite_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, wbufs) < 0) + P_TEST_ERROR; + + /* Restore wbufs from backup if the library modified them */ + if (mwbuf) { + HDmemcpy(total_wbuf1, total_wbuf1_bak, ndsets * DSET_SELECT_DIM * sizeof(int)); + HDmemcpy(ul_total_wbuf2, ul_total_wbuf2_bak, + ndsets * DSET_SELECT_DIM * sizeof(unsigned long)); + HDmemcpy(l_total_wbuf2, l_total_wbuf2_bak, ndsets * DSET_SELECT_DIM * sizeof(long)); + HDmemcpy(s1_total_wbuf3, s1_total_wbuf3_bak, ndsets * DSET_SELECT_DIM * sizeof(s1_t)); + HDmemcpy(s4_total_wbuf3, s4_total_wbuf3_bak, ndsets * DSET_SELECT_DIM * sizeof(s4_t)); + } + + if (H5Dread_multi(ndsets, dset_dids, r_mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) + P_TEST_ERROR; + + check_io_mode(dxpl, chunked); + + /* Verify result read */ + /* for i ndsets */ + for (i = 0; i < (int)ndsets; i++) { + switch (dset_types[i]) { + + case DSET_WITH_NO_CONV: + for (j = 0; j < (int)block[0]; j++) + if (rbufi1[i][j] != wbufi1[i][j]) { + nerrors++; + HDprintf(" Read different values than written.\n"); + HDprintf(" For dset %d at index %d\n", i, j + (int)start[0]); + break; + } + + break; + + case DSET_WITH_CONV_AND_NO_BKG: + if (s == SETTING_A) { + for (j = 0; j < (int)block[0]; j++) + if (l_rbufi2[i][j] != LONG_MAX) { + nerrors++; + HDprintf(" Read different values than written.\n"); + HDprintf(" For dset %d at index %d\n", i, j + (int)start[0]); + break; + } + } + else if (s == SETTING_B) { + for (j = 0; j < (int)block[0]; j++) + if (s_rbufi2[i][j] != SHRT_MAX) { + nerrors++; + HDprintf(" Read different values than written.\n"); + HDprintf(" For dset %d at index %d\n", i, j + (int)start[0]); + break; + } + } + + break; + + case DSET_WITH_CONV_AND_BKG: + if (s == SETTING_A) { + for (j = 0; j < (int)block[0]; j++) + if (s3_rbufi3[i][j].a != s1_wbufi3[i][j].a || + s3_rbufi3[i][j].b != s1_wbufi3[i][j].b || + s3_rbufi3[i][j].c != s1_wbufi3[i][j].c || + s3_rbufi3[i][j].d != s1_wbufi3[i][j].d) { + nerrors++; + HDprintf(" Read different values than written.\n"); + HDprintf(" For dset %d at index %d\n", i, j + (int)start[0]); + break; + } + } + else if (s == SETTING_B) { + for (j = 0; j < (int)block[0]; j++) + if (s1_rbufi3[i][j].a != s1_wbufi3[i][j].a || + s1_rbufi3[i][j].b != (DSET_SELECT_DIM + j + (int)start[0]) || + s1_rbufi3[i][j].c != s1_wbufi3[i][j].c || + s1_rbufi3[i][j].d != (DSET_SELECT_DIM + j + (int)start[0])) { + nerrors++; + HDprintf(" Read different values than written.\n"); + HDprintf(" For dset %d at index %d\n", i, j + (int)start[0]); + break; + } + } + + break; + + case DSET_NTTYPES: + default: + P_TEST_ERROR; + + } /* end switch dset_types */ + + } /* end for i ndsets */ + + } /* end for s settings */ + + /* Closing */ + if (H5Pclose(dcpl) < 0) + P_TEST_ERROR; + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + + if (H5Tclose(s1_tid) < 0) + P_TEST_ERROR; + if (H5Tclose(s3_tid) < 0) + P_TEST_ERROR; + if (H5Tclose(s4_tid) < 0) + P_TEST_ERROR; + + for (i = 0; i < (int)ndsets; i++) { + if (H5Sclose(file_sids[i]) < 0) + P_TEST_ERROR; + if (H5Dclose(dset_dids[i]) < 0) + P_TEST_ERROR; + /* Don't delete the last set of datasets */ + if ((n + 1) != niter) + if (H5Ldelete(fid, dset_names[i], H5P_DEFAULT) < 0) + P_TEST_ERROR; + } + + /* Freeing */ + HDfree(total_wbuf1); + total_wbuf1 = NULL; + HDfree(total_wbuf1_bak); + total_wbuf1_bak = NULL; + HDfree(total_rbuf1); + total_rbuf1 = NULL; + + HDfree(ul_total_wbuf2); + ul_total_wbuf2 = NULL; + HDfree(ul_total_wbuf2_bak); + ul_total_wbuf2_bak = NULL; + HDfree(l_total_rbuf2); + l_total_rbuf2 = NULL; + HDfree(l_total_wbuf2); + l_total_wbuf2 = NULL; + HDfree(l_total_wbuf2_bak); + l_total_wbuf2_bak = NULL; + HDfree(s_total_rbuf2); + s_total_rbuf2 = NULL; + + HDfree(s1_total_wbuf3); + s1_total_wbuf3 = NULL; + HDfree(s1_total_wbuf3_bak); + s1_total_wbuf3_bak = NULL; + HDfree(s3_total_rbuf3); + s3_total_rbuf3 = NULL; + HDfree(s4_total_wbuf3); + s4_total_wbuf3 = NULL; + HDfree(s4_total_wbuf3_bak); + s4_total_wbuf3_bak = NULL; + HDfree(s1_total_rbuf3); + s1_total_rbuf3 = NULL; + + } /* end for n niter */ + + CHECK_PASSED(); + + return; + +} /* test_multi_dsets_all() */ + +/* + * Test with various test_mode that no selection I/O is performed + * + * Note: It is the responsibility of the tester to + * understand and feed proper combination of test_mode + * as needed. + */ +static void +test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_mode) +{ + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hsize_t dims[1]; + hsize_t cdims[1]; + hbool_t is_chunked = FALSE; + hid_t tid = H5T_NATIVE_INT; + uint32_t no_selection_io_cause_write = 0; + uint32_t no_selection_io_cause_read = 0; + uint32_t no_selection_io_cause_write_expected = 0; + uint32_t no_selection_io_cause_read_expected = 0; + int wbuf[DSET_SELECT_DIM]; + int rbuf[DSET_SELECT_DIM]; + int i; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + P_TEST_ERROR; + + if (test_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET) { + if (H5Pset_layout(dcpl, H5D_COMPACT) < 0) + P_TEST_ERROR; + no_selection_io_cause_write_expected |= H5D_SEL_IO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET; + no_selection_io_cause_read_expected |= H5D_SEL_IO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET; + } + + if (test_mode == TEST_DISABLE_BY_API) { + if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_OFF) < 0) + P_TEST_ERROR; + no_selection_io_cause_write_expected |= H5D_SEL_IO_DISABLE_BY_API; + no_selection_io_cause_read_expected |= H5D_SEL_IO_DISABLE_BY_API; + } + + /* Datatype conversion */ + if (test_mode & TEST_DATATYPE_CONVERSION) { + if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0) + P_TEST_ERROR; + tid = H5T_NATIVE_UINT; + + /* If we're testing a too small tconv buffer, set the buffer to be too small */ + if (test_mode & TEST_TCONV_BUF_TOO_SMALL) { + 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 */ + dims[0] = DSET_SELECT_DIM; + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + + if (is_chunked) { + cdims[0] = DSET_SELECT_CHUNK_DIM; + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + } + + if ((did = H5Dcreate2(fid, "no_selection_io_cause", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, + H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + /* Initialize data */ + for (i = 0; i < DSET_SELECT_DIM; i++) + wbuf[i] = i; + + if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, dxpl, wbuf) < 0) + P_TEST_ERROR; + + if (H5Pget_no_selection_io_cause(dxpl, &no_selection_io_cause_write) < 0) + P_TEST_ERROR; + + /* Verify causes of no selection I/O for write are as expected */ + if (no_selection_io_cause_write != no_selection_io_cause_write_expected) + P_TEST_ERROR; + + if (H5Dread(did, tid, H5S_ALL, H5S_ALL, dxpl, rbuf) < 0) + P_TEST_ERROR; + + if (H5Pget_no_selection_io_cause(dxpl, &no_selection_io_cause_read) < 0) + P_TEST_ERROR; + + /* Verify causes of no selection I/O for read are as expected */ + if (no_selection_io_cause_read != no_selection_io_cause_read_expected) + 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(sid) < 0) + P_TEST_ERROR; + + if (H5Fclose(fid) < 0) + P_TEST_ERROR; + + return; + +} /* test_no_selection_io_cause_mode() */ + +/* + * Test for causes of not performing selection I/O + */ +static void +test_get_no_selection_io_cause(const char *filename, hid_t fapl) +{ + 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); + test_no_selection_io_cause_mode(filename, fapl, TEST_DATATYPE_CONVERSION | TEST_TCONV_BUF_TOO_SMALL); + test_no_selection_io_cause_mode( + filename, fapl, TEST_DATATYPE_CONVERSION | TEST_TCONV_BUF_TOO_SMALL | TEST_IN_PLACE_TCONV); + + CHECK_PASSED(); + + return; +} /* test_get_no_selection_io_cause() */ + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Runs tests with all combinations of configuration + * flags. + * + * Return: Success: 0 + * Failure: 1 + * + *------------------------------------------------------------------------- + */ +int +main(int argc, char *argv[]) +{ + int ret; + hid_t fapl = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; + int test_select_config; + unsigned chunked; + unsigned dtrans; + unsigned mwbuf; + + h5_reset(); + + /* Initialize MPI */ + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + P_TEST_ERROR; + + /* Set MPIO file driver */ + if (H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0) + P_TEST_ERROR; + + if ((fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + P_TEST_ERROR; + + /* Test with contiguous or chunked dataset */ + for (chunked = FALSE; chunked <= TRUE; chunked++) { + + /* Data transforms only apply to integer or floating-point datasets */ + /* therefore, not all tests are run with data transform */ + for (dtrans = FALSE; dtrans <= TRUE; dtrans++) { + + /* Test with and without modify_write_buf turned on */ + for (mwbuf = FALSE; mwbuf <= TRUE; mwbuf++) { + + if (MAINPROCESS) { + /* Print configuration message */ + printf("Testing for selection I/O "); + if (chunked) + printf("with chunked dataset, "); + else + printf("with contiguous dataset, "); + if (dtrans) + printf("data transform, "); + else + printf("without data transform, "); + if (mwbuf) + printf("and with modifying write buffers\n"); + else + printf("and without modifying write buffers\n"); + } + + for (test_select_config = (int)TEST_NO_TYPE_CONV; + test_select_config < (int)TEST_SELECT_NTESTS; test_select_config++) { + + switch (test_select_config) { + + case TEST_NO_TYPE_CONV: /* case 1 */ + if (MAINPROCESS) + TESTING_2("No type conversion (null case)"); + + test_no_type_conv(fid, chunked, dtrans, mwbuf); + + break; + + case TEST_NO_SIZE_CHANGE_NO_BKG: /* case 2 */ + if (MAINPROCESS) + TESTING_2("No size change, no background buffer"); + + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) { + if (MAINPROCESS) + SKIPPED(); + continue; + } + + test_no_size_change_no_bkg(fid, chunked, mwbuf); + + break; + + case TEST_LARGER_MEM_NO_BKG: /* case 3 */ + if (MAINPROCESS) + TESTING_2("Larger memory type, no background buffer"); + + test_larger_mem_type_no_bkg(fid, chunked, dtrans, mwbuf); + + break; + + case TEST_SMALLER_MEM_NO_BKG: /* case 4 */ + if (MAINPROCESS) + TESTING_2("Smaller memory type, no background buffer"); + + test_smaller_mem_type_no_bkg(fid, chunked, dtrans, mwbuf); + + break; + + case TEST_CMPD_WITH_BKG: /* case 5 */ + if (MAINPROCESS) + TESTING_2("Compound types with background buffer"); + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) { + if (MAINPROCESS) + SKIPPED(); + continue; + } + + test_cmpd_with_bkg(fid, chunked, mwbuf); + + break; + + case TEST_TYPE_CONV_SEL_EMPTY: /* case 6 */ + if (MAINPROCESS) + TESTING_2("Empty selections + Type conversion"); + + test_type_conv_sel_empty(fid, chunked, dtrans, mwbuf); + + break; + + case TEST_MULTI_CONV_NO_BKG: /* case 7 */ + if (MAINPROCESS) + TESTING_2("multi-datasets: type conv + no bkg buffer"); + + test_multi_dsets_no_bkg(fid, chunked, dtrans, mwbuf); + + break; + + case TEST_MULTI_CONV_BKG: /* case 8 */ + if (MAINPROCESS) + TESTING_2("multi-datasets: type conv + bkg buffer"); + + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) { + if (MAINPROCESS) + SKIPPED(); + } + else + test_multi_dsets_cmpd_with_bkg(fid, chunked, mwbuf); + + break; + + case TEST_MULTI_CONV_SIZE_CHANGE: /* case 9 */ + if (MAINPROCESS) + TESTING_2("multi-datasets: type conv + size change + no bkg buffer"); + + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) { + if (MAINPROCESS) + SKIPPED(); + } + else + test_multi_dsets_size_change_no_bkg(fid, chunked, mwbuf); + + break; + + case TEST_MULTI_CONV_SEL_EMPTY: /* case 10 */ + if (MAINPROCESS) + TESTING_2("multi-datasets: type conv + empty selections"); + + test_multi_dsets_conv_sel_empty(fid, chunked, dtrans, mwbuf); + + break; + + case TEST_MULTI_ALL: /* case 11 */ + if (MAINPROCESS) + TESTING_2("multi-datasets: no conv + conv without bkg + conv with bkg"); + + /* Data transforms does not apply to the dataset datatype for this test */ + if (dtrans) { + if (MAINPROCESS) + SKIPPED(); + } + else + test_multi_dsets_all(2, fid, chunked, mwbuf); + + break; + + case TEST_SELECT_NTESTS: + default: + P_TEST_ERROR; + break; + + } /* end switch */ + + } /* end for test_select_config */ + + } /* end mwbuf */ + + } /* end dtrans */ + } /* end chunked */ + + 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); + + /* 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) */ + if (MPI_Barrier(MPI_COMM_WORLD) != MPI_SUCCESS) + P_TEST_ERROR; + + /* Delete file */ + if (H5Fdelete(FILENAME, fapl) < 0) + P_TEST_ERROR; + + if (H5Pclose(fapl) < 0) + P_TEST_ERROR; + + /* 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) + HDprintf("***Parallel selection I/O dataset tests detected %d errors***\n", nerrors); + else + HDprintf("Parallel selection I/O dataset tests finished with no errors\n"); + printf("===================================\n"); + } + + /* close HDF5 library */ + H5close(); + + /* MPI_Finalize must be called AFTER H5close which may use MPI calls */ + MPI_Finalize(); + + /* cannot just return (nerrors) because exit code is limited to 1 byte */ + return (nerrors != 0); +} /* end main() */ diff --git a/testpar/t_subfiling_vfd.c b/testpar/t_subfiling_vfd.c index 85df3bd..f827aa5 100644 --- a/testpar/t_subfiling_vfd.c +++ b/testpar/t_subfiling_vfd.c @@ -425,7 +425,10 @@ test_stripe_sizes(void) VRFY(tmp_filename, "HDmalloc succeeded"); dxpl_id = H5Pcreate(H5P_DATASET_XFER); - VRFY((dxpl_id >= 0), "DCPL creation succeeded"); + VRFY((dxpl_id >= 0), "DXPL creation succeeded"); + + /* Set selection I/O mode on DXPL */ + VRFY((H5Pset_selection_io(dxpl_id, H5D_SELECTION_IO_MODE_ON) >= 0), "H5Pset_selection_io succeeded"); for (size_t i = 0; i < SUBF_NITER; i++) { H5FD_subfiling_params_t cfg; @@ -1011,12 +1014,19 @@ test_read_different_stripe_size(void) hid_t file_id = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; + hid_t dxpl_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; char *tmp_filename = NULL; void *buf = NULL; curr_nerrors = nerrors; + dxpl_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_id >= 0), "DXPL creation succeeded"); + + /* Set selection I/O mode on DXPL */ + VRFY((H5Pset_selection_io(dxpl_id, H5D_SELECTION_IO_MODE_ON) >= 0), "H5Pset_selection_io succeeded"); + if (MAINPROCESS) TESTING_2("file re-opening with different stripe size"); @@ -1066,7 +1076,7 @@ test_read_different_stripe_size(void) for (size_t i = 0; i < count[0]; i++) ((SUBF_C_TYPE *)buf)[i] = (SUBF_C_TYPE)((size_t)mpi_rank + i); - VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, dxpl_id, buf) >= 0), "Dataset write succeeded"); HDfree(buf); @@ -1133,7 +1143,7 @@ test_read_different_stripe_size(void) buf = HDcalloc(1, count[0] * sizeof(SUBF_C_TYPE)); VRFY(buf, "HDcalloc succeeded"); - VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, dxpl_id, buf) >= 0), "Dataset read succeeded"); for (size_t i = 0; i < count[0]; i++) { @@ -1185,6 +1195,7 @@ test_read_different_stripe_size(void) } H5E_END_TRY; + VRFY((H5Pclose(dxpl_id) >= 0), "DXPL close succeeded"); VRFY((H5Pclose(fapl_id) >= 0), "FAPL close succeeded"); HDfree(tmp_filename); @@ -1214,11 +1225,18 @@ test_subfiling_precreate_rank_0(void) hid_t file_id = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; + hid_t dxpl_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; void *buf = NULL; curr_nerrors = nerrors; + dxpl_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_id >= 0), "DXPL creation succeeded"); + + /* Set selection I/O mode on DXPL */ + VRFY((H5Pset_selection_io(dxpl_id, H5D_SELECTION_IO_MODE_ON) >= 0), "H5Pset_selection_io succeeded"); + if (MAINPROCESS) TESTING_2("file pre-creation on rank 0"); @@ -1278,7 +1296,7 @@ test_subfiling_precreate_rank_0(void) for (size_t i = 0; i < dset_dims[0]; i++) ((SUBF_C_TYPE *)buf)[i] = (SUBF_C_TYPE)((i / n_elements_per_rank) + (i % n_elements_per_rank)); - VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, dxpl_id, buf) >= 0), "Dataset write succeeded"); HDfree(buf); @@ -1357,7 +1375,7 @@ test_subfiling_precreate_rank_0(void) buf = HDcalloc(1, count[0] * sizeof(SUBF_C_TYPE)); VRFY(buf, "HDcalloc succeeded"); - VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, dxpl_id, buf) >= 0), "Dataset read succeeded"); for (size_t i = 0; i < n_elements_per_rank; i++) { @@ -1380,6 +1398,7 @@ test_subfiling_precreate_rank_0(void) H5E_END_TRY; VRFY((H5Pclose(fapl_id) >= 0), "FAPL close succeeded"); + VRFY((H5Pclose(dxpl_id) >= 0), "DXPL close succeeded"); CHECK_PASSED(); } @@ -1405,11 +1424,18 @@ test_subfiling_write_many_read_one(void) hid_t file_id = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; + hid_t dxpl_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; void *buf = NULL; curr_nerrors = nerrors; + dxpl_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_id >= 0), "DXPL creation succeeded"); + + /* Set selection I/O mode on DXPL */ + VRFY((H5Pset_selection_io(dxpl_id, H5D_SELECTION_IO_MODE_ON) >= 0), "H5Pset_selection_io succeeded"); + if (MAINPROCESS) TESTING_2("reading back file with single MPI rank"); @@ -1461,7 +1487,7 @@ test_subfiling_write_many_read_one(void) for (size_t i = 0; i < count[0]; i++) ((SUBF_C_TYPE *)buf)[i] = (SUBF_C_TYPE)((size_t)mpi_rank + i); - VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, dxpl_id, buf) >= 0), "Dataset write succeeded"); HDfree(buf); @@ -1486,7 +1512,7 @@ test_subfiling_write_many_read_one(void) buf = HDcalloc(1, target_size); VRFY(buf, "HDcalloc succeeded"); - VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, H5S_ALL, dxpl_id, buf) >= 0), "Dataset read succeeded"); for (size_t i = 0; i < (size_t)mpi_size; i++) { @@ -1516,6 +1542,7 @@ test_subfiling_write_many_read_one(void) VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Barrier succeeded"); VRFY((H5Sclose(fspace_id) >= 0), "File dataspace close succeeded"); + VRFY((H5Pclose(dxpl_id) >= 0), "DXPL close succeeded"); CHECK_PASSED(); } @@ -1543,11 +1570,18 @@ test_subfiling_write_many_read_few(void) hid_t file_id = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; + hid_t dxpl_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; void *buf = NULL; curr_nerrors = nerrors; + dxpl_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_id >= 0), "DXPL creation succeeded"); + + /* Set selection I/O mode on DXPL */ + VRFY((H5Pset_selection_io(dxpl_id, H5D_SELECTION_IO_MODE_ON) >= 0), "H5Pset_selection_io succeeded"); + if (MAINPROCESS) TESTING_2("reading back file with fewer MPI ranks than written with"); @@ -1609,7 +1643,7 @@ test_subfiling_write_many_read_few(void) for (size_t i = 0; i < count[0]; i++) ((SUBF_C_TYPE *)buf)[i] = (SUBF_C_TYPE)((size_t)mpi_rank + i); - VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, dxpl_id, buf) >= 0), "Dataset write succeeded"); HDfree(buf); @@ -1664,7 +1698,7 @@ test_subfiling_write_many_read_few(void) buf = HDcalloc(1, target_size); VRFY(buf, "HDcalloc succeeded"); - VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, H5S_ALL, dxpl_id, buf) >= 0), "Dataset read succeeded"); for (size_t i = 0; i < (size_t)mpi_size; i++) { @@ -1699,6 +1733,7 @@ test_subfiling_write_many_read_few(void) VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Barrier succeeded"); VRFY((H5Sclose(fspace_id) >= 0), "File dataspace close succeeded"); + VRFY((H5Pclose(dxpl_id) >= 0), "DXPL close succeeded"); CHECK_PASSED(); } @@ -1727,6 +1762,7 @@ test_subfiling_h5fuse(void) hid_t file_id = H5I_INVALID_HID; hid_t fapl_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; + hid_t dxpl_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; void *buf = NULL; int skip_test = 0; @@ -1734,6 +1770,12 @@ test_subfiling_h5fuse(void) curr_nerrors = nerrors; + dxpl_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl_id >= 0), "DXPL creation succeeded"); + + /* Set selection I/O mode on DXPL */ + VRFY((H5Pset_selection_io(dxpl_id, H5D_SELECTION_IO_MODE_ON) >= 0), "H5Pset_selection_io succeeded"); + if (MAINPROCESS) TESTING_2("h5fuse utility"); @@ -1826,7 +1868,7 @@ test_subfiling_h5fuse(void) for (size_t i = 0; i < count[0]; i++) ((SUBF_C_TYPE *)buf)[i] = (SUBF_C_TYPE)((size_t)mpi_rank + i); - VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dwrite(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, fspace_id, dxpl_id, buf) >= 0), "Dataset write succeeded"); HDfree(buf); @@ -1899,7 +1941,7 @@ test_subfiling_h5fuse(void) buf = HDcalloc(1, target_size); VRFY(buf, "HDcalloc succeeded"); - VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) >= 0), + VRFY((H5Dread(dset_id, SUBF_HDF5_TYPE, H5S_BLOCK, H5S_ALL, dxpl_id, buf) >= 0), "Dataset read succeeded"); for (size_t i = 0; i < (size_t)mpi_size; i++) { @@ -1969,6 +2011,7 @@ test_subfiling_h5fuse(void) } VRFY((H5Pclose(fapl_id) >= 0), "FAPL close succeeded"); + VRFY((H5Pclose(dxpl_id) >= 0), "DXPL close succeeded"); mpi_code_g = MPI_Barrier(comm_g); VRFY((mpi_code_g == MPI_SUCCESS), "MPI_Barrier succeeded"); @@ -2132,9 +2175,6 @@ main(int argc, char **argv) H5open(); - /* Enable selection I/O using internal temporary workaround */ - H5_use_selection_io_g = TRUE; - if (MAINPROCESS) { HDprintf("Testing Subfiling VFD functionality\n"); } |