summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScot Breitenfeld <brtnfld@hdfgroup.org>2024-01-29 19:13:33 (GMT)
committerLarry Knox <lrknox@hdfgroup.org>2024-02-14 21:32:01 (GMT)
commit30b0f89f869c947cce41dbdb983533400f607604 (patch)
tree50e930c644f08585e074693bc8b6429a603c682b
parent56d9be146fb27456e4c517e49ccf920396824d71 (diff)
downloadhdf5-30b0f89f869c947cce41dbdb983533400f607604.zip
hdf5-30b0f89f869c947cce41dbdb983533400f607604.tar.gz
hdf5-30b0f89f869c947cce41dbdb983533400f607604.tar.bz2
Add API support for Fortran MPI_F08 module definitions. (#3959)
* revert to using c-stub for _F08 MPI APIs * use mpi compiler wrappers for cmake and nvhpc
-rw-r--r--.github/workflows/nvhpc-cmake.yml4
-rw-r--r--CMakeLists.txt7
-rw-r--r--config/cmake/H5pubconf.h.in3
-rw-r--r--configure.ac19
-rw-r--r--fortran/src/CMakeLists.txt7
-rw-r--r--fortran/src/H5Pff.F90266
-rw-r--r--fortran/src/H5config_f.inc.cmake8
-rw-r--r--fortran/src/H5config_f.inc.in3
-rw-r--r--fortran/src/hdf5_fortrandll.def.in12
-rw-r--r--fortran/testpar/CMakeLists.txt1
-rw-r--r--fortran/testpar/Makefile.am2
-rw-r--r--fortran/testpar/mpi_param.F90326
-rw-r--r--fortran/testpar/ptest.F9010
-rw-r--r--release_docs/RELEASE.txt5
14 files changed, 649 insertions, 24 deletions
diff --git a/.github/workflows/nvhpc-cmake.yml b/.github/workflows/nvhpc-cmake.yml
index 0fd6974..b0b3143 100644
--- a/.github/workflows/nvhpc-cmake.yml
+++ b/.github/workflows/nvhpc-cmake.yml
@@ -33,8 +33,8 @@ jobs:
echo 'deb [signed-by=/usr/share/keyrings/nvidia-hpcsdk-archive-keyring.gpg] https://developer.download.nvidia.com/hpc-sdk/ubuntu/amd64 /' | sudo tee /etc/apt/sources.list.d/nvhpc.list
sudo apt-get update -y
sudo apt-get install -y nvhpc-23-9
- echo "CC=nvc" >> $GITHUB_ENV
- echo "FC=nvfortran" >> $GITHUB_ENV
+ echo "CC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin/mpicc" >> $GITHUB_ENV
+ echo "FC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/comm_libs/openmpi4/bin/mpifort" >> $GITHUB_ENV
echo "NVHPCSDK=/opt/nvidia/hpc_sdk" >> $GITHUB_ENV
echo "OMPI_CXX=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvc++" >> $GITHUB_ENV
echo "OMPI_CC=/opt/nvidia/hpc_sdk/Linux_x86_64/23.9/compilers/bin/nvc" >> $GITHUB_ENV
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f17f0e1..7a35aa5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1077,6 +1077,13 @@ if (EXISTS "${HDF5_SOURCE_DIR}/fortran" AND IS_DIRECTORY "${HDF5_SOURCE_DIR}/for
if (MPI_Fortran_LINK_FLAGS)
set (CMAKE_Fortran_EXE_LINKER_FLAGS "${MPI_Fortran_LINK_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}")
endif ()
+ # Check if MPI-3 Fortran 2008 module mpi_f08 is supported
+ if (MPI_Fortran_HAVE_F08_MODULE)
+ set (H5_HAVE_MPI_F08 1)
+ message (VERBOSE "MPI-3 Fortran 2008 module mpi_f08 is supported")
+ else ()
+ message (VERBOSE "MPI-3 Fortran 2008 module mpi_f08 is NOT supported")
+ endif ()
endif ()
#option (HDF5_INSTALL_MOD_FORTRAN "Copy FORTRAN mod files to include directory (NO SHARED STATIC)" "NO")
diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in
index 0ff22fe..f8756e9 100644
--- a/config/cmake/H5pubconf.h.in
+++ b/config/cmake/H5pubconf.h.in
@@ -243,6 +243,9 @@
/* Define if we have parallel support */
#cmakedefine H5_HAVE_PARALLEL @H5_HAVE_PARALLEL@
+/* Define if MPI Fortran supports mpi_f08 module */
+#cmakedefine H5_HAVE_MPI_F08 @H5_HAVE_MPI_F08@
+
/* Define if we have support for writing to filtered datasets in parallel */
#cmakedefine H5_HAVE_PARALLEL_FILTERED_WRITES @H5_HAVE_PARALLEL_FILTERED_WRITES@
diff --git a/configure.ac b/configure.ac
index c5a635b..44dc430 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2840,6 +2840,25 @@ if test -n "$PARALLEL"; then
AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])]
)
+
+ AC_LANG_PUSH([Fortran])
+ AC_MSG_CHECKING([for MPI-3 module mpi_f08])
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([],
+ [
+ USE mpi_f08
+ IMPLICIT NONE
+ TYPE(MPI_Comm) :: comm
+ TYPE(MPI_INFO) :: info
+ ]
+ )
+ ],
+ [AC_DEFINE([HAVE_MPI_F08], [1],
+ [Define if mpi_f08 module exist])
+ AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])]
+ )
+ AC_LANG_POP(Fortran)
fi
## ----------------------------------------------------------------------
diff --git a/fortran/src/CMakeLists.txt b/fortran/src/CMakeLists.txt
index 60c0c3a..4c28046 100644
--- a/fortran/src/CMakeLists.txt
+++ b/fortran/src/CMakeLists.txt
@@ -24,6 +24,13 @@ if (WIN32)
endif ()
endif ()
+if (H5_HAVE_MPI_F08) # MPI-3 module mpi_f08 supported
+ set (CMAKE_H5_HAVE_MPI_F08 1)
+else ()
+ set (H5_NOMPI_F08 ";")
+ set (CMAKE_H5_HAVE_MPI_F08 0)
+endif ()
+
# configure for Fortran preprocessor
# Define Parallel variable for passing to H5config_f.inc.cmake
diff --git a/fortran/src/H5Pff.F90 b/fortran/src/H5Pff.F90
index afd17f3..90a74f7 100644
--- a/fortran/src/H5Pff.F90
+++ b/fortran/src/H5Pff.F90
@@ -49,6 +49,12 @@ MODULE H5P
PRIVATE h5pget_integer, h5pget_char, h5pget_ptr
PRIVATE h5pregister_integer, h5pregister_ptr
PRIVATE h5pinsert_integer, h5pinsert_char, h5pinsert_ptr
+#ifdef H5_HAVE_PARALLEL
+ PRIVATE h5pset_fapl_mpio_f90, h5pget_fapl_mpio_f90
+#ifdef H5_HAVE_MPI_F08
+ PRIVATE h5pset_fapl_mpio_f08, h5pget_fapl_mpio_f08
+#endif
+#endif
#ifndef H5_DOXYGEN
@@ -101,7 +107,6 @@ MODULE H5P
MODULE PROCEDURE h5pinsert_ptr
END INTERFACE
-
INTERFACE
INTEGER(C_INT) FUNCTION H5Pset_fill_value(prp_id, type_id, fillvalue) &
BIND(C, NAME='H5Pset_fill_value')
@@ -182,6 +187,35 @@ MODULE H5P
#endif
#ifdef H5_HAVE_PARALLEL
+
+ INTERFACE h5pset_fapl_mpio_f
+ MODULE PROCEDURE h5pset_fapl_mpio_f90
+#ifdef H5_HAVE_MPI_F08
+ MODULE PROCEDURE h5pset_fapl_mpio_f08
+#endif
+ END INTERFACE
+
+ INTERFACE h5pget_fapl_mpio_f
+ MODULE PROCEDURE h5pget_fapl_mpio_f90
+#ifdef H5_HAVE_MPI_F08
+ MODULE PROCEDURE h5pget_fapl_mpio_f08
+#endif
+ END INTERFACE
+
+ INTERFACE H5Pset_mpi_params_f
+ MODULE PROCEDURE H5Pset_mpi_params_f90
+#ifdef H5_HAVE_MPI_F08
+ MODULE PROCEDURE H5Pset_mpi_params_f08
+#endif
+ END INTERFACE
+
+ INTERFACE H5Pget_mpi_params_f
+ MODULE PROCEDURE H5Pget_mpi_params_f90
+#ifdef H5_HAVE_MPI_F08
+ MODULE PROCEDURE H5Pget_mpi_params_f08
+#endif
+ END INTERFACE
+
#ifdef H5_HAVE_SUBFILING_VFD
!> \addtogroup FH5P
!> @{
@@ -5125,6 +5159,8 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr)
! *********************************************************************
#ifdef H5_HAVE_PARALLEL
+
+#ifdef H5_DOXYGEN
!>
!! \ingroup FH5P
!!
@@ -5143,21 +5179,69 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr)
INTEGER, INTENT(IN) :: comm
INTEGER, INTENT(IN) :: info
INTEGER, INTENT(OUT) :: hdferr
+ END SUBROUTINE h5pset_fapl_mpio_f
+!>
+!! \ingroup FH5P
+!!
+!! \brief Stores MPI IO communicator information to the file access property list.
+!!
+!! \note Supports MPI Fortran module mpi_f08
+!!
+!! \param prp_id File access property list identifier.
+!! \param comm MPI-3 communicator.
+!! \param info MPI-3 info object.
+!! \param hdferr \fortran_error
+!!
+!! See C API: @ref H5Pset_fapl_mpio()
+!!
+ SUBROUTINE h5pset_fapl_mpio_f(prp_id, comm, info, hdferr)
+ IMPLICIT NONE
+ INTEGER(HID_T), INTENT(IN) :: prp_id
+ TYPE(MPI_COMM), INTENT(IN) :: comm
+ TYPE(MPI_INFO), INTENT(IN) :: info
+ INTEGER, INTENT(OUT) :: hdferr
+ END SUBROUTINE h5pset_fapl_mpio_f
+
+#else
+
+ SUBROUTINE h5pset_fapl_mpio_f90(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_fapl_mpio_c(prp_id, comm, info) &
BIND(C,NAME='h5pset_fapl_mpio_c')
IMPORT :: HID_T
IMPLICIT NONE
- INTEGER(HID_T), INTENT(IN) :: prp_id
- INTEGER , INTENT(IN) :: comm
- INTEGER , INTENT(IN) :: info
+ INTEGER(HID_T) :: prp_id
+ INTEGER :: comm
+ INTEGER :: info
END FUNCTION h5pset_fapl_mpio_c
END INTERFACE
hdferr = h5pset_fapl_mpio_c(prp_id, comm, info)
- END SUBROUTINE h5pset_fapl_mpio_f
+ END SUBROUTINE h5pset_fapl_mpio_f90
+#ifdef H5_HAVE_MPI_F08
+ SUBROUTINE h5pset_fapl_mpio_f08(prp_id, comm, info, hdferr)
+ USE mpi_f08
+ IMPLICIT NONE
+ INTEGER(HID_T), INTENT(IN) :: prp_id
+ TYPE(MPI_COMM), INTENT(IN) :: comm
+ TYPE(MPI_INFO), INTENT(IN) :: info
+ INTEGER, INTENT(OUT) :: hdferr
+
+ CALL h5pset_fapl_mpio_f90(prp_id, comm%mpi_val, info%mpi_val, hdferr)
+
+ END SUBROUTINE h5pset_fapl_mpio_f08
+#endif
+
+#endif
+
+#ifdef H5_DOXYGEN
!>
!! \ingroup FH5P
!!
@@ -5168,9 +5252,44 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr)
!! \param info MPI-2 info object.
!! \param hdferr \fortran_error
!!
+!! \attention It is the responsibility of the application to free the MPI objects.
+!!
!! See C API: @ref H5Pget_fapl_mpio()
!!
- SUBROUTINE h5pget_fapl_mpio_f(prp_id, comm, info, hdferr)
+SUBROUTINE h5pget_fapl_mpio_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
+END SUBROUTINE h5pget_fapl_mpio_f
+!>
+!! \ingroup FH5P
+!!
+!! \brief Returns MPI communicator information.
+!!
+!! \note Supports MPI Fortran module mpi_f08
+!!
+!! \param prp_id File access property list identifier.
+!! \param comm MPI-3 communicator.
+!! \param info MPI-3 info object.
+!! \param hdferr \fortran_error
+!!
+!! \attention It is the responsibility of the application to free the MPI objects.
+!!
+!! See C API: @ref H5Pget_fapl_mpio()
+!!
+SUBROUTINE h5pget_fapl_mpio_f(prp_id, comm, info, hdferr)
+ IMPLICIT NONE
+ INTEGER(HID_T), INTENT(IN) :: prp_id
+ TYPE(MPI_COMM), INTENT(OUT) :: comm
+ TYPE(MPI_INFO), INTENT(OUT) :: info
+ INTEGER , INTENT(OUT) :: hdferr
+END SUBROUTINE h5pget_fapl_mpio_f
+
+#else
+
+ SUBROUTINE h5pget_fapl_mpio_f90(prp_id, comm, info, hdferr)
IMPLICIT NONE
INTEGER(HID_T), INTENT(IN) :: prp_id
INTEGER, INTENT(OUT) :: comm
@@ -5181,15 +5300,30 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr)
BIND(C,NAME='h5pget_fapl_mpio_c')
IMPORT :: HID_T
IMPLICIT NONE
- INTEGER(HID_T), INTENT(IN) :: prp_id
- INTEGER , INTENT(OUT) :: comm
- INTEGER , INTENT(OUT) :: info
+ INTEGER(HID_T) :: prp_id
+ INTEGER :: comm
+ INTEGER :: info
END FUNCTION h5pget_fapl_mpio_c
END INTERFACE
hdferr = h5pget_fapl_mpio_c(prp_id, comm, info)
- END SUBROUTINE h5pget_fapl_mpio_f
+ END SUBROUTINE h5pget_fapl_mpio_f90
+
+#ifdef H5_HAVE_MPI_F08
+ SUBROUTINE h5pget_fapl_mpio_f08(prp_id, comm, info, hdferr)
+ USE mpi_f08
+ IMPLICIT NONE
+ INTEGER(HID_T), INTENT(IN) :: prp_id
+ TYPE(MPI_COMM), INTENT(OUT) :: comm
+ TYPE(MPI_INFO), INTENT(OUT) :: info
+ INTEGER, INTENT(OUT) :: hdferr
+
+ CALL h5pget_fapl_mpio_f90(prp_id, comm%mpi_val, info%mpi_val, hdferr)
+
+ END SUBROUTINE h5pget_fapl_mpio_f08
+#endif
+#endif
#ifdef H5_HAVE_SUBFILING_VFD
!>
@@ -5376,14 +5510,15 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr)
END SUBROUTINE h5pget_mpio_no_collective_cause_f
+#ifdef H5_DOXYGEN
!>
!! \ingroup FH5P
!!
-!! \brief Set the MPI communicator and info.
+!! \brief Set the MPI communicator and information.
!!
!! \param prp_id File access property list identifier.
-!! \param comm The MPI communicator.
-!! \param info The MPI info object.
+!! \param comm MPI-2 communicator.
+!! \param info MPI-2 info object.
!! \param hdferr \fortran_error
!!
!! See C API: @ref H5Pset_mpi_params()
@@ -5394,6 +5529,37 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr)
INTEGER , INTENT(IN) :: comm
INTEGER , INTENT(IN) :: info
INTEGER , INTENT(OUT) :: hdferr
+ END SUBROUTINE H5Pset_mpi_params_f
+!>
+!! \ingroup FH5P
+!!
+!! \brief Set the MPI communicator and information.
+!!
+!! \note Supports MPI Fortran module mpi_f08
+!!
+!! \param prp_id File access property list identifier.
+!! \param comm MPI-3 communicator.
+!! \param info MPI-3 info object.
+!! \param hdferr \fortran_error
+!!
+!! See C API: @ref H5Pset_mpi_params()
+!!
+ SUBROUTINE H5Pset_mpi_params_f(prp_id, comm, info, hdferr)
+ IMPLICIT NONE
+ INTEGER(HID_T), INTENT(IN) :: prp_id
+ TYPE(MPI_COMM), INTENT(IN) :: comm
+ TYPE(MPI_INFO), INTENT(IN) :: info
+ INTEGER , INTENT(OUT) :: hdferr
+ END SUBROUTINE H5Pset_mpi_params_f
+
+#else
+
+ SUBROUTINE H5Pset_mpi_params_f90(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) &
@@ -5408,16 +5574,33 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr)
hdferr = H5Pset_mpi_params_c(prp_id, comm, info)
- END SUBROUTINE H5Pset_mpi_params_f
+ END SUBROUTINE H5Pset_mpi_params_f90
+
+#ifdef H5_HAVE_MPI_F08
+ SUBROUTINE H5Pset_mpi_params_f08(prp_id, comm, info, hdferr)
+ USE mpi_f08
+ IMPLICIT NONE
+ INTEGER(HID_T), INTENT(IN) :: prp_id
+ TYPE(MPI_COMM), INTENT(IN) :: comm
+ TYPE(MPI_INFO), INTENT(IN) :: info
+ INTEGER , INTENT(OUT) :: hdferr
+
+ CALL H5Pset_mpi_params_f90(prp_id, comm%mpi_val, info%mpi_val, hdferr)
+
+ END SUBROUTINE H5Pset_mpi_params_f08
+#endif
+
+#endif
+#ifdef H5_DOXYGEN
!>
!! \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 comm MPI-2 communicator.
+!! \param info MPI-2 info object.
!! \param hdferr \fortran_error
!!
!! See C API: @ref H5Pget_mpi_params()
@@ -5428,6 +5611,39 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr)
INTEGER , INTENT(OUT) :: comm
INTEGER , INTENT(OUT) :: info
INTEGER , INTENT(OUT) :: hdferr
+ END SUBROUTINE H5Pget_mpi_params_f
+!>
+!! \ingroup FH5P
+!!
+!! \brief Get the MPI communicator and information.
+!!
+!! \note Supports MPI Fortran module mpi_f08
+!!
+!! \param prp_id File access property list identifier.
+!! \param comm MPI-3 communicator.
+!! \param info MPI-3 info object.
+!! \param hdferr \fortran_error
+!!
+!! \attention It is the responsibility of the application to free the MPI objects.
+!!
+!! See C API: @ref H5Pget_mpi_params()
+!!
+ SUBROUTINE H5Pget_mpi_params_f(prp_id, comm, info, hdferr)
+ IMPLICIT NONE
+ INTEGER(HID_T), INTENT(IN) :: prp_id
+ TYPE(MPI_COMM), INTENT(OUT) :: comm
+ TYPE(MPI_INFO), INTENT(OUT) :: info
+ INTEGER , INTENT(OUT) :: hdferr
+ END SUBROUTINE H5Pget_mpi_params_f
+
+#else
+
+ SUBROUTINE H5Pget_mpi_params_f90(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) &
@@ -5442,7 +5658,23 @@ SUBROUTINE h5pset_attr_phase_change_f(ocpl_id, max_compact, min_dense, hdferr)
hdferr = H5Pget_mpi_params_c(prp_id, comm, info)
- END SUBROUTINE H5Pget_mpi_params_f
+ END SUBROUTINE H5Pget_mpi_params_f90
+
+#ifdef H5_HAVE_MPI_F08
+ SUBROUTINE H5Pget_mpi_params_f08(prp_id, comm, info, hdferr)
+ USE mpi_f08
+ IMPLICIT NONE
+ INTEGER(HID_T), INTENT(IN) :: prp_id
+ TYPE(MPI_COMM), INTENT(OUT) :: comm
+ TYPE(MPI_INFO), INTENT(OUT) :: info
+ INTEGER , INTENT(OUT) :: hdferr
+
+ CALL H5Pget_mpi_params_f90(prp_id, comm%mpi_val, info%mpi_val, hdferr)
+
+ END SUBROUTINE H5Pget_mpi_params_f08
+#endif
+
+#endif
!>
!! \ingroup FH5P
diff --git a/fortran/src/H5config_f.inc.cmake b/fortran/src/H5config_f.inc.cmake
index 77ff707..e6fa7b9 100644
--- a/fortran/src/H5config_f.inc.cmake
+++ b/fortran/src/H5config_f.inc.cmake
@@ -19,6 +19,14 @@
#define H5_HAVE_PARALLEL
#endif
+! Define if MPI supports mpi_f08 module
+#cmakedefine01 CMAKE_H5_HAVE_MPI_F08
+#if CMAKE_H5_HAVE_MPI_F08 == 0
+#undef H5_HAVE_MPI_F08
+#else
+#define H5_HAVE_MPI_F08
+#endif
+
! Define if there is subfiling support
#cmakedefine01 CMAKE_H5_HAVE_SUBFILING_VFD
#if CMAKE_H5_HAVE_SUBFILING_VFD == 0
diff --git a/fortran/src/H5config_f.inc.in b/fortran/src/H5config_f.inc.in
index afcfa6e..7f52255 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 MPI supports mpi_f08 module
+#undef HAVE_MPI_F08
+
! Define if we have subfiling support
#undef HAVE_SUBFILING_VFD
diff --git a/fortran/src/hdf5_fortrandll.def.in b/fortran/src/hdf5_fortrandll.def.in
index ccb770a..e29488f 100644
--- a/fortran/src/hdf5_fortrandll.def.in
+++ b/fortran/src/hdf5_fortrandll.def.in
@@ -421,14 +421,18 @@ H5P_mp_H5PSET_FILE_SPACE_PAGE_SIZE_F
H5P_mp_H5PGET_FILE_SPACE_PAGE_SIZE_F
H5P_mp_H5PGET_ACTUAL_SELECTION_IO_MODE_F
; Parallel
-@H5_NOPAREXP@H5P_mp_H5PSET_FAPL_MPIO_F
-@H5_NOPAREXP@H5P_mp_H5PGET_FAPL_MPIO_F
+@H5_NOPAREXP@H5P_mp_H5PSET_FAPL_MPIO_F90
+@H5_NOPAREXP@@H5_NOMPI_F08@H5P_mp_H5PSET_FAPL_MPIO_F08
+@H5_NOPAREXP@H5P_mp_H5PGET_FAPL_MPIO_F90
+@H5_NOPAREXP@@H5_NOMPI_F08@H5P_mp_H5PGET_FAPL_MPIO_F08
@H5_NOPAREXP@@H5_NOSUBFILING@H5P_mp_H5PSET_FAPL_SUBFILING_F
@H5_NOPAREXP@@H5_NOSUBFILING@H5P_mp_H5PGET_FAPL_SUBFILING_F
@H5_NOPAREXP@@H5_NOSUBFILING@H5P_mp_H5PSET_FAPL_IOC_F
@H5_NOPAREXP@@H5_NOSUBFILING@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_MPI_PARAMS_F90
+@H5_NOPAREXP@@H5_NOMPI_F08@H5P_mp_H5PSET_MPI_PARAMS_F08
+@H5_NOPAREXP@H5P_mp_H5PGET_MPI_PARAMS_F90
+@H5_NOPAREXP@@H5_NOMPI_F08@H5P_mp_H5PGET_MPI_PARAMS_F08
@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 e8f0107..4d3a330 100644
--- a/fortran/testpar/CMakeLists.txt
+++ b/fortran/testpar/CMakeLists.txt
@@ -20,6 +20,7 @@ add_executable (parallel_test
ptest.F90
hyper.F90
mdset.F90
+ mpi_param.F90
multidsetrw.F90
)
target_include_directories (parallel_test
diff --git a/fortran/testpar/Makefile.am b/fortran/testpar/Makefile.am
index 1c37409..3df1fee 100644
--- a/fortran/testpar/Makefile.am
+++ b/fortran/testpar/Makefile.am
@@ -39,7 +39,7 @@ check_PROGRAMS=$(TEST_PROG_PARA)
CHECK_CLEANFILES+=parf[12].h5 h5*_tests.h5 subf.h5* *.mod
# Test source files
-parallel_test_SOURCES=ptest.F90 hyper.F90 mdset.F90 multidsetrw.F90
+parallel_test_SOURCES=ptest.F90 hyper.F90 mdset.F90 multidsetrw.F90 mpi_param.F90
subfiling_test_SOURCES=subfiling.F90
async_test_SOURCES=async.F90
diff --git a/fortran/testpar/mpi_param.F90 b/fortran/testpar/mpi_param.F90
new file mode 100644
index 0000000..ba4eaaa
--- /dev/null
+++ b/fortran/testpar/mpi_param.F90
@@ -0,0 +1,326 @@
+! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+! Copyright by The HDF Group. *
+! All rights reserved. *
+! *
+! This file is part of HDF5. The full HDF5 copyright notice, including *
+! terms governing use, modification, and redistribution, is contained in *
+! the COPYING file, which can be found at the root of the source code *
+! distribution tree, or in https://www.hdfgroup.org/licenses. *
+! If you do not have access to either file, you may request a copy from *
+! help@hdfgroup.org. *
+! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+#include <H5config_f.inc>
+
+!
+! writes/reads dataset by hyperslabs
+!
+
+SUBROUTINE mpi_param_03(nerrors)
+
+ USE MPI
+ USE HDF5
+ USE TH5_MISC
+ USE TH5_MISC_GEN
+
+ IMPLICIT NONE
+ INTEGER, INTENT(inout) :: nerrors ! number of errors
+
+ INTEGER :: hdferror ! HDF hdferror flag
+ INTEGER(hid_t) :: fapl_id ! file access identifier
+ INTEGER :: mpi_size, mpi_size_ret ! number of processes in the group of communicator
+ INTEGER :: mpierror ! MPI hdferror flag
+ INTEGER :: mpi_rank ! rank of the calling process in the communicator
+
+ INTEGER :: info, info_ret
+ INTEGER :: comm, comm_ret
+ INTEGER :: nkeys
+ LOGICAL :: flag
+ INTEGER :: iconfig
+ CHARACTER(LEN=4) , PARAMETER :: in_key="host"
+ CHARACTER(LEN=10), PARAMETER :: in_value="myhost.org"
+
+ CHARACTER(LEN=MPI_MAX_INFO_KEY) :: key, value
+
+ ! Get the original sizes
+ CALL mpi_comm_rank( MPI_COMM_WORLD, mpi_rank, mpierror )
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_RANK *FAILED*"
+ 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
+
+ DO iconfig = 1, 2
+
+ ! Create the file access property
+ CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl_id, hdferror)
+ CALL check("h5pcreate_f", hdferror, nerrors)
+
+ ! Split the communicator
+ IF(mpi_rank.EQ.0)THEN
+ CALL MPI_Comm_split(MPI_COMM_WORLD, 1, mpi_rank, comm, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_SPLIT *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ ELSE
+ CALL MPI_Comm_split(MPI_COMM_WORLD, 0, mpi_rank, comm, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_SPLIT *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ ENDIF
+
+ ! Create and set an MPI INFO parameter
+
+ CALL MPI_Info_create(info, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_CREATE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL MPI_Info_set(info, in_key, in_value, mpierror )
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_SET *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+
+ IF(iconfig.EQ.1)THEN
+ ! Set and get the MPI parameters
+ CALL h5pset_fapl_mpio_f(fapl_id, comm, info, hdferror)
+ CALL check("h5pset_fapl_mpio_f", hdferror, nerrors)
+
+ CALL h5pget_fapl_mpio_f(fapl_id, comm_ret, info_ret, hdferror)
+ CALL check("h5pget_fapl_mpio_f", hdferror, nerrors)
+ ELSE
+ 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)
+ ENDIF
+
+
+ ! Check comm returned
+ CALL mpi_comm_size(comm_ret, mpi_size_ret, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_SIZE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ IF (mpi_rank.EQ.0)THEN
+ CALL VERIFY("h5pget_fapl_mpio_f", mpi_size_ret, 1, hdferror)
+ ELSE
+ CALL VERIFY("h5pget_fapl_mpio_f", mpi_size_ret, mpi_size-1, hdferror)
+ ENDIF
+
+ ! Check info returned
+ CALL MPI_info_get_nkeys( info_ret, nkeys, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_GET_NKEYS *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL VERIFY("h5pget_fapl_mpio_f", nkeys, 1, hdferror)
+
+ CALL MPI_Info_get_nthkey(info_ret, 0, key, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_GET_NTHKEY *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL VERIFY("h5pget_fapl_mpio_f", TRIM(key), in_key, hdferror)
+
+ CALL MPI_Info_get(info, key, MPI_MAX_INFO_KEY, value, flag, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_GET *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL VERIFY("h5pget_fapl_mpio_f", flag, .TRUE., hdferror)
+ CALL VERIFY("h5pget_fapl_mpio_f", TRIM(value), in_value, hdferror)
+
+ ! Free the MPI resources
+ CALL MPI_info_free(info_ret, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_FREE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL MPI_comm_free(comm_ret, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_FREE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL MPI_info_free(info, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_FREE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL MPI_comm_free(comm, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_FREE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+
+ CALL h5pclose_f(fapl_id, hdferror)
+ CALL check("h5pclose_f", hdferror, nerrors)
+ ENDDO
+
+END SUBROUTINE mpi_param_03
+
+SUBROUTINE mpi_param_08(nerrors)
+
+#ifdef H5_HAVE_MPI_F08
+
+ USE MPI_F08
+ USE HDF5
+ USE TH5_MISC
+ USE TH5_MISC_GEN
+
+ IMPLICIT NONE
+ INTEGER, INTENT(inout) :: nerrors ! number of errors
+
+ INTEGER :: hdferror ! HDF hdferror flag
+ INTEGER(hid_t) :: fapl_id ! file access identifier
+ INTEGER :: mpi_size, mpi_size_ret ! number of processes in the group of communicator
+ INTEGER :: mpierror ! MPI hdferror flag
+ INTEGER :: mpi_rank ! rank of the calling process in the communicator
+
+ TYPE(MPI_INFO) :: info, info_ret
+ TYPE(MPI_COMM) :: comm, comm_ret
+ INTEGER :: nkeys
+ LOGICAL :: flag
+ INTEGER :: iconfig
+ CHARACTER(LEN=4) , PARAMETER :: in_key="host"
+ CHARACTER(LEN=10), PARAMETER :: in_value="myhost.org"
+
+ CHARACTER(LEN=MPI_MAX_INFO_KEY) :: key, value
+
+ ! Get the original sizes
+ CALL mpi_comm_rank( MPI_COMM_WORLD, mpi_rank, mpierror )
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_RANK *FAILED*"
+ 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
+
+ DO iconfig = 1, 2
+
+ ! Create the file access property
+ CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl_id, hdferror)
+ CALL check("h5pcreate_f", hdferror, nerrors)
+
+ ! Split the communicator
+ IF(mpi_rank.EQ.0)THEN
+ CALL MPI_Comm_split(MPI_COMM_WORLD, 1, mpi_rank, comm, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_SPLIT *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ ELSE
+ CALL MPI_Comm_split(MPI_COMM_WORLD, 0, mpi_rank, comm, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_SPLIT *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ ENDIF
+
+ ! Create and set an MPI INFO parameter
+
+ CALL MPI_Info_create(info, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_CREATE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL MPI_Info_set(info, in_key, in_value, mpierror )
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_SET *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+
+ IF(iconfig.EQ.1)THEN
+ ! Set and get the MPI parameters
+ CALL h5pset_fapl_mpio_f(fapl_id, comm, info, hdferror)
+ CALL check("h5pset_fapl_mpio_f", hdferror, nerrors)
+
+ CALL h5pget_fapl_mpio_f(fapl_id, comm_ret, info_ret, hdferror)
+ CALL check("h5pget_fapl_mpio_f", hdferror, nerrors)
+ ELSE
+ 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)
+ ENDIF
+
+
+ ! Check comm returned
+ CALL mpi_comm_size(comm_ret, mpi_size_ret, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_SIZE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ IF (mpi_rank.EQ.0)THEN
+ CALL VERIFY("h5pget_fapl_mpio_f", mpi_size_ret, 1, hdferror)
+ ELSE
+ CALL VERIFY("h5pget_fapl_mpio_f", mpi_size_ret, mpi_size-1, hdferror)
+ ENDIF
+
+ ! Check info returned
+ CALL MPI_info_get_nkeys( info_ret, nkeys, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_GET_NKEYS *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL VERIFY("h5pget_fapl_mpio_f", nkeys, 1, hdferror)
+
+ CALL MPI_Info_get_nthkey(info_ret, 0, key, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_GET_NTHKEY *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL VERIFY("h5pget_fapl_mpio_f", TRIM(key), in_key, hdferror)
+
+ CALL MPI_Info_get(info, key, MPI_MAX_INFO_KEY, value, flag, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_GET *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL VERIFY("h5pget_fapl_mpio_f", flag, .TRUE., hdferror)
+ CALL VERIFY("h5pget_fapl_mpio_f", TRIM(value), in_value, hdferror)
+
+ ! Free the MPI resources
+ CALL MPI_info_free(info_ret, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_FREE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL MPI_comm_free(comm_ret, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_FREE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL MPI_info_free(info, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_INFO_FREE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+ CALL MPI_comm_free(comm, mpierror)
+ IF (mpierror .NE. MPI_SUCCESS) THEN
+ WRITE(*,*) "MPI_COMM_FREE *FAILED* Process = ", mpi_rank
+ nerrors = nerrors + 1
+ ENDIF
+
+ CALL h5pclose_f(fapl_id, hdferror)
+ CALL check("h5pclose_f", hdferror, nerrors)
+ ENDDO
+#else
+ INTEGER, INTENT(inout) :: nerrors ! number of errors
+ nerrors = -1 ! Skip test
+#endif
+
+END SUBROUTINE mpi_param_08
+
diff --git a/fortran/testpar/ptest.F90 b/fortran/testpar/ptest.F90
index b754e29..d2e9d10 100644
--- a/fortran/testpar/ptest.F90
+++ b/fortran/testpar/ptest.F90
@@ -58,6 +58,16 @@ PROGRAM parallel_test
IF(mpi_rank==0) CALL write_test_header("COMPREHENSIVE PARALLEL FORTRAN TESTS")
+ ret_total_error = 0
+ CALL mpi_param_03(ret_total_error)
+ IF(mpi_rank==0) CALL write_test_status(ret_total_error, &
+ 'Testing MPI communicator and info (F03)', total_error)
+
+ ret_total_error = 0
+ CALL mpi_param_08(ret_total_error)
+ IF(mpi_rank==0) CALL write_test_status(ret_total_error, &
+ 'Testing MPI communicator and info (F08)', total_error)
+
!
! test write/read dataset by hyperslabs (contiguous/chunk) with independent/collective MPI I/O
!
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 28d86d6..19a770d 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -102,6 +102,11 @@ New Features
Fortran Library:
----------------
+ - Add API support for Fortran MPI_F08 module definitions:
+ Adds support for MPI's MPI_F08 module datatypes: type(MPI_COMM) and type(MPI_INFO) for HDF5 APIs:
+ H5PSET_FAPL_MPIO_F, H5PGET_FAPL_MPIO_F, H5PSET_MPI_PARAMS_F, H5PGET_MPI_PARAMS_F
+ Ref. #3951
+
- Added Fortran APIs:
H5FGET_INTENT_F, H5SSEL_ITER_CREATE_F, H5SSEL_ITER_GET_SEQ_LIST_F,
H5SSEL_ITER_CLOSE_F, H5S_mp_H5SSEL_ITER_RESET_F