H5dread_f symbol missing in hdf5 (fortran) libraries


#1

Hi All,
I am facing an issue while compiling WRF-DA code (Code is attached.)
da_radiance.f (297.8 KB)

The compilation line which fails -

ftn -c -ip -O3  -w -ftz -fno-alias -align all -FR -convert big_endian   -r8        -real-size `expr 8 \* 8` -i4 -I../external/crtm_2.2.3/libsrc   -I/opt/cray/pe/hdf5/1.10.0.3/INTEL/16.0/include   -L/opt/cray/pe/hdf5/1.10.0.3/INTEL/16.0/lib/  -lhdf5hl_fortran -lhdf5_fortran -lhdf5  da_radiance.f 

  da_radiance.f(5884): error #6285: There is no matching specific subroutine for this generic subroutine call.   [H5DREAD_F]
      call H5Dread_f(dhnd1, &
-----------^

I tried searching relevant symbol in library, and as expected the symbol was not present (h5dread_f_c is present instead).

nm /opt/cray/pe/hdf5/1.10.0.3/INTEL/16.0/lib/libhdf5*|grep -i h5dread_f
nm: /opt/cray/pe/hdf5/1.10.0.3/INTEL/16.0/lib/libhdf5.settings: File format not recognized
nm: /opt/cray/pe/hdf5/1.10.0.3/INTEL/16.0/lib/libhdf5_cpp_intel_160.la: File format not recognized
                 U h5dread_f_c
                 U h5dread_f_c
0000000000001290 T h5dread_f_c
0000000000035320 T h5dread_f_c
                 U h5dread_f_c
                 U h5dread_f_c
0000000000001290 T h5dread_f_c
0000000000035320 T h5dread_f_c
                 U h5dread_f_c
                 U h5dread_f_c
0000000000001290 T h5dread_f_c
0000000000035320 T h5dread_f_c
0000000000035320 T h5dread_f_c
0000000000035320 T h5dread_f_c

I tried compiling hdf5-1.10.2. With a quick peek at the code, I saw that the function seems to have been declared (& commented) in fortran/src/H5Dff.F90 as -

!  M. Scot Breitenfeld
!  September 17, 2011
!
! Fortran2003 Interface:
!!  SUBROUTINE h5dread_f(dset_id, mem_type_id, buf, hdferr, &
!!                       mem_space_id, file_space_id, xfer_prp)
!!    INTEGER(HID_T), INTENT(IN)              :: dset_id
!!    INTEGER(HID_T), INTENT(IN)              :: mem_type_id
!!    TYPE(C_PTR)   , INTENT(INOUT)           :: buf
!!    INTEGER       , INTENT(OUT)             :: hdferr
!!    INTEGER(HID_T), INTENT(IN)   , OPTIONAL :: mem_space_id
!!    INTEGER(HID_T), INTENT(IN)   , OPTIONAL :: file_space_id
!!    INTEGER(HID_T), INTENT(IN)   , OPTIONAL :: xfer_prp
!*****
  SUBROUTINE h5dread_ptr(dset_id, mem_type_id, buf, hdferr, &
       mem_space_id, file_space_id, xfer_prp)

Nonetheless, i tried compiling hdf 1.10.2 with fortran (2003?) flag as -

CC="icc" FC="ifort" CXX="icpc" CFLAGS="-fPIC" FCFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure --prefix=$PWD/INSTALL --enable-fortran

Configure logs for fortran section -

           Fortran: yes
           Fortran Compiler: /opt/intel/compilers_and_libraries_2017.5.239/linux/bin/intel64/ifort ( Intel(R) Fortran Intel(R) 64 Compiler Version 17.0.5.239 Build 20170817)
           Fortran Flags: -fPIC
           H5 Fortran Flags:    -O3
           AM Fortran Flags:
           Shared Fortran Library: yes
           Static Fortran Library: yes

again , i am unable to see the h5dread_f symbol in hdf5 library -

user@machine$ nm INSTALL/lib/libhdf5_fortran.*|grep -i h5dread_f
                 U h5dread_f_c
                 U h5dread_f_c
0000000000001240 T h5dread_f_c
nm: INSTALL/lib/libhdf5_fortran.la: File format not recognized
000000000003c870 T h5dread_f_c
000000000003c870 T h5dread_f_c
000000000003c870 T h5dread_f_c

Is this function unsupported/phased out in latest versions of HDF5?
If yes then please share an appropriate (older) version of library & relevant compilation flags to get the symbol in library.
Please let me know if i can provide you with any further information.


#2

Puneet,

This is a fortran 90 thing. H5Dread_f is a generic interface, not a specific subroutine. This means that a call to H5Dread_f gets mapped at compile time into some other specific subroutine. H5Dread_f is defined in the 1.10.* source code, in H5Dff.F90, like this:

INTERFACE h5dread_f
   MODULE PROCEDURE h5dread_reference_obj
   MODULE PROCEDURE h5dread_reference_dsetreg
   MODULE PROCEDURE h5dread_char_scalar
   MODULE PROCEDURE h5dread_ptr
END INTERFACE

These other subroutines are all lower down in the same file, H5Dff.F90. You should find symbols for the specific routines in the library file, as seen in the following trimmed output. The name prefixes “h5d_mp_” are compiler-specific, and include the name of the nearest enclosing fortran source module:

/usr/local/ifort-17.0/lib 629> nm libhdf5_fortran.so.100.1.0 | grep 'T .*h5dread_' 
0000000000020f40 T h5d_mp_h5dread_char_scalar_
00000000000210b0 T h5d_mp_h5dread_ptr_
0000000000020c10 T h5d_mp_h5dread_reference_dsetreg_
0000000000020b60 T h5d_mp_h5dread_reference_obj_

Your error “no matching specific subroutine” means simply that your calling arguments do not correctly match any of the specific subroutines. Note this is a compile time error. The process never got to the link stage, so the contents of the library did not matter.

Check your calling argument types, dimensions, ordering, and other interface properties such as allocatable. HTH.

–Dave


#3

recently had a look at the working versions of read/write functions - https://support.hdfgroup.org/ftp/HDF5/current/src/unpacked/fortran/examples/h5_rdwt.f90

Here is the working version -
CALL H5dread_f(dset_id, H5T_NATIVE_INTEGER, data_out, data_dims, error)

INTEGER(HID_T) :: dset_id ! Dataset identifier

INTEGER, DIMENSION(7,7,3) :: data_out ! Output buffer
INTEGER(HSIZE_T), DIMENSION(7) :: data_dims
INTEGER :: error

non working version -

call H5Dread_f(dhnd1,H5T_NATIVE_DOUBLE,r8d1,sz1,iret,H5S_ALL_F,H5S_ALL_F)

integer(HID_T) dhnd1

real(8) :: r8d1(max_scan)
integer(HSIZE_T) sz1(3)
integer iret ! return status

Seems in order to make this legacy code work, i need to get rid of last 2 parameters(H5S_ALL_F,H5S_ALL_F) as introducing same in working version gave me same error. Will try & update if it works.

Case1:
On forcing integer size to be 8 bytes, the issue shows up
ftn -integer-size 64 test1.f90

test1.f90(63): error #6633: The type of the actual argument differs from the type of the dummy argument.   [ERROR]
  CALL h5dopen_f(file_id, dsetname, dset_id, error)
---------------------------------------------^
test1.f90(70): error #6285: There is no matching specific subroutine for this generic subroutine call.   [H5DWRITE_F]
  CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, dset_data, data_dims, error)
-------^
test1.f90(75): error #6285: There is no matching specific subroutine for this generic subroutine call.   [H5DREAD_F]
  CALL h5dread_f(dset_id, H5T_NATIVE_INTEGER, data_out, data_dims, error)
-------^
test1.f90(80): error #6633: The type of the actual argument differs from the type of the dummy argument.   [ERROR]
  CALL h5dclose_f(dset_id, error)
---------------------------^

in this scenario, i had to compile the HDF5 library with FCFLAGS="-fPIC -integer-size 64 "