Reference documentation for deal.II version Git fe553f7db3 2020-12-03 08:11:48 +0100
\(\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\}}\)
hdf5.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2018 - 2019 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/config.h>
17 
18 #ifdef DEAL_II_WITH_HDF5
19 
20 # include <deal.II/base/hdf5.h>
21 
22 # include <hdf5.h>
23 
25 
26 namespace HDF5
27 {
28  HDF5Object::HDF5Object(const std::string &name, const bool mpi)
29  : name(name)
30  , mpi(mpi)
31  {}
32 
33 
34 
35  std::string
37  {
38  return name;
39  }
40 
41 
42 
43  DataSet::DataSet(const std::string &name,
44  const hid_t & parent_group_id,
45  const bool mpi)
46  : HDF5Object(name, mpi)
47  , query_io_mode(false)
48  , io_mode(H5D_MPIO_NO_COLLECTIVE)
49  , local_no_collective_cause(H5D_MPIO_SET_INDEPENDENT)
50  , global_no_collective_cause(H5D_MPIO_SET_INDEPENDENT)
51  {
52  hdf5_reference = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
53  // Release the HDF5 resource
54  const herr_t ret = H5Dclose(*pointer);
55  AssertNothrow(ret >= 0, ExcInternalError());
56  (void)ret;
57  delete pointer;
58  });
59  dataspace = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
60  // Release the HDF5 resource
61  const herr_t ret = H5Sclose(*pointer);
62  AssertNothrow(ret >= 0, ExcInternalError());
63  (void)ret;
64  delete pointer;
65  });
66 
67  // rank_ret can take a negative value if the functions
68  // H5Sget_simple_extent_ndims and H5Sget_simple_extent_dims fail. rank is
69  // unsigned int therefore it can not be used to store the return value of
70  // H5Sget_simple_extent_ndims and H5Sget_simple_extent_dims
71  int rank_ret;
72 
73  *hdf5_reference = H5Dopen2(parent_group_id, name.data(), H5P_DEFAULT);
74  Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Dopen2"));
75  *dataspace = H5Dget_space(*hdf5_reference);
76  Assert(*dataspace >= 0, ExcMessage("Error at H5Dget_space"));
77  rank_ret = H5Sget_simple_extent_ndims(*dataspace);
78  Assert(rank_ret >= 0, ExcInternalError());
79  rank = rank_ret;
80  dimensions.resize(rank);
81  rank_ret =
82  H5Sget_simple_extent_dims(*dataspace, dimensions.data(), nullptr);
83  AssertDimension(rank_ret, static_cast<int>(rank));
84 
85  size = 1;
86  for (const auto &dimension : dimensions)
87  {
88  size *= dimension;
89  }
90  }
91 
92 
93 
94  DataSet::DataSet(const std::string & name,
95  const hid_t & parent_group_id,
96  const std::vector<hsize_t> & dimensions,
97  const std::shared_ptr<hid_t> &t_type,
98  const bool mpi)
99  : HDF5Object(name, mpi)
100  , rank(dimensions.size())
101  , dimensions(dimensions)
102  , query_io_mode(false)
103  , io_mode(H5D_MPIO_NO_COLLECTIVE)
104  , local_no_collective_cause(H5D_MPIO_SET_INDEPENDENT)
105  , global_no_collective_cause(H5D_MPIO_SET_INDEPENDENT)
106  {
107  hdf5_reference = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
108  // Release the HDF5 resource
109  const herr_t ret = H5Dclose(*pointer);
110  AssertNothrow(ret >= 0, ExcInternalError());
111  (void)ret;
112  delete pointer;
113  });
114  dataspace = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
115  // Release the HDF5 resource
116  const herr_t ret = H5Sclose(*pointer);
117  AssertNothrow(ret >= 0, ExcInternalError());
118  (void)ret;
119  delete pointer;
120  });
121 
122  *dataspace = H5Screate_simple(rank, dimensions.data(), nullptr);
123  Assert(*dataspace >= 0, ExcMessage("Error at H5Screate_simple"));
124 
125  *hdf5_reference = H5Dcreate2(parent_group_id,
126  name.data(),
127  *t_type,
128  *dataspace,
129  H5P_DEFAULT,
130  H5P_DEFAULT,
131  H5P_DEFAULT);
132  Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Dcreate2"));
133 
134  size = 1;
135  for (const auto &dimension : dimensions)
136  {
137  size *= dimension;
138  }
139  }
140 
141 
142 
143  void
144  DataSet::set_query_io_mode(const bool new_query_io_mode)
145  {
146  query_io_mode = new_query_io_mode;
147  }
148 
149 
150 
151  std::vector<hsize_t>
153  {
154  return dimensions;
155  }
156 
157 
158 
159  std::string
161  {
163  ExcMessage("query_io_mode should be true in order to use io_mode"));
164  switch (io_mode)
165  {
166  case (H5D_MPIO_NO_COLLECTIVE):
167  return std::string("H5D_MPIO_NO_COLLECTIVE");
168  break;
169  case (H5D_MPIO_CHUNK_INDEPENDENT):
170  return std::string("H5D_MPIO_CHUNK_INDEPENDENT");
171  break;
172  case (H5D_MPIO_CHUNK_COLLECTIVE):
173  return std::string("H5D_MPIO_CHUNK_COLLECTIVE");
174  break;
175  case (H5D_MPIO_CHUNK_MIXED):
176  return std::string("H5D_MPIO_CHUNK_MIXED");
177  break;
178  case (H5D_MPIO_CONTIGUOUS_COLLECTIVE):
179  return std::string("H5D_MPIO_CONTIGUOUS_COLLECTIVE");
180  break;
181  default:
182  Assert(false, ExcInternalError());
183  return std::string("Internal error");
184  break;
185  }
186  // The function should not reach this line.
187  Assert(false, ExcInternalError());
188  return std::string("Internal error");
189  }
190 
191 
192 
193  H5D_mpio_actual_io_mode_t
195  {
197  ExcMessage(
198  "query_io_mode should be true in order to use get_io_mode"));
199  return io_mode;
200  }
201 
202 
203 
204  std::string
206  {
207  Assert(
209  ExcMessage(
210  "query_io_mode should be true in order to use get_local_no_collective_cause()"));
212  }
213 
214 
215 
216  uint32_t
218  {
219  Assert(
221  ExcMessage(
222  "query_io_mode should be true in order to use get_local_no_collective_cause()"));
224  }
225 
226 
227 
228  std::string
230  {
231  Assert(
233  ExcMessage(
234  "query_io_mode should be true in order to use get_global_no_collective_cause()"));
236  }
237 
238 
239 
240  uint32_t
242  {
243  Assert(
245  ExcMessage(
246  "query_io_mode should be true in order to use get_global_no_collective_cause()"));
248  }
249 
250 
251  bool
253  {
254  return query_io_mode;
255  }
256 
257 
258 
259  unsigned int
261  {
262  return size;
263  }
264 
265 
266 
267  unsigned int
269  {
270  return rank;
271  }
272 
273 
274 
275  Group::Group(const std::string & name,
276  const Group & parentGroup,
277  const bool mpi,
278  const GroupAccessMode mode)
279  : HDF5Object(name, mpi)
280  {
281  hdf5_reference = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
282  // Release the HDF5 resource
283  const herr_t ret = H5Gclose(*pointer);
284  AssertNothrow(ret >= 0, ExcInternalError());
285  (void)ret;
286  delete pointer;
287  });
288  switch (mode)
289  {
290  case (GroupAccessMode::open):
291  *hdf5_reference =
292  H5Gopen2(*(parentGroup.hdf5_reference), name.data(), H5P_DEFAULT);
293  Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Gopen2"));
294  break;
296  *hdf5_reference = H5Gcreate2(*(parentGroup.hdf5_reference),
297  name.data(),
298  H5P_DEFAULT,
299  H5P_DEFAULT,
300  H5P_DEFAULT);
301  Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Gcreate2"));
302  break;
303  default:
304  Assert(false, ExcInternalError());
305  break;
306  }
307  }
308 
309 
310 
311  Group::Group(const std::string &name, const bool mpi)
312  : HDF5Object(name, mpi)
313  {}
314 
315 
316 
317  Group
318  Group::open_group(const std::string &name) const
319  {
320  return {name, *this, mpi, GroupAccessMode::open};
321  }
322 
323 
324 
325  Group
326  Group::create_group(const std::string &name) const
327  {
328  return {name, *this, mpi, GroupAccessMode::create};
329  }
330 
331 
332 
333  DataSet
334  Group::open_dataset(const std::string &name) const
335  {
336  return {name, *hdf5_reference, mpi};
337  }
338 
339 
340 
341  File::File(const std::string &name, const FileAccessMode mode)
342  : File(name,
343  mode,
344  false,
345 # ifdef DEAL_II_WITH_MPI
346  MPI_COMM_NULL
347 # else
348  0
349 # endif
350  )
351  {}
352 
353 
354 
355  File::File(const std::string & name,
356  const FileAccessMode mode,
357  const MPI_Comm & mpi_communicator)
358  : File(name, mode, true, mpi_communicator)
359  {}
360 
361 
362 
363  File::File(const std::string & name,
364  const FileAccessMode mode,
365  const bool mpi,
366  const MPI_Comm & mpi_communicator)
367  : Group(name, mpi)
368  {
369  hdf5_reference = std::shared_ptr<hid_t>(new hid_t, [](hid_t *pointer) {
370  // Release the HDF5 resource
371  const herr_t err = H5Fclose(*pointer);
372  AssertNothrow(err >= 0, ExcInternalError());
373  (void)err;
374  delete pointer;
375  });
376 
377  hid_t plist;
378  herr_t ret;
379 
380  if (mpi)
381  {
382 # ifdef DEAL_II_WITH_MPI
383 # ifdef H5_HAVE_PARALLEL
384  const MPI_Info info = MPI_INFO_NULL;
385 
386  plist = H5Pcreate(H5P_FILE_ACCESS);
387  Assert(plist >= 0, ExcMessage("Error at H5Pcreate"));
388  ret = H5Pset_fapl_mpio(plist, mpi_communicator, info);
389  Assert(ret >= 0, ExcMessage("Error at H5Pset_fapl_mpio"));
390 # else
391  AssertThrow(false, ExcMessage("HDF5 parallel support is disabled."));
392 # endif // H5_HAVE_PARALLEL
393 # else
394  AssertThrow(false, ExcMessage("MPI support is disabled."));
395 # endif // DEAL_II_WITH_MPI
396  }
397  else
398  {
399  plist = H5P_DEFAULT;
400  }
401 
402  switch (mode)
403  {
404  case (FileAccessMode::open):
405  *hdf5_reference = H5Fopen(name.data(), H5F_ACC_RDWR, plist);
406  Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Fopen"));
407  break;
408  case (FileAccessMode::create):
409  *hdf5_reference =
410  H5Fcreate(name.data(), H5F_ACC_TRUNC, H5P_DEFAULT, plist);
411  Assert(*hdf5_reference >= 0, ExcMessage("Error at H5Fcreate"));
412  break;
413  default:
414  Assert(false, ExcInternalError());
415  break;
416  }
417 
418  if (mpi)
419  {
420  // Release the HDF5 resource
421  ret = H5Pclose(plist);
422  Assert(ret >= 0, ExcMessage("Error at H5Pclose"));
423  }
424 
425  (void)ret;
426  (void)mpi_communicator;
427  }
428 } // namespace HDF5
429 
431 
432 #endif // DEAL_II_WITH_HDF5
#define AssertNothrow(cond, exc)
Definition: exceptions.h:1529
DataSet open_dataset(const std::string &name) const
Definition: hdf5.cc:334
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1623
GroupAccessMode
Definition: hdf5.h:1000
std::string get_name() const
Definition: hdf5.cc:36
H5D_mpio_actual_io_mode_t get_io_mode_as_hdf5_type()
Definition: hdf5.cc:194
Group(const std::string &name, const Group &parent_group, const bool mpi, const GroupAccessMode mode)
Definition: hdf5.cc:275
HDF5Object(const std::string &name, const bool mpi)
Definition: hdf5.cc:28
std::shared_ptr< hid_t > hdf5_reference
Definition: hdf5.h:433
#define AssertThrow(cond, exc)
Definition: exceptions.h:1576
FileAccessMode
Definition: hdf5.h:1097
unsigned int size
Definition: hdf5.h:958
DataSet(const std::string &name, const hid_t &parent_group_id, bool mpi)
Definition: hdf5.cc:43
bool query_io_mode
Definition: hdf5.h:969
static ::ExceptionBase & ExcMessage(std::string arg1)
Group create_group(const std::string &name) const
Definition: hdf5.cc:326
#define Assert(cond, exc)
Definition: exceptions.h:1466
void set_query_io_mode(const bool new_query_io_mode)
Definition: hdf5.cc:144
unsigned int get_rank() const
Definition: hdf5.cc:268
const std::string name
Definition: hdf5.h:424
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:372
std::string no_collective_cause_to_string(const uint32_t no_collective_cause)
Definition: hdf5.h:1529
unsigned int get_size() const
Definition: hdf5.cc:260
std::vector< hsize_t > dimensions
Definition: hdf5.h:948
uint32_t get_global_no_collective_cause_as_hdf5_type()
Definition: hdf5.cc:241
unsigned int rank
Definition: hdf5.h:942
std::shared_ptr< hid_t > dataspace
Definition: hdf5.h:953
Definition: hdf5.h:363
std::string get_local_no_collective_cause()
Definition: hdf5.cc:205
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:371
uint32_t local_no_collective_cause
Definition: hdf5.h:981
std::vector< hsize_t > get_dimensions() const
Definition: hdf5.cc:152
std::string get_global_no_collective_cause()
Definition: hdf5.cc:229
uint32_t global_no_collective_cause
Definition: hdf5.h:988
std::string get_io_mode()
Definition: hdf5.cc:160
const bool mpi
Definition: hdf5.h:438
H5D_mpio_actual_io_mode_t io_mode
Definition: hdf5.h:974
File(const std::string &name, const FileAccessMode mode)
Definition: hdf5.cc:341
uint32_t get_local_no_collective_cause_as_hdf5_type()
Definition: hdf5.cc:217
bool get_query_io_mode() const
Definition: hdf5.cc:252
static ::ExceptionBase & ExcInternalError()
Group open_group(const std::string &name) const
Definition: hdf5.cc:318