Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 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
|