diff options
Diffstat (limited to 'testpar')
-rw-r--r-- | testpar/API/CMakeLists.txt | 2 | ||||
-rw-r--r-- | testpar/CMakeLists.txt | 19 | ||||
-rw-r--r-- | testpar/CMakeTests.cmake | 9 | ||||
-rw-r--r-- | testpar/CMakeVFDTests.cmake | 3 | ||||
-rw-r--r-- | testpar/t_2Gio.c | 6 | ||||
-rw-r--r-- | testpar/t_bigio.c | 39 | ||||
-rw-r--r-- | testpar/t_file.c | 102 | ||||
-rw-r--r-- | testpar/t_filters_parallel.c | 33 | ||||
-rw-r--r-- | testpar/t_mpi.c | 46 | ||||
-rw-r--r-- | testpar/t_pflush2.c | 11 | ||||
-rw-r--r-- | testpar/t_ph5basic.c | 136 | ||||
-rw-r--r-- | testpar/t_pshutdown.c | 39 | ||||
-rw-r--r-- | testpar/t_shapesame.c | 56 | ||||
-rw-r--r-- | testpar/t_subfiling_vfd.c | 146 | ||||
-rw-r--r-- | testpar/t_vfd.c | 298 | ||||
-rw-r--r-- | testpar/testphdf5.c | 42 | ||||
-rw-r--r-- | testpar/testphdf5.h | 2 |
17 files changed, 891 insertions, 98 deletions
diff --git a/testpar/API/CMakeLists.txt b/testpar/API/CMakeLists.txt index 869a925..e9c7edd 100644 --- a/testpar/API/CMakeLists.txt +++ b/testpar/API/CMakeLists.txt @@ -94,7 +94,7 @@ target_compile_options ( target_compile_definitions ( h5_api_test_parallel PRIVATE - "$<$<CONFIG:Developer>:${HDF5_DEVELOPER_DEFS}>" + "${HDF5_TESTPAR_COMPILE_DEFS_PRIVATE}" ) if (NOT BUILD_SHARED_LIBS) TARGET_C_PROPERTIES (h5_api_test_parallel STATIC) diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt index 7894cff..106f79e 100644 --- a/testpar/CMakeLists.txt +++ b/testpar/CMakeLists.txt @@ -21,13 +21,19 @@ set (testphdf5_SOURCES ${HDF5_TEST_PAR_SOURCE_DIR}/t_oflush.c ) +################################################################################# +# Set private compile-time definitions added when +# compiling test source files +################################################################################# +set (HDF5_TESTPAR_COMPILE_DEFS_PRIVATE + "$<$<CONFIG:Developer>:${HDF5_DEVELOPER_DEFS}>" + "$<$<BOOL:HDF5_TEST_API>:H5_HAVE_TEST_API>" +) + #-- Adding test for testhdf5 add_executable (testphdf5 ${testphdf5_SOURCES}) target_compile_options(testphdf5 PRIVATE "${HDF5_CMAKE_C_FLAGS}") -target_compile_definitions(testphdf5 - PRIVATE - "$<$<CONFIG:Developer>:${HDF5_DEVELOPER_DEFS}>" -) +target_compile_definitions(testphdf5 PRIVATE "${HDF5_TESTPAR_COMPILE_DEFS_PRIVATE}") target_include_directories (testphdf5 PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>" ) @@ -54,10 +60,7 @@ endif () macro (ADD_H5P_EXE file) add_executable (${file} ${HDF5_TEST_PAR_SOURCE_DIR}/${file}.c) target_compile_options(${file} PRIVATE "${HDF5_CMAKE_C_FLAGS}") - target_compile_definitions(${file} - PRIVATE - "$<$<CONFIG:Developer>:${HDF5_DEVELOPER_DEFS}>" - ) + target_compile_definitions(${file} PRIVATE "${HDF5_TESTPAR_COMPILE_DEFS_PRIVATE}") target_include_directories (${file} PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>" ) diff --git a/testpar/CMakeTests.cmake b/testpar/CMakeTests.cmake index dfdde59..36a97ee 100644 --- a/testpar/CMakeTests.cmake +++ b/testpar/CMakeTests.cmake @@ -55,6 +55,9 @@ set_tests_properties (MPI_TEST_testphdf5 PROPERTIES ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_PAR_BINARY_DIR}" WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR} ) +if ("MPI_TEST_testphdf5" MATCHES "${HDF5_DISABLE_TESTS_REGEX}") + set_tests_properties (MPI_TEST_testphdf5 PROPERTIES DISABLED true) +endif () if (last_test) set_tests_properties (MPI_TEST_testphdf5 PROPERTIES DEPENDS ${last_test}) endif () @@ -68,6 +71,9 @@ foreach (skiptest ${SKIP_tests}) ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_PAR_BINARY_DIR}" WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR} ) + if ("MPI_TEST_testphdf5_${skiptest}" MATCHES "${HDF5_DISABLE_TESTS_REGEX}") + set_tests_properties (MPI_TEST_testphdf5_${skiptest} PROPERTIES DISABLED true) + endif () if (last_test) set_tests_properties (MPI_TEST_testphdf5_${skiptest} PROPERTIES DEPENDS ${last_test}) endif () @@ -131,6 +137,9 @@ foreach (h5_testp ${H5P_TESTS}) ENVIRONMENT "HDF5_ALARM_SECONDS=3600;srcdir=${HDF5_TEST_PAR_BINARY_DIR}" WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR} ) + if ("MPI_TEST_${h5_testp}" MATCHES "${HDF5_DISABLE_TESTS_REGEX}") + set_tests_properties (MPI_TEST_${h5_testp} PROPERTIES DISABLED true) + endif () if (last_test) set_tests_properties (MPI_TEST_${h5_testp} PROPERTIES DEPENDS ${last_test}) endif () diff --git a/testpar/CMakeVFDTests.cmake b/testpar/CMakeVFDTests.cmake index d630015..cdec5f7 100644 --- a/testpar/CMakeVFDTests.cmake +++ b/testpar/CMakeVFDTests.cmake @@ -47,6 +47,9 @@ macro (ADD_VFD_TEST vfdname resultcode) ENVIRONMENT "srcdir=${HDF5_TEST_PAR_BINARY_DIR}/${vfdname}" WORKING_DIRECTORY ${HDF5_TEST_PAR_BINARY_DIR}/${vfdname} ) + if ("MPI_TEST_VFD-${vfdname}-${h5_test}" MATCHES "${HDF5_DISABLE_TESTS_REGEX}") + set_tests_properties (MPI_TEST_VFD-${vfdname}-${h5_test} PROPERTIES DISABLED true) + endif () endif () endforeach () if (NOT "t_pflush1" IN_LIST H5P_VFD_${vfdname}_TESTS_SKIP) diff --git a/testpar/t_2Gio.c b/testpar/t_2Gio.c index c2aac77..48abf8e 100644 --- a/testpar/t_2Gio.c +++ b/testpar/t_2Gio.c @@ -4291,9 +4291,10 @@ main(int argc, char **argv) printf("2 GByte IO TESTS START\n"); printf("2 MPI ranks will run the tests...\n"); printf("===================================\n"); - h5_show_hostname(); } + h5_show_hostname(); + if (H5dont_atexit() < 0) { printf("Failed to turn off atexit processing. Continue.\n"); }; @@ -4345,8 +4346,7 @@ main(int argc, char **argv) #endif /* H5_HAVE_FILTER_DEFLATE */ /* Display testing information */ - if (MAINPROCESS) - TestInfo(argv[0]); + TestInfo(argv[0]); /* setup file access property list */ fapl = H5Pcreate(H5P_FILE_ACCESS); diff --git a/testpar/t_bigio.c b/testpar/t_bigio.c index 2726f91..151cdad 100644 --- a/testpar/t_bigio.c +++ b/testpar/t_bigio.c @@ -1855,6 +1855,11 @@ main(int argc, char **argv) hsize_t newsize = 1048576; /* Set the bigio processing limit to be 'newsize' bytes */ hsize_t oldsize = H5_mpi_set_bigio_count(newsize); +#ifdef H5_HAVE_TEST_API + int required = MPI_THREAD_MULTIPLE; + int provided; +#endif + int mpi_code; /* Having set the bigio handling to a size that is manageable, * we'll set our 'bigcount' variable to be 2X that limit so @@ -1864,9 +1869,37 @@ main(int argc, char **argv) if (newsize != oldsize) bigcount = newsize * 2; - MPI_Init(&argc, &argv); - MPI_Comm_size(MPI_COMM_WORLD, &mpi_size_g); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank_g); +#ifdef H5_HAVE_TEST_API + /* Attempt to initialize with MPI_THREAD_MULTIPLE if possible */ + if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(&argc, &argv, required, &provided))) { + printf("MPI_Init_thread failed with error code %d\n", mpi_code); + return -1; + } +#else + if (MPI_SUCCESS != (mpi_code = MPI_Init(&argc, &argv))) { + printf("MPI_Init failed with error code %d\n", mpi_code); + return -1; + } +#endif + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank_g))) { + printf("MPI_Comm_rank failed with error code %d\n", mpi_code); + MPI_Finalize(); + return -1; + } + +#ifdef H5_HAVE_TEST_API + /* Warn about missing MPI_THREAD_MULTIPLE support */ + if ((provided < required) && MAIN_PROCESS) + printf("** MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE **\n"); +#endif + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(MPI_COMM_WORLD, &mpi_size_g))) { + if (MAIN_PROCESS) + printf("MPI_Comm_size failed with error code %d\n", mpi_code); + MPI_Finalize(); + return -1; + } /* Attempt to turn off atexit post processing so that in case errors * happen during the test and the process is aborted, it will not get diff --git a/testpar/t_file.c b/testpar/t_file.c index 700ccc2..8f8b291 100644 --- a/testpar/t_file.c +++ b/testpar/t_file.c @@ -1119,3 +1119,105 @@ test_evict_on_close_parallel_unsupp(void) ret = H5Pclose(fapl_id); VRFY((SUCCEED == ret), "H5Pclose"); } + +/* + * Verify that MPI I/O hints are preserved after closing the file access property list + * as described in issue #3025 + * This is a test program from the user. + */ +void +test_fapl_preserve_hints(void) +{ + const char *filename; + const char *key = "hdf_info_fapl"; + const char *value = "xyz"; + MPI_Info info_used = MPI_INFO_NULL; + MPI_Info info = MPI_INFO_NULL; + hid_t fid = H5I_INVALID_HID; /* HDF5 file ID */ + hid_t fapl_id = H5I_INVALID_HID; /* File access plist */ + char key_used[MPI_MAX_INFO_KEY + 1]; + char *value_used = NULL; + bool same = false; + int flag = -1; + int nkeys_used; + int i; + int mpi_ret; /* MPI return value */ + herr_t ret; /* Generic return value */ + + filename = (const char *)GetTestParameters(); + + value_used = malloc(MPI_MAX_INFO_VAL + 1); + VRFY(value_used, "malloc succeeded"); + + /* set up MPI parameters */ + mpi_ret = MPI_Info_create(&info); + VRFY((mpi_ret >= 0), "MPI_Info_create succeeded"); + + mpi_ret = MPI_Info_set(info, key, value); + VRFY((mpi_ret == MPI_SUCCESS), "MPI_Info_set succeeded"); + + fapl_id = H5Pcreate(H5P_FILE_ACCESS); + VRFY((fapl_id != H5I_INVALID_HID), "H5Pcreate"); + + ret = H5Pset_fapl_mpio(fapl_id, MPI_COMM_WORLD, info); + VRFY((ret >= 0), "H5Pset_fapl_mpio"); + + fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + VRFY((fid != H5I_INVALID_HID), "H5Fcreate succeeded"); + + ret = H5Pclose(fapl_id); + VRFY((ret >= 0), "H5Pclose succeeded"); + + fapl_id = H5Fget_access_plist(fid); + VRFY((fapl_id != H5I_INVALID_HID), "H5Fget_access_plist succeeded"); + + ret = H5Pget_fapl_mpio(fapl_id, NULL, &info_used); + VRFY((ret >= 0), "H5Pget_fapl_mpio succeeded"); + + VRFY((info_used != MPI_INFO_NULL), "H5Pget_fapl_mpio"); + + mpi_ret = MPI_Info_get_nkeys(info_used, &nkeys_used); + VRFY((mpi_ret == MPI_SUCCESS), "MPI_Info_get_nkeys succeeded"); + + /* Loop over the # of keys */ + for (i = 0; i < nkeys_used; i++) { + + /* Memset the buffers to zero */ + memset(key_used, 0, MPI_MAX_INFO_KEY + 1); + memset(value_used, 0, MPI_MAX_INFO_VAL + 1); + + /* Get the nth key */ + mpi_ret = MPI_Info_get_nthkey(info_used, i, key_used); + VRFY((mpi_ret == MPI_SUCCESS), "MPI_Info_get_nthkey succeeded"); + + if (!strcmp(key_used, key)) { + mpi_ret = MPI_Info_get(info_used, key_used, MPI_MAX_INFO_VAL, value_used, &flag); + VRFY((mpi_ret == MPI_SUCCESS), "MPI_Info_get succeeded"); + + if (!strcmp(value_used, value)) { + + /* Both key_used and value_used are the same */ + same = true; + break; + } + } + } /* end for */ + + VRFY((same == true), "key_used and value_used are the same"); + + ret = H5Pclose(fapl_id); + VRFY((ret >= 0), "H5Pclose succeeded"); + + ret = H5Fclose(fid); + VRFY((ret >= 0), "H5Fclose succeeded"); + + /* Free the MPI info object */ + mpi_ret = MPI_Info_free(&info); + VRFY((mpi_ret >= 0), "MPI_Info_free succeeded"); + + mpi_ret = MPI_Info_free(&info_used); + VRFY((mpi_ret >= 0), "MPI_Info_free succeeded"); + + free(value_used); + +} /* end test_fapl_preserve_hints() */ diff --git a/testpar/t_filters_parallel.c b/testpar/t_filters_parallel.c index 6c05408..f60431b 100644 --- a/testpar/t_filters_parallel.c +++ b/testpar/t_filters_parallel.c @@ -547,8 +547,9 @@ verify_chunk_opt_status(size_t num_dsets, test_mode_t test_mode, bool any_io, bo /* Verify selection I/O mode on rank 0 */ if (mpi_rank == 0) { - /* No actual I/O performed, only reported I/O will be from allocation, even if "no" datasets were - * involved (num_dsets == 0 implies the call was expected to fail, but it fails after allocation). + /* No actual I/O performed, the only reported I/O will be from allocation which is vector I/O, + * even if "no" datasets were involved (num_dsets == 0 implies the call was expected to fail, + * but it fails after allocation). * Also if the test mode is mixed filtered and unfiltered and the call did not fail, then there * will always be an I/O callback made with raw data. This is because unfiltered datasets fall * back to scalar I/O when mixed with filtered, and scalar I/O reports an I/O call was made even @@ -557,9 +558,18 @@ verify_chunk_opt_status(size_t num_dsets, test_mode_t test_mode, bool any_io, bo * filtered dataset with no selection. Vector I/O does report an I/O call was made if passed a raw * data element of size 0, so this is consistent. */ if (!any_io) { - if (did_alloc || (num_dsets > 0 && test_mode == USE_MULTIPLE_DATASETS_MIXED_FILTERED)) + if (did_alloc && (num_dsets > 0 && test_mode == USE_MULTIPLE_DATASETS_MIXED_FILTERED)) { + VRFY((H5D_VECTOR_IO | H5D_SCALAR_IO) == actual_sel_io_mode_reduced, + "verified actual selection I/O mode was vector and scalar I/O"); + } + else if (did_alloc) { + VRFY(H5D_VECTOR_IO == actual_sel_io_mode_reduced, + "verified actual selection I/O mode was vector I/O"); + } + else if (num_dsets > 0 && test_mode == USE_MULTIPLE_DATASETS_MIXED_FILTERED) { VRFY(H5D_SCALAR_IO == actual_sel_io_mode_reduced, "verified actual selection I/O mode was scalar I/O"); + } else VRFY(0 == actual_sel_io_mode_reduced, "verified actual selection I/O mode was 0 (no I/O)"); @@ -588,19 +598,18 @@ verify_chunk_opt_status(size_t num_dsets, test_mode_t test_mode, bool any_io, bo switch (test_mode) { case USE_SINGLE_DATASET: case USE_MULTIPLE_DATASETS: - /* Collective case with only filtered datasets. If we performed allocation then there - * should be scalar I/O for allocation in addition to vector I/O for the actual data. - * If we're reading from an unallocated dataset then there should be no actual I/O. - * Otherwise there should only be vector I/O. */ - if (did_alloc) - VRFY((H5D_SCALAR_IO | H5D_VECTOR_IO) == actual_sel_io_mode_reduced, - "verified actual selection I/O mode was scalar and vector I/O"); - else if (unalloc_read) + /* Collective case with only filtered datasets. + * If we're reading from an unallocated dataset then there + * should be no actual I/O. + * Otherwise, only vector I/O is reported whether or not + * allocation happened. */ + if (unalloc_read) VRFY(0 == actual_sel_io_mode_reduced, "verified actual selection I/O mode was 0 (no I/O)"); - else + else { /* did_alloc || !unalloc_read */ VRFY(H5D_VECTOR_IO == actual_sel_io_mode_reduced, "verified actual selection I/O mode was vector I/O"); + } break; case USE_MULTIPLE_DATASETS_MIXED_FILTERED: diff --git a/testpar/t_mpi.c b/testpar/t_mpi.c index eff39d0..0f1e27b 100644 --- a/testpar/t_mpi.c +++ b/testpar/t_mpi.c @@ -53,14 +53,14 @@ test_mpio_overlap_writes(char *filename) MPI_Offset mpi_off; MPI_Status mpi_stat; - if (VERBOSE_MED) - printf("MPIO independent overlapping writes test on file %s\n", filename); - nerrs = 0; /* set up MPI parameters */ MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + if (VERBOSE_MED && MAINPROCESS) + printf("MPIO independent overlapping writes test on file %s\n", filename); + /* Need at least 2 processes */ if (mpi_size < 2) { if (MAINPROCESS) @@ -211,7 +211,7 @@ test_mpio_gb_file(char *filename) MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); - if (VERBOSE_MED) + if (VERBOSE_MED && MAINPROCESS) printf("MPI_Offset range test\n"); /* figure out the signness and sizeof MPI_Offset */ @@ -274,12 +274,13 @@ test_mpio_gb_file(char *filename) /* * Verify if we can write to a file of multiple GB sizes. */ - if (VERBOSE_MED) + if (VERBOSE_MED && MAINPROCESS) printf("MPIO GB file test %s\n", filename); if (sizeof_mpi_offset <= 4) { - printf("Skipped GB file range test " - "because MPI_Offset cannot support it\n"); + if (MAINPROCESS) + printf("Skipped GB file range test " + "because MPI_Offset cannot support it\n"); } else { buf = (char *)malloc(MB); @@ -294,7 +295,8 @@ test_mpio_gb_file(char *filename) mrc = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh); VRFY((mrc == MPI_SUCCESS), "MPI_FILE_OPEN"); - printf("MPIO GB file write test %s\n", filename); + if (MAINPROCESS) + printf("MPIO GB file write test %s\n", filename); /* instead of writing every bytes of the file, we will just write * some data around the 2 and 4 GB boundaries. That should cover @@ -333,7 +335,8 @@ test_mpio_gb_file(char *filename) */ /* open it again to verify the data written */ /* but only if there was no write errors */ - printf("MPIO GB file read test %s\n", filename); + if (MAINPROCESS) + printf("MPIO GB file read test %s\n", filename); if (errors_sum(writerrs) > 0) { printf("proc %d: Skip read test due to previous write errors\n", mpi_rank); goto finish; @@ -377,7 +380,8 @@ test_mpio_gb_file(char *filename) mrc = MPI_Barrier(MPI_COMM_WORLD); VRFY((mrc == MPI_SUCCESS), "Sync before leaving test"); - printf("Test if MPI_File_get_size works correctly with %s\n", filename); + if (MAINPROCESS) + printf("Test if MPI_File_get_size works correctly with %s\n", filename); mrc = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, info, &fh); VRFY((mrc == MPI_SUCCESS), ""); @@ -432,7 +436,6 @@ finish: static int test_mpio_1wMr(char *filename, int special_request) { - char hostname[128]; int mpi_size, mpi_rank; MPI_File fh; char mpi_err_str[MPI_MAX_ERROR_STRING]; @@ -456,19 +459,8 @@ test_mpio_1wMr(char *filename, int special_request) } /* show the hostname so that we can tell where the processes are running */ - if (VERBOSE_DEF) { -#ifdef H5_HAVE_GETHOSTNAME - if (gethostname(hostname, sizeof(hostname)) < 0) { - printf("gethostname failed\n"); - hostname[0] = '\0'; - } -#else - printf("gethostname unavailable\n"); - hostname[0] = '\0'; -#endif - PRINTID; - printf("hostname=%s\n", hostname); - } + if (VERBOSE_DEF) + h5_show_hostname(); /* Delete any old file in order to start anew. */ /* Must delete because MPI_File_open does not have a Truncate mode. */ @@ -1005,6 +997,10 @@ test_mpio_special_collective(char *filename) static int parse_options(int argc, char **argv) { + int mpi_rank; + + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + while (--argc) { if (**(++argv) != '-') { break; @@ -1053,7 +1049,7 @@ parse_options(int argc, char **argv) return (1); } H5Pclose(plist); - if (VERBOSE_MED) { + if (VERBOSE_MED && MAINPROCESS) { printf("Test filenames are:\n"); for (i = 0; i < n; i++) printf(" %s\n", filenames[i]); diff --git a/testpar/t_pflush2.c b/testpar/t_pflush2.c index 95ad125..e1dce1b 100644 --- a/testpar/t_pflush2.c +++ b/testpar/t_pflush2.c @@ -20,7 +20,8 @@ #include "h5test.h" -static const char *FILENAME[] = {"flush", "noflush", NULL}; +static const char *FLUSH_FILENAME[] = {"flush", NULL}; +static const char *NOFLUSH_FILENAME[] = {"noflush", NULL}; static int *data_g = NULL; @@ -173,7 +174,7 @@ main(int argc, char *argv[]) goto error; /* Check the case where the file was flushed */ - h5_fixname(FILENAME[0], fapl_id1, name, sizeof(name)); + h5_fixname(FLUSH_FILENAME[0], fapl_id1, name, sizeof(name)); if (check_test_file(name, sizeof(name), fapl_id1)) { H5_FAILED(); goto error; @@ -190,7 +191,7 @@ main(int argc, char *argv[]) H5Eget_auto2(H5E_DEFAULT, &func, NULL); H5Eset_auto2(H5E_DEFAULT, NULL, NULL); - h5_fixname(FILENAME[1], fapl_id2, name, sizeof(name)); + h5_fixname(NOFLUSH_FILENAME[0], fapl_id2, name, sizeof(name)); if (check_test_file(name, sizeof(name), fapl_id2)) { if (mpi_rank == 0) PASSED(); @@ -202,8 +203,8 @@ main(int argc, char *argv[]) H5Eset_auto2(H5E_DEFAULT, func, NULL); - h5_clean_files(&FILENAME[0], fapl_id1); - h5_clean_files(&FILENAME[1], fapl_id2); + h5_clean_files(FLUSH_FILENAME, fapl_id1); + h5_clean_files(NOFLUSH_FILENAME, fapl_id2); if (data_g) { free(data_g); diff --git a/testpar/t_ph5basic.c b/testpar/t_ph5basic.c index b627b7c..7fdefeb 100644 --- a/testpar/t_ph5basic.c +++ b/testpar/t_ph5basic.c @@ -177,3 +177,139 @@ test_fapl_mpio_dup(void) VRFY((mrc == MPI_SUCCESS), "MPI_Info_free"); } } /* end test_fapl_mpio_dup() */ + +/*------------------------------------------------------------------------- + * Function: test_get_dxpl_mpio + * + * Purpose: Test that H5Pget_dxpl_mpio will properly return the data + * transfer mode of collective and independent I/O access + * after setting it and writing some data. + * + * Return: Success: None + * Failure: Abort + *------------------------------------------------------------------------- + */ +void +test_get_dxpl_mpio(void) +{ + hid_t fid = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t fapl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + H5FD_mpio_xfer_t xfer_mode; + hsize_t dims[2] = {100, 100}; + hsize_t i, j; + int *data = NULL; + int mpi_rank, mpi_size; + const char *filename; + herr_t ret; + + if (VERBOSE_MED) + printf("Verify get_dxpl_mpio correctly gets the data transfer mode" + "set in the data transfer property list after a write\n"); + + /* Set up MPI for VRFY macro */ + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); + + /* Initialize data array */ + data = malloc(100 * 100 * sizeof(*data)); + VRFY((data != NULL), "Data buffer initialized properly"); + + /* Create parallel fapl */ + fapl = create_faccess_plist(MPI_COMM_WORLD, MPI_INFO_NULL, FACC_MPIO); + VRFY((fapl >= 0), "Fapl creation succeeded"); + + /* Create a file */ + filename = (const char *)GetTestParameters(); + fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + VRFY((fid >= 0), "H5Fcreate succeeded"); + + /* Create a dataset */ + sid = H5Screate_simple(2, dims, NULL); + VRFY((sid >= 0), "H5Screate succeeded"); + did = H5Dcreate2(fid, "dset", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + VRFY((did >= 0), "H5Dcreate2 succeeded"); + + /* Use collective I/O access */ + dxpl = H5Pcreate(H5P_DATASET_XFER); + VRFY((dxpl >= 0), "H5Pcreate succeeded"); + ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE); + VRFY((ret >= 0), "H5Pset_dxpl_mpio set to collective succeeded"); + + /* Write some data */ + for (i = 0; i < dims[0]; i++) + for (j = 0; j < dims[1]; j++) + data[(i * 100) + j] = (int)(i + (i * j) + j); + + ret = H5Dwrite(did, H5T_NATIVE_INT, sid, sid, dxpl, data); + VRFY((ret >= 0), "H5Dwrite succeeded"); + + /* Check to make sure the property is still correct */ + ret = H5Pget_dxpl_mpio(dxpl, &xfer_mode); + VRFY((ret >= 0), "H5Pget_dxpl_mpio succeeded"); + VRFY((xfer_mode == H5FD_MPIO_COLLECTIVE), "Xfer_mode retrieved" + " successfully"); + + /* Read the data */ + ret = H5Dread(did, H5T_NATIVE_INT, sid, sid, dxpl, data); + VRFY((ret >= 0), "H5Dread succeeded"); + + /* Check to make sure the property is still correct */ + ret = H5Pget_dxpl_mpio(dxpl, &xfer_mode); + VRFY((ret >= 0), "H5Pget_dxpl_mpio succeeded"); + VRFY((xfer_mode == H5FD_MPIO_COLLECTIVE), "Xfer_mode retrieved" + " successfully"); + + /* Check it does nothing on receiving NULL */ + ret = H5Pget_dxpl_mpio(dxpl, NULL); + VRFY((ret >= 0), "H5Pget_dxpl_mpio succeeded on NULL input"); + + /* Use independent I/O access */ + ret = H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_INDEPENDENT); + VRFY((ret >= 0), "H5Pset_dxpl_mpio set to independent succeeded"); + + /* Write some data */ + for (i = 0; i < dims[0]; i++) + for (j = 0; j < dims[1]; j++) + data[(i * 100) + j] = (int)(i + (j * j) + i); + + ret = H5Dwrite(did, H5T_NATIVE_INT, sid, sid, dxpl, data); + VRFY((ret >= 0), "H5Dwrite succeeded"); + + /* Check to make sure the property is still correct */ + ret = H5Pget_dxpl_mpio(dxpl, &xfer_mode); + VRFY((ret >= 0), "H5Pget_dxpl_mpio succeeded"); + VRFY((xfer_mode == H5FD_MPIO_INDEPENDENT), "Xfer_mode retrieved" + " successfully"); + + /* Read the data */ + ret = H5Dread(did, H5T_NATIVE_INT, sid, sid, dxpl, data); + VRFY((ret >= 0), "H5Dread succeeded"); + + /* Check to make sure the property is still correct */ + ret = H5Pget_dxpl_mpio(dxpl, &xfer_mode); + VRFY((ret >= 0), "H5Pget_dxpl_mpio succeeded"); + VRFY((xfer_mode == H5FD_MPIO_INDEPENDENT), "Xfer_mode retrieved" + " successfully"); + + /* Close everything */ + free(data); + + ret = H5Pclose(fapl); + VRFY((ret >= 0), "H5Pclose succeeded"); + + ret = H5Pclose(dxpl); + VRFY((ret >= 0), "H5Pclose succeeded"); + + ret = H5Dclose(did); + VRFY((ret >= 0), "H5Dclose succeeded"); + + ret = H5Sclose(sid); + VRFY((ret >= 0), "H5Sclose succeeded"); + + ret = H5Fclose(fid); + VRFY((ret >= 0), "H5Fclose succeeded"); + +} /* end test_get_dxpl_mpio() */ diff --git a/testpar/t_pshutdown.c b/testpar/t_pshutdown.c index b0b5da7..5293d35 100644 --- a/testpar/t_pshutdown.c +++ b/testpar/t_pshutdown.c @@ -41,10 +41,43 @@ main(int argc, char **argv) hsize_t stride[RANK]; hsize_t block[RANK]; DATATYPE *data_array = NULL; /* data buffer */ + int mpi_code; +#ifdef H5_HAVE_TEST_API + int required = MPI_THREAD_MULTIPLE; + int provided; +#endif + +#ifdef H5_HAVE_TEST_API + /* Attempt to initialize with MPI_THREAD_MULTIPLE if possible */ + if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(&argc, &argv, required, &provided))) { + printf("MPI_Init_thread failed with error code %d\n", mpi_code); + return -1; + } +#else + if (MPI_SUCCESS != (mpi_code = MPI_Init(&argc, &argv))) { + printf("MPI_Init failed with error code %d\n", mpi_code); + return -1; + } +#endif - MPI_Init(&argc, &argv); - MPI_Comm_size(comm, &mpi_size); - MPI_Comm_rank(comm, &mpi_rank); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) { + printf("MPI_Comm_rank failed with error code %d\n", mpi_code); + MPI_Finalize(); + return -1; + } + +#ifdef H5_HAVE_TEST_API + /* Warn about missing MPI_THREAD_MULTIPLE support */ + if ((provided < required) && MAINPROCESS) + printf("** MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE **\n"); +#endif + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &mpi_size))) { + if (MAINPROCESS) + printf("MPI_Comm_size failed with error code %d\n", mpi_code); + MPI_Finalize(); + return -1; + } if (MAINPROCESS) TESTING("proper shutdown of HDF5 library"); diff --git a/testpar/t_shapesame.c b/testpar/t_shapesame.c index 98e3077..e2112d5 100644 --- a/testpar/t_shapesame.c +++ b/testpar/t_shapesame.c @@ -4089,7 +4089,8 @@ parse_options(int argc, char **argv) case 'h': /* print help message--return with nerrors set */ return (1); default: - printf("Illegal option(%s)\n", *argv); + if (MAINPROCESS) + printf("Illegal option(%s)\n", *argv); nerrors++; return (1); } @@ -4098,12 +4099,14 @@ parse_options(int argc, char **argv) /* check validity of dimension and chunk sizes */ if (dim0 <= 0 || dim1 <= 0) { - printf("Illegal dim sizes (%d, %d)\n", dim0, dim1); + if (MAINPROCESS) + printf("Illegal dim sizes (%d, %d)\n", dim0, dim1); nerrors++; return (1); } if (chunkdim0 <= 0 || chunkdim1 <= 0) { - printf("Illegal chunkdim sizes (%d, %d)\n", chunkdim0, chunkdim1); + if (MAINPROCESS) + printf("Illegal chunkdim sizes (%d, %d)\n", chunkdim0, chunkdim1); nerrors++; return (1); } @@ -4128,9 +4131,11 @@ parse_options(int argc, char **argv) nerrors++; return (1); } - printf("Test filenames are:\n"); - for (i = 0; i < n; i++) - printf(" %s\n", filenames[i]); + if (MAINPROCESS) { + printf("Test filenames are:\n"); + for (i = 0; i < n; i++) + printf(" %s\n", filenames[i]); + } } return (0); @@ -4249,6 +4254,11 @@ int main(int argc, char **argv) { int mpi_size, mpi_rank; /* mpi variables */ + int mpi_code; +#ifdef H5_HAVE_TEST_API + int required = MPI_THREAD_MULTIPLE; + int provided; +#endif #ifndef H5_HAVE_WIN32_API /* Un-buffer the stdout and stderr */ @@ -4256,9 +4266,37 @@ main(int argc, char **argv) HDsetbuf(stdout, NULL); #endif - MPI_Init(&argc, &argv); - MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); +#ifdef H5_HAVE_TEST_API + /* Attempt to initialize with MPI_THREAD_MULTIPLE if possible */ + if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(&argc, &argv, required, &provided))) { + printf("MPI_Init_thread failed with error code %d\n", mpi_code); + return -1; + } +#else + if (MPI_SUCCESS != (mpi_code = MPI_Init(&argc, &argv))) { + printf("MPI_Init failed with error code %d\n", mpi_code); + return -1; + } +#endif + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank))) { + printf("MPI_Comm_rank failed with error code %d\n", mpi_code); + MPI_Finalize(); + return -1; + } + +#ifdef H5_HAVE_TEST_API + /* Warn about missing MPI_THREAD_MULTIPLE support */ + if ((provided < required) && MAINPROCESS) + printf("** MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE **\n"); +#endif + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(MPI_COMM_WORLD, &mpi_size))) { + if (MAINPROCESS) + printf("MPI_Comm_size failed with error code %d\n", mpi_code); + MPI_Finalize(); + return -1; + } mpi_rank_framework_g = mpi_rank; diff --git a/testpar/t_subfiling_vfd.c b/testpar/t_subfiling_vfd.c index 7c56599..45cb363 100644 --- a/testpar/t_subfiling_vfd.c +++ b/testpar/t_subfiling_vfd.c @@ -40,6 +40,8 @@ #define PATH_MAX 4096 #endif +#define DEFAULT_DEFLATE_LEVEL 9 + #define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0]) #define CHECK_PASSED() \ @@ -82,12 +84,15 @@ static char *config_dir = NULL; int nerrors = 0; int curr_nerrors = 0; +bool enable_compression = false; + /* Function pointer typedef for test functions */ typedef void (*test_func)(void); /* Utility functions */ static hid_t create_subfiling_ioc_fapl(MPI_Comm comm, MPI_Info info, bool custom_config, H5FD_subfiling_params_t *custom_cfg, int32_t thread_pool_size); +static hid_t create_dcpl_id(int rank, const hsize_t dims[], hid_t dxpl_id); /* Test functions */ static void test_create_and_close(void); @@ -182,7 +187,47 @@ error: return H5I_INVALID_HID; } +/* --------------------------------------------------------------------------- + * Function: create_dcpl_id + * + * Purpose: Creates dataset creation property list identifier with + * chunking and compression, and enforces the + * required collective IO. + * + * Return: Success: HID Dataset creation property list identifier, + * a non-negative value. + * Failure: H5I_INVALID_HID, a negative value. + * --------------------------------------------------------------------------- + */ +static hid_t +create_dcpl_id(int rank, const hsize_t dset_dims[], hid_t dxpl_id) +{ + hsize_t chunk_dims[1]; + hid_t ret_value = H5I_INVALID_HID; + + if ((ret_value = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR; + + if (enable_compression) { + if (H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) < 0) + TEST_ERROR; + chunk_dims[0] = dset_dims[0] / 2; + if (H5Pset_chunk(ret_value, rank, chunk_dims) < 0) + TEST_ERROR; + if (H5Pset_deflate(ret_value, DEFAULT_DEFLATE_LEVEL) < 0) + TEST_ERROR; + } + + return ret_value; +error: + if ((H5I_INVALID_HID != ret_value) && (H5Pclose(ret_value) < 0)) { + H5_FAILED(); + AT(); + } + + return H5I_INVALID_HID; +} /* * A simple test that creates and closes a file with the * subfiling VFD @@ -1060,6 +1105,7 @@ test_read_different_stripe_size(void) hid_t fapl_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; hid_t dxpl_id = H5I_INVALID_HID; + hid_t dcpl_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; char *tmp_filename = NULL; void *buf = NULL; @@ -1106,7 +1152,10 @@ test_read_different_stripe_size(void) fspace_id = H5Screate_simple(1, dset_dims, NULL); VRFY((fspace_id >= 0), "H5Screate_simple succeeded"); - dset_id = H5Dcreate2(file_id, "DSET", SUBF_HDF5_TYPE, fspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + dcpl_id = create_dcpl_id(1, dset_dims, dxpl_id); + VRFY((dcpl_id >= 0), "DCPL creation succeeded"); + + dset_id = H5Dcreate2(file_id, "DSET", SUBF_HDF5_TYPE, fspace_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT); VRFY((dset_id >= 0), "Dataset creation succeeded"); /* Select hyperslab */ @@ -1129,6 +1178,7 @@ test_read_different_stripe_size(void) VRFY((H5Sclose(fspace_id) >= 0), "File dataspace close succeeded"); VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Pclose(dcpl_id) >= 0), "DCPL close succeeded"); VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); /* Ensure all the subfiles are present */ @@ -1153,10 +1203,12 @@ test_read_different_stripe_size(void) VRFY((fclose(subfile_ptr) >= 0), "fclose on subfile succeeded"); /* Check file size */ - VRFY((HDstat(tmp_filename, &subfile_info) >= 0), "HDstat succeeded"); - subfile_size = (h5_stat_size_t)subfile_info.st_size; + if (!enable_compression) { + VRFY((HDstat(tmp_filename, &subfile_info) >= 0), "HDstat succeeded"); + subfile_size = (h5_stat_size_t)subfile_info.st_size; - VRFY((subfile_size >= cfg.stripe_size), "File size verification succeeded"); + VRFY((subfile_size >= cfg.stripe_size), "File size verification succeeded"); + } } } @@ -1376,10 +1428,12 @@ test_subfiling_precreate_rank_0(void) VRFY((fclose(subfile_ptr) >= 0), "fclose on subfile succeeded"); /* Check file size */ - VRFY((HDstat(tmp_filename, &subfile_info) >= 0), "HDstat succeeded"); - file_size = (h5_stat_size_t)subfile_info.st_size; + if (!enable_compression) { + VRFY((HDstat(tmp_filename, &subfile_info) >= 0), "HDstat succeeded"); + file_size = (h5_stat_size_t)subfile_info.st_size; - VRFY((file_size >= cfg.stripe_size), "File size verification succeeded"); + VRFY((file_size >= cfg.stripe_size), "File size verification succeeded"); + } } /* Verify that there aren't too many subfiles */ @@ -1470,6 +1524,7 @@ test_subfiling_write_many_read_one(void) hid_t fapl_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; hid_t dxpl_id = H5I_INVALID_HID; + hid_t dcpl_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; void *buf = NULL; @@ -1517,7 +1572,10 @@ test_subfiling_write_many_read_one(void) fspace_id = H5Screate_simple(1, dset_dims, NULL); VRFY((fspace_id >= 0), "H5Screate_simple succeeded"); - dset_id = H5Dcreate2(file_id, "DSET", SUBF_HDF5_TYPE, fspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + dcpl_id = create_dcpl_id(1, dset_dims, dxpl_id); + VRFY((dcpl_id >= 0), "DCPL creation succeeded"); + + dset_id = H5Dcreate2(file_id, "DSET", SUBF_HDF5_TYPE, fspace_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT); VRFY((dset_id >= 0), "Dataset creation succeeded"); /* Select hyperslab */ @@ -1539,6 +1597,7 @@ test_subfiling_write_many_read_one(void) buf = NULL; VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Pclose(dcpl_id) >= 0), "DCPL close succeeded"); VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); mpi_code_g = MPI_Barrier(comm_g); @@ -1616,6 +1675,7 @@ test_subfiling_write_many_read_few(void) hid_t fapl_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; hid_t dxpl_id = H5I_INVALID_HID; + hid_t dcpl_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; void *buf = NULL; @@ -1673,7 +1733,10 @@ test_subfiling_write_many_read_few(void) fspace_id = H5Screate_simple(1, dset_dims, NULL); VRFY((fspace_id >= 0), "H5Screate_simple succeeded"); - dset_id = H5Dcreate2(file_id, "DSET", SUBF_HDF5_TYPE, fspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + dcpl_id = create_dcpl_id(1, dset_dims, dxpl_id); + VRFY((dcpl_id >= 0), "DCPL creation succeeded"); + + dset_id = H5Dcreate2(file_id, "DSET", SUBF_HDF5_TYPE, fspace_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT); VRFY((dset_id >= 0), "Dataset creation succeeded"); /* Select hyperslab */ @@ -1695,6 +1758,7 @@ test_subfiling_write_many_read_few(void) buf = NULL; VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Pclose(dcpl_id) >= 0), "DCPL close succeeded"); VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); /* @@ -1808,6 +1872,7 @@ test_subfiling_h5fuse(void) hid_t fapl_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; hid_t dxpl_id = H5I_INVALID_HID; + hid_t dcpl_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; void *buf = NULL; int skip_test = 0; @@ -1833,7 +1898,7 @@ test_subfiling_h5fuse(void) if (MAINPROCESS) { FILE *h5fuse_script; - h5fuse_script = fopen("h5fuse.sh", "r"); + h5fuse_script = fopen("h5fuse", "r"); if (h5fuse_script) fclose(h5fuse_script); else @@ -1898,7 +1963,10 @@ test_subfiling_h5fuse(void) fspace_id = H5Screate_simple(1, dset_dims, NULL); VRFY((fspace_id >= 0), "H5Screate_simple succeeded"); - dset_id = H5Dcreate2(file_id, "DSET", SUBF_HDF5_TYPE, fspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + dcpl_id = create_dcpl_id(1, dset_dims, dxpl_id); + VRFY((dcpl_id >= 0), "DCPL creation succeeded"); + + dset_id = H5Dcreate2(file_id, "DSET", SUBF_HDF5_TYPE, fspace_id, H5P_DEFAULT, dcpl_id, H5P_DEFAULT); VRFY((dset_id >= 0), "Dataset creation succeeded"); /* Select hyperslab */ @@ -1919,8 +1987,11 @@ test_subfiling_h5fuse(void) free(buf); buf = NULL; + VRFY((H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_INDEPENDENT) >= 0), "H5Pset_dxpl_mpio succeeded"); + VRFY((H5Sclose(fspace_id) >= 0), "File dataspace close succeeded"); VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Pclose(dcpl_id) >= 0), "DCPL close succeeded"); VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); if (MAINPROCESS) { @@ -1943,7 +2014,7 @@ test_subfiling_h5fuse(void) SUBF_FILENAME, file_inode); args[0] = strdup("env"); - args[1] = strdup("./h5fuse.sh"); + args[1] = strdup("./h5fuse"); args[2] = strdup("-q"); args[3] = strdup("-f"); args[4] = tmp_filename; @@ -1973,8 +2044,10 @@ test_subfiling_h5fuse(void) } /* Verify the size of the fused file */ - VRFY((HDstat(SUBF_FILENAME, &file_info) >= 0), "HDstat succeeded"); - VRFY(((size_t)file_info.st_size >= target_size), "File size verification succeeded"); + if (!enable_compression) { + VRFY((HDstat(SUBF_FILENAME, &file_info) >= 0), "HDstat succeeded"); + VRFY(((size_t)file_info.st_size >= target_size), "File size verification succeeded"); + } /* Re-open file with sec2 driver and verify the data */ file_id = H5Fopen(SUBF_FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT); @@ -2414,9 +2487,28 @@ main(int argc, char **argv) if (num_iocs_g > mpi_size) num_iocs_g = mpi_size; - if (MAINPROCESS) { - printf("Re-running tests with environment variables set\n"); + if (MAINPROCESS) + printf(" Re-running tests with compression enabled\n"); + +#ifdef H5_HAVE_FILTER_DEFLATE + enable_compression = true; + for (size_t i = 0; i < ARRAY_SIZE(tests); i++) { + if (MPI_SUCCESS == (mpi_code_g = MPI_Barrier(comm_g))) { + (*tests[i])(); + } + else { + if (MAINPROCESS) + MESG("MPI_Barrier failed"); + nerrors++; + } } + enable_compression = false; +#else + if (MAINPROCESS) + SKIPPED(); +#endif + if (MAINPROCESS) + printf("\nRe-running tests with environment variables set\n"); for (size_t i = 0; i < ARRAY_SIZE(tests); i++) { if (MPI_SUCCESS == (mpi_code_g = MPI_Barrier(comm_g))) { @@ -2430,13 +2522,29 @@ main(int argc, char **argv) } if (MAINPROCESS) - puts(""); - + printf("\n Re-running tests with compression enabled\n"); +#ifdef H5_HAVE_FILTER_DEFLATE + enable_compression = true; + for (size_t i = 0; i < ARRAY_SIZE(tests); i++) { + if (MPI_SUCCESS == (mpi_code_g = MPI_Barrier(comm_g))) { + (*tests[i])(); + } + else { + if (MAINPROCESS) + MESG("MPI_Barrier failed"); + nerrors++; + } + } + enable_compression = false; +#else + if (MAINPROCESS) + SKIPPED(); +#endif if (nerrors) goto exit; if (MAINPROCESS) - puts("All Subfiling VFD tests passed\n"); + puts("\nAll Subfiling VFD tests passed\n"); exit: if (must_unset_stripe_size_env) diff --git a/testpar/t_vfd.c b/testpar/t_vfd.c index ac524ac..79b7e01 100644 --- a/testpar/t_vfd.c +++ b/testpar/t_vfd.c @@ -40,13 +40,14 @@ const char *FILENAMES[] = {"mpio_vfd_test_file_0", /*0*/ "mpio_vfd_test_file_4", /*4*/ "mpio_vfd_test_file_5", /*5*/ "mpio_vfd_test_file_6", /*6*/ - "subfiling_vfd_test_file_0", /*7*/ - "subfiling_vfd_test_file_1", /*8*/ - "subfiling_vfd_test_file_2", /*9*/ - "subfiling_vfd_test_file_3", /*10*/ - "subfiling_vfd_test_file_4", /*11*/ - "subfiling_vfd_test_file_5", /*12*/ - "subfiling_vfd_test_file_6", /*13*/ + "mpio_vfd_test_file_7", /*7*/ + "subfiling_vfd_test_file_0", /*8*/ + "subfiling_vfd_test_file_1", /*9*/ + "subfiling_vfd_test_file_2", /*10*/ + "subfiling_vfd_test_file_3", /*11*/ + "subfiling_vfd_test_file_4", /*12*/ + "subfiling_vfd_test_file_5", /*13*/ + "subfiling_vfd_test_file_6", /*14*/ NULL}; /* File Test Images @@ -100,6 +101,8 @@ static unsigned vector_write_test_6(int file_name_id, int mpi_rank, int mpi_size H5FD_mpio_collective_opt_t coll_opt_mode, const char *vfd_name); static unsigned vector_write_test_7(int file_name_id, int mpi_rank, int mpi_size, H5FD_mpio_xfer_t xfer_mode, H5FD_mpio_collective_opt_t coll_opt_mode, const char *vfd_name); +static unsigned vector_write_test_8(int file_name_id, int mpi_rank, int mpi_size, H5FD_mpio_xfer_t xfer_mode, + H5FD_mpio_collective_opt_t coll_opt_mode, const char *vfd_name); /* * Tests for selection I/O: * They are derived from test_selection_io() in test/vfd.c and modified for parallel testing. @@ -4159,6 +4162,280 @@ vector_write_test_7(int file_name_id, int mpi_rank, int mpi_size, H5FD_mpio_xfer } /* vector_write_test_7() */ +/*------------------------------------------------------------------------- + * Function: vector_write_test_8() + * + * Purpose: This test is to verify the fix for the following problem + * in H5FD__mpio_write_vector when calculating max_addr: + * --illegal reference occurs when referencing the s_sizes array + * with <count - 1> due to <count> exceeding the length of the + * size array which uses the compressed feature. + * + * 1) Open the test file with the specified VFD, and set + * the eoa. + * + * 2) Set the test file in a known state by writing zeros + * to all bytes in the test file. Since we have already + * tested this, do this via a vector write of zero_fi_buf. + * + * 3) Barrier + * + * 4) For each rank, define base_index equal to: + * + * mpi_rank * INTS_PER_RANK + * + * and define base_addr equal to + * + * base_index * sizeof(int32_t). + * + * Setup a vector of length INTS_PER_RANK - 1. + * Set up the size array with the compressed feature: + * --The first element has size (2 * sizeof(int32_t)) + * --The second and third elements are of size sizeof(int32_t) + * --The fourth element is zero. + * Set up addrs and bufs accordingly. + * + * Write the vector. + * + * 5) Barrier + * + * 6) On each rank, read the entire file into the read_fi_buf, + * and compare against increasing_fi_buf. + * Report failure if any differences are detected. + * + * 7) Close the test file. On rank 0, delete the test file. + * + * Return: false on success, true if any errors are detected. + * + *------------------------------------------------------------------------- + */ +static unsigned +vector_write_test_8(int file_name_id, int mpi_rank, int mpi_size, H5FD_mpio_xfer_t xfer_mode, + H5FD_mpio_collective_opt_t coll_opt_mode, const char *vfd_name) +{ + const char *fcn_name = "vector_write_test_8()"; + char test_title[120]; + char filename[512]; + haddr_t eoa; + haddr_t base_addr; + bool show_progress = false; + hid_t fapl_id = H5I_INVALID_HID; /* file access property list ID */ + hid_t dxpl_id = H5I_INVALID_HID; /* data access property list ID */ + H5FD_t *lf = NULL; /* VFD struct ptr */ + int cp = 0; + int i; + int base_index; + uint32_t count = 0; + size_t sizes[4]; + H5FD_mem_t types[2]; + + haddr_t *tt_addrs = NULL; /* For storing addrs */ + const void **tt_bufs = NULL; /* For storing buf pointers */ + + pass = true; + + if (mpi_rank == 0) { + + if (xfer_mode == H5FD_MPIO_INDEPENDENT) { + + snprintf(test_title, sizeof(test_title), "parallel vector write test 8 -- %s / independent", + vfd_name); + } + else if (coll_opt_mode == H5FD_MPIO_INDIVIDUAL_IO) { + + snprintf(test_title, sizeof(test_title), "parallel vector write test 8 -- %s / col op / ind I/O", + vfd_name); + } + else { + + assert(coll_opt_mode == H5FD_MPIO_COLLECTIVE_IO); + + snprintf(test_title, sizeof(test_title), "parallel vector write test 8 -- %s / col op / col I/O", + vfd_name); + } + + TESTING(test_title); + } + + show_progress = ((show_progress) && (mpi_rank == 0)); + + if (show_progress) + fprintf(stdout, "\n%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass); + + /* 1) Allocate local buffers for addrs and bufs, + open the test file with the specified VFD, set the eoa, and setup the dxpl */ + if (pass) { + + tt_addrs = (haddr_t *)malloc((INTS_PER_RANK) * sizeof(haddr_t *)); + tt_bufs = (const void **)malloc((INTS_PER_RANK) * sizeof(void *)); + + if (tt_addrs == NULL || tt_bufs == NULL) { + pass = false; + failure_mssg = "Can't allocate local addrs and bufs buffers."; + } + + if (pass) { + eoa = (haddr_t)mpi_size * (haddr_t)INTS_PER_RANK * (haddr_t)(sizeof(int32_t)); + + setup_vfd_test_file(file_name_id, filename, mpi_size, xfer_mode, coll_opt_mode, vfd_name, eoa, + &lf, &fapl_id, &dxpl_id); + } + } + + if (show_progress) + fprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass); + + /* 2) Using rank zero, write the entire negative_fi_buf to + * the file. + */ + if (pass) { + + size_t image_size = (size_t)mpi_size * (size_t)INTS_PER_RANK * sizeof(int32_t); + + if (mpi_rank == 0) { + + if (H5FDwrite(lf, H5FD_MEM_DRAW, H5P_DEFAULT, (haddr_t)0, image_size, (void *)zero_fi_buf) < 0) { + + pass = false; + failure_mssg = "H5FDwrite() on rank 0 failed.\n"; + } + } + } + + /* 3) Barrier */ + MPI_Barrier(comm); + + if (show_progress) + fprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass); + + /* 4) For each rank, define base_index equal to: + * + * mpi_rank * INTS_PER_RANK + * + * and define base_addr equal to + * + * base_index * sizeof(int32_t). + * + * Set up the array of sizes and types with the compressed feature + * as described in the routine header description. + */ + if (pass) { + + base_index = (mpi_rank * INTS_PER_RANK); + base_addr = (haddr_t)base_index * (haddr_t)sizeof(int32_t); + + count = INTS_PER_RANK - 1; + + types[0] = H5FD_MEM_DRAW; + types[1] = H5FD_MEM_NOLIST; + + sizes[0] = 2 * sizeof(int32_t); + sizes[1] = sizeof(int32_t); + sizes[2] = sizeof(int32_t); + sizes[3] = 0; + + tt_addrs[0] = base_addr; + tt_bufs[0] = (const void *)(&(increasing_fi_buf[base_index])); + + tt_addrs[0] = base_addr; + base_index += 2; + base_addr = (haddr_t)base_index * (haddr_t)sizeof(int32_t); + + for (i = 1; i < (INTS_PER_RANK - 1); i++) { + + tt_addrs[i] = base_addr + ((haddr_t)(i - 1) * (haddr_t)sizeof(int32_t)); + tt_bufs[i] = (const void *)(&(increasing_fi_buf[base_index + (i - 1)])); + } + + if (H5FDwrite_vector(lf, dxpl_id, count, types, tt_addrs, sizes, tt_bufs) < 0) { + + pass = false; + failure_mssg = "H5FDwrite_vector() failed (1).\n"; + } + } + + if (show_progress) + fprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass); + + /* 5) Barrier */ + MPI_Barrier(comm); + + if (show_progress) + fprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass); + + /* 6) On each rank, read the entire file into the read_fi_buf, + * and compare against increasing_fi_buf + * Report failure if any differences are detected. + */ + if (pass) { + + size_t image_size = (size_t)mpi_size * (size_t)INTS_PER_RANK * sizeof(int32_t); + + if (H5FDread(lf, H5FD_MEM_DRAW, H5P_DEFAULT, (haddr_t)0, image_size, (void *)read_fi_buf) < 0) { + + pass = false; + failure_mssg = "H5FDread() failed.\n"; + } + + for (i = 0; ((pass) && (i < mpi_size * INTS_PER_RANK)); i++) { + + if (read_fi_buf[i] != increasing_fi_buf[i]) { + + pass = false; + failure_mssg = "unexpected data read from file (1)"; + } + } + } /* end if */ + + if (show_progress) + fprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass); + + /* 7) Barrier */ + MPI_Barrier(comm); + + if (show_progress) + fprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass); + + /* 8) Close the test file and delete it (on rank 0 only). + * Close FAPL and DXPL. + */ + takedown_vfd_test_file(mpi_rank, filename, &lf, &fapl_id, &dxpl_id); + + /* Free the local buffers */ + if (tt_addrs) { + free(tt_addrs); + tt_addrs = NULL; + } + + if (tt_bufs) { + free(tt_bufs); + tt_bufs = NULL; + } + + if (show_progress) + fprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass); + + /* report results */ + if (mpi_rank == 0) { + + if (pass) { + + PASSED(); + } + else { + + H5_FAILED(); + + if ((disp_failure_mssgs) || (show_progress)) { + fprintf(stdout, "%s: failure_mssg = \"%s\"\n", fcn_name, failure_mssg); + } + } + } + + return (!pass); + +} /* vector_write_test_8() */ + static void test_vector_io(int mpi_rank, int mpi_size) { @@ -4249,6 +4526,13 @@ test_vector_io(int mpi_rank, int mpi_size) nerrs += vector_write_test_7(6, mpi_rank, mpi_size, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, "mpio"); + nerrs += + vector_write_test_8(7, mpi_rank, mpi_size, H5FD_MPIO_INDEPENDENT, H5FD_MPIO_INDIVIDUAL_IO, "mpio"); + nerrs += + vector_write_test_8(7, mpi_rank, mpi_size, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_INDIVIDUAL_IO, "mpio"); + nerrs += + vector_write_test_8(7, mpi_rank, mpi_size, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, "mpio"); + MPI_Barrier(comm); #ifdef H5_HAVE_SUBFILING_VFD diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index 2428c71..831b9de 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -301,10 +301,15 @@ int main(int argc, char **argv) { int mpi_size, mpi_rank; /* mpi variables */ + int mpi_code; H5Ptest_param_t ndsets_params, ngroups_params; H5Ptest_param_t collngroups_params; H5Ptest_param_t io_mode_confusion_params; H5Ptest_param_t rr_obj_flush_confusion_params; +#ifdef H5_HAVE_TEST_API + int required = MPI_THREAD_MULTIPLE; + int provided; +#endif #ifndef H5_HAVE_WIN32_API /* Un-buffer the stdout and stderr */ @@ -312,9 +317,37 @@ main(int argc, char **argv) HDsetbuf(stdout, NULL); #endif - MPI_Init(&argc, &argv); - MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); +#ifdef H5_HAVE_TEST_API + /* Attempt to initialize with MPI_THREAD_MULTIPLE if possible */ + if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(&argc, &argv, required, &provided))) { + printf("MPI_Init_thread failed with error code %d\n", mpi_code); + return -1; + } +#else + if (MPI_SUCCESS != (mpi_code = MPI_Init(&argc, &argv))) { + printf("MPI_Init failed with error code %d\n", mpi_code); + return -1; + } +#endif + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank))) { + printf("MPI_Comm_rank failed with error code %d\n", mpi_code); + MPI_Finalize(); + return -1; + } + +#ifdef H5_HAVE_TEST_API + /* Warn about missing MPI_THREAD_MULTIPLE support */ + if ((provided < required) && MAINPROCESS) + printf("** MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE **\n"); +#endif + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(MPI_COMM_WORLD, &mpi_size))) { + if (MAINPROCESS) + printf("MPI_Comm_size failed with error code %d\n", mpi_code); + MPI_Finalize(); + return -1; + } mpi_rank_framework_g = mpi_rank; @@ -351,6 +384,7 @@ main(int argc, char **argv) /* Tests are generally arranged from least to most complexity... */ AddTest("mpiodup", test_fapl_mpio_dup, NULL, "fapl_mpio duplicate", NULL); + AddTest("getdxplmpio", test_get_dxpl_mpio, NULL, "dxpl_mpio get", PARATESTFILE); AddTest("split", test_split_comm_access, NULL, "dataset using split communicators", PARATESTFILE); AddTest("h5oflusherror", test_oflush, NULL, "H5Oflush failure", PARATESTFILE); @@ -368,6 +402,8 @@ main(int argc, char **argv) AddTest("evictparassert", test_evict_on_close_parallel_unsupp, NULL, "Evict on close in parallel failure", PARATESTFILE); + AddTest("fapl_preserve", test_fapl_preserve_hints, NULL, "preserve MPI I/O hints after fapl closed", + PARATESTFILE); AddTest("idsetw", dataset_writeInd, NULL, "dataset independent write", PARATESTFILE); AddTest("idsetr", dataset_readInd, NULL, "dataset independent read", PARATESTFILE); diff --git a/testpar/testphdf5.h b/testpar/testphdf5.h index 6bbdb0d..31b7c69 100644 --- a/testpar/testphdf5.h +++ b/testpar/testphdf5.h @@ -234,6 +234,7 @@ void test_file_properties(void); void test_delete(void); void test_invalid_libver_bounds_file_close_assert(void); void test_evict_on_close_parallel_unsupp(void); +void test_fapl_preserve_hints(void); void multiple_dset_write(void); void multiple_group_write(void); void multiple_group_read(void); @@ -241,6 +242,7 @@ void collective_group_write_independent_group_read(void); void collective_group_write(void); void independent_group_read(void); void test_fapl_mpio_dup(void); +void test_get_dxpl_mpio(void); void test_split_comm_access(void); void test_page_buffer_access(void); void dataset_atomicity(void); |