Reference documentation for deal.II version GIT relicensing-1125-gadd8e16ae6 2024-07-19 10:00:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
hdf5.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2019 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#include <deal.II/base/config.h>
16
17#ifdef DEAL_II_WITH_HDF5
18
19# include <deal.II/base/hdf5.h>
20
21# include <hdf5.h>
22
23# include <iostream>
24
26
27namespace HDF5
28{
29 namespace internal
30 {
31 namespace HDF5ObjectImplementation
32 {
37 void
38 check_exception(const std::string &type, const std::string &name)
39 {
40# ifdef DEAL_II_WITH_MPI
41# if __cpp_lib_uncaught_exceptions >= 201411
42 // std::uncaught_exception() is deprecated in c++17
43 if (std::uncaught_exceptions() != 0)
44# else
45 if (std::uncaught_exception() == true)
46# endif
47 {
48 std::cerr
49 << "---------------------------------------------------------\n"
50 << "HDF5 " + type + " objects call " + name +
51 " to end access to\n"
52 << "them and release any resources they acquired. This call\n"
53 << "requires MPI synchronization. Since an exception is\n"
54 << "currently uncaught, this synchronization would likely\n"
55 << "deadlock because only the current process is trying to\n"
56 << "destroy the object. As a consequence, the program will be\n"
57 << "aborted and the HDF5 might be corrupted.\n"
58 << "---------------------------------------------------------"
59 << std::endl;
60
61 MPI_Abort(MPI_COMM_WORLD, 1);
62 }
63# else
64 (void)type;
65 (void)name;
66# endif
67 }
68 } // namespace HDF5ObjectImplementation
69 } // namespace internal
70
71
72
73 HDF5Object::HDF5Object(const std::string &name, const bool mpi)
74 : name(name)
75 , mpi(mpi)
76 {}
77
78
79
80 std::string
82 {
83 return name;
84 }
85
86
87
88 DataSet::DataSet(const std::string &name,
89 const hid_t &parent_group_id,
90 const bool mpi)
91 : HDF5Object(name, mpi)
92 , query_io_mode(false)
93 , io_mode(H5D_MPIO_NO_COLLECTIVE)
94 , local_no_collective_cause(H5D_MPIO_SET_INDEPENDENT)
95 , global_no_collective_cause(H5D_MPIO_SET_INDEPENDENT)
96 {
97 hdf5_reference = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
99 "H5Dclose");
100 // Release the HDF5 resource
101 const herr_t ret = H5Dclose(*pointer);
102 AssertNothrow(ret >= 0, ExcInternalError());
103 (void)ret;
104 delete pointer;
105 });
106 dataspace = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
108 "H5Sclose");
109 // Release the HDF5 resource
110 const herr_t ret = H5Sclose(*pointer);
111 AssertNothrow(ret >= 0, ExcInternalError());
112 (void)ret;
113 delete pointer;
114 });
115
116 // rank_ret can take a negative value if the functions
117 // H5Sget_simple_extent_ndims and H5Sget_simple_extent_dims fail. rank is
118 // unsigned int therefore it can not be used to store the return value of
119 // H5Sget_simple_extent_ndims and H5Sget_simple_extent_dims
120 int rank_ret;
121
122 *hdf5_reference = H5Dopen2(parent_group_id, name.data(), H5P_DEFAULT);
123 Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Dopen2"));
124 *dataspace = H5Dget_space(*hdf5_reference);
125 Assert(*dataspace >= 0, ExcMessage("Error at H5Dget_space"));
126 rank_ret = H5Sget_simple_extent_ndims(*dataspace);
127 Assert(rank_ret >= 0, ExcInternalError());
128 rank = rank_ret;
129 dimensions.resize(rank);
130 rank_ret =
131 H5Sget_simple_extent_dims(*dataspace, dimensions.data(), nullptr);
132 AssertDimension(rank_ret, static_cast<int>(rank));
133
134 size = 1;
135 for (const auto &dimension : dimensions)
136 {
137 size *= dimension;
138 }
139 }
140
141
142
143 DataSet::DataSet(const std::string &name,
144 const hid_t &parent_group_id,
145 const std::vector<hsize_t> &dimensions,
146 const std::shared_ptr<hid_t> &t_type,
147 const bool mpi)
148 : HDF5Object(name, mpi)
149 , rank(dimensions.size())
150 , dimensions(dimensions)
151 , query_io_mode(false)
152 , io_mode(H5D_MPIO_NO_COLLECTIVE)
153 , local_no_collective_cause(H5D_MPIO_SET_INDEPENDENT)
154 , global_no_collective_cause(H5D_MPIO_SET_INDEPENDENT)
155 {
156 hdf5_reference = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
158 "H5Dclose");
159 // Release the HDF5 resource
160 const herr_t ret = H5Dclose(*pointer);
161 AssertNothrow(ret >= 0, ExcInternalError());
162 (void)ret;
163 delete pointer;
164 });
165 dataspace = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
167 "H5Sclose");
168 // Release the HDF5 resource
169 const herr_t ret = H5Sclose(*pointer);
170 AssertNothrow(ret >= 0, ExcInternalError());
171 (void)ret;
172 delete pointer;
173 });
174
175 *dataspace = H5Screate_simple(rank, dimensions.data(), nullptr);
176 Assert(*dataspace >= 0, ExcMessage("Error at H5Screate_simple"));
177
178 *hdf5_reference = H5Dcreate2(parent_group_id,
179 name.data(),
180 *t_type,
181 *dataspace,
182 H5P_DEFAULT,
183 H5P_DEFAULT,
184 H5P_DEFAULT);
185 Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Dcreate2"));
186
187 size = 1;
188 for (const auto &dimension : dimensions)
189 {
190 size *= dimension;
191 }
192 }
193
194
195
196 void
197 DataSet::set_query_io_mode(const bool new_query_io_mode)
198 {
199 query_io_mode = new_query_io_mode;
200 }
201
202
203
204 std::vector<hsize_t>
206 {
207 return dimensions;
208 }
209
210
211
212 std::string
214 {
216 ExcMessage("query_io_mode should be true in order to use io_mode"));
217 switch (io_mode)
218 {
219 case (H5D_MPIO_NO_COLLECTIVE):
220 return std::string("H5D_MPIO_NO_COLLECTIVE");
221 break;
222 case (H5D_MPIO_CHUNK_INDEPENDENT):
223 return std::string("H5D_MPIO_CHUNK_INDEPENDENT");
224 break;
225 case (H5D_MPIO_CHUNK_COLLECTIVE):
226 return std::string("H5D_MPIO_CHUNK_COLLECTIVE");
227 break;
228 case (H5D_MPIO_CHUNK_MIXED):
229 return std::string("H5D_MPIO_CHUNK_MIXED");
230 break;
231 case (H5D_MPIO_CONTIGUOUS_COLLECTIVE):
232 return std::string("H5D_MPIO_CONTIGUOUS_COLLECTIVE");
233 break;
234 default:
236 return std::string("Internal error");
237 break;
238 }
239 // The function should not reach this line.
241 return std::string("Internal error");
242 }
243
244
245
246 H5D_mpio_actual_io_mode_t
248 {
251 "query_io_mode should be true in order to use get_io_mode"));
252 return io_mode;
253 }
254
255
256
257 std::string
259 {
260 Assert(
263 "query_io_mode should be true in order to use get_local_no_collective_cause()"));
265 }
266
267
268
269 std::uint32_t
271 {
272 Assert(
275 "query_io_mode should be true in order to use get_local_no_collective_cause()"));
277 }
278
279
280
281 std::string
283 {
284 Assert(
287 "query_io_mode should be true in order to use get_global_no_collective_cause()"));
289 }
290
291
292
293 std::uint32_t
295 {
296 Assert(
299 "query_io_mode should be true in order to use get_global_no_collective_cause()"));
301 }
302
303
304 bool
306 {
307 return query_io_mode;
308 }
309
310
311
312 unsigned int
314 {
315 return size;
316 }
317
318
319
320 unsigned int
322 {
323 return rank;
324 }
325
326
327
328 Group::Group(const std::string &name,
329 const Group &parentGroup,
330 const bool mpi,
331 const GroupAccessMode mode)
332 : HDF5Object(name, mpi)
333 {
334 hdf5_reference = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
336 // Release the HDF5 resource
337 const herr_t ret = H5Gclose(*pointer);
338 AssertNothrow(ret >= 0, ExcInternalError());
339 (void)ret;
340 delete pointer;
341 });
342 switch (mode)
343 {
346 H5Gopen2(*(parentGroup.hdf5_reference), name.data(), H5P_DEFAULT);
347 Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Gopen2"));
348 break;
350 *hdf5_reference = H5Gcreate2(*(parentGroup.hdf5_reference),
351 name.data(),
352 H5P_DEFAULT,
353 H5P_DEFAULT,
354 H5P_DEFAULT);
355 Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Gcreate2"));
356 break;
357 default:
359 break;
360 }
361 }
362
363
364
365 Group::Group(const std::string &name, const bool mpi)
366 : HDF5Object(name, mpi)
367 {}
368
369
370
371 Group
372 Group::open_group(const std::string &name) const
373 {
374 return {name, *this, mpi, GroupAccessMode::open};
375 }
376
377
378
379 Group
380 Group::create_group(const std::string &name) const
381 {
382 return {name, *this, mpi, GroupAccessMode::create};
383 }
384
385
386
387 DataSet
388 Group::open_dataset(const std::string &name) const
389 {
390 return {name, *hdf5_reference, mpi};
391 }
392
393
394
395 File::File(const std::string &name, const FileAccessMode mode)
396 : File(name,
397 mode,
398 false,
399# ifdef DEAL_II_WITH_MPI
400 MPI_COMM_NULL
401# else
402 0
403# endif
404 )
405 {}
406
407
408
409 File::File(const std::string &name,
410 const FileAccessMode mode,
411 const MPI_Comm mpi_communicator)
412 : File(name, mode, true, mpi_communicator)
413 {}
414
415
416
417 File::File(const std::string &name,
418 const FileAccessMode mode,
419 const bool mpi,
420 const MPI_Comm mpi_communicator)
421 : Group(name, mpi)
422 {
423 hdf5_reference = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
425 // Release the HDF5 resource
426 const herr_t err = H5Fclose(*pointer);
427 AssertNothrow(err >= 0, ExcInternalError());
428 (void)err;
429 delete pointer;
430 });
431
432 hid_t plist;
433 herr_t ret;
434
435 if (mpi)
436 {
437# ifdef DEAL_II_WITH_MPI
438# ifdef H5_HAVE_PARALLEL
439 const MPI_Info info = MPI_INFO_NULL;
440
441 plist = H5Pcreate(H5P_FILE_ACCESS);
442 Assert(plist >= 0, ExcMessage("Error at H5Pcreate"));
443 ret = H5Pset_fapl_mpio(plist, mpi_communicator, info);
444 Assert(ret >= 0, ExcMessage("Error at H5Pset_fapl_mpio"));
445# else
446 AssertThrow(false, ExcMessage("HDF5 parallel support is disabled."));
447# endif // H5_HAVE_PARALLEL
448# else
449 AssertThrow(false, ExcMessage("MPI support is disabled."));
450# endif // DEAL_II_WITH_MPI
451 }
452 else
453 {
454 plist = H5P_DEFAULT;
455 }
456
457 switch (mode)
458 {
460 *hdf5_reference = H5Fopen(name.data(), H5F_ACC_RDWR, plist);
461 Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Fopen"));
462 break;
465 H5Fcreate(name.data(), H5F_ACC_TRUNC, H5P_DEFAULT, plist);
466 Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Fcreate"));
467 break;
468 default:
470 break;
471 }
472
473 if (mpi)
474 {
475 // Release the HDF5 resource
476 ret = H5Pclose(plist);
477 Assert(ret >= 0, ExcMessage("Error at H5Pclose"));
478 }
479
480 (void)ret;
481 (void)mpi_communicator;
482 }
483} // namespace HDF5
484
486
487#endif // DEAL_II_WITH_HDF5
unsigned int rank
Definition hdf5.h:924
unsigned int get_rank() const
Definition hdf5.cc:321
bool query_io_mode
Definition hdf5.h:951
std::vector< hsize_t > get_dimensions() const
Definition hdf5.cc:205
std::vector< hsize_t > dimensions
Definition hdf5.h:930
std::uint32_t get_local_no_collective_cause_as_hdf5_type()
Definition hdf5.cc:270
unsigned int get_size() const
Definition hdf5.cc:313
std::shared_ptr< hid_t > dataspace
Definition hdf5.h:935
DataSet(const std::string &name, const hid_t &parent_group_id, bool mpi)
Definition hdf5.cc:88
std::string get_local_no_collective_cause()
Definition hdf5.cc:258
std::string get_io_mode()
Definition hdf5.cc:213
std::uint32_t local_no_collective_cause
Definition hdf5.h:963
std::string get_global_no_collective_cause()
Definition hdf5.cc:282
bool get_query_io_mode() const
Definition hdf5.cc:305
std::uint32_t global_no_collective_cause
Definition hdf5.h:970
std::uint32_t get_global_no_collective_cause_as_hdf5_type()
Definition hdf5.cc:294
H5D_mpio_actual_io_mode_t get_io_mode_as_hdf5_type()
Definition hdf5.cc:247
void set_query_io_mode(const bool new_query_io_mode)
Definition hdf5.cc:197
unsigned int size
Definition hdf5.h:940
H5D_mpio_actual_io_mode_t io_mode
Definition hdf5.h:956
File(const std::string &name, const FileAccessMode mode)
Definition hdf5.cc:395
FileAccessMode
Definition hdf5.h:1080
DataSet open_dataset(const std::string &name) const
Definition hdf5.cc:388
Group open_group(const std::string &name) const
Definition hdf5.cc:372
Group(const std::string &name, const Group &parent_group, const bool mpi, const GroupAccessMode mode)
Definition hdf5.cc:328
Group create_group(const std::string &name) const
Definition hdf5.cc:380
GroupAccessMode
Definition hdf5.h:983
std::shared_ptr< hid_t > hdf5_reference
Definition hdf5.h:414
std::string get_name() const
Definition hdf5.cc:81
const std::string name
Definition hdf5.h:405
HDF5Object(const std::string &name, const bool mpi)
Definition hdf5.cc:73
const bool mpi
Definition hdf5.h:419
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:502
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertNothrow(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
#define DEAL_II_ASSERT_UNREACHABLE()
void check_exception(const std::string &type, const std::string &name)
Definition hdf5.cc:38
std::string no_collective_cause_to_string(const std::uint32_t no_collective_cause)
Definition hdf5.h:1536
Definition hdf5.h:345