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