LCOV - code coverage report
Current view: top level - src - hdf5_wrapper.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 0.0 % 251 0
Test Date: 2025-07-25 12:55:17 Functions: 0.0 % 19 0

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief A wrapper around the HDF5 Fortran API
      10              : !> \par History
      11              : !>      04.2023 created [SB]
      12              : !> \author Stefano Battaglia
      13              : ! **************************************************************************************************
      14              : MODULE hdf5_wrapper
      15              : 
      16              : #ifdef __HDF5
      17              :    USE hdf5, ONLY: &
      18              :       h5aclose_f, h5acreate_f, h5aopen_f, h5aread_f, h5awrite_f, h5close_f, h5dclose_f, &
      19              :       h5dcreate_f, h5dget_space_f, h5dopen_f, h5dread_f, h5dwrite_f, h5f_acc_rdonly_f, &
      20              :       h5f_acc_trunc_f, h5fclose_f, h5fcreate_f, h5fopen_f, h5gclose_f, h5gcreate_f, h5gopen_f, &
      21              :       h5open_f, h5s_scalar_f, h5sclose_f, h5screate_f, h5screate_simple_f, &
      22              :       h5sget_simple_extent_npoints_f, h5t_c_s1, h5t_cset_utf8_f, h5t_enum_f, h5t_native_double, &
      23              :       h5t_native_integer, h5t_str_nullpad_f, h5t_string, h5tclose_f, h5tcopy_f, h5tcreate_f, &
      24              :       h5tenum_insert_f, h5tset_cset_f, h5tset_size_f, h5tset_strpad_f, hid_t, hsize_t, size_t
      25              : #endif
      26              :    USE iso_c_binding, ONLY: C_LOC, &
      27              :                             c_ptr
      28              :    USE kinds, ONLY: dp
      29              : #include "./base/base_uses.f90"
      30              : 
      31              :    IMPLICIT NONE
      32              : 
      33              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'hdf5_wrapper'
      34              : #ifdef __HDF5
      35              :    INTEGER, PARAMETER, PUBLIC           :: hdf5_id = hid_t
      36              : #endif
      37              : 
      38              : CONTAINS
      39              : 
      40              : #ifdef __HDF5
      41              : ! **************************************************************************************************
      42              : !> \brief Initialize the HDF5 fortran API
      43              : ! **************************************************************************************************
      44            0 :    SUBROUTINE h5open()
      45              :       INTEGER                                            :: error
      46              : 
      47            0 :       CALL h5open_f(error)
      48            0 :       IF (error < 0) CPABORT('ERROR: failed to initialize HDF5 interface')
      49              : 
      50            0 :    END SUBROUTINE h5open
      51              : 
      52              : ! **************************************************************************************************
      53              : !> \brief Close the HDF5 fortran API
      54              : ! **************************************************************************************************
      55            0 :    SUBROUTINE h5close()
      56              :       INTEGER                                            :: error
      57              : 
      58            0 :       CALL h5close_f(error)
      59            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 interface')
      60              : 
      61            0 :    END SUBROUTINE h5close
      62              : 
      63              : ! **************************************************************************************************
      64              : !> \brief Create a HDF5 file
      65              : !> \param filename the name of the hdf5 file
      66              : !> \param file_id the file id of the hdf5 file
      67              : ! **************************************************************************************************
      68            0 :    SUBROUTINE h5fcreate(filename, file_id)
      69              :       CHARACTER(LEN=*), INTENT(IN)                       :: filename
      70              :       INTEGER(KIND=hid_t), INTENT(OUT)                   :: file_id
      71              : 
      72              :       INTEGER                                            :: error
      73              : 
      74            0 :       CALL h5fcreate_f(filename, h5f_acc_trunc_f, file_id, error)
      75            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 file')
      76              : 
      77            0 :    END SUBROUTINE h5fcreate
      78              : 
      79              : ! **************************************************************************************************
      80              : !> \brief Open a HDF5 file
      81              : !> \param filename the name of the hdf5 file
      82              : !> \param file_id the file id of the hdf5 file
      83              : ! **************************************************************************************************
      84            0 :    SUBROUTINE h5fopen(filename, file_id)
      85              :       CHARACTER(LEN=*), INTENT(IN)                       :: filename
      86              :       INTEGER(KIND=hid_t), INTENT(OUT)                   :: file_id
      87              : 
      88              :       INTEGER                                            :: error
      89              : 
      90            0 :       CALL h5fopen_f(TRIM(filename), h5f_acc_rdonly_f, file_id, error)
      91            0 :       IF (error < 0) CPABORT('ERROR: failed to open HDF5 file')
      92              : 
      93            0 :    END SUBROUTINE h5fopen
      94              : 
      95              : ! **************************************************************************************************
      96              : !> \brief Close a HDF5 file
      97              : !> \param file_id the file id of the hdf5 file
      98              : ! **************************************************************************************************
      99            0 :    SUBROUTINE h5fclose(file_id)
     100              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: file_id
     101              : 
     102              :       INTEGER                                            :: error
     103              : 
     104            0 :       CALL h5fclose_f(file_id, error)
     105            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 file')
     106              : 
     107            0 :    END SUBROUTINE h5fclose
     108              : 
     109              : ! **************************************************************************************************
     110              : !> \brief Create a HDF5 group
     111              : !> \param loc_id file or group identifier
     112              : !> \param name name of the group
     113              : !> \param grp_id group identifier
     114              : ! **************************************************************************************************
     115            0 :    SUBROUTINE h5gcreate(loc_id, name, grp_id)
     116              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     117              :       CHARACTER(LEN=*), INTENT(IN)                       :: name
     118              :       INTEGER(KIND=hid_t), INTENT(OUT)                   :: grp_id
     119              : 
     120              :       INTEGER                                            :: error
     121              : 
     122            0 :       CALL h5gcreate_f(loc_id, name, grp_id, error)
     123            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 group')
     124              : 
     125            0 :    END SUBROUTINE h5gcreate
     126              : 
     127              : ! **************************************************************************************************
     128              : !> \brief Open a HDF5 group
     129              : !> \param loc_id file or group identifier
     130              : !> \param name name of the group
     131              : !> \param grp_id group identifier
     132              : ! **************************************************************************************************
     133            0 :    SUBROUTINE h5gopen(loc_id, name, grp_id)
     134              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     135              :       CHARACTER(LEN=*), INTENT(IN)                       :: name
     136              :       INTEGER(KIND=hid_t), INTENT(OUT)                   :: grp_id
     137              : 
     138              :       INTEGER                                            :: error
     139              : 
     140            0 :       CALL h5gopen_f(loc_id, name, grp_id, error)
     141            0 :       IF (error < 0) CPABORT('ERROR: failed to open HDF5 group')
     142              : 
     143            0 :    END SUBROUTINE h5gopen
     144              : 
     145              : ! **************************************************************************************************
     146              : !> \brief Close a HDF5 group
     147              : !> \param grp_id group identifier
     148              : ! **************************************************************************************************
     149            0 :    SUBROUTINE h5gclose(grp_id)
     150              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: grp_id
     151              : 
     152              :       INTEGER                                            :: error
     153              : 
     154            0 :       CALL h5gclose_f(grp_id, error)
     155            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 group')
     156              : 
     157            0 :    END SUBROUTINE h5gclose
     158              : 
     159              : ! **************************************************************************************************
     160              : !> \brief Write a variable-length string attribute
     161              : !> \param loc_id either file id or group id
     162              : !> \param attr_name the name of the attribute
     163              : !> \param attr_data the attribute data, i.e. the string to write
     164              : ! **************************************************************************************************
     165            0 :    SUBROUTINE h5awrite_varlen_string(loc_id, attr_name, attr_data)
     166              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     167              :       CHARACTER(LEN=*), INTENT(IN)                       :: attr_name
     168              :       CHARACTER(LEN=*), INTENT(IN), TARGET               :: attr_data
     169              : 
     170              :       INTEGER                                            :: error, output_unit
     171              :       INTEGER(KIND=hid_t)                                :: attr_id, space_id, type_id
     172              :       TYPE(c_ptr)                                        :: buffer
     173              :       TYPE(c_ptr), TARGET                                :: in_between_ptr
     174              : 
     175              :       ! create a scalar dataspace
     176            0 :       CALL h5screate_f(h5s_scalar_f, space_id, error)
     177            0 :       IF (error < 0) THEN
     178              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     179            0 :             ' ERROR: failed to create HDF5 dataspace'
     180            0 :          RETURN
     181              :       END IF
     182              : 
     183              :       ! create a variable-length string type
     184            0 :       CALL h5tcopy_f(h5t_string, type_id, error)
     185            0 :       CALL h5tset_cset_f(type_id, h5t_cset_utf8_f, error)
     186            0 :       CALL h5tset_strpad_f(type_id, h5t_str_nullpad_f, error)
     187              : 
     188              :       ! create the attribute
     189            0 :       CALL h5acreate_f(loc_id, attr_name, type_id, space_id, attr_id, error)
     190            0 :       IF (error < 0) THEN
     191              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     192            0 :             ' ERROR: failed to create HDF5 attribute'
     193            0 :          RETURN
     194              :       END IF
     195              : 
     196              :       ! weird in-between pointer needed for variable-length
     197              :       ! string to a scalar dataspace
     198            0 :       in_between_ptr = C_LOC(attr_data)
     199              :       ! the actual pointer to be passed
     200            0 :       buffer = C_LOC(in_between_ptr)
     201              : 
     202              :       ! write the string attribute to file
     203            0 :       CALL h5awrite_f(attr_id, type_id, buffer, error)
     204            0 :       IF (error < 0) THEN
     205              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     206            0 :             ' ERROR: failed to write HDF5 attribute'
     207            0 :          RETURN
     208              :       END IF
     209              : 
     210              :       ! close attribute
     211            0 :       CALL h5aclose_f(attr_id, error)
     212            0 :       IF (error < 0) THEN
     213              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     214            0 :             ' ERROR: failed to close HDF5 attribute'
     215            0 :          RETURN
     216              :       END IF
     217              : 
     218              :       ! close dataspace
     219            0 :       CALL h5sclose_f(space_id, error)
     220            0 :       IF (error < 0) THEN
     221              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     222            0 :             ' ERROR: failed to close HDF5 dataspace'
     223            0 :          RETURN
     224              :       END IF
     225              : 
     226              :       ! close datatype
     227            0 :       CALL h5tclose_f(type_id, error)
     228            0 :       IF (error < 0) THEN
     229              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     230            0 :             ' ERROR: failed to close HDF5 datatype'
     231            0 :          RETURN
     232              :       END IF
     233              : 
     234              :    END SUBROUTINE h5awrite_varlen_string
     235              : 
     236              : ! **************************************************************************************************
     237              : !> \brief Write a fixed-length string attribute
     238              : !> \param loc_id either file id or group id
     239              : !> \param attr_name the name of the attribute
     240              : !> \param attr_data the attribute data, i.e. the string to write
     241              : ! **************************************************************************************************
     242            0 :    SUBROUTINE h5awrite_fixlen_string(loc_id, attr_name, attr_data)
     243              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     244              :       CHARACTER(LEN=*), INTENT(IN)                       :: attr_name
     245              :       CHARACTER(LEN=*), INTENT(IN), TARGET               :: attr_data
     246              : 
     247              :       INTEGER                                            :: error, output_unit
     248              :       INTEGER(KIND=hid_t)                                :: attr_id, space_id, type_id
     249              :       TYPE(c_ptr)                                        :: buffer
     250              : 
     251              :       ! create a scalar dataspace
     252            0 :       CALL h5screate_f(h5s_scalar_f, space_id, error)
     253            0 :       IF (error < 0) THEN
     254              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     255            0 :             ' ERROR: failed to create HDF5 dataspace'
     256            0 :          RETURN
     257              :       END IF
     258              : 
     259              :       ! create a fixed-length string datatype
     260            0 :       CALL h5tcopy_f(h5t_c_s1, type_id, error)
     261            0 :       CALL h5tset_cset_f(type_id, h5t_cset_utf8_f, error)
     262            0 :       CALL h5tset_size_f(type_id, LEN(attr_data, size_t), error)
     263              : 
     264              :       ! create the attribute
     265            0 :       CALL h5acreate_f(loc_id, attr_name, type_id, space_id, attr_id, error)
     266            0 :       IF (error < 0) THEN
     267              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     268            0 :             ' ERROR: failed to create HDF5 attribute'
     269            0 :          RETURN
     270              :       END IF
     271              : 
     272              :       ! the actual pointer to be passed
     273            0 :       buffer = C_LOC(attr_data)
     274              : 
     275              :       ! write the string attribute to file
     276            0 :       CALL h5awrite_f(attr_id, type_id, buffer, error)
     277            0 :       IF (error < 0) THEN
     278              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     279            0 :             ' ERROR: failed to write HDF5 attribute'
     280            0 :          RETURN
     281              :       END IF
     282              : 
     283              :       ! close attribute
     284            0 :       CALL h5aclose_f(attr_id, error)
     285            0 :       IF (error < 0) THEN
     286              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     287            0 :             ' ERROR: failed to close HDF5 attribute'
     288            0 :          RETURN
     289              :       END IF
     290              : 
     291              :       ! close dataspace
     292            0 :       CALL h5sclose_f(space_id, error)
     293            0 :       IF (error < 0) THEN
     294              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     295            0 :             ' ERROR: failed to close HDF5 dataspace'
     296            0 :          RETURN
     297              :       END IF
     298              : 
     299              :       ! close datatype
     300            0 :       CALL h5tclose_f(type_id, error)
     301            0 :       IF (error < 0) THEN
     302              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     303            0 :             ' ERROR: failed to close HDF5 datatype'
     304            0 :          RETURN
     305              :       END IF
     306              : 
     307              :    END SUBROUTINE h5awrite_fixlen_string
     308              : 
     309              : ! **************************************************************************************************
     310              : !> \brief Write a boolean attribute
     311              : !> \param loc_id either file id or group id
     312              : !> \param attr_name the name of the attribute
     313              : !> \param attr_data the attribute data, i.e. the logical to write (.true. or .false.)
     314              : ! **************************************************************************************************
     315            0 :    SUBROUTINE h5awrite_boolean(loc_id, attr_name, attr_data)
     316              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     317              :       CHARACTER(LEN=*), INTENT(IN)                       :: attr_name
     318              :       LOGICAL, INTENT(IN)                                :: attr_data
     319              : 
     320              :       INTEGER                                            :: error, output_unit
     321              :       INTEGER(KIND=hid_t)                                :: attr_id, space_id, type_id
     322              :       INTEGER(KIND=size_t)                               :: enum_size = 1
     323              :       INTEGER, TARGET                                    :: attr_data_to_int
     324              :       TYPE(c_ptr)                                        :: buffer
     325              : 
     326              :       ! 8-bit integers in enum bool_type
     327              : 
     328              :       ! create a scalar dataspace
     329            0 :       CALL h5screate_f(h5s_scalar_f, space_id, error)
     330            0 :       IF (error < 0) THEN
     331              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     332            0 :             ' ERROR: failed to create HDF5 dataspace'
     333            0 :          RETURN
     334              :       END IF
     335              : 
     336              :       ! create the datatype
     337            0 :       CALL h5tcreate_f(h5t_enum_f, enum_size, type_id, error)
     338            0 :       CALL h5tenum_insert_f(type_id, "FALSE", 0, error)
     339            0 :       CALL h5tenum_insert_f(type_id, "TRUE", 1, error)
     340              : 
     341            0 :       IF (attr_data) THEN
     342            0 :          attr_data_to_int = 1
     343              :       ELSE
     344            0 :          attr_data_to_int = 0
     345              :       END IF
     346              :       ! the C pointer to the actual data
     347            0 :       buffer = C_LOC(attr_data_to_int)
     348              : 
     349              :       ! create the attribute
     350            0 :       CALL h5acreate_f(loc_id, attr_name, type_id, space_id, attr_id, error)
     351            0 :       IF (error < 0) THEN
     352              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     353            0 :             ' ERROR: failed to create HDF5 attribute'
     354            0 :          RETURN
     355              :       END IF
     356              : 
     357              :       ! write the string attribute to file
     358            0 :       CALL h5awrite_f(attr_id, type_id, buffer, error)
     359            0 :       IF (error < 0) THEN
     360              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     361            0 :             ' ERROR: failed to write HDF5 attribute'
     362            0 :          RETURN
     363              :       END IF
     364              : 
     365              :       ! close attribute
     366            0 :       CALL h5aclose_f(attr_id, error)
     367            0 :       IF (error < 0) THEN
     368              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     369            0 :             ' ERROR: failed to close HDF5 attribute'
     370            0 :          RETURN
     371              :       END IF
     372              : 
     373              :       ! close dataspace
     374            0 :       CALL h5sclose_f(space_id, error)
     375            0 :       IF (error < 0) THEN
     376              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     377            0 :             ' ERROR: failed to close HDF5 dataspace'
     378            0 :          RETURN
     379              :       END IF
     380              : 
     381              :       ! close datatype
     382            0 :       CALL h5tclose_f(type_id, error)
     383            0 :       IF (error < 0) THEN
     384              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     385            0 :             ' ERROR: failed to close HDF5 datatype'
     386            0 :          RETURN
     387              :       END IF
     388              : 
     389              :    END SUBROUTINE h5awrite_boolean
     390              : 
     391              : ! **************************************************************************************************
     392              : !> \brief Write a (scalar) integer attribute
     393              : !> \param loc_id either file id or group id
     394              : !> \param attr_name the name of the attribute
     395              : !> \param attr_data the attribute data, i.e. the integer to write
     396              : ! **************************************************************************************************
     397            0 :    SUBROUTINE h5awrite_integer_scalar(loc_id, attr_name, attr_data)
     398              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     399              :       CHARACTER(LEN=*), INTENT(IN)                       :: attr_name
     400              :       INTEGER, INTENT(IN), TARGET                        :: attr_data
     401              : 
     402              :       INTEGER                                            :: error, output_unit
     403              :       INTEGER(KIND=hid_t)                                :: attr_id, space_id, type_id
     404              :       TYPE(c_ptr)                                        :: buffer
     405              : 
     406              :       ! create a scalar dataspace
     407            0 :       CALL h5screate_f(h5s_scalar_f, space_id, error)
     408            0 :       IF (error < 0) THEN
     409              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     410            0 :             ' ERROR: failed to create HDF5 dataspace'
     411            0 :          RETURN
     412              :       END IF
     413              : 
     414              :       ! the C pointer to the actual data
     415            0 :       buffer = C_LOC(attr_data)
     416              : 
     417              :       ! set the type of data
     418            0 :       type_id = h5t_native_integer
     419              : 
     420              :       ! create the attribute
     421            0 :       CALL h5acreate_f(loc_id, attr_name, type_id, space_id, attr_id, error)
     422            0 :       IF (error < 0) THEN
     423              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     424            0 :             ' ERROR: failed to create HDF5 attribute'
     425            0 :          RETURN
     426              :       END IF
     427              : 
     428              :       ! write the string attribute to file
     429            0 :       CALL h5awrite_f(attr_id, type_id, buffer, error)
     430            0 :       IF (error < 0) THEN
     431              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     432            0 :             ' ERROR: failed to write HDF5 attribute'
     433            0 :          RETURN
     434              :       END IF
     435              : 
     436              :       ! close attribute
     437            0 :       CALL h5aclose_f(attr_id, error)
     438            0 :       IF (error < 0) THEN
     439              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     440            0 :             ' ERROR: failed to close HDF5 attribute'
     441            0 :          RETURN
     442              :       END IF
     443              : 
     444              :       ! close dataspace
     445            0 :       CALL h5sclose_f(space_id, error)
     446            0 :       IF (error < 0) THEN
     447              :          WRITE (UNIT=output_unit, FMT="(/,T5,A,/)") &
     448            0 :             ' ERROR: failed to close HDF5 dataspace'
     449            0 :          RETURN
     450              :       END IF
     451              : 
     452              :    END SUBROUTINE h5awrite_integer_scalar
     453              : 
     454              : ! **************************************************************************************************
     455              : !> \brief Write a (scalar) double precision attribute
     456              : !> \param loc_id either file id or group id
     457              : !> \param attr_name the name of the attribute
     458              : !> \param attr_data the attribute data, i.e. the double to write
     459              : ! **************************************************************************************************
     460            0 :    SUBROUTINE h5awrite_double_scalar(loc_id, attr_name, attr_data)
     461              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     462              :       CHARACTER(LEN=*), INTENT(IN)                       :: attr_name
     463              :       REAL(KIND=dp), INTENT(IN), TARGET                  :: attr_data
     464              : 
     465              :       INTEGER                                            :: error
     466              :       INTEGER(KIND=hid_t)                                :: attr_id, space_id, type_id
     467              :       TYPE(c_ptr)                                        :: buffer
     468              : 
     469              :       ! create a scalar dataspace
     470            0 :       CALL h5screate_f(h5s_scalar_f, space_id, error)
     471            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 dataspace')
     472              : 
     473              :       ! the C pointer to the actual data
     474            0 :       buffer = C_LOC(attr_data)
     475              : 
     476              :       ! set the type of data
     477            0 :       type_id = h5t_native_double
     478              : 
     479              :       ! create the attribute
     480            0 :       CALL h5acreate_f(loc_id, attr_name, type_id, space_id, attr_id, error)
     481            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 attribute')
     482              : 
     483              :       ! write the string attribute to file
     484            0 :       CALL h5awrite_f(attr_id, type_id, buffer, error)
     485            0 :       IF (error < 0) CPABORT('ERROR: failed to write HDF5 attribute')
     486              : 
     487              :       ! close attribute
     488            0 :       CALL h5aclose_f(attr_id, error)
     489            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 attribute')
     490              : 
     491              :       ! close dataspace
     492            0 :       CALL h5sclose_f(space_id, error)
     493            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 dataspace')
     494              : 
     495            0 :    END SUBROUTINE h5awrite_double_scalar
     496              : 
     497              : ! **************************************************************************************************
     498              : !> \brief Write an array of fixed-length string attribute
     499              : !> \param loc_id either file id or group id
     500              : !> \param attr_name the name of the attribute
     501              : !> \param attr_data the attribute data, i.e. the array of strings
     502              : ! **************************************************************************************************
     503            0 :    SUBROUTINE h5awrite_string_simple(loc_id, attr_name, attr_data)
     504              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     505              :       CHARACTER(LEN=*), INTENT(IN)                       :: attr_name
     506              :       CHARACTER(LEN=*), DIMENSION(:), INTENT(IN), TARGET :: attr_data
     507              : 
     508              :       INTEGER                                            :: error
     509              :       INTEGER(KIND=hid_t)                                :: attr_id, space_id, type_id
     510              :       INTEGER(KIND=hsize_t), DIMENSION(2)                :: dims
     511              :       TYPE(c_ptr)                                        :: buffer
     512              : 
     513            0 :       dims(1) = LEN(attr_data(1), kind=hsize_t) ! length of a string entry
     514            0 :       dims(2) = SIZE(attr_data, kind=hsize_t)   ! length of array of strings
     515              : 
     516              :       ! create a fixed-length string datatype
     517            0 :       CALL h5tcopy_f(h5t_c_s1, type_id, error)
     518            0 :       CALL h5tset_cset_f(type_id, h5t_cset_utf8_f, error)
     519            0 :       CALL h5tset_size_f(type_id, INT(dims(1), size_t), error)
     520              : 
     521              :       ! create a simple dataspace
     522            0 :       CALL h5screate_simple_f(1, dims(2:2), space_id, error)
     523            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 dataspace')
     524              : 
     525              :       ! create the atrtibute
     526            0 :       CALL h5acreate_f(loc_id, attr_name, type_id, space_id, attr_id, error)
     527            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 attribute')
     528              : 
     529              :       ! the actual pointer to be passed
     530            0 :       buffer = C_LOC(attr_data(1))
     531              : 
     532              :       ! write the string array attribute to file
     533            0 :       CALL h5awrite_f(attr_id, type_id, buffer, error)
     534            0 :       IF (error < 0) CPABORT('ERROR: failed to write HDF5 attribute')
     535              : 
     536              :       ! close attribute
     537            0 :       CALL h5aclose_f(attr_id, error)
     538            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 attribute')
     539              : 
     540              :       ! close dataspace
     541            0 :       CALL h5sclose_f(space_id, error)
     542            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 dataspace')
     543              : 
     544              :       ! close datatype
     545            0 :       CALL h5tclose_f(type_id, error)
     546            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 datatype')
     547              : 
     548            0 :    END SUBROUTINE h5awrite_string_simple
     549              : 
     550              : ! **************************************************************************************************
     551              : !> \brief Write an array of doubles attribute
     552              : !> \param loc_id either file id or group id
     553              : !> \param attr_name the name of the attribute
     554              : !> \param attr_data the attribute data, i.e. the array of doubles
     555              : ! **************************************************************************************************
     556            0 :    SUBROUTINE h5awrite_double_simple(loc_id, attr_name, attr_data)
     557              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     558              :       CHARACTER(LEN=*), INTENT(IN)                       :: attr_name
     559              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), TARGET    :: attr_data
     560              : 
     561              :       INTEGER                                            :: error
     562              :       INTEGER(KIND=hid_t)                                :: attr_id, space_id, type_id
     563              :       INTEGER(KIND=hsize_t), DIMENSION(1)                :: dims
     564              :       TYPE(c_ptr)                                        :: buffer
     565              : 
     566            0 :       dims(1) = SIZE(attr_data, kind=hsize_t)   ! length of array of strings
     567              : 
     568              :       ! set the type of data
     569            0 :       type_id = h5t_native_double
     570              : 
     571              :       ! create a simple dataspace
     572            0 :       CALL h5screate_simple_f(1, dims, space_id, error)
     573            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 dataspace')
     574              : 
     575              :       ! create the atrtibute
     576            0 :       CALL h5acreate_f(loc_id, attr_name, type_id, space_id, attr_id, error)
     577            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 attribute')
     578              : 
     579              :       ! the actual pointer to be passed
     580            0 :       buffer = C_LOC(attr_data(1))
     581              : 
     582              :       ! write the string array attribute to file
     583            0 :       CALL h5awrite_f(attr_id, type_id, buffer, error)
     584            0 :       IF (error < 0) CPABORT('ERROR: failed to write HDF5 attribute')
     585              : 
     586              :       ! close attribute
     587            0 :       CALL h5aclose_f(attr_id, error)
     588            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 attribute')
     589              : 
     590              :       ! close dataspace
     591            0 :       CALL h5sclose_f(space_id, error)
     592            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 dataspace')
     593              : 
     594            0 :    END SUBROUTINE h5awrite_double_simple
     595              : 
     596              : ! **************************************************************************************************
     597              : !> \brief Write an array of integers attribute
     598              : !> \param loc_id either file id or group id
     599              : !> \param attr_name the name of the attribute
     600              : !> \param attr_data the attribute data, i.e. the array of integers
     601              : ! **************************************************************************************************
     602            0 :    SUBROUTINE h5awrite_integer_simple(loc_id, attr_name, attr_data)
     603              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     604              :       CHARACTER(LEN=*), INTENT(IN)                       :: attr_name
     605              :       INTEGER, DIMENSION(:), INTENT(IN), TARGET          :: attr_data
     606              : 
     607              :       INTEGER                                            :: error
     608              :       INTEGER(KIND=hid_t)                                :: attr_id, space_id, type_id
     609              :       INTEGER(KIND=hsize_t), DIMENSION(1)                :: dims
     610              :       TYPE(c_ptr)                                        :: buffer
     611              : 
     612            0 :       dims(1) = SIZE(attr_data, kind=hsize_t)   ! length of array of strings
     613              : 
     614              :       ! set the type of data
     615            0 :       type_id = h5t_native_integer
     616              : 
     617              :       ! create a simple dataspace
     618            0 :       CALL h5screate_simple_f(1, dims, space_id, error)
     619            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 dataspace')
     620              : 
     621              :       ! create the atrtibute
     622            0 :       CALL h5acreate_f(loc_id, attr_name, type_id, space_id, attr_id, error)
     623            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 attribute')
     624              : 
     625              :       ! the actual pointer to be passed
     626            0 :       buffer = C_LOC(attr_data(1))
     627              : 
     628              :       ! write the string array attribute to file
     629            0 :       CALL h5awrite_f(attr_id, type_id, buffer, error)
     630            0 :       IF (error < 0) CPABORT('ERROR: failed to write HDF5 attribute')
     631              : 
     632              :       ! close attribute
     633            0 :       CALL h5aclose_f(attr_id, error)
     634            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 attribute')
     635              : 
     636              :       ! close dataspace
     637            0 :       CALL h5sclose_f(space_id, error)
     638            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 dataspace')
     639              : 
     640            0 :    END SUBROUTINE h5awrite_integer_simple
     641              : 
     642              : ! **************************************************************************************************
     643              : !> \brief Write a dataset containing an array of doubles
     644              : !> \param loc_id either file id or group id
     645              : !> \param dset_name the name of the dataset
     646              : !> \param dset_data the dataset data, i.e. the array of doubles
     647              : ! **************************************************************************************************
     648            0 :    SUBROUTINE h5dwrite_double_simple(loc_id, dset_name, dset_data)
     649              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     650              :       CHARACTER(LEN=*), INTENT(IN)                       :: dset_name
     651              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), TARGET    :: dset_data
     652              : 
     653              :       INTEGER                                            :: error
     654              :       INTEGER(KIND=hid_t)                                :: dset_id, space_id, type_id
     655              :       INTEGER(KIND=hsize_t), DIMENSION(1)                :: dims
     656              :       TYPE(c_ptr)                                        :: buffer
     657              : 
     658            0 :       dims(1) = SIZE(dset_data, kind=hsize_t)   ! length of array
     659              : 
     660              :       ! set the type of data
     661            0 :       type_id = h5t_native_double
     662              : 
     663              :       ! create a simple dataspace
     664            0 :       CALL h5screate_simple_f(1, dims, space_id, error)
     665            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 dataspace')
     666              : 
     667              :       ! create the dataset
     668            0 :       CALL h5dcreate_f(loc_id, dset_name, type_id, space_id, dset_id, error)
     669            0 :       IF (error < 0) CPABORT('ERROR: failed to create HDF5 dataset')
     670              : 
     671              :       ! the actual pointer to be passed
     672            0 :       buffer = C_LOC(dset_data(1))
     673              : 
     674              :       ! write the string array attribute to file
     675            0 :       CALL h5dwrite_f(dset_id, type_id, buffer, error)
     676            0 :       IF (error < 0) CPABORT('ERROR: failed to write HDF5 dataset')
     677              : 
     678              :       ! close dataset
     679            0 :       CALL h5dclose_f(dset_id, error)
     680            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 dataset')
     681              : 
     682              :       ! close dataspace
     683            0 :       CALL h5sclose_f(space_id, error)
     684            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 dataspace')
     685              : 
     686            0 :    END SUBROUTINE h5dwrite_double_simple
     687              : 
     688              : ! **************************************************************************************************
     689              : !> \brief Read a dataset containing an array of doubles
     690              : !> \param loc_id either file id or group id
     691              : !> \param dset_name the name of the dataset
     692              : !> \param dset_data where the read dataset data will be written
     693              : ! **************************************************************************************************
     694            0 :    SUBROUTINE h5dread_double_simple(loc_id, dset_name, dset_data)
     695              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     696              :       CHARACTER(LEN=*), INTENT(IN)                       :: dset_name
     697              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: dset_data
     698              : 
     699              :       INTEGER                                            :: error
     700              :       INTEGER(KIND=hid_t)                                :: dset_id, npoints, space_id, type_id
     701              :       INTEGER(KIND=hsize_t), DIMENSION(1)                :: dims
     702              : 
     703            0 :       dims(1) = SIZE(dset_data, kind=hsize_t)   ! length of array
     704              : 
     705              :       ! set the type of data
     706            0 :       type_id = h5t_native_double
     707              : 
     708              :       ! open the dataset
     709            0 :       CALL h5dopen_f(loc_id, dset_name, dset_id, error)
     710            0 :       IF (error < 0) CPABORT('ERROR: failed to open HDF5 dataset')
     711              : 
     712              :       ! get information on the dataspace
     713            0 :       CALL h5dget_space_f(dset_id, space_id, error)
     714            0 :       IF (error < 0) CPABORT('ERROR: failed to fetch HDF5 dataspace info')
     715              : 
     716              :       ! get dataspace dims
     717            0 :       CALL h5sget_simple_extent_npoints_f(space_id, npoints, error)
     718            0 :       IF (error < 0) CPABORT('ERROR: failed to fetch HDF5 dataspace dimension')
     719              : 
     720              :       ! read the data
     721            0 :       CALL h5dread_f(dset_id, type_id, dset_data, dims, error)
     722            0 :       IF (error < 0) CPABORT('ERROR: failed to read HDF5 dataset')
     723              : 
     724              :       ! close dataset
     725            0 :       CALL h5dclose_f(dset_id, error)
     726            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 dataset')
     727              : 
     728              :       ! close dataspace
     729            0 :       CALL h5sclose_f(space_id, error)
     730            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 dataspace')
     731              : 
     732            0 :    END SUBROUTINE h5dread_double_simple
     733              : 
     734              : ! **************************************************************************************************
     735              : !> \brief Read an attribute containing a scalar double
     736              : !> \param loc_id either file id or group id
     737              : !> \param attr_name ...
     738              : !> \param attr_data ...
     739              : ! **************************************************************************************************
     740            0 :    SUBROUTINE h5aread_double_scalar(loc_id, attr_name, attr_data)
     741              :       INTEGER(KIND=hid_t), INTENT(IN)                    :: loc_id
     742              :       CHARACTER(LEN=*), INTENT(IN)                       :: attr_name
     743              :       REAL(KIND=dp), INTENT(OUT), TARGET                 :: attr_data
     744              : 
     745              :       INTEGER                                            :: error
     746              :       INTEGER(KIND=hid_t)                                :: attr_id, type_id
     747              :       TYPE(c_ptr)                                        :: buffer
     748              : 
     749              :       ! set the type of data
     750            0 :       type_id = h5t_native_double
     751              : 
     752              :       ! open the attribute
     753            0 :       CALL h5aopen_f(loc_id, attr_name, attr_id, error)
     754            0 :       IF (error < 0) CPABORT('ERROR: failed to open HDF5 attribute')
     755              : 
     756            0 :       buffer = C_LOC(attr_data)
     757              :       ! read the data
     758            0 :       CALL h5aread_f(attr_id, type_id, buffer, error)
     759            0 :       IF (error < 0) CPABORT('ERROR: failed to read HDF5 attribute')
     760              : 
     761              :       ! close the attribute
     762            0 :       CALL h5aclose_f(attr_id, error)
     763            0 :       IF (error < 0) CPABORT('ERROR: failed to close HDF5 attribute')
     764              : 
     765            0 :    END SUBROUTINE h5aread_double_scalar
     766              : 
     767              : #endif
     768              : 
     769              : END MODULE hdf5_wrapper
        

Generated by: LCOV version 2.0-1