From e80079fd21ffe6978ac69e7632e069cc44874675 Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Thu, 6 Oct 2022 11:08:56 -0500 Subject: [PATCH] Subfiling Fortran wrapper work. (#2143) * added C ref. for Fortran constants * added C ref. for Fortran constants * move constant paramters to H5* module listing * added back comment * Fortran subfiling and ioc FD with tests. H5Pset/get_mpi_params wrappers with tests, misc.. parallel test clean-up. * misc. fixes * fixed CMake testpar issues, formatted, misc. updates * updated tests --- CMakeLists.txt | 1 + fortran/src/H5Pf.c | 81 ++++++ fortran/src/H5Pff.F90 | 243 ++++++++++++++++++ fortran/src/H5_f.c | 31 +++ fortran/src/H5_ff.F90 | 32 ++- fortran/src/H5config_f.inc.cmake | 8 +- fortran/src/H5config_f.inc.in | 3 + fortran/src/H5f90global.F90 | 19 +- fortran/src/H5f90proto.h | 2 + fortran/src/hdf5_fortrandll.def.in | 6 + fortran/testpar/CMakeLists.txt | 44 +++- fortran/testpar/CMakeTests.cmake | 1 + fortran/testpar/Makefile.am | 5 +- fortran/testpar/hyper.F90 | 31 ++- fortran/testpar/mdset.F90 | 1 - fortran/testpar/ptest.F90 | 4 +- fortran/testpar/subfiling.F90 | 391 +++++++++++++++++++++++++++++ src/H5FDsubfiling/H5FDsubfiling.h | 1 + 18 files changed, 870 insertions(+), 34 deletions(-) create mode 100644 fortran/testpar/subfiling.F90 diff --git a/CMakeLists.txt b/CMakeLists.txt index d1ef0ae64f..15caa32727 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1133,6 +1133,7 @@ if (EXISTS "${HDF5_SOURCE_DIR}/fortran" AND IS_DIRECTORY "${HDF5_SOURCE_DIR}/for # Parallel IO usage requires MPI to be Linked and Included if (H5_HAVE_PARALLEL) + find_package(MPI REQUIRED COMPONENTS Fortran) set (LINK_Fortran_LIBS ${LINK_Fortran_LIBS} ${MPI_Fortran_LIBRARIES}) if (MPI_Fortran_LINK_FLAGS) set (CMAKE_Fortran_EXE_LINKER_FLAGS "${MPI_Fortran_LINK_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}") diff --git a/fortran/src/H5Pf.c b/fortran/src/H5Pf.c index 876457f54b..58f8f243b0 100644 --- a/fortran/src/H5Pf.c +++ b/fortran/src/H5Pf.c @@ -5473,6 +5473,87 @@ h5pget_fapl_mpio_c(hid_t_f *prp_id, int_f *comm, int_f *info) ret_value = 0; return ret_value; } + +/****if* H5Pf/h5pset_mpi_params_c + * NAME + * h5pset_mpi_params_c + * PURPOSE + * Set the MPI communicator and info. + * INPUTS + * prp_id - property list identifier + * comm - MPI communicator + * info - MPI info object + * RETURNS + * 0 on success, -1 on failure + * AUTHOR + * M.S. Breitenfeld + * October 2022 + * + * SOURCE + */ +int_f +h5pset_mpi_params_c(hid_t_f *prp_id, int_f *comm, int_f *info) +/******/ +{ + int ret_value = -1; + hid_t c_prp_id; + herr_t ret; + MPI_Comm c_comm; + MPI_Info c_info; + c_comm = MPI_Comm_f2c(*comm); + c_info = MPI_Info_f2c(*info); + + /* + * Call H5Pset_mpi_params. + */ + c_prp_id = *prp_id; + ret = H5Pset_mpi_params(c_prp_id, c_comm, c_info); + if (ret < 0) + return ret_value; + ret_value = 0; + return ret_value; +} + +/****if* H5Pf/h5pget_mpi_params_c + * NAME + * h5pget_mpi_params_c + * PURPOSE + * Get the MPI communicator and info. + * INPUTS + * prp_id - property list identifier + * comm - MPI communicator + * info - MPI info object + * RETURNS + * 0 on success, -1 on failure + * AUTHOR + * M.S. Breitenfeld + * October 2022 + * + * SOURCE + */ +int_f +h5pget_mpi_params_c(hid_t_f *prp_id, int_f *comm, int_f *info) +/******/ +{ + int ret_value = -1; + hid_t c_prp_id; + herr_t ret; + MPI_Comm c_comm; + MPI_Info c_info; + + /* + * Call H5Pget_mpi_params function. + */ + c_prp_id = *prp_id; + ret = H5Pget_mpi_params(c_prp_id, &c_comm, &c_info); + if (ret < 0) + return ret_value; + *comm = (int_f)MPI_Comm_c2f(c_comm); + *info = (int_f)MPI_Info_c2f(c_info); + ret_value = 0; + return ret_value; +} + /****if* H5Pf/h5pset_dxpl_mpio_c * NAME * h5pset_dxpl_mpio_c diff --git a/fortran/src/H5Pff.F90 b/fortran/src/H5Pff.F90 index 40c0a92955..4de2a9d558 100644 --- a/fortran/src/H5Pff.F90 +++ b/fortran/src/H5Pff.F90 @@ -182,6 +182,37 @@ MODULE H5P #endif +#ifdef H5_HAVE_PARALLEL +#ifdef H5_HAVE_SUBFILING_VFD +!> \addtogroup FH5P +!> @{ + + !> @brief H5FD_subfiling_params_t derived type used in the subfiling VFD. + TYPE, BIND(C) :: H5FD_subfiling_params_t + INTEGER(ENUM_T) :: ioc_selection !< Method to select I/O concentrators + INTEGER(C_INT64_T) :: stripe_size !< Size (in bytes) of data stripes in subfiles + INTEGER(C_INT32_T) :: stripe_count !< Target number of subfiles to use + END TYPE H5FD_subfiling_params_t + + !> @brief H5FD_subfiling_config_t derived type used in the subfiling VFD. + TYPE, BIND(C) :: H5FD_subfiling_config_t + INTEGER(C_INT32_T) :: magic !< Set to H5FD_SUBFILING_FAPL_MAGIC_F + INTEGER(C_INT32_T) :: version !< Set to H5FD_CURR_SUBFILING_FAPL_VERSION_F + INTEGER(HID_T) :: ioc_fapl_id !< The FAPL setup with the stacked VFD to use for I/O concentrators + LOGICAL(C_BOOL) :: require_ioc !< Whether to use the IOC VFD (currently must always be TRUE) + TYPE(H5FD_subfiling_params_t) :: shared_cfg !< Subfiling/IOC parameters (stripe size, stripe count, etc.) + END TYPE H5FD_subfiling_config_t + + !> @brief H5FD_ioc_config_t derived type used in the IOC VFD (SUBFILING). + TYPE, BIND(C) :: H5FD_ioc_config_t + INTEGER(C_INT32_T) :: magic !< Must be set to H5FD_IOC_FAPL_MAGIC_F + INTEGER(C_INT32_T) :: version !< Must be set to H5FD_IOC_CURR_FAPL_VERSION_F + INTEGER(C_INT32_T) :: thread_pool_size !< Number of I/O concentrator worker threads to use + END TYPE H5FD_ioc_config_t +!> @} +#endif +#endif + CONTAINS !> @@ -5042,6 +5073,218 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr) END SUBROUTINE h5pget_fapl_mpio_f +#ifdef H5_HAVE_SUBFILING_VFD +!> +!! \ingroup FH5P +!! +!! \brief Modifies the specified File Access Property List to use the #H5FD_SUBFILING driver. +!! +!! \param prp_id File access property list identifier. +!! \param hdferr \fortran_error +!! \param vfd_config #H5FD_SUBFILING driver configuration derived type. +!! +!! See C API: @ref herr_t H5Pset_fapl_subfiling(hid_t fapl_id, const H5FD_subfiling_config_t *vfd_config); +!! + SUBROUTINE h5pset_fapl_subfiling_f(prp_id, hdferr, vfd_config) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + INTEGER, INTENT(OUT) :: hdferr + TYPE(H5FD_subfiling_config_t), OPTIONAL, TARGET :: vfd_config + TYPE(C_PTR) :: f_ptr + + INTERFACE + INTEGER FUNCTION H5Pset_fapl_subfiling(prp_id, vfd_config) & + BIND(C,NAME='H5Pset_fapl_subfiling') + IMPORT :: HID_T, C_PTR + IMPLICIT NONE + INTEGER(HID_T), VALUE :: prp_id + TYPE(C_PTR) , VALUE :: vfd_config + END FUNCTION h5pset_fapl_subfiling + END INTERFACE + + IF(PRESENT(vfd_config))THEN + f_ptr = C_LOC(vfd_config) + ELSE + f_ptr = C_NULL_PTR + ENDIF + + hdferr = h5pset_fapl_subfiling(prp_id, f_ptr) + + END SUBROUTINE h5pset_fapl_subfiling_f + +!> +!! \ingroup FH5P +!! +!! \brief Queries a File Access Property List for #H5FD_SUBFILING file driver properties. +!! +!! \param prp_id File access property list identifier. +!! \param vfd_config #H5FD_SUBFILING driver configuration derived type. +!! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_fapl_subfiling(hid_t fapl_id, H5FD_subfiling_config_t *config_out); +!! + SUBROUTINE h5pget_fapl_subfiling_f(prp_id, vfd_config, hdferr) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + TYPE(H5FD_subfiling_config_t), TARGET :: vfd_config + INTEGER, INTENT(OUT) :: hdferr + TYPE(C_PTR) :: f_ptr + + INTERFACE + INTEGER FUNCTION H5Pget_fapl_subfiling(prp_id, vfd_config) & + BIND(C,NAME='H5Pget_fapl_subfiling') + IMPORT :: HID_T, C_PTR + IMPLICIT NONE + INTEGER(HID_T), VALUE :: prp_id + TYPE(C_PTR) , VALUE :: vfd_config + END FUNCTION H5Pget_fapl_subfiling + END INTERFACE + + f_ptr = C_LOC(vfd_config) + hdferr = h5pget_fapl_subfiling(prp_id, f_ptr) + + END SUBROUTINE h5pget_fapl_subfiling_f + +!> +!! \ingroup FH5P +!! +!! \brief Modifies the specified File Access Property List to use the #H5FD_IOC driver. +!! +!! \param prp_id File access property list identifier. +!! \param hdferr \fortran_error +!! \param vfd_config #H5FD_IOC driver configuration derived type. +!! +!! See C API: @ref herr_t H5Pset_fapl_ioc(hid_t fapl_id, const H5FD_ioc_config_t *vfd_config); +!! + SUBROUTINE h5pset_fapl_ioc_f(prp_id, hdferr, vfd_config) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + TYPE(H5FD_ioc_config_t), OPTIONAL, TARGET :: vfd_config + INTEGER, INTENT(OUT) :: hdferr + TYPE(C_PTR) :: f_ptr + + INTERFACE + INTEGER FUNCTION H5Pset_fapl_ioc(prp_id, vfd_config) & + BIND(C,NAME='H5Pset_fapl_ioc') + IMPORT :: HID_T, C_PTR + IMPLICIT NONE + INTEGER(HID_T), VALUE :: prp_id + TYPE(C_PTR) , VALUE :: vfd_config + END FUNCTION h5pset_fapl_ioc + END INTERFACE + + IF(PRESENT(vfd_config))THEN + f_ptr = C_LOC(vfd_config) + ELSE + f_ptr = C_NULL_PTR + ENDIF + + hdferr = h5pset_fapl_ioc(prp_id, f_ptr) + + END SUBROUTINE h5pset_fapl_ioc_f + +!> +!! \ingroup FH5P +!! +!! \brief Queries a File Access Property List for #H5FD_IOC file driver properties. +!! +!! \param prp_id File access property list identifier. +!! \param vfd_config #H5FD_IOC driver configuration derived type. +!! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *config_out); +!! + SUBROUTINE h5pget_fapl_ioc_f(prp_id, vfd_config, hdferr) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + TYPE(H5FD_ioc_config_t), TARGET :: vfd_config + INTEGER, INTENT(OUT) :: hdferr + TYPE(C_PTR) :: f_ptr + + INTERFACE + INTEGER FUNCTION H5Pget_fapl_ioc(prp_id, vfd_config) & + BIND(C,NAME='H5Pget_fapl_ioc') + IMPORT :: HID_T, C_PTR + IMPLICIT NONE + INTEGER(HID_T), VALUE :: prp_id + TYPE(C_PTR) , VALUE :: vfd_config + END FUNCTION H5Pget_fapl_ioc + END INTERFACE + + f_ptr = C_LOC(vfd_config) + hdferr = h5pget_fapl_ioc(prp_id, f_ptr) + + END SUBROUTINE h5pget_fapl_ioc_f +#endif + +!> +!! \ingroup FH5P +!! +!! \brief Set the MPI communicator and info. +!! +!! \param prp_id File access property list identifier. +!! \param comm The MPI communicator. +!! \param info The MPI info object. +!! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pset_mpi_params(hid_t plist_id, MPI_Comm comm, MPI_Info info); +!! + SUBROUTINE H5Pset_mpi_params_f(prp_id, comm, info, hdferr) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + INTEGER , INTENT(IN) :: comm + INTEGER , INTENT(IN) :: info + INTEGER , INTENT(OUT) :: hdferr + + INTERFACE + INTEGER FUNCTION h5pset_mpi_params_c(prp_id, comm, info) & + BIND(C,NAME='h5pset_mpi_params_c') + IMPORT :: HID_T + IMPLICIT NONE + INTEGER(HID_T) :: prp_id + INTEGER :: comm + INTEGER :: info + END FUNCTION H5pset_mpi_params_c + END INTERFACE + + hdferr = H5Pset_mpi_params_c(prp_id, comm, info) + + END SUBROUTINE H5Pset_mpi_params_f + +!> +!! \ingroup FH5P +!! +!! \brief Get the MPI communicator and info. +!! +!! \param prp_id File access property list identifier. +!! \param comm The MPI communicator. +!! \param info The MPI info object. +!! \param hdferr \fortran_error +!! +!! See C API: @ref herr_t H5Pget_mpi_params(hid_t fapl_id, MPI_Comm *comm, MPI_Info *info); +!! + SUBROUTINE H5Pget_mpi_params_f(prp_id, comm, info, hdferr) + IMPLICIT NONE + INTEGER(HID_T), INTENT(IN) :: prp_id + INTEGER , INTENT(OUT) :: comm + INTEGER , INTENT(OUT) :: info + INTEGER , INTENT(OUT) :: hdferr + + INTERFACE + INTEGER FUNCTION h5pget_mpi_params_c(prp_id, comm, info) & + BIND(C,NAME='h5pget_mpi_params_c') + IMPORT :: HID_T + IMPLICIT NONE + INTEGER(HID_T) :: prp_id + INTEGER :: comm + INTEGER :: info + END FUNCTION H5pget_mpi_params_c + END INTERFACE + + hdferr = H5Pget_mpi_params_c(prp_id, comm, info) + + END SUBROUTINE H5Pget_mpi_params_f + !> !! \ingroup FH5P !! diff --git a/fortran/src/H5_f.c b/fortran/src/H5_f.c index 468debefbb..385241d846 100644 --- a/fortran/src/H5_f.c +++ b/fortran/src/H5_f.c @@ -525,6 +525,31 @@ h5init_flags_c(int_f *h5d_flags, size_t_f *h5d_size_flags, int_f *h5e_flags, hid h5fd_flags[8] = (int_f)H5FD_MEM_LHEAP; h5fd_flags[9] = (int_f)H5FD_MEM_OHDR; h5fd_flags[10] = (int_f)H5FD_MEM_NTYPES; +#ifdef H5_HAVE_SUBFILING_VFD + h5fd_flags[11] = (int_f)H5FD_SUBFILING_CURR_FAPL_VERSION; + h5fd_flags[12] = (int_f)H5FD_SUBFILING_FAPL_MAGIC; + h5fd_flags[13] = (int_f)H5FD_SUBFILING_DEFAULT_STRIPE_COUNT; + h5fd_flags[14] = (int_f)H5FD_IOC_FAPL_MAGIC; + h5fd_flags[15] = (int_f)H5FD_IOC_CURR_FAPL_VERSION; + h5fd_flags[16] = (int_f)H5FD_IOC_DEFAULT_THREAD_POOL_SIZE; + h5fd_flags[17] = (int_f)SELECT_IOC_ONE_PER_NODE; + h5fd_flags[18] = (int_f)SELECT_IOC_EVERY_NTH_RANK; + h5fd_flags[19] = (int_f)SELECT_IOC_WITH_CONFIG; + h5fd_flags[20] = (int_f)SELECT_IOC_TOTAL; + h5fd_flags[21] = (int_f)ioc_selection_options; +#else + h5fd_flags[11] = 0; + h5fd_flags[12] = 0; + h5fd_flags[13] = 0; + h5fd_flags[14] = 0; + h5fd_flags[15] = 0; + h5fd_flags[16] = 0; + h5fd_flags[17] = 0; + h5fd_flags[18] = 0; + h5fd_flags[19] = 0; + h5fd_flags[20] = 0; + h5fd_flags[21] = 0; +#endif /* * H5FD flags of type hid_t @@ -536,6 +561,12 @@ h5init_flags_c(int_f *h5d_flags, size_t_f *h5d_size_flags, int_f *h5e_flags, hid h5fd_hid_flags[4] = (hid_t_f)H5FD_MULTI; h5fd_hid_flags[5] = (hid_t_f)H5FD_SEC2; h5fd_hid_flags[6] = (hid_t_f)H5FD_STDIO; + h5fd_hid_flags[7] = (hid_t_f)H5FD_SUBFILING; +#ifdef H5_HAVE_SUBFILING_VFD + h5fd_hid_flags[8] = (hid_t_f)H5FD_SUBFILING_DEFAULT_STRIPE_SIZE; +#else + h5fd_hid_flags[8] = 0; +#endif /* * H5G flags diff --git a/fortran/src/H5_ff.F90 b/fortran/src/H5_ff.F90 index 1dc90c2f78..8c7acfec9b 100644 --- a/fortran/src/H5_ff.F90 +++ b/fortran/src/H5_ff.F90 @@ -92,12 +92,12 @@ MODULE H5LIB ! ! H5FD flags declaration ! - INTEGER, PARAMETER :: H5FD_FLAGS_LEN = 11 + INTEGER, PARAMETER :: H5FD_FLAGS_LEN = 22 INTEGER, DIMENSION(1:H5FD_FLAGS_LEN) :: H5FD_flags ! ! H5FD file drivers flags declaration ! - INTEGER, PARAMETER :: H5FD_HID_FLAGS_LEN = 7 + INTEGER, PARAMETER :: H5FD_HID_FLAGS_LEN = 9 INTEGER(HID_T), DIMENSION(1:H5FD_HID_FLAGS_LEN) :: H5FD_hid_flags ! ! H5I flags declaration @@ -436,16 +436,30 @@ CONTAINS H5FD_MEM_LHEAP_F = H5FD_flags(9) H5FD_MEM_OHDR_F = H5FD_flags(10) H5FD_MEM_NTYPES_F = H5FD_flags(11) + H5FD_SUBFILING_CURR_FAPL_VERSION_F = H5FD_flags(12) + H5FD_SUBFILING_FAPL_MAGIC_F = H5FD_flags(13) + H5FD_SUBFILING_DEFAULT_STRIPE_COUNT_F = H5FD_flags(14) + H5FD_IOC_FAPL_MAGIC_F = H5FD_flags(15) + H5FD_IOC_CURR_FAPL_VERSION_F = H5FD_flags(16) + H5FD_IOC_DEFAULT_THREAD_POOL_SIZE_F = H5FD_flags(17) + SELECT_IOC_ONE_PER_NODE_F = H5FD_flags(18) + SELECT_IOC_EVERY_NTH_RANK_F = H5FD_flags(19) + SELECT_IOC_WITH_CONFIG_F = H5FD_flags(20) + SELECT_IOC_TOTAL_F = H5FD_flags(21) + IOC_SELECTION_OPTIONS_F = H5FD_flags(22) + ! ! H5FD file driver flags ! - H5FD_CORE_F = H5FD_hid_flags(1) - H5FD_FAMILY_F = H5FD_hid_flags(2) - H5FD_LOG_F = H5FD_hid_flags(3) - H5FD_MPIO_F = H5FD_hid_flags(4) - H5FD_MULTI_F = H5FD_hid_flags(5) - H5FD_SEC2_F = H5FD_hid_flags(6) - H5FD_STDIO_F = H5FD_hid_flags(7) + H5FD_CORE_F = H5FD_hid_flags(1) + H5FD_FAMILY_F = H5FD_hid_flags(2) + H5FD_LOG_F = H5FD_hid_flags(3) + H5FD_MPIO_F = H5FD_hid_flags(4) + H5FD_MULTI_F = H5FD_hid_flags(5) + H5FD_SEC2_F = H5FD_hid_flags(6) + H5FD_STDIO_F = H5FD_hid_flags(7) + H5FD_SUBFILING_F = H5FD_hid_flags(8) + H5FD_SUBFILING_DEFAULT_STRIPE_SIZE_F = H5FD_hid_flags(9) ! ! H5I flags declaration ! diff --git a/fortran/src/H5config_f.inc.cmake b/fortran/src/H5config_f.inc.cmake index 565d6eb338..46dfb690aa 100644 --- a/fortran/src/H5config_f.inc.cmake +++ b/fortran/src/H5config_f.inc.cmake @@ -11,12 +11,18 @@ ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! fortran/src/H5config_f.inc. Generated from fortran/src/H5config_f.inc.in by configure -! Define if we have parallel support +! Define if there is parallel support #cmakedefine01 H5_HAVE_PARALLEL #if H5_HAVE_PARALLEL == 0 #undef H5_HAVE_PARALLEL #endif +! Define if there is subfiling support +#cmakedefine01 H5_HAVE_SUBFILING_VFD +#if H5_HAVE_SUBFILING_VFD == 0 +#undef H5_HAVE_SUBFILING_VFD +#endif + ! Define if the intrinsic function STORAGE_SIZE exists #define H5_FORTRAN_HAVE_STORAGE_SIZE @H5_FORTRAN_HAVE_STORAGE_SIZE@ diff --git a/fortran/src/H5config_f.inc.in b/fortran/src/H5config_f.inc.in index 685b4d20dd..0ce33eccd0 100644 --- a/fortran/src/H5config_f.inc.in +++ b/fortran/src/H5config_f.inc.in @@ -17,6 +17,9 @@ ! Define if we have parallel support #undef HAVE_PARALLEL +! Define if we have subfiling support +#undef HAVE_SUBFILING_VFD + ! Define if the intrinsic function STORAGE_SIZE exists #undef FORTRAN_HAVE_STORAGE_SIZE diff --git a/fortran/src/H5f90global.F90 b/fortran/src/H5f90global.F90 index 12e40bfa8a..6ad3366a40 100644 --- a/fortran/src/H5f90global.F90 +++ b/fortran/src/H5f90global.F90 @@ -425,7 +425,8 @@ MODULE H5GLOBAL !DEC$ATTRIBUTES DLLEXPORT :: H5FD_SEC2_F !DEC$ATTRIBUTES DLLEXPORT :: H5FD_STDIO_F !DEC$endif - +!> \addtogroup FH5P +!> @{ INTEGER :: H5FD_MPIO_INDEPENDENT_F !< H5FD_MPIO_INDEPENDENT INTEGER :: H5FD_MPIO_COLLECTIVE_F !< H5FD_MPIO_COLLECTIVE INTEGER :: H5FD_MEM_NOLIST_F !< H5FD_MEM_NOLIST @@ -437,6 +438,18 @@ MODULE H5GLOBAL INTEGER :: H5FD_MEM_LHEAP_F !< H5FD_MEM_LHEAP INTEGER :: H5FD_MEM_OHDR_F !< H5FD_MEM_OHDR INTEGER :: H5FD_MEM_NTYPES_F !< H5FD_MEM_NTYPES + INTEGER :: H5FD_SUBFILING_CURR_FAPL_VERSION_F !< H5FD_SUBFILING_CURR_FAPL_VERSION + INTEGER :: H5FD_SUBFILING_FAPL_MAGIC_F !< H5FD_SUBFILING_FAPL_MAGIC + INTEGER :: H5FD_SUBFILING_DEFAULT_STRIPE_COUNT_F !< H5FD_SUBFILING_DEFAULT_STRIPE_COUNT + INTEGER :: H5FD_IOC_CURR_FAPL_VERSION_F !< H5FD_IOC_CURR_FAPL_VERSION + INTEGER :: H5FD_IOC_FAPL_MAGIC_F !< H5FD_IOC_FAPL_MAGIC + INTEGER :: H5FD_IOC_DEFAULT_THREAD_POOL_SIZE_F !< H5FD_IOC_DEFAULT_THREAD_POOL_SIZE + INTEGER :: SELECT_IOC_ONE_PER_NODE_F !< Default, SELECT_IOC_ONE_PER_NODE + INTEGER :: SELECT_IOC_EVERY_NTH_RANK_F !< Starting at rank 0, select-next += N, SELECT_IOC_EVERY_NTH_RANK + INTEGER :: SELECT_IOC_WITH_CONFIG_F !< NOT IMPLEMENTED: Read-from-file, SELECT_IOC_WITH_CONFIG + INTEGER :: SELECT_IOC_TOTAL_F !< Starting at rank 0, mpi_size / total, SELECT_IOC_TOTAL + INTEGER :: IOC_SELECTION_OPTIONS_F !< Sentinel value, IOC_SELECTION_OPTIONS + INTEGER(HID_T) :: H5FD_CORE_F !< H5FD_CORE INTEGER(HID_T) :: H5FD_FAMILY_F !< H5FD_FAMILY INTEGER(HID_T) :: H5FD_LOG_F !< H5FD_LOG @@ -444,6 +457,10 @@ MODULE H5GLOBAL INTEGER(HID_T) :: H5FD_MULTI_F !< H5FD_MULTI INTEGER(HID_T) :: H5FD_SEC2_F !< H5FD_SEC2 INTEGER(HID_T) :: H5FD_STDIO_F !< H5FD_STDIO + INTEGER(HID_T) :: H5FD_SUBFILING_F !< H5FD_SUBFILING + INTEGER(HID_T) :: H5FD_SUBFILING_DEFAULT_STRIPE_SIZE_F !< H5FD_SUBFILING_DEFAULT_STRIPE_SIZE + +!> @} ! ! H5I flags declaration ! diff --git a/fortran/src/H5f90proto.h b/fortran/src/H5f90proto.h index 0b348b7fb2..3cfba71843 100644 --- a/fortran/src/H5f90proto.h +++ b/fortran/src/H5f90proto.h @@ -534,6 +534,8 @@ H5_FCDLL int_f h5pget_chunk_cache_c(hid_t_f *dapl_id, size_t_f *rdcc_nslots, siz H5_FCDLL int_f h5pget_mpio_actual_io_mode_c(hid_t_f *dxpl_id, int_f *actual_io_mode); H5_FCDLL int_f h5pget_fapl_mpio_c(hid_t_f *prp_id, int_f *comm, int_f *info); H5_FCDLL int_f h5pset_fapl_mpio_c(hid_t_f *prp_id, int_f *comm, int_f *info); +H5_FCDLL int_f h5pget_mpi_params_c(hid_t_f *prp_id, int_f *comm, int_f *info); +H5_FCDLL int_f h5pset_mpi_params_c(hid_t_f *prp_id, int_f *comm, int_f *info); H5_FCDLL int_f h5pget_dxpl_mpio_c(hid_t_f *prp_id, int_f *data_xfer_mode); H5_FCDLL int_f h5pset_dxpl_mpio_c(hid_t_f *prp_id, int_f *data_xfer_mode); #endif diff --git a/fortran/src/hdf5_fortrandll.def.in b/fortran/src/hdf5_fortrandll.def.in index 4207239f44..f61f74bae2 100644 --- a/fortran/src/hdf5_fortrandll.def.in +++ b/fortran/src/hdf5_fortrandll.def.in @@ -344,6 +344,12 @@ H5P_mp_H5PGET_FILE_LOCKING_F ; Parallel @H5_NOPAREXP@H5P_mp_H5PSET_FAPL_MPIO_F @H5_NOPAREXP@H5P_mp_H5PGET_FAPL_MPIO_F +@H5_NOPAREXP@H5P_mp_H5PSET_FAPL_SUBFILING_F +@H5_NOPAREXP@H5P_mp_H5PGET_FAPL_SUBFILING_F +@H5_NOPAREXP@H5P_mp_H5PSET_FAPL_IOC_F +@H5_NOPAREXP@H5P_mp_H5PGET_FAPL_IOC_F +@H5_NOPAREXP@H5P_mp_H5PSET_MPI_PARAMS_F +@H5_NOPAREXP@H5P_mp_H5PGET_MPI_PARAMS_F @H5_NOPAREXP@H5P_mp_H5PSET_DXPL_MPIO_F @H5_NOPAREXP@H5P_mp_H5PGET_DXPL_MPIO_F @H5_NOPAREXP@H5P_mp_H5PGET_MPIO_ACTUAL_IO_MODE_F diff --git a/fortran/testpar/CMakeLists.txt b/fortran/testpar/CMakeLists.txt index c6712d3e26..e395937822 100644 --- a/fortran/testpar/CMakeLists.txt +++ b/fortran/testpar/CMakeLists.txt @@ -4,7 +4,7 @@ project (HDF5_FORTRAN_TESTPAR C Fortran) #----------------------------------------------------------------------------- # Setup include Directories #----------------------------------------------------------------------------- -set (TESTPAR_INCLUDES ${MPI_Fortran_INCLUDE_DIRS} ${HDF5_F90_BINARY_DIR} ${HDF5_F90_SRC_DIR}/src)) +set (TESTPAR_INCLUDES ${MPI_Fortran_INCLUDE_DIRS} ${HDF5_F90_BINARY_DIR} ${HDF5_F90_SRC_DIR}/src) if (NOT BUILD_SHARED_LIBS) set (TESTPAR_INCLUDES ${TESTPAR_INCLUDES} ${CMAKE_Fortran_MODULE_DIRECTORY}/static) else () @@ -53,12 +53,50 @@ else () ) endif () -#set_property(TARGET parallel_test APPEND PROPERTY LINK_FLAGS $<$:"-SUBSYSTEM:CONSOLE">) -#set_property(TARGET parallel_test APPEND PROPERTY LINK_FLAGS $<$:${WIN_LINK_FLAGS}>) if(MSVC) set_property(TARGET parallel_test PROPERTY LINK_FLAGS "/SUBSYSTEM:CONSOLE ${WIN_LINK_FLAGS}") endif() +#-- Adding test for subfiling_test +add_executable (subfiling_test + subfiling.F90 +) +target_include_directories (subfiling_test + PRIVATE ${TESTPAR_INCLUDES} +) +target_compile_options(subfiling_test + PRIVATE + "${HDF5_CMAKE_Fortran_FLAGS}" + $<$:${WIN_COMPILE_FLAGS}> +) +if (NOT BUILD_SHARED_LIBS) + target_link_libraries (subfiling_test + PRIVATE + ${HDF5_F90_TEST_LIB_TARGET} ${HDF5_F90_LIB_TARGET} ${HDF5_LIB_TARGET} ${LINK_Fortran_LIBS} + $<$:"ws2_32.lib"> + ) + set_target_properties (subfiling_test PROPERTIES + FOLDER test/fortran + LINKER_LANGUAGE Fortran + Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/static + ) +else () + target_link_libraries (subfiling_test + PRIVATE + ${HDF5_F90_TEST_LIBSH_TARGET} ${HDF5_F90_LIBSH_TARGET} ${HDF5_LIBSH_TARGET} ${LINK_Fortran_LIBS} + $<$:"ws2_32.lib"> + ) + set_target_properties (subfiling_test PROPERTIES + FOLDER test/fortran + LINKER_LANGUAGE Fortran + Fortran_MODULE_DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/shared + ) +endif () + +if(MSVC) + set_property(TARGET subfiling_test PROPERTY LINK_FLAGS "/SUBSYSTEM:CONSOLE ${WIN_LINK_FLAGS}") +endif() + if (HDF5_TEST_FORTRAN AND HDF5_TEST_PARALLEL) include (CMakeTests.cmake) endif () diff --git a/fortran/testpar/CMakeTests.cmake b/fortran/testpar/CMakeTests.cmake index 02eb897705..1d893d5719 100644 --- a/fortran/testpar/CMakeTests.cmake +++ b/fortran/testpar/CMakeTests.cmake @@ -16,3 +16,4 @@ ############################################################################## ############################################################################## add_test (NAME MPI_TEST_FORT_parallel_test COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) +add_test (NAME MPI_TEST_FORT_subfiling_test COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $ ${MPIEXEC_POSTFLAGS}) \ No newline at end of file diff --git a/fortran/testpar/Makefile.am b/fortran/testpar/Makefile.am index 00538f4a8d..bd5c725af9 100644 --- a/fortran/testpar/Makefile.am +++ b/fortran/testpar/Makefile.am @@ -33,14 +33,15 @@ else endif # These are our main targets -TEST_PROG_PARA=parallel_test +TEST_PROG_PARA=parallel_test subfiling_test check_PROGRAMS=$(TEST_PROG_PARA) # Temporary files -CHECK_CLEANFILES+=parf[12].h5 +CHECK_CLEANFILES+=parf[12].h5 subf.h5* # Test source files parallel_test_SOURCES=ptest.F90 hyper.F90 mdset.F90 +subfiling_test_SOURCES=subfiling.F90 # The tests depend on several libraries. LDADD=$(LIBH5FTEST) $(LIBH5TEST) $(LIBH5F) $(LIBHDF5) diff --git a/fortran/testpar/hyper.F90 b/fortran/testpar/hyper.F90 index 4dc18a7841..910fe1f9ad 100644 --- a/fortran/testpar/hyper.F90 +++ b/fortran/testpar/hyper.F90 @@ -29,7 +29,6 @@ SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors) INTEGER, INTENT(in) :: mpi_size ! number of processes in the group of communicator INTEGER, INTENT(in) :: mpi_rank ! rank of the calling process in the communicator INTEGER, INTENT(inout) :: nerrors ! number of errors - INTEGER :: mpierror ! MPI hdferror flag INTEGER :: hdferror ! HDF hdferror flag INTEGER(hsize_t), DIMENSION(1) :: dims ! dataset dimensions INTEGER(hsize_t), DIMENSION(1) :: cdims ! chunk dimensions @@ -285,33 +284,33 @@ SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors) CALL check("h5pcreate_f", hdferror, nerrors) CALL h5pset_fapl_mpio_f(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5pset_fapl_mpio_f", hdferror, nerrors) CALL h5fopen_f(filename, H5F_ACC_RDWR_F, file_id, hdferror, access_prp = fapl_id) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5fopen_f", hdferror, nerrors) CALL h5screate_simple_f(1, dims, fspace_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5screate_simple_f", hdferror, nerrors) CALL h5screate_simple_f(1, dims, mspace_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check(" h5screate_simple_f", hdferror, nerrors) CALL h5dopen_f(file_id, "dset", dset_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5dopen_f", hdferror, nerrors) ! ! select hyperslab in memory ! CALL h5sselect_hyperslab_f(mspace_id, H5S_SELECT_SET_F, start, counti, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5sselect_hyperslab_f", hdferror, nerrors) ! ! select hyperslab in the file ! CALL h5sselect_hyperslab_f(fspace_id, H5S_SELECT_SET_F, start, counti, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5sselect_hyperslab_f", hdferror, nerrors) ! ! create a property list for collective dataset read @@ -322,7 +321,7 @@ SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors) IF (do_collective) THEN CALL h5pset_dxpl_mpio_f(dxpl_id, H5FD_MPIO_COLLECTIVE_F, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5pset_dxpl_mpio_f", hdferror, nerrors) ENDIF ! @@ -330,29 +329,29 @@ SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors) ! CALL h5dread_f(dset_id,H5T_NATIVE_INTEGER,rbuf,dims,hdferror,file_space_id=fspace_id,mem_space_id=mspace_id,xfer_prp=dxpl_id) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5dread_f", hdferror, nerrors) ! ! close HDF5 I/O ! CALL h5pclose_f(fapl_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5pclose_f", hdferror, nerrors) CALL h5pclose_f(dxpl_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5pclose_f", hdferror, nerrors) CALL h5sclose_f(fspace_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5sclose_f", hdferror, nerrors) CALL h5sclose_f(mspace_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5sclose_f", hdferror, nerrors) CALL h5dclose_f(dset_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5dclose_f", hdferror, nerrors) CALL h5fclose_f(file_id, hdferror) - CALL check("h5pcreate_f", hdferror, nerrors) + CALL check("h5fclose_f", hdferror, nerrors) ! ! compare read and write data. each process compares a subset of the array diff --git a/fortran/testpar/mdset.F90 b/fortran/testpar/mdset.F90 index 9aa7b9ef90..917c19335d 100644 --- a/fortran/testpar/mdset.F90 +++ b/fortran/testpar/mdset.F90 @@ -29,7 +29,6 @@ SUBROUTINE multiple_dset_write(length, do_collective, do_chunk, mpi_size, mpi_ra INTEGER, INTENT(in) :: mpi_size ! number of processes in the group of communicator INTEGER, INTENT(in) :: mpi_rank ! rank of the calling process in the communicator INTEGER, INTENT(inout) :: nerrors ! number of errors - INTEGER :: mpierror ! MPI hdferror flag INTEGER :: hdferror ! HDF hdferror flag INTEGER(hsize_t), DIMENSION(1) :: dims ! dataset dimensions INTEGER(hsize_t), DIMENSION(1) :: cdims ! chunk dimensions diff --git a/fortran/testpar/ptest.F90 b/fortran/testpar/ptest.F90 index 30abb88973..0883ac285b 100644 --- a/fortran/testpar/ptest.F90 +++ b/fortran/testpar/ptest.F90 @@ -29,7 +29,7 @@ PROGRAM parallel_test INTEGER :: mpi_size ! number of processes in the group of communicator INTEGER :: mpi_rank ! rank of the calling process in the communicator INTEGER :: length = 12000 ! length of array - INTEGER :: i,j + INTEGER :: i,j, sum ! use collective MPI I/O LOGICAL, DIMENSION(1:2) :: do_collective = (/.FALSE.,.TRUE./) CHARACTER(LEN=11), DIMENSION(1:2) :: chr_collective =(/"independent", "collective "/) @@ -82,6 +82,8 @@ PROGRAM parallel_test ! CALL h5close_f(hdferror) + CALL MPI_ALLREDUCE(total_error, sum, 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, mpierror) + ! ! close MPI ! diff --git a/fortran/testpar/subfiling.F90 b/fortran/testpar/subfiling.F90 new file mode 100644 index 0000000000..330bab8831 --- /dev/null +++ b/fortran/testpar/subfiling.F90 @@ -0,0 +1,391 @@ +! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +! Copyright by The HDF Group. * +! Copyright by the Board of Trustees of the University of Illinois. * +! 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. * +! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +! +! main program for subfiling HDF5 Fortran tests +! + +#include + +PROGRAM subfiling_test + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_INT64_T + USE HDF5 + USE MPI + USE TH5_MISC + + IMPLICIT NONE + + INTEGER :: total_error = 0 ! sum of the number of errors + INTEGER :: mpierror ! MPI hdferror flag + INTEGER :: mpi_rank ! rank of the calling process in the communicator + +#ifdef H5_HAVE_SUBFILING_VFD + + CHARACTER(LEN=7), PARAMETER :: filename = "subf.h5" + + INTEGER :: hdferror ! HDF hdferror flag + INTEGER :: mpi_size, mpi_size_ret ! number of processes in the group of communicator + INTEGER :: required, provided + LOGICAL :: file_exists + + INTEGER(HID_T) :: fapl_id + INTEGER(HID_T) :: file_id + INTEGER :: comm, comm_ret + INTEGER :: info, info_ret + CHARACTER(LEN=3) :: info_val + CHARACTER(LEN=180) :: subfname + INTEGER :: i, sum + INTEGER(C_INT64_T) inode + TYPE(H5FD_subfiling_config_t) :: vfd_config + TYPE(H5FD_ioc_config_t) :: vfd_config_ioc + LOGICAL :: flag + + INTEGER :: nerrors = 0 + + INTEGER(HID_T) :: driver_id + + ! + ! initialize MPI + ! + required = MPI_THREAD_MULTIPLE + CALL mpi_init_thread(required, provided, mpierror) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_INIT_THREAD *FAILED*" + nerrors = nerrors + 1 + ENDIF + IF (provided .NE. required) THEN + WRITE(*,*) "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE *FAILED*" + nerrors = nerrors + 1 + ENDIF + CALL mpi_comm_rank( MPI_COMM_WORLD, mpi_rank, mpierror ) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_COMM_RANK *FAILED* Process = ", mpi_rank + nerrors = nerrors + 1 + ENDIF + CALL mpi_comm_size( MPI_COMM_WORLD, mpi_size, mpierror ) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_COMM_SIZE *FAILED* Process = ", mpi_rank + nerrors = nerrors + 1 + ENDIF + + IF(nerrors.NE.0)THEN + IF(mpi_rank==0) CALL write_test_status(sum, & + 'Testing Initializing mpi_init_thread', total_error) + CALL MPI_Barrier(MPI_COMM_WORLD, mpierror) + CALL mpi_abort(MPI_COMM_WORLD, 1, mpierror) + ENDIF + + ! + ! initialize the HDF5 fortran interface + ! + CALL h5open_f(hdferror) + + ! *********************************** + ! Test H5Pset/get_mpi_params_f APIs + ! *********************************** + nerrors = 0 + IF(mpi_size.GT.2)THEN + + IF (mpi_rank.LE.1)THEN + CALL MPI_Comm_split(MPI_COMM_WORLD, 1, mpi_rank, comm, mpierror) + ELSE + CALL MPI_Comm_split(MPI_COMM_WORLD, 0, mpi_rank, comm, mpierror) + ENDIF + + CALL MPI_Info_create(info, mpierror) + CALL MPI_Info_set( info, "foo", "bar", mpierror) + + IF (mpi_rank.LE.1)THEN + + CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl_id, hdferror) + CALL check("h5pcreate_f", hdferror, nerrors) + + CALL H5Pset_mpi_params_f(fapl_id, comm, info, hdferror) + CALL check("H5Pset_mpi_params_f", hdferror, nerrors) + + CALL H5Pget_mpi_params_f(fapl_id, comm_ret, info_ret, hdferror) + CALL check("H5Pget_mpi_params_f", hdferror, nerrors) + + CALL mpi_comm_size(comm_ret, mpi_size_ret, mpierror) + + IF(mpi_size_ret.NE.2)THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed H5Pset_mpi_params_f and H5Pget_mpi_params_f sequence" + nerrors = nerrors + 1 + ENDIF + + CALL mpi_info_get(info_ret,"foo", 3, info_val, flag, mpierror) + IF(flag .EQV. .TRUE.)THEN + IF(info_val.NE."bar")THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed H5Pset_mpi_params_f and H5Pget_mpi_params_f sequence" + nerrors = nerrors + 1 + ENDIF + ELSE + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed to find info value with mpi_info_get" + nerrors = nerrors + 1 + ENDIF + CALL h5pclose_f(fapl_id, hdferror) + ENDIF + + CALL MPI_Comm_free(comm, mpierror) + CALL MPI_Info_free(info, mpierror) + + ENDIF + + CALL MPI_REDUCE(nerrors, sum, 1, MPI_INTEGER, MPI_SUM, 0, MPI_COMM_WORLD, mpierror) + IF(mpi_rank==0) CALL write_test_status(sum, & + 'Testing H5Pset/get_mpi_params_f', total_error) + + ! ********************************************************* + ! Setup file access property list with subfiling I/O access + ! ********************************************************* + + nerrors = 0 + CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl_id, hdferror) + CALL check("h5pcreate_f", hdferror, nerrors) + + CALL H5Pset_mpi_params_f(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL, hdferror) + CALL check("H5Pset_mpi_params_f", hdferror, nerrors) + + CALL H5Pget_mpi_params_f(fapl_id, comm, info, hdferror) + CALL check("H5Pset_mpi_params_f", hdferror, nerrors) + + CALL mpi_comm_size(comm, mpi_size_ret, mpierror) + IF(mpi_size_ret.NE.mpi_size)THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed H5Pset_mpi_params_f and H5Pget_mpi_params_f sequence" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_mpi_params_f with defaults ', total_error) + + ! Verify no new enum parameters have been added in C and not updated in Fortran + IF( IOC_SELECTION_OPTIONS_F .NE. 4)THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Mismatch between Fortran and C H5FD_subfiling_ioc_select_t definitions" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing Subfiling FD is registered', total_error) + + ! ********************************************************* + ! Check the default subfiling parameters + ! ********************************************************* + nerrors = 0 + CALL h5pset_fapl_subfiling_f(fapl_id, hdferror) + CALL check("h5pset_fapl_subfiling_f", hdferror, nerrors) + + CALL h5pget_driver_f(fapl_id, driver_id, hdferror) + CALL check("h5pget_driver_f", hdferror, nerrors) + + IF( driver_id .NE. H5FD_SUBFILING_F) THEN + WRITE(*,*) "Wrong file driver type returned" + nerrors = nerrors + 1 + ENDIF + + ! ********************************************************* + ! Check the default parameters for subfiling and ioc + ! ********************************************************* + + CALL h5pget_fapl_subfiling_f(fapl_id, vfd_config, hdferror) + CALL check("h5pget_fapl_subfiling_f", hdferror, nerrors) + + CALL h5pset_fapl_ioc_f(vfd_config%ioc_fapl_id, hdferror) + CALL check("h5pset_fapl_ioc_f", hdferror, nerrors) + + CALL h5pget_fapl_ioc_f(vfd_config%ioc_fapl_id, vfd_config_ioc, hdferror) + CALL check("h5pget_fapl_ioc_f", hdferror, nerrors) + + IF(vfd_config%magic .NE. H5FD_SUBFILING_FAPL_MAGIC_F .OR. & + vfd_config%version .NE. H5FD_SUBFILING_CURR_FAPL_VERSION_F .OR. & + vfd_config%require_ioc .NEQV. .TRUE. .OR. & + vfd_config%shared_cfg%ioc_selection .NE. SELECT_IOC_ONE_PER_NODE_F .OR. & + vfd_config%shared_cfg%stripe_size .NE. H5FD_SUBFILING_DEFAULT_STRIPE_SIZE_F .OR. & + vfd_config%shared_cfg%stripe_count .NE. H5FD_SUBFILING_DEFAULT_STRIPE_COUNT_F & + )THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed h5pget_fapl_subfiling_f" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_fapl_subfiling_f with defaults', total_error) + + nerrors = 0 + IF(vfd_config_ioc%magic.NE. H5FD_IOC_FAPL_MAGIC_F .OR. & + vfd_config_ioc%version .NE. H5FD_IOC_CURR_FAPL_VERSION_F .OR. & + vfd_config_ioc%thread_pool_size .NE. H5FD_IOC_DEFAULT_THREAD_POOL_SIZE_F & + )THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed h5pget_fapl_ioc_f" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_fapl_ioc_f with defaults', total_error) + + ! ********************************************************* + ! Testing creating a file with subfiling, default settings + ! ********************************************************* + + CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, hdferror, access_prp = fapl_id) + CALL check("h5fcreate_f", hdferror, nerrors) + + CALL h5fclose_f(file_id, hdferror) + CALL check("h5fclose_f", hdferror, nerrors) + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Fcreate with subfiling with default settings', total_error) + + ! ********************************************************* + ! Testing creating a file with subfiling, modified settings + ! ********************************************************* + + ! Testing modifying defaults for subfiling FD + + vfd_config%magic = H5FD_SUBFILING_FAPL_MAGIC_F + vfd_config%version = H5FD_SUBFILING_CURR_FAPL_VERSION_F + vfd_config%require_ioc = .TRUE. + vfd_config%shared_cfg%ioc_selection = SELECT_IOC_ONE_PER_NODE_F + vfd_config%shared_cfg%stripe_size = 16*1024*1024 + vfd_config%shared_cfg%stripe_count = 3 + + nerrors = 0 + CALL h5pset_fapl_subfiling_f(fapl_id, hdferror, vfd_config) + CALL check("h5pset_fapl_ioc_f", hdferror, nerrors) + + CALL h5pget_fapl_subfiling_f(fapl_id, vfd_config, hdferror) + CALL check("h5pget_fapl_ioc_f", hdferror, nerrors) + + IF(vfd_config%magic .NE. H5FD_SUBFILING_FAPL_MAGIC_F .OR. & + vfd_config%version .NE. H5FD_SUBFILING_CURR_FAPL_VERSION_F .OR. & + vfd_config%require_ioc .NEQV. .TRUE. .OR. & + vfd_config%shared_cfg%ioc_selection .NE. SELECT_IOC_ONE_PER_NODE_F .OR. & + vfd_config%shared_cfg%stripe_size .NE. 16*1024*1024 .OR. & + vfd_config%shared_cfg%stripe_count .NE. 3 & + )THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed h5pget_fapl_subfiling_f" + nerrors = nerrors + 1 + ENDIF + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_fapl_subfiling_f with custom settings', total_error) + + vfd_config_ioc%magic = H5FD_IOC_FAPL_MAGIC_F + vfd_config_ioc%version = H5FD_IOC_CURR_FAPL_VERSION_F + vfd_config_ioc%thread_pool_size = 2 + + nerrors = 0 + CALL h5pset_fapl_ioc_f(vfd_config%ioc_fapl_id, hdferror, vfd_config_ioc) + CALL check("h5pset_fapl_ioc_f", hdferror, nerrors) + + CALL h5pget_fapl_ioc_f(vfd_config%ioc_fapl_id, vfd_config_ioc, hdferror) + CALL check("h5pget_fapl_ioc_f", hdferror, nerrors) + + IF(vfd_config_ioc%magic .NE. H5FD_IOC_FAPL_MAGIC_F .OR. & + vfd_config_ioc%version .NE. H5FD_IOC_CURR_FAPL_VERSION_F .OR. & + vfd_config_ioc%thread_pool_size .NE. 2 & + )THEN + IF(mpi_rank.EQ.0) & + WRITE(*,*) "Failed h5pget_fapl_ioc_f" + nerrors = nerrors + 1 + ENDIF + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Pset/get_fapl_ioc_f with custom settings', total_error) + + ! ********************************************************* + ! Testing creating a file with subfiling, custom settings + ! ********************************************************* + + CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, hdferror, access_prp = fapl_id) + CALL check("h5pcreate_f", hdferror, nerrors) + + CALL h5fclose_f(file_id, hdferror) + CALL check("h5fclose_f", hdferror, nerrors) + + IF(mpi_rank.EQ.0)THEN + INQUIRE(FILE=filename, EXIST=file_exists) + IF(.NOT.file_exists)THEN + WRITE(*,"(A,A)") "Failed to find the stub subfile ",TRIM(filename) + nerrors = nerrors + 1 + ENDIF + + CALL EXECUTE_COMMAND_LINE("stat --format='%i' "//filename//" >> tmp_inode", EXITSTAT=i) + IF(i.ne.0)THEN + WRITE(*,"(A,A)") "Failed to stat the stub subfile ",TRIM(filename) + nerrors = nerrors + 1 + ENDIF + + OPEN(11,FILE="tmp_inode") + READ(11,*) inode + CLOSE(11,STATUS="delete") + + DO i = 1, vfd_config%shared_cfg%stripe_count + WRITE(subfname,'(A,".subfile_",I0,"_",I0,"_of_",I0)') filename,inode,i,vfd_config%shared_cfg%stripe_count + INQUIRE(FILE=subfname, EXIST=file_exists) + IF(.NOT.file_exists)THEN + WRITE(*,"(A,A)") "Failed to create the subfile ",TRIM(subfname) + nerrors = nerrors + 1 + ENDIF + ENDDO + + ENDIF + + CALL h5pclose_f(fapl_id, hdferror) + CALL check("h5pclose_f", hdferror, nerrors) + + IF(mpi_rank==0) CALL write_test_status(nerrors, & + 'Testing H5Fcreate with subfiling with custom settings', total_error) + + ! + ! close HDF5 interface + ! + CALL h5close_f(hdferror) + + CALL MPI_ALLREDUCE(total_error, sum, 1, MPI_INTEGER, MPI_SUM, MPI_COMM_WORLD, mpierror) + + ! + ! close MPI + ! + IF (sum == 0) THEN + CALL mpi_finalize(mpierror) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_FINALIZE *FAILED* Process = ", mpi_rank + ENDIF + ELSE + WRITE(*,*) 'Errors detected in process ', mpi_rank + CALL mpi_abort(MPI_COMM_WORLD, 1, mpierror) + IF (mpierror .NE. MPI_SUCCESS) THEN + WRITE(*,*) "MPI_ABORT *FAILED* Process = ", mpi_rank + ENDIF + ENDIF + ! + ! end main program + ! + +#else + + CALL mpi_init(mpierror) + CALL mpi_comm_rank(MPI_COMM_WORLD, mpi_rank, mpierror) + IF(mpi_rank==0) CALL write_test_status( -1, & + 'Subfiling not enabled', total_error) + CALL mpi_finalize(mpierror) + +#endif + +END PROGRAM subfiling_test diff --git a/src/H5FDsubfiling/H5FDsubfiling.h b/src/H5FDsubfiling/H5FDsubfiling.h index 23dae62a1e..62eaa0a33a 100644 --- a/src/H5FDsubfiling/H5FDsubfiling.h +++ b/src/H5FDsubfiling/H5FDsubfiling.h @@ -188,6 +188,7 @@ typedef enum { SELECT_IOC_WITH_CONFIG, /* NOT IMPLEMENTED: Read-from-file */ SELECT_IOC_TOTAL, /* Starting at rank 0, mpi_size / total */ ioc_selection_options /* Sentinel value */ + /* NOTE: Add to the Fortran constants (H5f90global.F90) when adding new entries */ } H5FD_subfiling_ioc_select_t; /**