LCOV - code coverage report
Current view: top level - src - hdf5_wrapper.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:34a1bdb) Lines: 60.5 % 261 158
Test Date: 2026-03-22 06:30:46 Functions: 73.7 % 19 14

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

Generated by: LCOV version 2.0-1