From 7cc749199f0b1808ad2cd7268b42ccc368644bb5 Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Fri, 29 Dec 2023 22:23:49 -0600 Subject: [PATCH 01/12] added subfiling example --- HDF5Examples/CMakeLists.txt | 3 +- HDF5Examples/FORTRAN/H5G/h5_version.h.in | 23 -- HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt | 2 + .../FORTRAN/H5PAR/Fortran_sourcefiles.cmake | 1 + .../FORTRAN/H5PAR/ph5_f90_dataset.F90 | 3 +- .../FORTRAN/H5PAR/ph5_f90_file_create.F90 | 2 +- .../H5PAR/ph5_f90_hyperslab_by_chunk.F90 | 3 +- .../H5PAR/ph5_f90_hyperslab_by_col.F90 | 3 +- .../H5PAR/ph5_f90_hyperslab_by_pattern.F90 | 2 +- .../H5PAR/ph5_f90_hyperslab_by_row.F90 | 2 +- .../FORTRAN/H5PAR/ph5_f90_subfiling.F90 | 248 ++++++++++++++++++ configure.ac | 14 +- fortran/src/CMakeLists.txt | 2 + fortran/src/H5_f.c | 2 + fortran/src/H5_ff.F90 | 6 +- fortran/src/H5config_f.inc.cmake | 21 +- fortran/src/H5config_f.inc.in | 18 ++ fortran/src/H5f90global.F90 | 6 +- fortran/src/Makefile.am | 2 + 19 files changed, 322 insertions(+), 41 deletions(-) delete mode 100644 HDF5Examples/FORTRAN/H5G/h5_version.h.in create mode 100644 HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 diff --git a/HDF5Examples/CMakeLists.txt b/HDF5Examples/CMakeLists.txt index 6f8b53c0167..6e5f0cdc2e5 100644 --- a/HDF5Examples/CMakeLists.txt +++ b/HDF5Examples/CMakeLists.txt @@ -159,7 +159,8 @@ if (${H5_LIBVER_DIR} GREATER 16) endif () configure_file (${H5EX_F90_SRC_DIR}/H5D/h5_version.h.in ${PROJECT_BINARY_DIR}/FORTRAN/H5D/h5_version.h @ONLY) - configure_file (${H5EX_F90_SRC_DIR}/H5G/h5_version.h.in ${PROJECT_BINARY_DIR}/FORTRAN/H5G/h5_version.h @ONLY) + configure_file (${H5EX_F90_SRC_DIR}/H5D/h5_version.h.in ${PROJECT_BINARY_DIR}/FORTRAN/H5G/h5_version.h @ONLY) + configure_file (${H5EX_F90_SRC_DIR}/H5D/h5_version.h.in ${PROJECT_BINARY_DIR}/FORTRAN/H5PAR/h5_version.h @ONLY) else () set (HDF_BUILD_FORTRAN OFF CACHE BOOL "Build examples FORTRAN support" FORCE) endif () diff --git a/HDF5Examples/FORTRAN/H5G/h5_version.h.in b/HDF5Examples/FORTRAN/H5G/h5_version.h.in deleted file mode 100644 index 68276759df4..00000000000 --- a/HDF5Examples/FORTRAN/H5G/h5_version.h.in +++ /dev/null @@ -1,23 +0,0 @@ -! Version numbers -! -! For major interface/format changes -! -#define H5_VERS_MAJOR @H5_VERS_MAJOR@ -! -! For minor interface/format changes -! -#define H5_VERS_MINOR @H5_VERS_MINOR@ -! -! For tweaks, bug-fixes, or development -! -#define H5_VERS_RELEASE @H5_VERS_RELEASE@ - -! macros for comparing versions - -#define H5_VERSION_GE(Maj, Min, Rel) \ - (((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR == Min) && (H5_VERS_RELEASE >= Rel)) || \ - ((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR > Min)) || (H5_VERS_MAJOR > Maj)) - -#define H5_VERSION_LE(Maj, Min, Rel) \ - (((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR == Min) && (H5_VERS_RELEASE <= Rel)) || \ - ((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR < Min)) || (H5_VERS_MAJOR < Maj)) diff --git a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt index d3124a15fa5..05f5543dc6c 100644 --- a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt @@ -12,7 +12,9 @@ project (HDF5Examples_FORTRAN_H5PAR Fortran) INCLUDE_DIRECTORIES ( ${CMAKE_Fortran_MODULE_DIRECTORY}${HDF_MOD_EXT} ${PROJECT_BINARY_DIR} + ${HDF5_F90_BINARY_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + ) #----------------------------------------------------------------------------- diff --git a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake index 39c8940b9c1..beda0d3256c 100644 --- a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake +++ b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake @@ -8,4 +8,5 @@ set (examples ph5_f90_hyperslab_by_col ph5_f90_hyperslab_by_pattern ph5_f90_hyperslab_by_chunk + ph5_f90_subfiling ) diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_dataset.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_dataset.F90 index 9819ab3c739..f7e4185411a 100644 --- a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_dataset.F90 +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_dataset.F90 @@ -1,10 +1,9 @@ PROGRAM DATASET USE HDF5 ! This module contains all necessary modules + USE MPI IMPLICIT NONE - - INCLUDE 'mpif.h' CHARACTER(LEN=10), PARAMETER :: filename = "sds.h5" ! File name CHARACTER(LEN=8), PARAMETER :: dsetname = "IntArray" ! Dataset name diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_file_create.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_file_create.F90 index 7944b5ab39b..b5aa090e643 100644 --- a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_file_create.F90 +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_file_create.F90 @@ -5,10 +5,10 @@ PROGRAM FILE_CREATE USE HDF5 ! This module contains all necessary modules + USE MPI IMPLICIT NONE - INCLUDE 'mpif.h' CHARACTER(LEN=10), PARAMETER :: filename = "sds.h5" ! File name INTEGER(HID_T) :: file_id ! File identifier diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_chunk.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_chunk.F90 index c74e55dbdcf..7be9389e77d 100644 --- a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_chunk.F90 +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_chunk.F90 @@ -4,11 +4,10 @@ PROGRAM DATASET_BY_CHUNK USE HDF5 ! This module contains all necessary modules -! USE MPI + USE MPI IMPLICIT NONE - include 'mpif.h' CHARACTER(LEN=11), PARAMETER :: filename = "sds_chnk.h5" ! File name CHARACTER(LEN=8), PARAMETER :: dsetname = "IntArray" ! Dataset name diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_col.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_col.F90 index dc92667c053..affb7992c26 100644 --- a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_col.F90 +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_col.F90 @@ -1,7 +1,6 @@ ! -! Number of processes is assumed to be 1 or multiples of 2 (1,2,4,6,8) +! Number of processes is assumed to be 1 or powers of 2 (2,4,8) ! - PROGRAM DATASET_BY_COL USE HDF5 ! This module contains all necessary modules diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_pattern.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_pattern.F90 index dd02c634e78..c7e8da13a7a 100644 --- a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_pattern.F90 +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_pattern.F90 @@ -5,10 +5,10 @@ PROGRAM DATASET_BY_PATTERN USE HDF5 ! This module contains all necessary modules + USE MPI IMPLICIT NONE - include 'mpif.h' CHARACTER(LEN=10), PARAMETER :: filename = "sds_pat.h5" ! File name CHARACTER(LEN=8), PARAMETER :: dsetname = "IntArray" ! Dataset name diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_row.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_row.F90 index f66da2a2f0a..66d5b250258 100644 --- a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_row.F90 +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_hyperslab_by_row.F90 @@ -4,10 +4,10 @@ PROGRAM DATASET_BY_ROW USE HDF5 ! This module contains all necessary modules + USE MPI IMPLICIT NONE - include 'mpif.h' CHARACTER(LEN=10), PARAMETER :: filename = "sds_row.h5" ! File name CHARACTER(LEN=8), PARAMETER :: dsetname = "IntArray" ! Dataset name diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 new file mode 100644 index 00000000000..e63b499e4e7 --- /dev/null +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 @@ -0,0 +1,248 @@ +! +! Example of using HDF5's Subfiling VFD to write to an +! HDF5 file that is striped across multiple subfiles +! +! If the HDF5_NOCLEANUP environment variable is set, the +! files that this example creates will not be removed as +! the example finishes. +! +! In general, the current working directory in which compiling +! is done, is not suitable for parallel I/O and there is no +! standard pathname for parallel file systems. In some cases, +! the parallel file name may even need some parallel file type +! prefix such as: "pfs:/GF/...". Therefore, this example parses +! the HDF5_PARAPREFIX environment variable for a prefix, if one +! is needed. +! + +! An optional include to determine the correct HDF5 version +! for selecting the appropriate HDF5 API parameters. This is +! not part of the HDF5 library and is generally unnecessary. +! This information is now included in "H5config_f.inc" starting +! with version 1.14.4. +#include "h5_version.h" + +! An optional include for the configure definitions. +#if H5_VERSION_GE(1, 14, 4) +#include "H5config_f.inc" +#endif + +#if defined(H5_HAVE_PARALLEL) && defined(H5_HAVE_SUBFILING_VFD) + +MODULE subf + + USE HDF5 + USE MPI + + CHARACTER(LEN=31), PARAMETER :: EXAMPLE_FILE = "h5_subfiling_default_example.h5" + CHARACTER(LEN=30), PARAMETER :: EXAMPLE_FILE2 = "h5_subfiling_custom_example.h5" + CHARACTER(LEN=33), PARAMETER :: EXAMPLE_FILE3 = "h5_subfiling_precreate_example.h5" + + CHARACTER(LEN=4), PARAMETER :: EXAMPLE_DSET_NAME = "DSET" + INTEGER , PARAMETER :: EXAMPLE_DSET_DIMS = 2 + + ! Have each MPI rank write 16MiB of data + INTEGER, PARAMETER :: EXAMPLE_DSET_NY = 4194304 + +CONTAINS + + ! Cleanup created files + + SUBROUTINE cleanup(filename, fapl_id) + + IMPLICIT NONE + INTEGER(HID_T) :: fapl_id + CHARACTER(*) :: filename + + LOGICAL :: do_cleanup + INTEGER :: status + + CALL get_environment_variable("HDF5_NOCLEANUP", STATUS=status) + !IF(status.EQ.0) CALL H5Fdelete_f(filename, fapl_id, status) + IF(status.EQ.0)THEN + OPEN(UNIT=15, IOSTAT=status, FILE=filename, STATUS='old') + IF(status .EQ. 0) CLOSE(15, STATUS='DELETE') + ENDIF + + END SUBROUTINE cleanup + + ! An example of using the HDF5 Subfiling VFD with + ! its default settings of 1 subfile per node, with + ! a stripe size of 32MiB + + SUBROUTINE subfiling_write_default(fapl_id, mpi_size, mpi_rank) + + IMPLICIT NONE + INTEGER(HID_T) :: fapl_id + INTEGER :: mpi_size + INTEGER :: mpi_rank + + INTEGER, DIMENSION(:), ALLOCATABLE, TARGET :: wdata + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: dset_dims + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: start + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: count + INTEGER(hid_t) :: file_id + INTEGER(hid_t) :: subfiling_fapl + INTEGER(hid_t) :: dset_id + INTEGER(hid_t) :: filespace + CHARACTER(LEN=512) :: filename, par_prefix + INTEGER :: status + INTEGER(SIZE_T) :: i + TYPE(C_PTR) :: f_ptr + + ! + ! Make a copy of the FAPL so we don't disturb + ! it for the other examples + ! + CALL H5Pcopy_f(fapl_id, subfiling_fapl, status) + + ! + ! Set Subfiling VFD on FAPL using default settings + ! (use IOC VFD, 1 IOC per node, 32MiB stripe size) + ! + ! Note that all of Subfiling's configuration settings + ! can be adjusted with environment variables as well + ! in this case. + ! + + CALL H5Pset_fapl_subfiling_f(subfiling_fapl, status) + + ! + ! OPTIONAL: Set alignment of objects in HDF5 file to + ! be equal to the Subfiling stripe size. + ! Choosing a Subfiling stripe size and HDF5 + ! object alignment value that are some + ! multiple of the disk block size can + ! generally help performance by ensuring + ! that I/O is well-aligned and doesn't + ! excessively cross stripe boundaries. + ! + ! Note that this option can substantially + ! increase the size of the resulting HDF5 + ! files, so it is a good idea to keep an eye + ! on this. + ! + + CALL H5Pset_alignment_f(subfiling_fapl, 0_HSIZE_T, 33554432_HSIZE_T, status) ! ALIGN to default 32MiB stripe size + + ! Parse any parallel prefix and create filename + par_prefix(:) = "" + CALL get_environment_variable("HDF5_PARAPREFIX", VALUE=par_prefix, STATUS=status) + filename = TRIM(par_prefix)//EXAMPLE_FILE + + ! Create a new file collectively + CALL H5Fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, status, access_prp = subfiling_fapl) + + ! Create the dataspace for the dataset. The second + ! dimension varies with the number of MPI ranks + ! while the first dimension is fixed. + + dset_dims(1) = EXAMPLE_DSET_NY + dset_dims(2) = mpi_size + CALL H5Screate_simple_f(EXAMPLE_DSET_DIMS, dset_dims, filespace, status) + + ! Create the dataset with default properties + + CALL H5Dcreate_f(file_id, EXAMPLE_DSET_NAME, H5T_NATIVE_INTEGER, filespace, dset_id, status) + ! Each MPI rank writes from a contiguous memory + ! region to the hyperslab in the file + + start(1) = 0 + start(2) = mpi_rank + count(1) = dset_dims(1) + count(2) = 1 + CALL H5Sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, start, count, status) + + ! Initialize data buffer + ALLOCATE(wdata(COUNT(1)*COUNT(2))) + DO i = 1, COUNT(1)*COUNT(2) + wdata(i) = mpi_rank + ENDDO + + ! Write to dataset + f_ptr = C_LOC(wdata) + CALL H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, status, mem_space_id=H5S_BLOCK_F, file_space_id=filespace) + + ! Close/release resources. + DEALLOCATE(wdata) + CALL H5Dclose_f(dset_id, status) + CALL H5Sclose_f(filespace, status) + + CALL H5Fclose_f(file_id, status) + + CALL cleanup(EXAMPLE_FILE, subfiling_fapl) + + CALL H5Pclose_f(subfiling_fapl, status) + + END SUBROUTINE subfiling_write_default + +END MODULE subf + +PROGRAM main + + USE SUBF + IMPLICIT NONE + + INTEGER :: comm = MPI_COMM_WORLD + INTEGER :: info = MPI_INFO_NULL + INTEGER(HID_T) :: fapl_id + INTEGER :: mpi_size + INTEGER :: mpi_rank + INTEGER :: required + INTEGER :: provided + INTEGER :: status + + ! HDF5 Subfiling VFD requires MPI_Init_thread with MPI_THREAD_MULTIPLE + required = MPI_THREAD_MULTIPLE + provided = 0 + CALL mpi_init_thread(required, provided, status) + IF (provided .NE. required) THEN + WRITE(*,*) "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE *FAILED*" + CALL MPI_Abort(comm, -1, status) + ENDIF + + CALL MPI_Comm_size(comm, mpi_size, status) + CALL MPI_Comm_rank(comm, mpi_rank, status) + + ! + ! Initialize HDF5 library and Fortran interfaces. + ! + CALL h5open_f(status) + + ! + ! Set up File Access Property List with MPI + ! parameters for the Subfiling VFD to use + CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl_id, status) + CALL H5Pset_mpi_params_f(fapl_id, comm, info, status) + + ! Use Subfiling VFD with default settings + CALL subfiling_write_default(fapl_id, mpi_size, mpi_rank) + + ! Use Subfiling VFD with custom settings + ! call subfiling_write_custom(fapl_id, mpi_size, mpi_rank) + + ! Use Subfiling VFD to precreate the HDF5 file on MPI rank + ! call subfiling_write_precreate(fapl_id, mpi_size, mpi_rank) + + CALL H5Pclose_f(fapl_id, status) + ! + ! Close FORTRAN interfaces and HDF5 library. + ! + CALL h5close_f(status) + + IF(mpi_rank .EQ. 0) WRITE(*,"(A)") "PHDF5 example finished with no errors" + + CALL MPI_Finalize(status) + +END PROGRAM main + +#else + +! dummy program since HDF5 is not parallel-enabled + +PROGRAM main + WRITE(*,"(A)") "Example program cannot run - HDF5 must be built with parallel support and Subfiling VFD support" +END PROGRAM main + +! H5_HAVE_PARALLEL && H5_HAVE_SUBFILING_VFD +#endif diff --git a/configure.ac b/configure.ac index 689ab3d2a42..a72c8b3562d 100644 --- a/configure.ac +++ b/configure.ac @@ -546,6 +546,16 @@ AC_CHECK_SIZEOF([float]) AC_CHECK_SIZEOF([double]) AC_CHECK_SIZEOF([long double]) +## HDF5 version from the first line of the README.md file. +H5_VERSION="`cut -d' ' -f3 $srcdir/README.md | head -1`" + +VERS_MAJOR=`echo $H5_VERSION | cut -d. -f1` +VERS_MINOR=`echo $H5_VERSION | cut -d. -f2` +VERS_RELEASE=`echo $H5_VERSION | cut -d. -f3` +AC_DEFINE_UNQUOTED([VERS_MAJOR], $VERS_MAJOR, [Define major library version]) +AC_DEFINE_UNQUOTED([VERS_MINOR], $VERS_MINOR, [Define minor library version]) +AC_DEFINE_UNQUOTED([VERS_RELEASE], $VERS_RELEASE, [Define release library version]) + ## ---------------------------------------------------------------------- ## Check if the Fortran interface should be enabled ## @@ -3633,10 +3643,6 @@ fi ## and installed with the libraries (used to generate libhdf5.settings). ## -## HDF5 version from the first line of the README.md file. -H5_VERSION="`cut -d' ' -f3 $srcdir/README.md | head -1`" -AC_SUBST([H5_VERSION]) - ## Configuration date AC_SUBST([CONFIG_DATE]) CONFIG_DATE="`date`" diff --git a/fortran/src/CMakeLists.txt b/fortran/src/CMakeLists.txt index 87557db82ab..60c0c3a96a2 100644 --- a/fortran/src/CMakeLists.txt +++ b/fortran/src/CMakeLists.txt @@ -431,6 +431,7 @@ if (BUILD_STATIC_LIBS) FILES ${HDF5_F90_BINARY_DIR}/static/H5f90i_gen.h ${HDF5_F90_BINARY_DIR}/static/H5fortran_types.F90 + ${HDF5_F90_BINARY_DIR}/H5config_f.inc DESTINATION ${HDF5_INSTALL_INCLUDE_DIR} COMPONENT @@ -441,6 +442,7 @@ else () FILES ${HDF5_F90_BINARY_DIR}/shared/H5f90i_gen.h ${HDF5_F90_BINARY_DIR}/shared/H5fortran_types.F90 + ${HDF5_F90_BINARY_DIR}/H5config_f.inc DESTINATION ${HDF5_INSTALL_INCLUDE_DIR} COMPONENT diff --git a/fortran/src/H5_f.c b/fortran/src/H5_f.c index 0392c2bdfa6..b1dc7dba5ea 100644 --- a/fortran/src/H5_f.c +++ b/fortran/src/H5_f.c @@ -771,6 +771,8 @@ h5init_flags_c(int_f *h5d_flags, size_t_f *h5d_size_flags, int_f *h5e_flags, hid * H5S flags */ h5s_hid_flags[0] = (hid_t_f)H5S_ALL; + h5s_hid_flags[1] = (hid_t_f)H5S_BLOCK; + h5s_hid_flags[2] = (hid_t_f)H5S_PLIST; h5s_hsize_flags[0] = (hsize_t_f)H5S_UNLIMITED; diff --git a/fortran/src/H5_ff.F90 b/fortran/src/H5_ff.F90 index 05a48ace48c..fe6337ad747 100644 --- a/fortran/src/H5_ff.F90 +++ b/fortran/src/H5_ff.F90 @@ -139,7 +139,7 @@ MODULE H5LIB INTEGER, DIMENSION(1:H5S_FLAGS_LEN) :: H5S_flags INTEGER, PARAMETER :: H5S_HSIZE_FLAGS_LEN = 1 INTEGER(HSIZE_T), DIMENSION(1:H5S_HSIZE_FLAGS_LEN) :: H5S_hsize_flags - INTEGER, PARAMETER :: H5S_HID_FLAGS_LEN = 1 + INTEGER, PARAMETER :: H5S_HID_FLAGS_LEN = 3 INTEGER(HSIZE_T), DIMENSION(1:H5S_HID_FLAGS_LEN) :: H5S_hid_flags ! ! H5T flags declaration @@ -632,7 +632,9 @@ END FUNCTION h5init1_flags_c ! ! H5S flags ! - H5S_ALL_F = H5S_hid_flags(1) + H5S_ALL_F = H5S_hid_flags(1) + H5S_BLOCK_F = H5S_hid_flags(2) + H5S_PLIST_F = H5S_hid_flags(3) H5S_UNLIMITED_F = H5S_hsize_flags(1) diff --git a/fortran/src/H5config_f.inc.cmake b/fortran/src/H5config_f.inc.cmake index 665207641ee..c02cec03afc 100644 --- a/fortran/src/H5config_f.inc.cmake +++ b/fortran/src/H5config_f.inc.cmake @@ -9,7 +9,7 @@ ! If you do not have access to either file, you may request a copy from * ! help@hdfgroup.org. * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -! fortran/src/H5config_f.inc. Generated from fortran/src/H5config_f.inc.in by configure +! fortran/H5config_f.inc. Generated from fortran/src/H5config_f.inc.cmake by CMake ! Define if there is parallel support #cmakedefine01 CMAKE_H5_HAVE_PARALLEL @@ -116,3 +116,22 @@ #else #define H5_NO_DEPRECATED_SYMBOLS #endif + +! For major interface/format changes +#define H5_VERS_MAJOR @H5_VERS_MAJOR@ + +! For minor interface/format changes +#define H5_VERS_MINOR @H5_VERS_MINOR@ + +! For tweaks, bug-fixes, or development +#define H5_VERS_RELEASE @H5_VERS_RELEASE@ + +! macros for comparing versions +#define H5_VERSION_GE(Maj, Min, Rel) \ + (((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR == Min) && (H5_VERS_RELEASE >= Rel)) || \ + ((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR > Min)) || (H5_VERS_MAJOR > Maj)) + +#define H5_VERSION_LE(Maj, Min, Rel) \ + (((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR == Min) && (H5_VERS_RELEASE <= Rel)) || \ + ((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR < Min)) || (H5_VERS_MAJOR < Maj)) + diff --git a/fortran/src/H5config_f.inc.in b/fortran/src/H5config_f.inc.in index 3aeded931d9..5fe1bcc663a 100644 --- a/fortran/src/H5config_f.inc.in +++ b/fortran/src/H5config_f.inc.in @@ -80,3 +80,21 @@ ! Define if deprecated public API symbols are disabled #undef NO_DEPRECATED_SYMBOLS +! For major interface/format changes +#undef VERS_MAJOR + +! For minor interface/format changes +#undef VERS_MINOR + +! For tweaks, bug-fixes, or development +#undef VERS_RELEASE + +! macros for comparing versions +#define VERSION_GE(Maj, Min, Rel) \ + (((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR == Min) && (H5_VERS_RELEASE >= Rel)) || \ + ((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR > Min)) || (H5_VERS_MAJOR > Maj)) + +#define VERSION_LE(Maj, Min, Rel) \ + (((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR == Min) && (H5_VERS_RELEASE <= Rel)) || \ + ((H5_VERS_MAJOR == Maj) && (H5_VERS_MINOR < Min)) || (H5_VERS_MAJOR < Maj)) + diff --git a/fortran/src/H5f90global.F90 b/fortran/src/H5f90global.F90 index aa046235eb3..fb25f7efcc2 100644 --- a/fortran/src/H5f90global.F90 +++ b/fortran/src/H5f90global.F90 @@ -773,6 +773,8 @@ MODULE H5GLOBAL !DEC$if defined(BUILD_HDF5_DLL) !DEC$ATTRIBUTES DLLEXPORT :: H5S_UNLIMITED_F !DEC$ATTRIBUTES DLLEXPORT :: H5S_ALL_F + !DEC$ATTRIBUTES DLLEXPORT :: H5S_BLOCK_F + !DEC$ATTRIBUTES DLLEXPORT :: H5S_PLIST_F !DEC$ATTRIBUTES DLLEXPORT :: H5S_SCALAR_F !DEC$ATTRIBUTES DLLEXPORT :: H5S_SIMPLE_F !DEC$ATTRIBUTES DLLEXPORT :: H5S_NULL_F @@ -796,7 +798,9 @@ MODULE H5GLOBAL !> @{ INTEGER(HSIZE_T) :: H5S_UNLIMITED_F !< H5S_UNLIMITED - INTEGER(HID_T) :: H5S_ALL_F !< H5S_ALL + INTEGER(HID_T) :: H5S_ALL_F !< H5S_ALL + INTEGER(HID_T) :: H5S_BLOCK_F !< H5S_BLOCK + INTEGER(HID_T) :: H5S_PLIST_F !< H5S_PLIST INTEGER :: H5S_SCALAR_F !< H5S_SCALAR INTEGER :: H5S_SIMPLE_F !< H5S_SIMPLE diff --git a/fortran/src/Makefile.am b/fortran/src/Makefile.am index d42a41d2c9f..44561f62c14 100644 --- a/fortran/src/Makefile.am +++ b/fortran/src/Makefile.am @@ -75,6 +75,7 @@ install-data-local: fi $(CP) $(top_builddir)/$(subdir)/H5f90i_gen.h $(DESTDIR)$(includedir)/. $(CP) $(top_srcdir)/fortran/src/H5f90i.h $(DESTDIR)$(includedir)/. + $(CP) $(top_builddir)/$(subdir)/H5config_f.inc $(DESTDIR)$(includedir)/. uninstall-local: @if test -n "$(F9XMODEXT)" -a "X$(F9XMODEXT)" != "Xo"; then \ @@ -84,6 +85,7 @@ uninstall-local: fi; \ $(RM) $(DESTDIR)$(bindir)/$(H5FC_NAME) $(RM) $(DESTDIR)$(includedir)/H5f90i*.h + $(RM) $(DESTDIR)$(includedir)/H5config_f.inc # Also install and uninstall (uninstall-local above) h5fc script install-exec-local: From bc27cc4a665c90dc7fe76d45b66c804b4a4f17ff Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Fri, 29 Dec 2023 23:18:30 -0600 Subject: [PATCH 02/12] complete subfiling example --- .../FORTRAN/H5PAR/ph5_f90_subfiling.F90 | 302 +++++++++++++++++- 1 file changed, 300 insertions(+), 2 deletions(-) diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 index e63b499e4e7..cecf657ea5c 100644 --- a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 @@ -176,6 +176,304 @@ SUBROUTINE subfiling_write_default(fapl_id, mpi_size, mpi_rank) END SUBROUTINE subfiling_write_default + ! + ! An example of using the HDF5 Subfiling VFD with + ! custom settings + ! + + SUBROUTINE subfiling_write_custom(fapl_id, mpi_size, mpi_rank) + + IMPLICIT NONE + INTEGER(HID_T) :: fapl_id + INTEGER :: mpi_size + INTEGER :: mpi_rank + + INTEGER, DIMENSION(:), ALLOCATABLE, TARGET :: wdata + + TYPE(H5FD_subfiling_config_t) :: subf_config + TYPE(H5FD_ioc_config_t) :: ioc_config + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: dset_dims + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: start + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: count + INTEGER(hid_t) :: file_id + INTEGER(hid_t) :: subfiling_fapl + INTEGER(hid_t) :: dset_id + INTEGER(hid_t) :: filespace + CHARACTER(LEN=512) :: filename, par_prefix + INTEGER :: status + INTEGER(SIZE_T) :: i + TYPE(C_PTR) :: f_ptr + + ! Make a copy of the FAPL so we don't disturb + ! it for the other examples + + CALL H5Pcopy_f(fapl_id, subfiling_fapl, status) + + ! Get a default Subfiling and IOC configuration + CALL h5pget_fapl_subfiling_f(subfiling_fapl, subf_config, status) + CALL h5pget_fapl_ioc_f(subfiling_fapl,ioc_config, status) + + ! Set Subfiling configuration to use a 1MiB + ! stripe size and the SELECT_IOC_EVERY_NTH_RANK + ! selection method. By default, without a setting + ! in the H5FD_SUBFILING_IOC_SELECTION_CRITERIA + ! environment variable, this will use every MPI + ! rank as an I/O concentrator. + + subf_config%shared_cfg%stripe_size = 1048576 + subf_config%shared_cfg%ioc_selection = SELECT_IOC_EVERY_NTH_RANK_F + + ! Set IOC configuration to use 2 worker threads + ! per IOC instead of the default setting and + ! update IOC configuration with new subfiling + ! configuration. + + ioc_config%thread_pool_size = 2 + + ! Set our new configuration on the IOC + ! FAPL used for Subfiling + + CALL H5Pset_fapl_ioc_f(subf_config%ioc_fapl_id, status, ioc_config) + + ! Finally, set our new Subfiling configuration + ! on the original FAPL + + CALL H5Pset_fapl_subfiling_f(subfiling_fapl, status, subf_config) + ! + ! OPTIONAL: Set alignment of objects in HDF5 file to + ! be equal to the Subfiling stripe size. + ! Choosing a Subfiling stripe size and HDF5 + ! object alignment value that are some + ! multiple of the disk block size can + ! generally help performance by ensuring + ! that I/O is well-aligned and doesn't + ! excessively cross stripe boundaries. + ! + ! Note that this option can substantially + ! increase the size of the resulting HDF5 + ! files, so it is a good idea to keep an eye + ! on this. + ! + + CALL H5Pset_alignment_f(subfiling_fapl, 0_HSIZE_T, 33554432_HSIZE_T, status) ! ALIGN to default 32MiB stripe size + + ! Parse any parallel prefix and create filename + par_prefix(:) = "" + CALL get_environment_variable("HDF5_PARAPREFIX", VALUE=par_prefix, STATUS=status) + filename = TRIM(par_prefix)//EXAMPLE_FILE + + ! Create a new file collectively + CALL H5Fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, status, access_prp = subfiling_fapl) + + ! Create the dataspace for the dataset. The second + ! dimension varies with the number of MPI ranks + ! while the first dimension is fixed. + + dset_dims(1) = EXAMPLE_DSET_NY + dset_dims(2) = mpi_size + CALL H5Screate_simple_f(EXAMPLE_DSET_DIMS, dset_dims, filespace, status) + + ! Create the dataset with default properties + + CALL H5Dcreate_f(file_id, EXAMPLE_DSET_NAME, H5T_NATIVE_INTEGER, filespace, dset_id, status) + ! Each MPI rank writes from a contiguous memory + ! region to the hyperslab in the file + + start(1) = 0 + start(2) = mpi_rank + count(1) = dset_dims(1) + count(2) = 1 + CALL H5Sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, start, count, status) + + ! Initialize data buffer + ALLOCATE(wdata(COUNT(1)*COUNT(2))) + DO i = 1, COUNT(1)*COUNT(2) + wdata(i) = mpi_rank + ENDDO + + ! Write to dataset + f_ptr = C_LOC(wdata) + CALL H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, status, mem_space_id=H5S_BLOCK_F, file_space_id=filespace) + + ! Close/release resources. + DEALLOCATE(wdata) + CALL H5Dclose_f(dset_id, status) + CALL H5Sclose_f(filespace, status) + + CALL H5Fclose_f(file_id, status) + + CALL cleanup(EXAMPLE_FILE, subfiling_fapl) + + CALL H5Pclose_f(subfiling_fapl, status) + + END SUBROUTINE subfiling_write_custom + + ! + ! An example of pre-creating an HDF5 file on MPI rank + ! 0 when using the HDF5 Subfiling VFD. In this case, + ! the subfiling stripe count must be set so that rank + ! 0 knows how many subfiles to pre-create. + + SUBROUTINE subfiling_write_precreate(fapl_id, mpi_size, mpi_rank) + + IMPLICIT NONE + INTEGER(HID_T) :: fapl_id + INTEGER :: mpi_size + INTEGER :: mpi_rank + + INTEGER, DIMENSION(:), ALLOCATABLE, TARGET :: wdata + TYPE(H5FD_subfiling_config_t) :: subf_config + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: dset_dims + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: start + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: count + INTEGER(hid_t) :: file_id + INTEGER(hid_t) :: subfiling_fapl + INTEGER(hid_t) :: dset_id + INTEGER(hid_t) :: filespace + CHARACTER(LEN=512) :: filename, par_prefix + INTEGER :: status + INTEGER(SIZE_T) :: i + TYPE(C_PTR) :: f_ptr + + ! Make a copy of the FAPL so we don't disturb + ! it for the other examples + + CALL H5Pcopy_f(fapl_id, subfiling_fapl, status) + + ! Get a default Subfiling and IOC configuration + CALL h5pget_fapl_subfiling_f(subfiling_fapl, subf_config, status) + + ! + ! Set the Subfiling stripe count so that rank + ! 0 knows how many subfiles the logical HDF5 + ! file should consist of. In this case, use + ! 5 subfiles with a default stripe size of + ! 32MiB. + + subf_config%shared_cfg%stripe_count = 5 + ! + ! OPTIONAL: Set alignment of objects in HDF5 file to + ! be equal to the Subfiling stripe size. + ! Choosing a Subfiling stripe size and HDF5 + ! object alignment value that are some + ! multiple of the disk block size can + ! generally help performance by ensuring + ! that I/O is well-aligned and doesn't + ! excessively cross stripe boundaries. + ! + ! Note that this option can substantially + ! increase the size of the resulting HDF5 + ! files, so it is a good idea to keep an eye + ! on this. + ! + + CALL H5Pset_alignment_f(subfiling_fapl, 0_HSIZE_T, 1048576_HSIZE_T, status) ! Align to custom 1MiB stripe size + + ! Parse any parallel prefix and create filename + par_prefix(:) = "" + CALL get_environment_variable("HDF5_PARAPREFIX", VALUE=par_prefix, STATUS=status) + filename = TRIM(par_prefix)//EXAMPLE_FILE + + ! Set dataset dimensionality + dset_dims(1) = EXAMPLE_DSET_NY + dset_dims(2) = mpi_size + + IF (mpi_rank .EQ. 0) THEN + ! + ! Make sure only this rank opens the file + ! + CALL H5Pset_mpi_params_f(subfiling_fapl, MPI_COMM_SELF, MPI_INFO_NULL, status) + + ! + ! Set the Subfiling VFD on our FAPL using + ! our custom configuration + ! + CALL H5Pset_fapl_subfiling_f(subfiling_fapl, status, subf_config); + + ! + ! Create a new file on rank 0 + ! + CALL H5Fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, status, access_prp = subfiling_fapl) + + ! Create the dataspace for the dataset. The second + ! dimension varies with the number of MPI ranks + ! while the first dimension is fixed. + ! + CALL H5Screate_simple_f(EXAMPLE_DSET_DIMS, dset_dims, filespace, status) + + ! Create the dataset with default properties + + CALL H5Dcreate_f(file_id, EXAMPLE_DSET_NAME, H5T_NATIVE_INTEGER, filespace, dset_id, status) + + ! Initialize data buffer + ALLOCATE(wdata(dset_dims(1)*dset_dims(2))) + DO i = 1, dset_dims(1)*dset_dims(2) + wdata(i) = i + ENDDO + + ! + ! Rank 0 writes to the whole dataset + ! + f_ptr = C_LOC(wdata) + CALL H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, status, mem_space_id=H5S_BLOCK_F, file_space_id=filespace) + + ! + ! Close/release resources. + ! + DEALLOCATE(wdata) + CALL H5Dclose_f(dset_id, status) + CALL H5Sclose_f(filespace, status) + + CALL H5Fclose_f(file_id, status) + ENDIF + + CALL MPI_Barrier(MPI_COMM_WORLD, status) + + ! + ! Use all MPI ranks to re-open the file and + ! read back the dataset that was created + ! + CALL H5Pset_mpi_params_f(subfiling_fapl, MPI_COMM_WORLD, MPI_INFO_NULL, status) + + ! + ! Use the same subfiling configuration as rank 0 + ! used to create the file + ! + CALL H5Pset_fapl_subfiling_f(subfiling_fapl, status, subf_config) + + ! + ! Re-open the file on all ranks + ! + + CALL H5Fopen_f(filename, H5F_ACC_RDONLY_F, file_id, status, access_prp=subfiling_fapl) + + ! + ! Open the dataset that was created + ! + CALL H5Dopen_f(file_id, EXAMPLE_DSET_NAME, dset_id, status) + + ! + ! Initialize data buffer + ! + + ALLOCATE(wdata(dset_dims(1)*dset_dims(2))) + ! + ! Read the dataset on all ranks + ! + f_ptr = C_LOC(wdata) + CALL H5Dread_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, status, mem_space_id=H5S_BLOCK_F, file_space_id=H5S_ALL_F) + + DEALLOCATE(wdata) + + CALL H5Dclose_f(dset_id, status) + CALL H5Fclose_f(file_id, status) + + CALL cleanup(EXAMPLE_FILE, subfiling_fapl) + + CALL H5Pclose_f(subfiling_fapl, status) + + END SUBROUTINE subfiling_write_precreate + END MODULE subf PROGRAM main @@ -219,10 +517,10 @@ PROGRAM main CALL subfiling_write_default(fapl_id, mpi_size, mpi_rank) ! Use Subfiling VFD with custom settings - ! call subfiling_write_custom(fapl_id, mpi_size, mpi_rank) + CALL subfiling_write_custom(fapl_id, mpi_size, mpi_rank) ! Use Subfiling VFD to precreate the HDF5 file on MPI rank - ! call subfiling_write_precreate(fapl_id, mpi_size, mpi_rank) + CALL subfiling_write_precreate(fapl_id, mpi_size, mpi_rank) CALL H5Pclose_f(fapl_id, status) ! From dddbebdee9d9e44274084c2d8cb58aae64500c0e Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Sun, 31 Dec 2023 12:42:05 -0600 Subject: [PATCH 03/12] Added filtered writes with no selection example --- .../FORTRAN/H5PAR/Fortran_sourcefiles.cmake | 1 + .../H5PAR/ph5_f90_filtered_writes_no_sel.F90 | 376 ++++++++++++++++++ 2 files changed, 377 insertions(+) create mode 100644 HDF5Examples/FORTRAN/H5PAR/ph5_f90_filtered_writes_no_sel.F90 diff --git a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake index beda0d3256c..9a610373fb0 100644 --- a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake +++ b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake @@ -4,6 +4,7 @@ set (examples ph5_f90_dataset ph5_f90_file_create + ph5_f90_filtered_writes_no_sel ph5_f90_hyperslab_by_row ph5_f90_hyperslab_by_col ph5_f90_hyperslab_by_pattern diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_filtered_writes_no_sel.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_filtered_writes_no_sel.F90 new file mode 100644 index 00000000000..4c7299e4b80 --- /dev/null +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_filtered_writes_no_sel.F90 @@ -0,0 +1,376 @@ +! +! Example of using the parallel HDF5 library to collectively write to +! datasets with filters applied to them when one or MPI ranks do not +! have data to contribute to the dataset. +! +! If the HDF5_NOCLEANUP environment variable is set, the file that +! this example creates will not be removed as the example finishes. +! +! The need of requirement of parallel file prefix is that in general +! the current working directory in which compiling is done, is not suitable +! for parallel I/O and there is no standard pathname for parallel file +! systems. In some cases, the parallel file name may even need some +! parallel file type prefix such as: "pfs:/GF/...". Therefore, this +! example parses the HDF5_PARAPREFIX environment variable for a prefix, +! if one is needed. + +! An optional include to determine the correct HDF5 version +! for selecting the appropriate HDF5 API parameters. This is +! not part of the HDF5 library and is generally unnecessary. +! This information is now included in "H5config_f.inc" starting +! with version 1.14.4. +#include "h5_version.h" + +! An optional include for the configure definitions. +#if H5_VERSION_GE(1, 14, 4) +#include "H5config_f.inc" +#endif + +#if defined(H5_HAVE_PARALLEL) + +MODULE filter + USE HDF5 + USE MPI + + IMPLICIT NONE + + CHARACTER(LEN=29), PARAMETER :: EXAMPLE_FILE = "ph5_filtered_writes_no_sel.h5" + INTEGER , PARAMETER :: EXAMPLE_DSET_DIMS = 2 + CHARACTER(LEN=4) , PARAMETER :: EXAMPLE_DSET_NAME = "DSET" + INTEGER , PARAMETER :: EXAMPLE_DSET_CHUNK_DIM_SIZE = 10 + INTEGER , PARAMETER :: PATH_MAX = 512 + + ! Global variables + INTEGER :: mpi_rank, mpi_size + +CONTAINS + ! + ! Routine to set an HDF5 filter on the given DCPL + ! + SUBROUTINE set_filter(dcpl_id) + + IMPLICIT NONE + INTEGER(HID_T) :: dcpl_id + LOGICAL :: filter_avail + INTEGER :: status + + ! + ! Check if 'deflate' filter is available + ! + CALL H5Zfilter_avail_f(H5Z_FILTER_DEFLATE_F, filter_avail, status) + IF(status .LT. 0)THEN + RETURN + ELSE IF(filter_avail)THEN + ! + ! Set 'deflate' filter with reasonable + ! compression level on DCPL + + CALL H5Pset_deflate_f(dcpl_id, 6, status) + ELSE + ! + ! Set Fletcher32 checksum filter on DCPL + ! since it is always available in HDF5 + CALL H5Pset_fletcher32_f(dcpl_id, status) + ENDIF + END SUBROUTINE set_filter + ! + ! Routine to fill a data buffer with data. Assumes + ! dimension rank is 2 and data is stored contiguous. + + + SUBROUTINE fill_databuf(start, count, stride, wdata) + + IMPLICIT NONE + INTEGER(HSIZE_T), DIMENSION(*) :: start, count, stride + INTEGER, DIMENSION(*) :: wdata + INTEGER(HSIZE_T) :: i, j, icnt + + ! Use MPI rank value for data + icnt = 1 + DO i = 1, COUNT(1) + DO j = 1, COUNT(2) + wdata(icnt) = mpi_rank + icnt = icnt + 1 + ENDDO + ENDDO + + END SUBROUTINE fill_databuf + ! + ! Cleanup created files + ! + SUBROUTINE cleanup(filename) + + IMPLICIT NONE + CHARACTER(*) :: filename + + LOGICAL :: do_cleanup + INTEGER :: status + + CALL get_environment_variable("HDF5_NOCLEANUP", STATUS=status) + IF(status.EQ.0)THEN + CALL MPI_File_delete(filename, MPI_INFO_NULL, status) + ENDIF + + END SUBROUTINE cleanup + ! + ! Routine to write to a dataset in a fashion + ! where no chunks in the dataset are written + ! to by more than 1 MPI rank. This will + ! generally give the best performance as the + ! MPI ranks will need the least amount of + ! inter-process communication. + + SUBROUTINE write_dataset_some_no_sel(file_id, dxpl_id) + + IMPLICIT NONE + INTEGER(HID_T) :: file_id, dxpl_id + + INTEGER, DIMENSION(1:EXAMPLE_DSET_CHUNK_DIM_SIZE, 4*EXAMPLE_DSET_CHUNK_DIM_SIZE), TARGET :: wdata + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: dataset_dims + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: chunk_dims + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: start + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: stride + INTEGER(hsize_t), DIMENSION(1:EXAMPLE_DSET_DIMS) :: count + LOGICAL :: no_selection = .FALSE. + INTEGER(hid_t) :: dset_id + INTEGER(hid_t) :: dcpl_id + INTEGER(hid_t) :: file_dataspace + INTEGER(hid_t) :: sel_type + TYPE(C_PTR) :: f_ptr + INTEGER :: status + + ! + ! ------------------------------------ + ! Setup Dataset Creation Property List + ! ------------------------------------ + + CALL H5Pcreate_f(H5P_DATASET_CREATE_F, dcpl_id, status) + + ! + ! REQUIRED: Dataset chunking must be enabled to + ! apply a data filter to the dataset. + ! Chunks in the dataset are of size + ! EXAMPLE_DSET_CHUNK_DIM_SIZE x EXAMPLE_DSET_CHUNK_DIM_SIZE. + + chunk_dims(1) = EXAMPLE_DSET_CHUNK_DIM_SIZE + chunk_dims(2) = EXAMPLE_DSET_CHUNK_DIM_SIZE + CALL H5Pset_chunk_f(dcpl_id, EXAMPLE_DSET_DIMS, chunk_dims, status) + + ! Set filter to be applied to created datasets + CALL set_filter(dcpl_id) + + ! + ! ------------------------------------ + ! Define the dimensions of the dataset + ! and create it + ! ------------------------------------ + + ! Create a dataset composed of 4 chunks + ! per MPI rank. The first dataset dimension + ! scales according to the number of MPI ranks. + ! The second dataset dimension stays fixed + ! according to the chunk size. + + dataset_dims(1) = EXAMPLE_DSET_CHUNK_DIM_SIZE * mpi_size + dataset_dims(2) = 4 * EXAMPLE_DSET_CHUNK_DIM_SIZE + + CALL H5Screate_simple_f(EXAMPLE_DSET_DIMS, dataset_dims, file_dataspace, status) + + ! Create the dataset + CALL H5Dcreate_f(file_id, EXAMPLE_DSET_NAME, H5T_NATIVE_INTEGER, file_dataspace, dset_id, status, dcpl_id=dcpl_id) + + ! + ! ------------------------------------ + ! Setup selection in the dataset for + ! each MPI rank + ! ------------------------------------ + + ! + ! Odd rank value MPI ranks do not + ! contribute any data to the dataset. + + IF(MOD(mpi_rank, 2) .NE. 0) no_selection = .TRUE. + + IF(no_selection)THEN + ! + ! MPI ranks not contributing data to + ! the dataset should call H5Sselect_none + ! on the file dataspace that will be + ! passed to H5Dwrite. + + CALL H5Sselect_none_f(file_dataspace, status) + sel_type = H5S_BLOCK_F + ELSE + ! + ! Even MPI ranks contribute data to + ! the dataset. Each MPI rank's selection + ! covers a single chunk in the first dataset + ! dimension. Each MPI rank's selection + ! covers 4 chunks in the second dataset + ! dimension. This leads to each contributing + ! MPI rank writing to 4 chunks of the dataset. + + start(1) = mpi_rank * EXAMPLE_DSET_CHUNK_DIM_SIZE + start(2) = 0 + stride(1) = 1 + stride(2) = 1 + count(1) = EXAMPLE_DSET_CHUNK_DIM_SIZE + count(2) = 4 * EXAMPLE_DSET_CHUNK_DIM_SIZE + + CALL H5Sselect_hyperslab_f(file_dataspace, H5S_SELECT_SET_F, start, count, status, stride=stride) + + sel_type = H5S_ALL_F + ! + ! -------------------------------------- + ! Fill data buffer with MPI rank's rank + ! value to make it easy to see which + ! part of the dataset each rank wrote to + ! -------------------------------------- + + CALL fill_databuf(start, count, stride, wdata) + ENDIF + + ! + ! --------------------------------- + ! Write to the dataset collectively + ! --------------------------------- + f_ptr = C_LOC(wdata) + CALL H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, status, & + mem_space_id=sel_type, file_space_id=file_dataspace, xfer_prp=dxpl_id) + + ! + ! -------------- + ! Close HDF5 IDs + ! -------------- + + CALL H5Sclose_f(file_dataspace,status) + CALL H5Pclose_f(dcpl_id,status) + CALL H5Dclose_f(dset_id,status) + + END SUBROUTINE write_dataset_some_no_sel + END MODULE filter + + PROGRAM main + + USE filter + IMPLICIT NONE + + INTEGER :: comm = MPI_COMM_WORLD + INTEGER :: info = MPI_INFO_NULL + INTEGER(hid_t) :: file_id + INTEGER(hid_t) :: fapl_id + INTEGER(hid_t) :: dxpl_id + CHARACTER(LEN=PATH_MAX) :: par_prefix + CHARACTER(LEN=PATH_MAX) :: filename + INTEGER :: status + + CALL MPI_Init(status) + CALL MPI_Comm_size(comm, mpi_size, status) + CALL MPI_Comm_rank(comm, mpi_rank, status) + + ! + ! Initialize HDF5 library and Fortran interfaces. + ! + CALL h5open_f(status) + ! + ! ---------------------------------- + ! Start parallel access to HDF5 file + ! ---------------------------------- + + ! Setup File Access Property List with parallel I/O access + CALL H5Pcreate_f(H5P_FILE_ACCESS_F, fapl_id, status) + CALL H5Pset_fapl_mpio_f(fapl_id, comm, info, status) + + ! + ! OPTIONAL: Set collective metadata reads on FAPL to allow + ! parallel writes to filtered datasets to perform + ! better at scale. While not strictly necessary, + ! this is generally recommended. + + CALL H5Pset_all_coll_metadata_ops_f(fapl_id, .TRUE., status) + + ! + ! OPTIONAL: Set the latest file format version for HDF5 in + ! order to gain access to different dataset chunk + ! index types and better data encoding methods. + ! While not strictly necessary, this is generally + ! recommended. + + CALL H5Pset_libver_bounds_f(fapl_id, H5F_LIBVER_LATEST_F, H5F_LIBVER_LATEST_F, status) + + ! Parse any parallel prefix and create filename + par_prefix(:) = "" + CALL get_environment_variable("HDF5_PARAPREFIX", VALUE=par_prefix, STATUS=status) + filename = TRIM(par_prefix)//EXAMPLE_FILE + + ! Create HDF5 file + CALL H5Fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, status, access_prp = fapl_id) + + ! + ! -------------------------------------- + ! Setup Dataset Transfer Property List + ! with collective I/O + ! -------------------------------------- + + + CALL H5Pcreate_f(H5P_DATASET_XFER_F, dxpl_id, status) + + ! + ! REQUIRED: Setup collective I/O for the dataset + ! write operations. Parallel writes to + ! filtered datasets MUST be collective, + ! even if some ranks have no data to + ! contribute to the write operation. + + CALL H5Pset_dxpl_mpio_f(dxpl_id, H5FD_MPIO_COLLECTIVE_F, status) + + ! + ! -------------------------------- + ! Create and write to the dataset + ! -------------------------------- + + ! + ! Write to a dataset in a fashion where no + ! chunks in the dataset are written to by + ! more than 1 MPI rank and some MPI ranks + ! have nothing to contribute to the dataset. + ! In this case, the MPI ranks that have no + ! data to contribute must still participate + ! in the collective H5Dwrite call, but should + ! call H5Sselect_none on the file dataspace + ! passed to the H5Dwrite call. + + CALL write_dataset_some_no_sel(file_id, dxpl_id) + + ! + ! ------------------ + ! Close all HDF5 IDs + ! ------------------ + + CALL H5Pclose_f(dxpl_id, status) + CALL H5Pclose_f(fapl_id, status) + CALL H5Fclose_f(file_id, status) + ! + ! Close FORTRAN interfaces and HDF5 library. + ! + CALL h5close_f(status) + + IF(mpi_rank .EQ. 0) WRITE(*,"(A)") "PHDF5 example finished with no errors" + + ! + ! ------------------------------------ + ! Cleanup created HDF5 file and finish + ! ------------------------------------ + CALL cleanup(filename) + + CALL MPI_Finalize(status) + +END PROGRAM main + +#else + +PROGRAM main + WRITE(*,"(A)") "HDF5 not configured with parallel support or parallel filtered writes are disabled!" +END PROGRAM main + +#endif From 67bef18b0110d4a7954526f3e6e367bc8eab3465 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 29 Dec 2023 08:42:35 -0600 Subject: [PATCH 04/12] Add 'warning density' computation to the warnhist script (#3910) * Add 'warning density' computation to the warnhist script, along with several cleanups to it. Add "--enable-show-all-warnings" configure (and CMake) option to disable compiler diagnostic suppression (and therefore show all the otherwise suppressed compiler diagnostics), disabled by default. Clean up a buncn of misc. warnings. Signed-off-by: Quincey Koziol --- bin/warnhist | 301 ++++++++++++++++++++++++++--- config/cmake/ConfigureChecks.cmake | 11 ++ config/cmake/H5pubconf.h.in | 3 + configure.ac | 39 ++++ fortran/src/H5config_f.inc.cmake | 4 +- release_docs/INSTALL_CMake.txt | 1 + src/H5Dpkg.h | 2 +- src/H5EApkg.h | 2 +- src/H5ESpkg.h | 2 +- src/H5Idbg.c | 15 +- src/H5Iint.c | 58 ++---- src/H5Ipkg.h | 11 +- src/H5Pprivate.h | 2 +- src/H5Tpkg.h | 2 +- src/H5private.h | 8 + test/event_set.c | 4 +- tools/src/h5import/h5import.c | 84 ++++---- utils/mirror_vfd/mirror_writer.c | 1 - 18 files changed, 414 insertions(+), 136 deletions(-) diff --git a/bin/warnhist b/bin/warnhist index 1e63a550b39..b77202f9504 100755 --- a/bin/warnhist +++ b/bin/warnhist @@ -22,8 +22,13 @@ use warnings; # Perl modules/settings use strict; use Getopt::Std; +use File::Find; +use File::Basename; +use Cwd; +#use Data::Dumper; # Global variables, for accumulating information +my %options=(); my $totalcount = 0; my $notecount = 0; my $dupcount = 0; @@ -54,11 +59,25 @@ my $last_fort_name; my $last_fort_line; my $last_fort_offset; +# Info about source files +my %c_files; +my %c_files_counted; +my %cpp_files; +my %cpp_files_counted; +my %fort_files; +my %fort_files_counted; +my $c_lines = 0; +my $cpp_lines = 0; +my $fort_lines = 0; + # Display usage sub do_help { - print "Usage: 'warnhist [-h, --help] [-t ] [-w ] [-W] [-f ] [-F] [-s ] [-S ] [file]'\n"; - print "\t-h, --help\tDisplay this usage\n"; - print "\t-t \tTrim pathname prefix from filenames, \n"; + print "Usage: 'warnhist [-h, --help] [-t ] [-w ] [-W] [-f ] [-F]\n"; + print "\t[-s ] [-S ] [-d] [-p Trim pathname prefix from filenames, \n"; print "\t-w \tDisplay files for a given warning index list, \n"; print "\t\t can be a single value, a range, or a comma separated list\n"; print "\t\tFor example: '0' or '0,4' or '8-10' or '0,2-4,8-10,13'\n"; @@ -67,10 +86,13 @@ sub do_help { print "\t\t can be a single value, a range, or a comma separated list\n"; print "\t\tFor example: '0' or '0,4' or '8-10' or '0,2-4,8-10,13'\n"; print "\t-F\tDisplay warnings for all files\n"; - print "\t-s \tDisplay files for warnings which contain a string, \n"; + print "\t-s Display files for warnings which contain a\n"; + print "\t\tstring, \n"; print "\t\t is a comma separated list, with no spaces\n"; - print "\t\tFor example: 'Wunused-dummy-argument' or 'Wunused-dummy-argument,Wunused-variable'\n"; - print "\t-S \tDisplay warnings for files which contain a string, \n"; + print "\t\tFor example: 'Wunused-dummy-argument' or\n"; + print "\t\t'Wunused-dummy-argument,Wunused-variable'\n"; + print "\t-S Display warnings for files which contain a\n"; + print "\t\tstring, \n"; print "\t\t is a comma separated list, with no spaces\n"; print "\t\tFor example: 'H5Fint' or 'H5Fint,H5Gnode'\n"; print "\t-l\tDisplay line numbers for file/warning\n"; @@ -78,18 +100,182 @@ sub do_help { print "\t-i \tIgnore named files, \n"; print "\t\t is a comma separated list, with no spaces\n"; print "\t\tFor example: 'H5LTparse' or 'H5LTparse,H5LTanalyze'\n"; + print "\t-d\tCompute warning density for compiled source files. Paths to the\n"; + print "\t\troot of a directory containing source may be provided with the\n"; + print "\t\t'-p ' option. If the path list is given, only those\n"; + print "\t\tdirectories are scanned for source files. If the path list\n"; + print "\t\toption is not given, the current working directory is scanned.\n"; + print "\t-p \tPaths to search for compiled files. Compiled files\n"; + print "\t\tare only used when computing warning density and are not\n"; + print "\t\tnecessary for just analyzing warnings in build output.\n"; + print "\t\t is a comma separated list, with no spaces\n"; + print "\t\tFor example: '/home/koziol/hdf5' or '.,~/dev/hdf5,~/dev/build'\n"; + print "\t-q\tSuppress warning output\n"; print "\tfile\tFilename containing build output\n"; print "\t\tIf no file is given, standard input is used.\n"; exit; } +# Count # of lines in a file +sub line_count { + my ($name) = @_; +#print "name = '$name'\n"; + my $tmp; + my $lines = 0; + + open (FILE, $name) or die "Can't open '$name': $!"; + $lines++ while ($tmp = ); + close FILE; +#print "$lines\n"; + + return $lines; +} + +# Recursively search a directory hierarchy for source files +# Adds results to the global %c_files, %cpp_files, and %fort_files hashes +sub parse_tree { + my ($root_path) = @_; +#print "root_path = $root_path\n"; + + my $path_checker = sub { + my $name = $File::Find::name; + if (-f $name) { + my $bn = basename($name); + + # Check for different kinds of source files + # Use lists here: https://gist.github.com/ppisarczyk/43962d06686722d26d176fad46879d41#file-programming_languages_extensions-json + + # FORTRAN source file + if($bn =~ /.*(\.f90)|(\.f)|(\.f03)|(\.f08)|(\.f77)|(\.f95)|(\.for)|(\.fpp)$/i) { + $bn =~ s/(\.f90)|(\.f)|(\.f03)|(\.f08)|(\.f77)|(\.f95)|(\.for)|(\.fpp)$//ig; + if(!exists $fort_files{$bn}) { + $fort_files{$bn} = [ $name ]; + } else { + push @{ $fort_files{$bn} }, $name; + } + # C++ source file + } elsif($bn =~ /.*(\.cpp)|(\.c\+\+)|(\.cc)|(\.cp)|(\.cxx)$/i) { + $bn =~ s/(\.cpp)|(\.c\+\+)|(\.cc)|(\.cp)|(\.cxx)$//ig; + if(!exists $cpp_files{$bn}) { + $cpp_files{$bn} = [ $name ]; + } else { + push @{ $cpp_files{$bn} }, $name; + } + # C source file + } elsif($bn =~ /.*(\.c)$/i) { + $bn =~ s/(\.c)$//g; + if(!exists $c_files{$bn}) { + $c_files{$bn} = [ $name ]; + } else { + push @{ $c_files{$bn} }, $name; + } + } + } + }; + find($path_checker, $root_path); + +#print Dumper \%c_files; +#print Dumper \%cpp_files; +#print Dumper \%fort_files; +} + +sub count_file_loc { + my ($filename, $typename, $file_paths, $files_counted, $count) = @_; + + # Attempt to detect and handle object file name mangling by Automake + if(!exists $file_paths->{$filename} && $filename =~ /\-/) { + my ($bn) = $filename =~ /\S+\-(\S+)$/x; + if(exists $file_paths->{$bn}) { + if(!exists $options{q}) { + warn "No path for $typename source file '$filename', but '$bn' has path, assuming automake generated object file name"; + } + $filename = $bn; + } + } + + if(exists $file_paths->{$filename}) { + my $filecount = 0; + + # Attempt to count LOC for files with same name + if(scalar(@{$file_paths->{$filename}}) > 1) { + $filecount = $files_counted->{$filename}++; + + # Issue warning about multiple source files with same name + if($filecount == 0 && !exists $options{q}) { + local $" = ', '; # '$"' is documented in https://perldoc.perl.org/perlvar + warn "Multiple paths for $typename source file named '$filename', assuming each is compiled once, paths: [@{$file_paths->{$filename}}]\n"; + } + + # Sanity check for too many compiles of a file + if($filecount >= scalar(@{$file_paths->{$filename}})) { + if(!exists $options{q}) { + local $" = ', '; # '$"' is documented in https://perldoc.perl.org/perlvar + warn "Too many compiles of $typename source file named '$filename' with paths: [@{$file_paths->{$filename}}], disabling warning density calculations\n"; + } + delete $options{d}; + } + } + + # Increment the # of lines of code (if not too many) + if($filecount < scalar(@{$file_paths->{$filename}})) { + ${$count} += line_count($file_paths->{$filename}[$filecount]); + } + } else { + if(!exists $options{q}) { + warn "No path for $typename source file '$filename', e '-p' option to specify, disabling warning density calculations\n"; + } + delete $options{d}; + } +} + +# Compute LOC for compiled source file +sub count_source_loc { + my ($compile_line) = @_; +#print "compile_line = $compile_line\n"; + my $filetype; + my $filename; + + ($filetype, $filename) = $compile_line =~ /^\s+(CC|FC|CXX|PPFC)\s+(\S*)\.l*o$/x; + if($filename =~ /\//) { + $filename = basename($filename); + } +#print "filetype = '$filetype'\n"; +#print "filename = '$filename'\n"; + + if($filetype =~ /FC|PPFC/) { # FORTRAN source file + count_file_loc($filename, "FORTRAN", \%fort_files, \%fort_files_counted, \$fort_lines); + } elsif($filetype =~ /CXX/) { # C++ source file + count_file_loc($filename, "C++", \%cpp_files, \%cpp_files_counted, \$cpp_lines); + } elsif($filetype =~ /CC/) { # C source file + count_file_loc($filename, "C", \%c_files, \%c_files_counted, \$c_lines); + } +} + +sub sanity_check_loc { + my ($typename, $file_paths, $files_counted) = @_; + + if(scalar keys %{$files_counted} > 0) { + for my $x (keys(%{$files_counted})) { +#print "x = $x, # of compiles = ${$files_counted}{$x}, # of paths = ", scalar(@{$file_paths->{$x}}), "\n"; + if($files_counted->{$x} != scalar(@{$file_paths->{$x}})) { + if(!exists $options{q}) { + warn "# of compiles of C source file '$x' ($files_counted->{$x}) != # of paths (", scalar(@{$file_paths->{$x}}), "), disabling warning density calculation\n"; + } + # Don't print warning density, it's not accurate + delete $options{d}; + last; + } + } + } +} + + sub main::HELP_MESSAGE { do_help(); } # declare the Perl command line flags/options we want to allow -my %options=(); -getopts("FWhut:w:f:s:S:i:l", \%options); +getopts("FWhut:w:f:s:S:i:ldp:q", \%options); # Display usage, if requested if($options{h}) { @@ -185,6 +371,20 @@ if($options{u}) { $genericize = 0; } +# Scan source files, if warning density requested +if(exists $options{d}) { + if(exists $options{p}) { + my @pathnames = split /,/, $options{p}; +#print STDERR @pathnames; + for my $path (@pathnames) { + parse_tree($path); + } + } else { + # Scan the current working directory + parse_tree(getcwd); + } +} + PARSE_LINES: while (<>) { my $name; @@ -197,7 +397,7 @@ while (<>) { my $extra2; # Retain last FORTRAN compile line, which comes a few lines before warning - if($_ =~ /.*\.[fF]90:.*/) { + if($_ =~ /.*((\.inc)|(\.f90)|(\.f)|(\.f03)|(\.f08)|(\.f77)|(\.f95)|(\.for)|(\.fpp))\:.*/i) { ($last_fort_name, $last_fort_line, $last_fort_offset) = split /\:/, $_; ($last_fort_line, $toss) = split /\./, $last_fort_line; } @@ -212,17 +412,30 @@ while (<>) { $last_c_name = $_; } + # Compute LOC for compiled source files, if warning density requested + if(exists $options{d}) { + # Check for compilation line + if($_ =~ /^\s+(CC|FC|CXX|PPFC)\s+/) { + count_source_loc($_); + } + } + # Skip lines that don't have the word "warning" next if $_ !~ /[Ww]arning/; # Skip warnings from linker next if $_ =~ /ld: warning:/; + # Skip warnings from make + next if $_ =~ /^Makefile:[\d]*: warning:/; + # Skip warnings from build_py and install_lib next if $_ =~ /warning: (build_py|install_lib)/; - # Skip variables with the word 'warning' in them - next if $_ =~ /_warning_/; + # Skip variables with the word 'warning' (case insensitively) in them + next if $_ =~ /_warning_/i; + next if $_ =~ /_warning/i; + next if $_ =~ /warning_/i; # Skip AMD Optimizing Compiler (aocc) lines "<#> warning(s) generated." next if $_ =~ / warnings? generated\./; @@ -235,13 +448,9 @@ while (<>) { # Check for weird formatting of warning message $line = "??"; $offset = "??"; - if($_ =~ /^cc1: warning:.*/) { + if($_ =~ /^(cc1|): warning:.*/) { $name = $last_c_name; ($toss, $toss, $warning, $extra, $extra2) = split /\:/, $_; - # Check for CMAKE build with warning on first line and no filename - } elsif($_ =~ /^\s*[Ww]arning:.*/) { - $name = $last_c_name; - ($toss, $warning, $extra, $extra2) = split /\:/, $_; # Check for file-scope gcc Fortran warning output } elsif($_ =~ /f\d\d\d: Warning:/) { # These are interspersed with the "compiling a file" output @@ -274,9 +483,9 @@ while (<>) { } elsif($_ =~ /^\".*, line [0-9]+: *[Ww]arning:.*/) { ($name, $toss, $warning, $extra, $extra2) = split /\:/, $_; ($name, $line) = split /\,/, $name; - $name =~ s/^\"//g; - $name =~ s/\"$//g; - $line =~ s/^\s*line\s*//g; + $name =~ s/^\"//g; + $name =~ s/\"$//g; + $line =~ s/^\s*line\s*//g; # Check for Intel icc warning } elsif($_ =~ /.*[A-Za-z0-9_]\.[chC]\(.*[0-9]\):.*#.*/) { ($last_c_name, $toss, $warning) = split /\:/, $last_c_name; @@ -294,19 +503,13 @@ while (<>) { # Check for extra ':' followed by more text in original warning string, # and append the ':' and text back onto the parsed warning - # (Use 'length $extra' idiom to avoid warning when $extra is undefined) - if(length $extra ) { + if(defined $extra) { $warning = join ':', $warning, $extra; } - if(length $extra2 ) { + if(defined $extra2) { $warning = join ':', $warning, $extra2; } - # Restore the C++ '::' symbol now that we've parsed out the parts of the line - while($warning =~ /@@@@/) { - $warning =~ s/@@@@/\:\:/g; - } - # Trim leading '..' paths from filename while($name =~ /^\.\.\//) { $name =~ s/^\.\.\///g; @@ -336,6 +539,11 @@ while (<>) { next } + # Restore the C++ '::' symbol now that we've parsed out the parts of the line + while($warning =~ /@@@@/) { + $warning =~ s/@@@@/\:\:/g; + } + # Get rid of leading & trailing whitespace $warning =~ s/^\s//g; $warning =~ s/\s$//g; @@ -383,8 +591,8 @@ while (<>) { if($warning =~ /'[A-Za-z_0-9\(\)\*\,\[\]\.\<\>\&\:\+\#\-\=]+[A-Za-z_0-9\(\)\*\,\[\]\.\<\>\&\:\+\#\-\=\ ]*'/) { $warning =~ s/'[A-Za-z_0-9\(\)\*\,\[\]\.\<\>\&\:\+\#\-\=]+[A-Za-z_0-9\(\)\*\,\[\]\.\<\>\&\:\+\#\-\=\ ]*'/'-'/g; } - if($warning =~ /'%[\#0\-\ \+]*[,;\:_]?[0-9\*]*\.?[0-9\*]*[hjltzL]*[aAcdeEfFgGinosuxX]'/) { - $warning =~ s/'%[\#0\-\ \+]*[,;\:_]?[0-9\*]*\.?[0-9\*]*[hjltzL]*[aAcdeEfFgGinosuxX]'/'-'/g; + if($warning =~ /'%[\#0\-\ \+]*[,;\:_]?[0-9\*]*\.?[0-9\*]*[hjltzL]*[aAcdeEfFgGinopsuxX]'/) { + $warning =~ s/'%[\#0\-\ \+]*[,;\:_]?[0-9\*]*\.?[0-9\*]*[hjltzL]*[aAcdeEfFgGinopsuxX]'/'-'/g; } # Genericize C/C++ "" warnings into "-" @@ -397,6 +605,11 @@ while (<>) { $warning =~ s/=[A-Za-z_0-9]*\]/=-\]/g; } + # Genericize C/C++ "No such file or directory" warnings into "-" + if($warning =~ /^[A-Za-z_0-9\/]*: No such file or directory/) { + $warning =~ s/^[A-Za-z_0-9\/]*:/'-':/g; + } + # Genericize FORTRAN "at ()" into "at (-)", "REAL()" into "REAL(-)", # and "INTEGER()" into "INTEGER(-)" if($warning =~ /.*at\s\([0-9]+\).*/) { @@ -449,7 +662,31 @@ while (<>) { # print STDERR "warning = \"$warning\"\n"; } -print "Total unique [non-ignored] warnings: $totalcount\n"; +# Sanity check compiled source files with multiple paths when computing +# warning density +# (Check $options{d} each time, because any of the sanity checks could disable +# displaying the warning density) +if(exists $options{d}) { + sanity_check_loc("C", \%c_files, \%c_files_counted); +} +if(exists $options{d}) { + sanity_check_loc("FORTRAN", \%fort_files, \%fort_files_counted); +} +if(exists $options{d}) { + sanity_check_loc("C++", \%cpp_files, \%cpp_files_counted); +} + + +# +# Display results +# + +print "\nTotal unique [non-ignored] warnings: $totalcount\n"; +# Display warning density, if requested +if(exists $options{d}) { + print "Lines of code compiled: (C/C++/FORTRAN): ", ($c_lines + $cpp_lines + $fort_lines), " ($c_lines/$cpp_lines/$fort_lines)\n"; + printf "Warning density (<# of warnings> / <# of LOC compiled>): %10.10f\n", $totalcount / ($c_lines + $cpp_lines + $fort_lines); +} print "Ignored notes / supplemental warning lines [not counted in unique warnings]: $notecount\n"; print "Duplicated warning lines [not counted in unique warnings]: $dupcount\n"; print "Total ignored warnings: $ignorecount\n"; @@ -484,7 +721,7 @@ for my $x (sort {$warn_count{$b} <=> $warn_count{$a}} keys(%warn_count)) { $match = 1; } - if($match) { + if($match || exists $options{W}) { for my $y (sort {$warn_file{$x}{$b} <=> $warn_file{$x}{$a}} keys(%{$warn_file{$x}})) { printf ("\t%4d - %s\n", $warn_file{$x}{$y}, $y); if(exists $options{l}) { @@ -522,7 +759,7 @@ for my $x (sort {$file_count{$b} <=> $file_count{$a}} keys(%file_count)) { $match = 1; } - if($match) { + if($match || exists $options{F}) { for my $y (sort {$file_warn{$x}{$b} <=> $file_warn{$x}{$a}} keys(%{$file_warn{$x}})) { printf ("\t%4d - %s\n", $file_warn{$x}{$y}, $y); if(exists $options{l}) { diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 801336358bf..df28f76bd7d 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -594,6 +594,17 @@ if (HDF5_ENABLE_CODESTACK) endif () MARK_AS_ADVANCED (HDF5_ENABLE_CODESTACK) +# ---------------------------------------------------------------------- +# Check if they would like to show all warnings (not suppressed internally) +#----------------------------------------------------------------------------- +option (HDF5_SHOW_ALL_WARNINGS "Show all warnings (not suppressed internally)." OFF) +mark_as_advanced (HDF5_SHOW_ALL_WARNINGS) +if (HDF5_SHOW_ALL_WARNINGS) + message (STATUS "....All warnings will be displayed") + set (${HDF_PREFIX}_SHOW_ALL_WARNINGS 1) +endif () +MARK_AS_ADVANCED (HDF5_SHOW_ALL_WARNINGS) + # ---------------------------------------------------------------------- # Check if they would like to use file locking by default #----------------------------------------------------------------------------- diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 847c835eaea..2534b8e2542 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -631,6 +631,9 @@ /* Check exception handling functions during data conversions */ #cmakedefine H5_WANT_DCONV_EXCEPTION @H5_WANT_DCONV_EXCEPTION@ +/* Define if showing all compiler warnings are desired (i.e. don't suppress them internally) */ +#cmakedefine H5_SHOW_ALL_WARNINGS @H5_SHOW_ALL_WARNINGS@ + /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if !defined(__APPLE__) diff --git a/configure.ac b/configure.ac index a72c8b3562d..1e5a770e475 100644 --- a/configure.ac +++ b/configure.ac @@ -2321,6 +2321,45 @@ case "X-$DEV_WARNINGS" in ;; esac +## ---------------------------------------------------------------------- +## Check if they would like suppessed compiler diagnostics displayed +## (i.e. not suppressed) +## +## NOTE: Compiler diagnostics (i.e. warnings) are suppressed for some +## "noisy" warnings that are harmless (in the opinion of the primary +## HDF5 development team), but this option is provided to allow +## developers to see those warnings. +## +AC_MSG_CHECKING([whether showing all compiler warnings is enabled]) +AC_ARG_ENABLE([show-all-warnings], + [AS_HELP_STRING([--enable-show-all-warnings], + [Enable showing all compiler warnings (for developer debugging). + [default=no] + ])], + [SHOW_ALL_WARNINGS=$enableval]) + +## Set the default level. +if test "X-$SHOW_ALL_WARNINGS" = X- ; then + SHOW_ALL_WARNINGS=no +fi + +## Allow this variable to be substituted in +## other files (src/libhdf5.settings.in, etc.) +AC_SUBST([SHOW_ALL_WARNINGS]) + +case "X-$SHOW_ALL_WARNINGS" in + X-yes) + AC_MSG_RESULT([yes]) + AC_DEFINE([SHOW_ALL_WARNINGS], [1], [Define if showing all warnings is desired (i.e. not suppressed internally with H5_DIAG_OFF)]) + ;; + X-no) + AC_MSG_RESULT([no]) + ;; + *) + AC_MSG_ERROR([Unrecognized value: $SHOW_ALL_WARNINGS]) + ;; +esac + ## ---------------------------------------------------------------------- ## Check if the compiler should use profiling flags/settings ## diff --git a/fortran/src/H5config_f.inc.cmake b/fortran/src/H5config_f.inc.cmake index c02cec03afc..77ff7071640 100644 --- a/fortran/src/H5config_f.inc.cmake +++ b/fortran/src/H5config_f.inc.cmake @@ -28,8 +28,8 @@ #endif ! Define if on APPLE -#cmakedefine01 H5_HAVE_DARWIN -#if H5_HAVE_DARWIN == 0 +#cmakedefine01 CMAKE_H5_HAVE_DARWIN +#if CMAKE_H5_HAVE_DARWIN == 0 #undef H5_HAVE_DARWIN #else #define H5_HAVE_DARWIN diff --git a/release_docs/INSTALL_CMake.txt b/release_docs/INSTALL_CMake.txt index 27c185d544c..90e816e4fa4 100644 --- a/release_docs/INSTALL_CMake.txt +++ b/release_docs/INSTALL_CMake.txt @@ -826,6 +826,7 @@ ALLOW_UNSUPPORTED "Allow unsupported combinations of configure opti HDF5_EXTERNAL_LIB_PREFIX "Use prefix for custom library naming." "" HDF5_DISABLE_COMPILER_WARNINGS "Disable compiler warnings" OFF HDF5_ENABLE_ALL_WARNINGS "Enable all warnings" OFF +HDF5_SHOW_ALL_WARNINGS "Show all warnings (i.e. not suppress "noisy" ones internally)" OFF HDF5_ENABLE_CODESTACK "Enable the function stack tracing (for developer debugging)." OFF HDF5_ENABLE_COVERAGE "Enable code coverage for Libraries and Programs" OFF HDF5_ENABLE_DEBUG_APIS "Turn on extra debug output in all packages" OFF diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index a3695ae8544..dc842e8825b 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -727,7 +727,7 @@ H5_DLL herr_t H5D__chunk_allocated(const H5D_t *dset, hsize_t *nbytes); H5_DLL herr_t H5D__chunk_allocate(const H5D_t *dset, bool full_overwrite, const hsize_t old_dim[]); H5_DLL herr_t H5D__chunk_file_alloc(const H5D_chk_idx_info_t *idx_info, const H5F_block_t *old_chunk, H5F_block_t *new_chunk, bool *need_insert, const hsize_t *scaled); -H5_DLL void *H5D__chunk_mem_alloc(size_t size, void *pline); +H5_DLL void *H5D__chunk_mem_alloc(size_t size, void *pline) H5_ATTR_MALLOC; H5_DLL void H5D__chunk_mem_free(void *chk, void *pline); H5_DLL void *H5D__chunk_mem_xfree(void *chk, const void *pline); H5_DLL void *H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline); diff --git a/src/H5EApkg.h b/src/H5EApkg.h index 90ba02a02d8..e8b5a13e8d4 100644 --- a/src/H5EApkg.h +++ b/src/H5EApkg.h @@ -389,7 +389,7 @@ H5_DLL herr_t H5EA__destroy_flush_depend(H5AC_info_t *parent_entry, H5AC_info_t H5_DLL H5EA_hdr_t *H5EA__hdr_alloc(H5F_t *f); H5_DLL herr_t H5EA__hdr_init(H5EA_hdr_t *hdr, void *ctx_udata); H5_DLL haddr_t H5EA__hdr_create(H5F_t *f, const H5EA_create_t *cparam, void *ctx_udata); -H5_DLL void *H5EA__hdr_alloc_elmts(H5EA_hdr_t *hdr, size_t nelmts); +H5_DLL void *H5EA__hdr_alloc_elmts(H5EA_hdr_t *hdr, size_t nelmts) H5_ATTR_MALLOC; H5_DLL herr_t H5EA__hdr_free_elmts(H5EA_hdr_t *hdr, size_t nelmts, void *elmts); H5_DLL herr_t H5EA__hdr_incr(H5EA_hdr_t *hdr); H5_DLL herr_t H5EA__hdr_decr(H5EA_hdr_t *hdr); diff --git a/src/H5ESpkg.h b/src/H5ESpkg.h index f7c70e8f0c7..1da58a68679 100644 --- a/src/H5ESpkg.h +++ b/src/H5ESpkg.h @@ -75,7 +75,7 @@ typedef int (*H5ES_list_iter_func_t)(H5ES_event_t *ev, void *ctx); /******************************/ /* Package Private Prototypes */ /******************************/ -H5_DLL H5ES_t *H5ES__create(void); +H5_DLL H5ES_t *H5ES__create(void) H5_ATTR_MALLOC; H5_DLL herr_t H5ES__insert_request(H5ES_t *es, H5VL_t *connector, void *token); H5_DLL herr_t H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, bool *op_failed); H5_DLL herr_t H5ES__get_requests(H5ES_t *es, H5_iter_order_t order, hid_t *connector_ids, void **requests, diff --git a/src/H5Idbg.c b/src/H5Idbg.c index 4c7d1ec17c5..7910b1ce43d 100644 --- a/src/H5Idbg.c +++ b/src/H5Idbg.c @@ -83,13 +83,13 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) fprintf(stderr, " id = %" PRIdHID "\n", info->id); fprintf(stderr, " count = %u\n", info->count); - fprintf(stderr, " obj = 0x%8p\n", info->object); + fprintf(stderr, " obj = 0x%8p\n", info->u.c_object); fprintf(stderr, " marked = %d\n", info->marked); /* Get the group location, so we get get the name */ switch (type) { case H5I_GROUP: { - const H5VL_object_t *vol_obj = (const H5VL_object_t *)info->object; + const H5VL_object_t *vol_obj = (const H5VL_object_t *)info->u.c_object; object = H5VL_object_data(vol_obj); if (H5_VOL_NATIVE == vol_obj->connector->cls->value) @@ -98,7 +98,7 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) } case H5I_DATASET: { - const H5VL_object_t *vol_obj = (const H5VL_object_t *)info->object; + const H5VL_object_t *vol_obj = (const H5VL_object_t *)info->u.c_object; object = H5VL_object_data(vol_obj); if (H5_VOL_NATIVE == vol_obj->connector->cls->value) @@ -107,13 +107,10 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) } case H5I_DATATYPE: { - const H5T_t *dt = (const H5T_t *)info->object; + H5T_t *dt = info->u.object; - H5_GCC_CLANG_DIAG_OFF("cast-qual") - object = (void *)H5T_get_actual_type((H5T_t *)dt); - H5_GCC_CLANG_DIAG_ON("cast-qual") - - path = H5T_nameof(object); + object = H5T_get_actual_type((H5T_t *)dt); + path = H5T_nameof(object); break; } diff --git a/src/H5Iint.c b/src/H5Iint.c index 7d8b4acd0cc..1c5321461cc 100644 --- a/src/H5Iint.c +++ b/src/H5Iint.c @@ -369,17 +369,16 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) */ if (udata->force || (info->count - (!udata->app_ref * info->app_count)) <= 1) { /* Check if this is an un-realized future object */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") if (info->is_future) { /* Discard the future object */ - if ((info->discard_cb)((void *)info->object) < 0) { + if ((info->discard_cb)(info->u.object) < 0) { if (udata->force) { #ifdef H5I_DEBUG if (H5DEBUG(I)) { fprintf(H5DEBUG(I), "H5I: discard type=%d obj=%p " "failure ignored\n", - (int)udata->type_info->cls->type, info->object); + (int)udata->type_info->cls->type, info->u.c_object); } #endif /* H5I_DEBUG */ @@ -395,14 +394,14 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) else { /* Check for a 'free' function and call it, if it exists */ if (udata->type_info->cls->free_func && - (udata->type_info->cls->free_func)((void *)info->object, H5_REQUEST_NULL) < 0) { + (udata->type_info->cls->free_func)(info->u.object, H5_REQUEST_NULL) < 0) { if (udata->force) { #ifdef H5I_DEBUG if (H5DEBUG(I)) { fprintf(H5DEBUG(I), "H5I: free type=%d obj=%p " "failure ignored\n", - (int)udata->type_info->cls->type, info->object); + (int)udata->type_info->cls->type, info->u.c_object); } #endif /* H5I_DEBUG */ @@ -415,7 +414,6 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) mark = true; } } - H5_GCC_CLANG_DIAG_ON("cast-qual") /* Remove ID if requested */ if (mark) { @@ -524,7 +522,7 @@ H5I__register(H5I_type_t type, const void *object, bool app_ref, H5I_future_real info->id = new_id; info->count = 1; /* initial reference count */ info->app_count = !!app_ref; - info->object = object; + info->u.c_object = object; info->is_future = (NULL != realize_cb); info->realize_cb = realize_cb; info->discard_cb = discard_cb; @@ -633,7 +631,7 @@ H5I_register_using_existing_id(H5I_type_t type, void *object, bool app_ref, hid_ info->id = existing_id; info->count = 1; /* initial reference count*/ info->app_count = !!app_ref; - info->object = object; + info->u.object = object; /* This API call is only used by the native VOL connector, which is * not asynchronous. */ @@ -677,12 +675,10 @@ H5I_subst(hid_t id, const void *new_object) HGOTO_ERROR(H5E_ID, H5E_NOTFOUND, NULL, "can't get ID ref count"); /* Get the old object pointer to return */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - ret_value = (void *)info->object; - H5_GCC_CLANG_DIAG_ON("cast-qual") + ret_value = info->u.object; /* Set the new object pointer for the ID */ - info->object = new_object; + info->u.c_object = new_object; done: FUNC_LEAVE_NOAPI(ret_value) @@ -709,12 +705,9 @@ H5I_object(hid_t id) FUNC_ENTER_NOAPI_NOERR /* General lookup of the ID */ - if (NULL != (info = H5I__find_id(id))) { + if (NULL != (info = H5I__find_id(id))) /* Get the object pointer to return */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - ret_value = (void *)info->object; - H5_GCC_CLANG_DIAG_ON("cast-qual") - } + ret_value = info->u.object; FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_object() */ @@ -742,12 +735,9 @@ H5I_object_verify(hid_t id, H5I_type_t type) assert(type >= 1 && (int)type < H5I_next_type_g); /* Verify that the type of the ID is correct & lookup the ID */ - if (type == H5I_TYPE(id) && NULL != (info = H5I__find_id(id))) { + if (type == H5I_TYPE(id) && NULL != (info = H5I__find_id(id))) /* Get the object pointer to return */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - ret_value = (void *)info->object; - H5_GCC_CLANG_DIAG_ON("cast-qual") - } + ret_value = info->u.object; FUNC_LEAVE_NOAPI(ret_value) } /* H5I_object_verify() */ @@ -898,9 +888,7 @@ H5I__remove_common(H5I_type_info_t *type_info, hid_t id) if (type_info->last_id_info == info) type_info->last_id_info = NULL; - H5_GCC_CLANG_DIAG_OFF("cast-qual") - ret_value = (void *)info->object; - H5_GCC_CLANG_DIAG_ON("cast-qual") + ret_value = info->u.object; if (!H5I_marking_s) info = H5FL_FREE(H5I_id_info_t, info); @@ -1000,8 +988,7 @@ H5I__dec_ref(hid_t id, void **request) /* Get the ID's type */ type_info = H5I_type_info_array_g[H5I_TYPE(id)]; - H5_GCC_CLANG_DIAG_OFF("cast-qual") - if (!type_info->cls->free_func || (type_info->cls->free_func)((void *)info->object, request) >= 0) { + if (!type_info->cls->free_func || (type_info->cls->free_func)(info->u.object, request) >= 0) { /* Remove the node from the type */ if (NULL == H5I__remove_common(type_info, id)) HGOTO_ERROR(H5E_ID, H5E_CANTDELETE, (-1), "can't remove ID node"); @@ -1009,7 +996,6 @@ H5I__dec_ref(hid_t id, void **request) } /* end if */ else ret_value = -1; - H5_GCC_CLANG_DIAG_ON("cast-qual") } /* end if */ else { --(info->count); @@ -1482,9 +1468,7 @@ H5I__iterate_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) /* The stored object pointer might be an H5VL_object_t, in which * case we'll need to get the wrapped object struct (H5F_t *, etc.). */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - object = H5I__unwrap((void *)info->object, type); - H5_GCC_CLANG_DIAG_ON("cast-qual") + object = H5I__unwrap(info->u.object, type); /* Invoke callback function */ cb_ret_val = (*udata->user_func)((void *)object, info->id, udata->user_udata); @@ -1607,14 +1591,13 @@ H5I__find_id(hid_t id) } /* Check if this is a future ID */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") if (id_info && id_info->is_future) { hid_t actual_id = H5I_INVALID_HID; /* ID for actual object */ void *future_object; /* Pointer to the future object */ void *actual_object; /* Pointer to the actual object */ /* Invoke the realize callback, to get the actual object */ - if ((id_info->realize_cb)((void *)id_info->object, &actual_id) < 0) + if ((id_info->realize_cb)(id_info->u.object, &actual_id) < 0) HGOTO_DONE(NULL); /* Verify that we received a valid ID, of the same type */ @@ -1624,10 +1607,10 @@ H5I__find_id(hid_t id) HGOTO_DONE(NULL); /* Swap the actual object in for the future object */ - future_object = (void *)id_info->object; + future_object = id_info->u.object; actual_object = H5I__remove_common(type_info, actual_id); assert(actual_object); - id_info->object = actual_object; + id_info->u.object = actual_object; /* Discard the future object */ if ((id_info->discard_cb)(future_object) < 0) @@ -1639,7 +1622,6 @@ H5I__find_id(hid_t id) id_info->realize_cb = NULL; id_info->discard_cb = NULL; } - H5_GCC_CLANG_DIAG_ON("cast-qual") /* Set return value */ ret_value = id_info; @@ -1674,9 +1656,7 @@ H5I__find_id_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) assert(udata); /* Get a pointer to the VOL connector's data */ - H5_GCC_CLANG_DIAG_OFF("cast-qual") - object = H5I__unwrap((void *)info->object, type); - H5_GCC_CLANG_DIAG_ON("cast-qual") + object = H5I__unwrap(info->u.object, type); /* Check for a match */ if (object == udata->object) { diff --git a/src/H5Ipkg.h b/src/H5Ipkg.h index 620796278f4..c42c61d3d1b 100644 --- a/src/H5Ipkg.h +++ b/src/H5Ipkg.h @@ -56,10 +56,13 @@ /* ID information structure used */ typedef struct H5I_id_info_t { - hid_t id; /* ID for this info */ - unsigned count; /* Ref. count for this ID */ - unsigned app_count; /* Ref. count of application visible IDs */ - const void *object; /* Pointer associated with the ID */ + hid_t id; /* ID for this info */ + unsigned count; /* Ref. count for this ID */ + unsigned app_count; /* Ref. count of application visible IDs */ + union { + const void *c_object; /* Const pointer associated with the ID */ + void *object; /* Pointer associated with the ID */ + } u; /* Future ID info */ bool is_future; /* Whether this ID represents a future object */ diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index fa70e386dc3..36c24579959 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -175,7 +175,7 @@ H5_DLL herr_t H5P_insert(H5P_genplist_t *plist, const char *name, size_t size, v H5_DLL herr_t H5P_remove(H5P_genplist_t *plist, const char *name); H5_DLL htri_t H5P_exist_plist(const H5P_genplist_t *plist, const char *name); H5_DLL htri_t H5P_class_isa(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2); -H5_DLL char *H5P_get_class_name(H5P_genclass_t *pclass); +H5_DLL char *H5P_get_class_name(H5P_genclass_t *pclass) H5_ATTR_MALLOC; /* Internal helper routines */ H5_DLL herr_t H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, bool recurse); diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 7a79d449c0f..b9e24be912b 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -870,7 +870,7 @@ H5_DLL herr_t H5T__enum_insert(const H5T_t *dt, const char *name, const void *va H5_DLL herr_t H5T__get_member_value(const H5T_t *dt, unsigned membno, void *value); /* Field functions (for both compound & enumerated types) */ -H5_DLL char *H5T__get_member_name(H5T_t const *dt, unsigned membno); +H5_DLL char *H5T__get_member_name(H5T_t const *dt, unsigned membno) H5_ATTR_MALLOC; H5_DLL herr_t H5T__sort_value(const H5T_t *dt, int *map); H5_DLL herr_t H5T__sort_name(const H5T_t *dt, int *map); diff --git a/src/H5private.h b/src/H5private.h index 3aaa0d52453..5663c00123f 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -497,8 +497,16 @@ #define H5_DIAG_DO_PRAGMA(x) _Pragma(#x) #define H5_DIAG_PRAGMA(x) H5_DIAG_DO_PRAGMA(GCC diagnostic x) +/* Allow suppression of compiler diagnostics unless H5_SHOW_ALL_WARNINGS is + * defined (enabled with '--enable-show-all-warnings' configure option). + */ +#ifndef H5_SHOW_ALL_WARNINGS #define H5_DIAG_OFF(x) H5_DIAG_PRAGMA(push) H5_DIAG_PRAGMA(ignored H5_DIAG_JOINSTR("-W", x)) #define H5_DIAG_ON(x) H5_DIAG_PRAGMA(pop) +#else +#define H5_DIAG_OFF(x) +#define H5_DIAG_ON(x) +#endif /* Macros for enabling/disabling particular GCC-only warnings. * These pragmas are only implemented usefully in gcc 4.6+ diff --git a/test/event_set.c b/test/event_set.c index 52aa6ba5a4b..9e659aada15 100644 --- a/test/event_set.c +++ b/test/event_set.c @@ -22,8 +22,8 @@ static const char *FILENAME[] = {"event_set_1", NULL}; static hid_t connector_ids_g[EVENT_SET_NUM_CONNECTOR_IDS]; -herr_t fake_wait_request_wait(void *req, uint64_t timeout, H5VL_request_status_t *status); -herr_t fake_wait_request_free(void *req); +herr_t fake_wait_request_wait(void *req, uint64_t timeout, H5VL_request_status_t *status); +H5_ATTR_CONST herr_t fake_wait_request_free(void *req); /* A VOL class struct that describes a VOL class with no * functionality, other than a wait that returns success. diff --git a/tools/src/h5import/h5import.c b/tools/src/h5import/h5import.c index 2d3574a2f83..663f68a7479 100644 --- a/tools/src/h5import/h5import.c +++ b/tools/src/h5import/h5import.c @@ -26,48 +26,48 @@ #endif /* Local function declarations */ -static int gtoken(char *s); -static int process(struct Options *opt); -static int processConfigurationFile(char *infile, struct Input *in); -static int mapKeywordToIndex(char *key); -static int parsePathInfo(struct path_info *path, char *strm); -static int parseDimensions(struct Input *in, char *strm); -static int getInputSize(struct Input *in, int ival); -static int getInputClass(struct Input *in, char *strm); -static int getInputClassType(struct Input *in, char *strm); -static int getInputByteOrder(struct Input *in, FILE *strm); -static int InputClassStrToInt(char *temp); -static int getRank(struct Input *in, FILE *strm); -static int getDimensionSizes(struct Input *in, FILE *strm); -static int getOutputSize(struct Input *in, FILE *strm); -static int getOutputClass(struct Input *in, FILE *strm); -static int OutputClassStrToInt(char *temp); -static int getOutputArchitecture(struct Input *in, FILE *strm); -static int OutputArchStrToInt(const char *temp); -static int getOutputByteOrder(struct Input *in, FILE *strm); -static int OutputByteOrderStrToInt(const char *temp); -static int getChunkedDimensionSizes(struct Input *in, FILE *strm); -static int getCompressionType(struct Input *in, FILE *strm); -static int CompressionTypeStrToInt(char *temp); -static int getCompressionParameter(struct Input *in, FILE *strm); -static int getExternalFilename(struct Input *in, FILE *strm); -static int getMaximumDimensionSizes(struct Input *in, FILE *strm); -static int processDataFile(char *infile, struct Input *in, hid_t file_id); -static int readIntegerData(FILE *strm, struct Input *in); -static int readFloatData(FILE *strm, struct Input *in); -static int allocateIntegerStorage(struct Input *in); -static int allocateFloatStorage(struct Input *in); -static int readUIntegerData(FILE *strm, struct Input *in); -static int allocateUIntegerStorage(struct Input *in); -static int validateConfigurationParameters(struct Input *in); -static int processStrData(FILE *strm, struct Input *in, hid_t file_id); -static int processStrHDFData(FILE *strm, struct Input *in, hid_t file_id); -uint16_t swap_uint16(uint16_t val); -int16_t swap_int16(int16_t val); -uint32_t swap_uint32(uint32_t val); -int32_t swap_int32(int32_t val); -int64_t swap_int64(int64_t val); -uint64_t swap_uint64(uint64_t val); +static int gtoken(char *s); +static int process(struct Options *opt); +static int processConfigurationFile(char *infile, struct Input *in); +static int mapKeywordToIndex(char *key); +static int parsePathInfo(struct path_info *path, char *strm); +static int parseDimensions(struct Input *in, char *strm); +static int getInputSize(struct Input *in, int ival); +static int getInputClass(struct Input *in, char *strm); +static int getInputClassType(struct Input *in, char *strm); +static int getInputByteOrder(struct Input *in, FILE *strm); +static int InputClassStrToInt(char *temp); +static int getRank(struct Input *in, FILE *strm); +static int getDimensionSizes(struct Input *in, FILE *strm); +static int getOutputSize(struct Input *in, FILE *strm); +static int getOutputClass(struct Input *in, FILE *strm); +static int OutputClassStrToInt(char *temp); +static int getOutputArchitecture(struct Input *in, FILE *strm); +static int OutputArchStrToInt(const char *temp); +static int getOutputByteOrder(struct Input *in, FILE *strm); +static int OutputByteOrderStrToInt(const char *temp); +static int getChunkedDimensionSizes(struct Input *in, FILE *strm); +static int getCompressionType(struct Input *in, FILE *strm); +static int CompressionTypeStrToInt(char *temp); +static int getCompressionParameter(struct Input *in, FILE *strm); +static int getExternalFilename(struct Input *in, FILE *strm); +static int getMaximumDimensionSizes(struct Input *in, FILE *strm); +static int processDataFile(char *infile, struct Input *in, hid_t file_id); +static int readIntegerData(FILE *strm, struct Input *in); +static int readFloatData(FILE *strm, struct Input *in); +static int allocateIntegerStorage(struct Input *in); +static int allocateFloatStorage(struct Input *in); +static int readUIntegerData(FILE *strm, struct Input *in); +static int allocateUIntegerStorage(struct Input *in); +static int validateConfigurationParameters(struct Input *in); +static int processStrData(FILE *strm, struct Input *in, hid_t file_id); +static int processStrHDFData(FILE *strm, struct Input *in, hid_t file_id); +H5_ATTR_CONST uint16_t swap_uint16(uint16_t val); +H5_ATTR_CONST int16_t swap_int16(int16_t val); +H5_ATTR_CONST uint32_t swap_uint32(uint32_t val); +H5_ATTR_CONST int32_t swap_int32(int32_t val); +H5_ATTR_CONST int64_t swap_int64(int64_t val); +H5_ATTR_CONST uint64_t swap_uint64(uint64_t val); int main(int argc, char *argv[]) diff --git a/utils/mirror_vfd/mirror_writer.c b/utils/mirror_vfd/mirror_writer.c index a5a1d27f90b..f1569657deb 100644 --- a/utils/mirror_vfd/mirror_writer.c +++ b/utils/mirror_vfd/mirror_writer.c @@ -29,7 +29,6 @@ /* in detailed logging */ #define HEXDUMP_WRITEDATA 0 /* Toggle whether to print bytes to write */ /* in detailed logging */ -#define LISTENQ 80 /* max pending Driver requests */ #define MW_SESSION_MAGIC 0x88F36B32u #define MW_SOCK_COMM_MAGIC 0xDF10A157u From 00121b9fe48f1166315ecfbf89124b618883782b Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Sat, 30 Dec 2023 17:33:31 -0600 Subject: [PATCH 05/12] Added H5Fdelete_f with test (#3912) --- fortran/src/H5Fff.F90 | 43 +++++++++++++++++++++++-- fortran/src/hdf5_fortrandll.def.in | 1 + fortran/test/tH5F.F90 | 51 ++++++++++++++++++++++++------ release_docs/RELEASE.txt | 3 ++ 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/fortran/src/H5Fff.F90 b/fortran/src/H5Fff.F90 index d31117784e5..79aa5a7a34b 100644 --- a/fortran/src/H5Fff.F90 +++ b/fortran/src/H5Fff.F90 @@ -256,6 +256,43 @@ END SUBROUTINE h5fflush_f !> !! \ingroup FH5F !! +!! \brief Deletes an HDF5 file +!! +!! \param name Name of the file to delete +!! \param hdferr \fortran_error +!! \param access_prp File access property list identifier +!! +!! See C API: @ref H5Fdelete() +!! + SUBROUTINE h5fdelete_f(name, hdferr, access_prp) + IMPLICIT NONE + CHARACTER(LEN=*), INTENT(IN) :: name + INTEGER , INTENT(OUT) :: hdferr + INTEGER(HID_T) , INTENT(IN), OPTIONAL :: access_prp + + INTEGER(HID_T) :: access_prp_default + CHARACTER(LEN=LEN_TRIM(name)+1,KIND=C_CHAR) :: c_name + + INTERFACE + INTEGER(C_INT) FUNCTION H5Fdelete(name, access_prp_default) BIND(C,NAME='H5Fdelete') + IMPORT :: C_CHAR, C_INT + IMPORT :: HID_T + CHARACTER(KIND=C_CHAR), DIMENSION(*) :: name + INTEGER(HID_T), VALUE :: access_prp_default + END FUNCTION H5Fdelete + END INTERFACE + + c_name = TRIM(name)//C_NULL_CHAR + + access_prp_default = H5P_DEFAULT_F + IF (PRESENT(access_prp)) access_prp_default = access_prp + + hdferr = INT(H5Fdelete(c_name, access_prp_default)) + + END SUBROUTINE h5fdelete_f +!> +!! \ingroup FH5F +!! !! \brief Asynchronously flushes all buffers associated with a file to disk. !! !! \param object_id Identifier of object used to identify the file. @@ -285,7 +322,7 @@ SUBROUTINE h5fflush_async_f(object_id, scope, es_id, hdferr, file, func, line) INTEGER(KIND=C_INT) :: line_default = 0 INTERFACE - INTEGER FUNCTION H5Fflush_async(file, func, line, object_id, scope, es_id) & + INTEGER(C_INT) FUNCTION H5Fflush_async(file, func, line, object_id, scope, es_id) & BIND(C,NAME='H5Fflush_async') IMPORT :: C_CHAR, C_INT, C_PTR IMPORT :: HID_T @@ -303,8 +340,8 @@ END FUNCTION H5Fflush_async IF(PRESENT(func)) func_default = func IF(PRESENT(line)) line_default = INT(line, C_INT) - hdferr = H5Fflush_async(file_default, func_default, line_default, & - object_id, INT(scope, C_INT), es_id) + hdferr = INT(H5Fflush_async(file_default, func_default, line_default, & + object_id, INT(scope, C_INT), es_id)) END SUBROUTINE h5fflush_async_f !> diff --git a/fortran/src/hdf5_fortrandll.def.in b/fortran/src/hdf5_fortrandll.def.in index 55f4f2b579b..119e140e399 100644 --- a/fortran/src/hdf5_fortrandll.def.in +++ b/fortran/src/hdf5_fortrandll.def.in @@ -121,6 +121,7 @@ H5ES_mp_H5ESGET_ERR_COUNT_F H5ES_mp_H5ESCLOSE_F ; H5F H5F_mp_H5FCREATE_F +H5F_mp_H5FDELETE_F H5F_mp_H5FCREATE_ASYNC_F H5F_mp_H5FFLUSH_F H5F_mp_H5FFLUSH_ASYNC_F diff --git a/fortran/test/tH5F.F90 b/fortran/test/tH5F.F90 index b4d973e6844..7f9490b7d20 100644 --- a/fortran/test/tH5F.F90 +++ b/fortran/test/tH5F.F90 @@ -479,10 +479,11 @@ SUBROUTINE mountingtest(cleanup, total_error) total_error = total_error + 1 ENDIF - if(cleanup) CALL h5_cleanup_f(filename1, H5P_DEFAULT_F, error) + IF(cleanup) CALL h5_cleanup_f(filename1, H5P_DEFAULT_F, error) CALL check("h5_cleanup_f", error, total_error) - if(cleanup) CALL h5_cleanup_f(filename2, H5P_DEFAULT_F, error) + IF(cleanup) CALL h5_cleanup_f(filename2, H5P_DEFAULT_F, error) CALL check("h5_cleanup_f", error, total_error) + RETURN END SUBROUTINE mountingtest @@ -853,7 +854,9 @@ SUBROUTINE plisttest(cleanup, total_error) INTEGER(HID_T) :: access_id ! File Access property list identifier !flag to check operation success - INTEGER :: error + INTEGER :: error + !file status + LOGICAL :: status ! !Create a file1 using default properties. @@ -920,10 +923,37 @@ SUBROUTINE plisttest(cleanup, total_error) CALL h5fclose_f(file2_id, error) CALL check("h5fclose_f",error,total_error) - if(cleanup) CALL h5_cleanup_f(filename1, H5P_DEFAULT_F, error) - CALL check("h5_cleanup_f", error, total_error) - if(cleanup) CALL h5_cleanup_f(filename2, H5P_DEFAULT_F, error) - CALL check("h5_cleanup_f", error, total_error) + ! Test file deletion + CALL h5fis_accessible_f(filename1, status, error) + CALL check("h5fis_accessible_f",error,total_error) + IF ( .NOT. status ) THEN + WRITE(*,*) "ERROR: File ", filename1, " is not accessible as hdf5" + END IF + + CALL h5fdelete_f(filename1, error, H5P_DEFAULT_F) + CALL check("h5fdelete_f", error, total_error) + + INQUIRE(FILE=filename1, EXIST=status) + IF ( status ) THEN + WRITE(*,*) "ERROR: File ", filename1, " was not removed by H5Fdelete_f" + END IF + + CALL h5fis_accessible_f(filename2, status, error) + CALL check("h5fis_accessible_f",error,total_error) + IF ( .NOT. status ) THEN + WRITE(*,*) "ERROR: File ", filename2, " is not accessible as hdf5" + total_error=total_error + 1 + END IF + + CALL h5fdelete_f(filename2, error) + CALL check("h5fdelete_f", error, total_error) + + INQUIRE(FILE=filename2, EXIST=status) + IF ( status ) THEN + WRITE(*,*) "ERROR: File ", filename2, " was not removed by H5Fdelete_f" + total_error=total_error + 1 + END IF + RETURN END SUBROUTINE plisttest @@ -1320,6 +1350,7 @@ SUBROUTINE test_get_file_image(total_error) TYPE(C_PTR) :: f_ptr ! Pointer INTEGER(hid_t) :: fapl ! File access property INTEGER :: error ! Error flag + CHARACTER(LEN=18), PARAMETER :: filename="tget_file_image.h5" ! Create new properties for file access CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl, error) @@ -1330,7 +1361,7 @@ SUBROUTINE test_get_file_image(total_error) CALL check("h5pset_fapl_stdio_f", error, total_error) ! Create the file - CALL h5fcreate_f("tget_file_image.h5", H5F_ACC_TRUNC_F, file_id, error, H5P_DEFAULT_F, fapl) + CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, error, H5P_DEFAULT_F, fapl) CALL check("h5fcreate_f", error, total_error) ! Set up data space for new data set @@ -1357,7 +1388,7 @@ SUBROUTINE test_get_file_image(total_error) CALL check("h5fflush_f",error, total_error) ! Open the test file using standard I/O calls - OPEN(UNIT=10,FILE='tget_file_image.h5', ACCESS='STREAM') + OPEN(UNIT=10,FILE=filename, ACCESS='STREAM') ! Get the size of the test file ! ! Since we use the eoa to calculate the image size, the file size @@ -1406,7 +1437,7 @@ SUBROUTINE test_get_file_image(total_error) ALLOCATE(file_image_ptr(1:image_size)) ! Open the test file using standard I/O calls - OPEN(UNIT=10,FILE='tget_file_image.h5', FORM='UNFORMATTED', ACCESS='STREAM') + OPEN(UNIT=10,FILE=filename, FORM='UNFORMATTED', ACCESS='STREAM') ! Read the test file from disk into the buffer DO i = 1, image_size diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index dda38522fb8..1a40da7ee46 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -388,6 +388,9 @@ New Features Fortran Library: ---------------- + - Added Fortran APIs: + h5fdelete_f + - Added Fortran APIs: h5vlnative_addr_to_token_f and h5vlnative_token_to_address_f From 48dcd8490ec5820f4eaf95536c3acb8b90b91d39 Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Sun, 31 Dec 2023 15:09:21 -0600 Subject: [PATCH 06/12] moved subfiling list --- HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt | 6 ++++++ HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt index 05f5543dc6c..cc9d5e8e3ec 100644 --- a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt @@ -22,6 +22,12 @@ INCLUDE_DIRECTORIES ( #----------------------------------------------------------------------------- include (Fortran_sourcefiles.cmake) +if (HDF5_ENABLE_SUBFILING_VFD) + set (examples $examples + ph5_f90_subfiling + ) +endif() + foreach (example_name ${examples}) add_executable (${EXAMPLE_VARNAME}_f90_${example_name} ${PROJECT_SOURCE_DIR}/${example_name}.F90) target_compile_options(${EXAMPLE_VARNAME}_f90_${example_name} diff --git a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake index 9a610373fb0..e098700aa52 100644 --- a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake +++ b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake @@ -9,5 +9,4 @@ set (examples ph5_f90_hyperslab_by_col ph5_f90_hyperslab_by_pattern ph5_f90_hyperslab_by_chunk - ph5_f90_subfiling ) From 01be85b0e77baabedfc5d964288f0f7798525d9b Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Sun, 31 Dec 2023 15:40:45 -0600 Subject: [PATCH 07/12] removed #ifs --- HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt | 6 ----- .../FORTRAN/H5PAR/Fortran_sourcefiles.cmake | 6 +++++ .../FORTRAN/H5PAR/ph5_f90_subfiling.F90 | 25 ------------------- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt index cc9d5e8e3ec..05f5543dc6c 100644 --- a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt @@ -22,12 +22,6 @@ INCLUDE_DIRECTORIES ( #----------------------------------------------------------------------------- include (Fortran_sourcefiles.cmake) -if (HDF5_ENABLE_SUBFILING_VFD) - set (examples $examples - ph5_f90_subfiling - ) -endif() - foreach (example_name ${examples}) add_executable (${EXAMPLE_VARNAME}_f90_${example_name} ${PROJECT_SOURCE_DIR}/${example_name}.F90) target_compile_options(${EXAMPLE_VARNAME}_f90_${example_name} diff --git a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake index e098700aa52..e60595d1085 100644 --- a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake +++ b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake @@ -10,3 +10,9 @@ set (examples ph5_f90_hyperslab_by_pattern ph5_f90_hyperslab_by_chunk ) + +if (HDF5_ENABLE_SUBFILING_VFD) + set (examples $examples + ph5_f90_subfiling + ) +endif() \ No newline at end of file diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 index cecf657ea5c..fc30717e1b9 100644 --- a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_subfiling.F90 @@ -15,20 +15,6 @@ ! is needed. ! -! An optional include to determine the correct HDF5 version -! for selecting the appropriate HDF5 API parameters. This is -! not part of the HDF5 library and is generally unnecessary. -! This information is now included in "H5config_f.inc" starting -! with version 1.14.4. -#include "h5_version.h" - -! An optional include for the configure definitions. -#if H5_VERSION_GE(1, 14, 4) -#include "H5config_f.inc" -#endif - -#if defined(H5_HAVE_PARALLEL) && defined(H5_HAVE_SUBFILING_VFD) - MODULE subf USE HDF5 @@ -533,14 +519,3 @@ PROGRAM main CALL MPI_Finalize(status) END PROGRAM main - -#else - -! dummy program since HDF5 is not parallel-enabled - -PROGRAM main - WRITE(*,"(A)") "Example program cannot run - HDF5 must be built with parallel support and Subfiling VFD support" -END PROGRAM main - -! H5_HAVE_PARALLEL && H5_HAVE_SUBFILING_VFD -#endif From ee6077b432ea5ce0231b87fa27085d39e43a8aaf Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Tue, 2 Jan 2024 12:06:49 -0600 Subject: [PATCH 08/12] clean-up --- HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt | 1 - .../FORTRAN/H5PAR/Fortran_sourcefiles.cmake | 8 +++++-- .../H5PAR/ph5_f90_filtered_writes_no_sel.F90 | 22 ------------------- 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt index 05f5543dc6c..866f3ef4a8c 100644 --- a/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt +++ b/HDF5Examples/FORTRAN/H5PAR/CMakeLists.txt @@ -14,7 +14,6 @@ INCLUDE_DIRECTORIES ( ${PROJECT_BINARY_DIR} ${HDF5_F90_BINARY_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} - ) #----------------------------------------------------------------------------- diff --git a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake index e60595d1085..b6ea957821f 100644 --- a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake +++ b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake @@ -4,7 +4,6 @@ set (examples ph5_f90_dataset ph5_f90_file_create - ph5_f90_filtered_writes_no_sel ph5_f90_hyperslab_by_row ph5_f90_hyperslab_by_col ph5_f90_hyperslab_by_pattern @@ -15,4 +14,9 @@ if (HDF5_ENABLE_SUBFILING_VFD) set (examples $examples ph5_f90_subfiling ) -endif() \ No newline at end of file +endif() +if (HDF5_VERSION_STRING VERSION_GREATER_EQUAL "1.14.4") + set (examples $examples + ph5_f90_filtered_writes_no_sel + ) +endif() diff --git a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_filtered_writes_no_sel.F90 b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_filtered_writes_no_sel.F90 index 4c7299e4b80..ffec2fb54b2 100644 --- a/HDF5Examples/FORTRAN/H5PAR/ph5_f90_filtered_writes_no_sel.F90 +++ b/HDF5Examples/FORTRAN/H5PAR/ph5_f90_filtered_writes_no_sel.F90 @@ -14,20 +14,6 @@ ! example parses the HDF5_PARAPREFIX environment variable for a prefix, ! if one is needed. -! An optional include to determine the correct HDF5 version -! for selecting the appropriate HDF5 API parameters. This is -! not part of the HDF5 library and is generally unnecessary. -! This information is now included in "H5config_f.inc" starting -! with version 1.14.4. -#include "h5_version.h" - -! An optional include for the configure definitions. -#if H5_VERSION_GE(1, 14, 4) -#include "H5config_f.inc" -#endif - -#if defined(H5_HAVE_PARALLEL) - MODULE filter USE HDF5 USE MPI @@ -366,11 +352,3 @@ PROGRAM main CALL MPI_Finalize(status) END PROGRAM main - -#else - -PROGRAM main - WRITE(*,"(A)") "HDF5 not configured with parallel support or parallel filtered writes are disabled!" -END PROGRAM main - -#endif From 0e3ada0e4b84f8fbfdc71acc952360ba63b4bdf0 Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Tue, 2 Jan 2024 12:08:53 -0600 Subject: [PATCH 09/12] clean-up --- HDF5Examples/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/HDF5Examples/CMakeLists.txt b/HDF5Examples/CMakeLists.txt index 6e5f0cdc2e5..63adad67c0d 100644 --- a/HDF5Examples/CMakeLists.txt +++ b/HDF5Examples/CMakeLists.txt @@ -160,7 +160,6 @@ if (${H5_LIBVER_DIR} GREATER 16) configure_file (${H5EX_F90_SRC_DIR}/H5D/h5_version.h.in ${PROJECT_BINARY_DIR}/FORTRAN/H5D/h5_version.h @ONLY) configure_file (${H5EX_F90_SRC_DIR}/H5D/h5_version.h.in ${PROJECT_BINARY_DIR}/FORTRAN/H5G/h5_version.h @ONLY) - configure_file (${H5EX_F90_SRC_DIR}/H5D/h5_version.h.in ${PROJECT_BINARY_DIR}/FORTRAN/H5PAR/h5_version.h @ONLY) else () set (HDF_BUILD_FORTRAN OFF CACHE BOOL "Build examples FORTRAN support" FORCE) endif () From bbea3e46a50bbd6a86c5df233edd834a9431dcdc Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Tue, 2 Jan 2024 12:21:23 -0600 Subject: [PATCH 10/12] updated release doc. --- release_docs/RELEASE.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 1a40da7ee46..de5caa8a092 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -388,6 +388,12 @@ New Features Fortran Library: ---------------- + - Added Fortran Parameters: + H5S_BLOCK_F and H5S_PLIST_F + + - The configuration definitions file, H5config_f.inc, is now installed + and the HDF5 version number has been added to it. + - Added Fortran APIs: h5fdelete_f From d107eeea3d96435032fcdf826cdcd78fe4e48720 Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Tue, 2 Jan 2024 13:26:20 -0600 Subject: [PATCH 11/12] fixed typo --- HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake index b6ea957821f..af2bb574dc7 100644 --- a/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake +++ b/HDF5Examples/FORTRAN/H5PAR/Fortran_sourcefiles.cmake @@ -11,12 +11,12 @@ set (examples ) if (HDF5_ENABLE_SUBFILING_VFD) - set (examples $examples + set (examples ${examples} ph5_f90_subfiling ) endif() if (HDF5_VERSION_STRING VERSION_GREATER_EQUAL "1.14.4") - set (examples $examples + set (examples ${examples} ph5_f90_filtered_writes_no_sel ) endif() From 168d497ec6c6e62d5cd3c6c4a44e095be3781e19 Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Tue, 2 Jan 2024 13:51:28 -0600 Subject: [PATCH 12/12] added missing AC_SUBST --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 1e5a770e475..e594cccb71b 100644 --- a/configure.ac +++ b/configure.ac @@ -548,6 +548,7 @@ AC_CHECK_SIZEOF([long double]) ## HDF5 version from the first line of the README.md file. H5_VERSION="`cut -d' ' -f3 $srcdir/README.md | head -1`" +AC_SUBST([H5_VERSION]) VERS_MAJOR=`echo $H5_VERSION | cut -d. -f1` VERS_MINOR=`echo $H5_VERSION | cut -d. -f2`