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
|