3
votes

I am just picking up, and trying to clean up, some Fortran code that makes use of an HDF5 library. In that library there is a function defined like this:

SUBROUTINE h5dwrite_f(dset_id, mem_type_id, buf, dims, hdferr, & 
                      mem_space_id, file_space_id, xfer_prp)
  IMPLICIT NONE
  INTEGER(HID_T), INTENT(IN) :: dset_id      ! Dataset identifier
  INTEGER(HID_T), INTENT(IN) :: mem_type_id  ! Memory datatype identifier
  TYPE, INTENT(IN) :: buf                    ! Data buffer; may be a scalar 
                                             ! or an array
  ...

The key input here being buf. I have a bunch of different parts of my code that make use of this subroutine and have wrapper subroutines that only differ by one line, and the input type, so I'd like to generify the code a bit. The only difference in all of my subroutines that call this is the mem_type_id and the actual type of the value being passed to buf. For example, in one call mem_type_id is H5T_NATIVE_CHARACTER and buf is a string, while in another mem_type_id is H5T_NATIVE_REAL and buf is a real.

I tried to replicate what is in their subroutine declaration, so I'd have a "type" input, but it doesn't compile.

  subroutine StoreDataIntoH5File (vname, vval, mem_type_id)
    character, intent (in) :: vname*(*)
    type, intent (in) :: vval                  ! use generic type statement
    integer(HID_T), intent(in) :: mem_type_id  ! Memory datatype identifier
    ...
    call h5dwrite_f (dset_id, mem_type_id, vval, (/1_HSIZE_T/), hdf5_error)

Is there a way to do what I'm looking for? In any other language I'd describe it as wanting to have an input of type object, or in C I might go about using a void*. Basically, this API seems to be able to take a generic input type and I'm trying to replicate that, since my subroutine is wrapping it.

I'm happy to go the pointer route, basically I just want to be able to share this subroutine for a variety of input variable types, the same way that the subroutine it calls (h5dwrite_f) does.

1
Are you sure that's type and not something like type(*)? - francescalus
@francescalus I'm not sure at all... That is on my list of things to try! - zaknotzach
@francescalus Nope, tried type(*) and that didn't cut it. Still getting compilation errors, it seems to think I'm trying to do a type declaration. - zaknotzach
Having looked at the HDF5 documentation, I see they do indeed use type alone. This isn't valid Fortran, but is shorthand for "an arbitrary Fortran type". You can look at the HDF5 APIs provided in your installation for more detail (if you can find it). You can also see the Fortran 2003 API using type(c_ptr). - francescalus
I confirm francescalus' comment: the documentation states type for the declaration but the library actually implements the routine for many argument types separately and combines the subroutines into a single interface name. - Pierre de Buyl

1 Answers

0
votes

In HDF5, the Fortran bindings are overloaded for all argument combinations. You can either do the same (repeat code with overloading) or handle yourself the call to the C HDF5 library. I advise the former solution! (Can be mostly automated by looping over the argument combinations).