DASH  0.3.0
dash::io::hdf5::StoreHDF Class Reference

DASH wrapper to store an dash::Array or dash::Matrix in an HDF5 file using parallel IO. More...

#include <StorageDriver.h>

Classes

struct  hdf5_filespace_spec
 hdf5 pattern specification for parallel IO More...
 
struct  hdf5_hyperslab_spec
 
struct  hdf5_pattern_spec
 hdf5 pattern specification for parallel IO More...
 

Static Public Member Functions

template<typename View_t >
static void write (View_t &array, std::string filename, std::string datapath, hdf5_options foptions=hdf5_options(), type_converter_fun_type to_h5_dt_converter=get_h5_datatype< typename dash::view_traits< View_t >::origin_type::value_type >)
 Store all dash::Matrix values in an HDF5 file using parallel IO. More...
 
template<typename Container_t >
static std::enable_if< _compatible_pattern< typename Container_t::pattern_type >) &&_is_origin_view< Container_t >), void >::type read (Container_t &matrix, std::string filename, std::string datapath, hdf5_options foptions=hdf5_options(), type_converter_fun_type to_h5_dt_converter=get_h5_datatype< typename Container_t::value_type >)
 Read an HDF5 dataset into a dash container using parallel IO if the matrix is already allocated, the sizes have to match the HDF5 dataset sizes and all data will be overwritten. More...
 
template<class Container_t >
static std::enable_if< !(_compatible_pattern< typename Container_t::pattern_type >) &&_is_origin_view< Container_t >)), void >::type read (Container_t &matrix, std::string filename, std::string datapath, hdf5_options foptions=hdf5_options(), type_converter_fun_type to_h5_dt_converter=get_h5_datatype< typename Container_t::value_type >)
 

Detailed Description

DASH wrapper to store an dash::Array or dash::Matrix in an HDF5 file using parallel IO.

All operations are collective.

Examples:
ex.08.io-hdf5/main.cpp.

Definition at line 77 of file StorageDriver.h.

Member Function Documentation

◆ read() [1/2]

template<typename Container_t >
static std::enable_if< _compatible_pattern<typename Container_t::pattern_type>) && _is_origin_view<Container_t>), void>:: type dash::io::hdf5::StoreHDF::read ( Container_t &  matrix,
std::string  filename,
std::string  datapath,
hdf5_options  foptions = hdf5_options(),
type_converter_fun_type  to_h5_dt_converter = get_h5_datatype<typename Container_t::value_type> 
)
inlinestatic

Read an HDF5 dataset into a dash container using parallel IO if the matrix is already allocated, the sizes have to match the HDF5 dataset sizes and all data will be overwritten.

Otherwise the matrix will be allocated.

Collective operation.

Parameters
matrixImport data in this Container
filenameFilename of HDF5 file including extension
datapathHDF5 Dataset in which the data is stored
foptionsoptions how to open and modify data
to_h5_dt_converterstd::function to convert native type into h5 type

Definition at line 269 of file StorageDriver.h.

References dash::Team::All(), dart__io__hdf5__prep_mpio(), DART_OK, dash::ndim(), and dash::rank().

280  {
281  using pattern_t = typename Container_t::pattern_type;
282  using extent_t = typename pattern_t::size_type;
283  using index_t = typename Container_t::index_type;
284  using value_t = typename Container_t::value_type;
285 
286  constexpr auto ndim = pattern_t::ndim();
287 
288  static_assert(std::is_same<index_t, typename pattern_t::index_type>::value,
289  "Specified index_t differs from pattern_t::index_type");
290 
291  // HDF5 definition
292  hid_t file_id;
293  hid_t h5dset;
294  hid_t internal_type;
295  hid_t plist_id; // property list identifier
296  hid_t filespace;
297  // global data dims
298  hsize_t data_dimsf[ndim];
299  herr_t status;
300  // Map native types to HDF5 types
301  hid_t h5datatype;
302  // rank of hdf5 dataset
303  int rank;
304 
305  // Check if matrix is already allocated
306  bool is_alloc = (matrix.size() != 0);
307 
308  // Setup MPI IO
309  plist_id = H5Pcreate(H5P_FILE_ACCESS);
310  if (is_alloc) {
311  DASH_ASSERT_RETURNS(
312  dart__io__hdf5__prep_mpio(plist_id, matrix.team().dart_id()),
313  DART_OK);
314  } else {
315  DASH_ASSERT_RETURNS(
316  dart__io__hdf5__prep_mpio(plist_id, dash::Team::All().dart_id()),
317  DART_OK);
318  }
319 
320  // HD5 create file
321  file_id = H5Fopen(filename.c_str(), H5P_DEFAULT, plist_id);
322 
323  // close property list
324  H5Pclose(plist_id);
325 
326  // Create dataset
327  h5dset = H5Dopen(file_id, datapath.c_str(), H5P_DEFAULT);
328 
329  // Get dimensions of data
330  filespace = H5Dget_space(h5dset);
331  rank = H5Sget_simple_extent_ndims(filespace);
332 
333  DASH_ASSERT_EQ(rank, ndim,
334  "Data dimension of HDF5 dataset does not match matrix "
335  "dimension");
336 
337  status = H5Sget_simple_extent_dims(filespace, data_dimsf, NULL);
338 
339  std::array<extent_t, ndim> size_extents;
340 
341  // set matrix size according to hdf5 dataset dimensions
342  for (int i = 0; i < ndim; ++i) {
343  size_extents[i] = data_dimsf[i];
344  }
345 
346  // Check if file contains DASH metadata and recreate the pattern
347  auto pat_key = foptions.pattern_metadata_key.c_str();
348 
349  if (!is_alloc // not allocated
350  && foptions.restore_pattern // pattern should be restored
351  && H5Aexists(h5dset, pat_key)) // hdf5 contains pattern
352  {
353  _restore_pattern(matrix, h5dset, foptions);
354  } else if (is_alloc) {
355  DASH_LOG_DEBUG("Matrix already allocated");
356  // Check if matrix extents match data extents
357  auto container_extents = _get_container_extents(matrix);
358  for (int i = 0; i < ndim; ++i) {
359  DASH_ASSERT_EQ(size_extents[i], container_extents.extent[i],
360  "Container extents do not match data extents");
361  }
362  } else {
363  // Auto deduce pattern
364  const pattern_t pattern(dash::SizeSpec<ndim, typename pattern_t::size_type>(size_extents),
367 
368  matrix.allocate(pattern);
369  }
370 
371  h5datatype = to_h5_dt_converter();
372  internal_type = H5Tcopy(h5datatype);
373 
374  // ----------- prepare and read dataset ------------------
375 
376  _read_dataset_impl(matrix, h5dset, internal_type);
377 
378  // ----------- end prepare and read dataset --------------
379 
380  // Close all
381  H5Dclose(h5dset);
382  H5Tclose(internal_type);
383  H5Fclose(file_id);
384 
385  matrix.team().barrier();
386  }
constexpr dim_t rank(const DimensionalType &d)
Definition: Dimensional.h:64
Signals success.
Definition: dart_types.h:33
Specifies cartesian extents in a specific number of dimensions.
Definition: Cartesian.h:197
constexpr dim_t ndim(const DimensionalType &d)
Definition: Dimensional.h:56
Specifies the arrangement of team units in a specified number of dimensions.
Definition: TeamSpec.h:33
dart_ret_t dart__io__hdf5__prep_mpio(hid_t plist_id, dart_team_t teamid)
setup hdf5 for parallel io using mpi-io
static Team & All()
The invariant Team instance containing all available units.
Definition: Team.h:213
DistributionSpec describes distribution patterns of all dimensions,.
Definition: Dimensional.h:222

◆ read() [2/2]

template<class Container_t >
static std::enable_if< !(_compatible_pattern<typename Container_t::pattern_type>) && _is_origin_view<Container_t>)), void>:: type dash::io::hdf5::StoreHDF::read ( Container_t &  matrix,
std::string  filename,
std::string  datapath,
hdf5_options  foptions = hdf5_options(),
type_converter_fun_type  to_h5_dt_converter = get_h5_datatype<typename Container_t::value_type> 
)
inlinestatic
Parameters
matrixImport data in this Container
filenameFilename of HDF5 file including extension
datapathHDF5 Dataset in which the data is stored
foptionsoptions how to open and modify data
to_h5_dt_converterstd::function to convert native type into h5 type

Definition at line 393 of file StorageDriver.h.

404  {}

◆ write()

template<typename View_t >
static void dash::io::hdf5::StoreHDF::write ( View_t &  array,
std::string  filename,
std::string  datapath,
hdf5_options  foptions = hdf5_options(),
type_converter_fun_type  to_h5_dt_converter = get_h5_datatype< typename dash::view_traits<View_t>::origin_type::value_type> 
)
inlinestatic

Store all dash::Matrix values in an HDF5 file using parallel IO.

Collective operation.

Parameters
arrayArray to store
filenameFilename of HDF5 file including extension
datapathHDF5 Dataset in which the data is stored
foptions
Parameters
arrayImport data in this Container
filenameFilename of HDF5 file including extension
datapathHDF5 Dataset in which the data is stored
foptionsoptions how to open and modify data
to_h5_dt_converterstd::function to convert native type into h5 type

Definition at line 122 of file StorageDriver.h.

References dart__io__hdf5__prep_mpio(), dash::Team::dart_id(), DART_OK, dash::for_each(), dash::Shared< ElementType >::get(), dash::ndim(), and dash::Shared< ElementType >::set().

133  {
134  using Container_t = typename dash::view_traits<View_t>::origin_type;
135  using pattern_t = typename Container_t::pattern_type;
136  using extent_t = typename pattern_t::size_type;
137  using index_t = typename Container_t::index_type;
138  using value_t = typename Container_t::value_type;
139 
140  constexpr auto ndim = pattern_t::ndim();
141 
142  // Check if container dims match pattern dims
143  _verify_container_dims(array);
144  static_assert(std::is_same<index_t, typename pattern_t::index_type>::value,
145  "Specified index_t differs from pattern_t::index_type");
146 
147  const dash::Team& team = array.team();
148 
149  // Map native types to HDF5 types
150  auto h5datatype = to_h5_dt_converter();
151  // for tracking opened groups
152  std::list<hid_t> open_groups;
153  // Split path in groups and dataset
154  auto path_vec = _split_string(datapath, '/');
155  auto dataset = path_vec.back();
156  // remove dataset from path
157  path_vec.pop_back();
158 
159  /* HDF5 definition */
160  hid_t file_id;
161  hid_t h5dset;
162  hid_t internal_type;
163  hid_t plist_id; // property list identifier
164  hid_t filespace;
165  hid_t loc_id;
166 
167  // setup mpi access
168  plist_id = H5Pcreate(H5P_FILE_ACCESS);
169  DASH_ASSERT_RETURNS(dart__io__hdf5__prep_mpio(plist_id, team.dart_id()),
170  DART_OK);
171 
172  dash::Shared<int> f_exists;
173  if (team.myid() == 0) {
174  if (access(filename.c_str(), F_OK) != -1) {
175  // check if file exists
176  f_exists.set(static_cast<int>(H5Fis_hdf5(filename.c_str())));
177  } else {
178  f_exists.set(-1);
179  }
180  }
181  team.barrier();
182 
183  if (foptions.overwrite_file || (f_exists.get() <= 0)) {
184  // HD5 create file
185  file_id =
186  H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, plist_id);
187  } else {
188  // Open file in RW mode
189  file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, plist_id);
190  }
191 
192  // close property list
193  H5Pclose(plist_id);
194 
195  // Traverse path
196  loc_id = file_id;
197  for (std::string elem : path_vec) {
198  if (H5Lexists(loc_id, elem.c_str(), H5P_DEFAULT)) {
199  // open group
200  DASH_LOG_DEBUG("Open Group", elem);
201  loc_id = H5Gopen2(loc_id, elem.c_str(), H5P_DEFAULT);
202  } else {
203  // create group
204  DASH_LOG_DEBUG("Create Group", elem);
205  loc_id = H5Gcreate2(loc_id, elem.c_str(), H5P_DEFAULT, H5P_DEFAULT,
206  H5P_DEFAULT);
207  }
208  if (loc_id != file_id) {
209  open_groups.push_back(loc_id);
210  }
211  }
212 
213  // view extents are relevant (instead of pattern extents)
214  auto filespace_extents = _get_container_extents(array);
215 
216  // Create dataspace
217  filespace = H5Screate_simple(ndim, filespace_extents.extent, NULL);
218  internal_type = H5Tcopy(h5datatype);
219 
220  if (foptions.modify_dataset) {
221  // Open dataset in RW mode
222  h5dset = H5Dopen(loc_id, dataset.c_str(), H5P_DEFAULT);
223  } else {
224  // Create dataset
225  h5dset = H5Dcreate(loc_id, dataset.c_str(), internal_type, filespace,
226  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
227  }
228 
229  // Close global dataspace
230  H5Sclose(filespace);
231 
232  // ----------- prepare and write dataset --------------
233 
234  _write_dataset_impl(array, h5dset, internal_type);
235 
236  // ----------- end prepare and write dataset --------------
237 
238  // Add Attributes
239  if (foptions.store_pattern && _is_origin_view<Container_t>()) {
240  DASH_LOG_DEBUG("store pattern in hdf5 file");
241  _store_pattern(array, h5dset, foptions);
242  }
243 
244  // Close all
245  H5Dclose(h5dset);
246  H5Tclose(internal_type);
247 
248  std::for_each(open_groups.rbegin(), open_groups.rend(),
249  [](hid_t& group_id) { H5Gclose(group_id); });
250 
251  H5Fclose(file_id);
252 
253  team.barrier();
254  }
Signals success.
Definition: dart_types.h:33
reference get()
Get a reference on the shared value.
Definition: Shared.h:239
void set(const value_type &val)
Set the value of the shared element.
Definition: Shared.h:226
A Team instance specifies a subset of all available units.
Definition: Team.h:41
constexpr dim_t ndim(const DimensionalType &d)
Definition: Dimensional.h:56
dart_ret_t dart__io__hdf5__prep_mpio(hid_t plist_id, dart_team_t teamid)
setup hdf5 for parallel io using mpi-io
Shared access to a value in global memory across a team.
Definition: Shared.h:23
void for_each(const GlobInputIt &first, const GlobInputIt &last, UnaryFunction func)
Invoke a function on every element in a range distributed by a pattern.
Definition: ForEach.h:32
dart_team_t dart_id() const
Index of this team relative to global team dash::Team::All().
Definition: Team.h:522

The documentation for this class was generated from the following file: