DASH  0.3.0
StorageDriver.h
1 #ifndef DASH__IO__HDF5__STORAGEDRIVER_H__
2 #define DASH__IO__HDF5__STORAGEDRIVER_H__
3 
4 #include <dash/internal/Config.h>
5 
6 #ifdef DASH_ENABLE_HDF5
7 
8 #ifndef DASH_MPI_IMPL_ID
9 #error "HDF5 module requires dart-mpi"
10 #endif
11 
12 #include <dash/Exception.h>
13 #include <dash/Init.h>
14 #include <dash/Array.h>
15 #include <dash/Matrix.h>
16 #include <dash/Shared.h>
17 
18 #include <sys/stat.h>
19 
20 #include <hdf5.h>
21 #include <hdf5_hl.h>
22 
23 #include <iostream>
24 #include <unistd.h>
25 #include <string>
26 #include <vector>
27 #include <list>
28 #include <array>
29 #include <string>
30 #include <sstream>
31 #include <typeinfo>
32 #include <type_traits>
33 #include <functional>
34 #include <utility>
35 
36 #include <dash/dart/if/dart_io.h>
37 
38 namespace dash {
39 namespace io {
40 namespace hdf5 {
41 
43 template <typename T>
44 hid_t get_h5_datatype();
45 
47 using type_converter_fun_type = std::function<hid_t()>;
48 
56 struct hdf5_options {
58  bool overwrite_file = true;
63  bool modify_dataset = false;
65  bool store_pattern = true;
67  bool restore_pattern = true;
69  std::string pattern_metadata_key = "DASH_PATTERN";
70 };
71 
77 class StoreHDF {
82  template <class pattern_t>
83  static constexpr bool _compatible_pattern() {
88  // TODO: check if mapping is regular by checking pattern property
89  }
90 
91  template <class ViewType>
92  static constexpr bool _is_origin_view() {
94  }
95 
96  static std::vector<std::string> _split_string(const std::string& str,
97  const char delim) {
98  std::vector<std::string> elems;
99  std::stringstream ss;
100  ss.str(str);
101  std::string item;
102  while (std::getline(ss, item, delim)) {
103  if (item != "") {
104  elems.push_back(item);
105  }
106  }
107  return elems;
108  }
109 
110  public:
121  template <typename View_t>
122  static void write(
124  View_t& array,
126  std::string filename,
128  std::string datapath,
130  hdf5_options foptions = hdf5_options(),
132  type_converter_fun_type to_h5_dt_converter = get_h5_datatype<
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  }
255 
264  template <typename Container_t>
265  typename std::enable_if<
266  _compatible_pattern<typename Container_t::pattern_type>() &&
267  _is_origin_view<Container_t>(),
268  void>::
269  type static read(
271  Container_t& matrix,
273  std::string filename,
275  std::string datapath,
277  hdf5_options foptions = hdf5_options(),
279  type_converter_fun_type to_h5_dt_converter =
280  get_h5_datatype<typename Container_t::value_type>) {
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  }
387 
388  template <class Container_t>
389  typename std::enable_if<
390  !(_compatible_pattern<typename Container_t::pattern_type>() &&
391  _is_origin_view<Container_t>()),
392  void>::
393  type static read(
395  Container_t& matrix,
397  std::string filename,
399  std::string datapath,
401  hdf5_options foptions = hdf5_options(),
403  type_converter_fun_type to_h5_dt_converter =
404  get_h5_datatype<typename Container_t::value_type>) {}
405 
406  public:
410  template <dim_t ndim>
412  std::array<hsize_t, ndim> count{{0}};
413  std::array<hsize_t, ndim> stride{{0}};
414  std::array<hsize_t, ndim> offset{{0}};
415  std::array<hsize_t, ndim> block{{0}};
416 
417  hdf5_pattern_spec() = default;
418  };
419 
423  template <dim_t ndim>
425  hsize_t extent[ndim] = {0};
426  };
427 
428  template <dim_t ndim>
432  std::array<hsize_t, ndim> data_extf{{0}};
433  std::array<hsize_t, ndim> data_extm{{0}};
434  // approx. amount of data this unit contribs in this hyperslab
435  size_t contrib_data = 0;
436  bool contrib_blocks = false;
437 
438  // cannot be defaulted as otherwise const construction is not
439  // possible in clang
440  hdf5_hyperslab_spec() {};
441  };
442 
443  private:
444  enum class Mode : uint16_t {
445  READ = 0x1,
446  WRITE = 0x2
447  };
448 
449  template <class BlockSpec_t, typename index_t>
450  index_t static inline _blockspec_at(const BlockSpec_t& lblockspec,
451  const std::array<index_t, 1>& coords) {
452  return coords[0];
453  }
454 
455  template <class BlockSpec_t, typename index_t, std::size_t ndim>
456  index_t static inline _blockspec_at(const BlockSpec_t& lblockspec,
457  const std::array<index_t, ndim>& coords) {
458  return lblockspec.at(coords);
459  }
460 
465  template <class pattern_t>
466  const static inline hdf5_hyperslab_spec<pattern_t::ndim()> _get_hdf_slab_body(
468  const pattern_t& pattern,
470  const std::vector<dim_t> dimensions) {
471  using index_t = typename pattern_t::index_type;
472  constexpr auto ndim = pattern_t::ndim();
474  auto & ms = hs.memory;
475  auto & ts = hs.dataset;
476 
477  const auto & lblockspec = pattern.local_blockspec();
478 
479  // get the index of the start block of the current slab
480  // if local space is not empty
481  if (lblockspec.size() == 0) {
482  return hdf5_hyperslab_spec<ndim>();
483  }
484  std::array<index_t, ndim> coords{{0}};
485  index_t lblckidx;
486  for (auto d : dimensions) {
487  coords[d] = lblockspec.extent(d) - 1;
488  }
489  lblckidx = _blockspec_at(lblockspec, coords);
490 
491  hs.contrib_blocks = true;
492  // setup extends per dimension
493  for (int i = 0; i < ndim; ++i) {
494  auto tilesize = pattern.blocksize(i);
495  auto num_tiles = pattern.local_extent(i) / tilesize;
496 
497  // if the current dimension is in dimensions look at the undefilled blocks
498  if (std::find(dimensions.begin(), dimensions.end(), i) !=
499  dimensions.end()) {
500  // only look at underfilled blocks in this dimension
501  ts.count[i] = 1;
502  ts.block[i] = pattern.local_block(lblckidx).extent(i);
503  if (pattern.local_extent(i) == num_tiles * tilesize) {
504  // not underfilled on this unit
505  return hdf5_hyperslab_spec<ndim>();
506  }
507  } else {
508  // look at not undefilled blocks in this dimension
509  if (num_tiles == 0) {
510  // only underfilled blocks in this dimension
511  return hdf5_hyperslab_spec<ndim>();
512  }
513  ts.count[i] = num_tiles;
514  ts.block[i] = tilesize;
515  }
516  ts.offset[i] = pattern.local_block(lblckidx).offset(i);
517 
518  if (num_tiles > 1) {
519  ts.stride[i] = pattern.teamspec().extent(i) * ts.block[i];
520  } else {
521  ts.stride[i] = 1;
522  }
523 
524  ms.count[i] = ts.count[i];
525  ms.block[i] = ts.block[i];
526  ms.offset[i] = pattern.local_block_local(lblckidx).offset(i);
527  ms.stride[i] = tilesize;
528 
529  hs.data_extm[i] = pattern.local_extent(i);
530  hs.contrib_data *= ts.count[i] * ts.block[i];
531 
532  DASH_LOG_DEBUG("dimensions", dimensions);
533  DASH_LOG_DEBUG("ts.count", i, ts.count[i]);
534  DASH_LOG_DEBUG("ts.offset", i, ts.offset[i]);
535  DASH_LOG_DEBUG("ts.block", i, ts.block[i]);
536  DASH_LOG_DEBUG("ts.stride", i, ts.stride[i]);
537  DASH_LOG_DEBUG("ms.count", i, ms.count[i]);
538  DASH_LOG_DEBUG("ms.block", i, ms.block[i]);
539  DASH_LOG_DEBUG("ms.offset", i, ms.offset[i]);
540  DASH_LOG_DEBUG("ms.stride", i, ms.stride[i]);
541  }
542  hs.contrib_blocks = true;
543  return hs;
544  }
545 
550  template <typename PatternT>
551  const static inline std::vector<hdf5_hyperslab_spec<PatternT::ndim()>>
552  _get_hdf_slabs_with_underfilled(const PatternT& pattern) {
553  static constexpr auto ndim = PatternT::ndim();
554  std::vector<hdf5_hyperslab_spec<ndim>> specs_hyperslab;
555  std::vector<dim_t> dimensions;
556 
557  // iteration over powerset of {0, ..., ndim-1}
558  specs_hyperslab.push_back(_get_hdf_slab_body(pattern, dimensions));
559  // initialize dimensions so that it is equal to {0} in the first iteration
560  dimensions.push_back(-1);
561  while (dimensions.size() > 0) {
562  ++dimensions.back();
563  if (ndim == dimensions.back()) {
564  dimensions.pop_back();
565  continue;
566  } else if (pattern.underfilled_blocksize(dimensions.back()) == 0) {
567  continue;
568  } // else
569  auto& current_hs = _get_hdf_slab_body(pattern, dimensions);
570  if (current_hs.contrib_blocks) {
571  specs_hyperslab.push_back(current_hs);
572  }
573  dimensions.push_back(dimensions.back());
574  }
575 
576  return specs_hyperslab;
577  }
578 
583  template <dim_t ndim, MemArrange Arr, typename index_t>
584  const static inline std::vector<hdf5_hyperslab_spec<ndim>>
586  _get_hdf_slabs(const dash::Pattern<ndim, Arr, index_t>& pattern) {
587 
588  return _get_hdf_slabs_with_underfilled(pattern);
589  }
590 
595  template <dim_t ndim, MemArrange Arr, typename index_t>
596  const static inline std::vector<hdf5_hyperslab_spec<ndim>>
598  _get_hdf_slabs(const dash::TilePattern<ndim, Arr, index_t>& pattern) {
599 
600  return _get_hdf_slabs_with_underfilled(pattern);
601  }
602 
606  template <class pattern_t>
607  const static inline std::vector<hdf5_hyperslab_spec<pattern_t::ndim()>>
608  _get_hdf_slabs(const pattern_t& pattern) {
609 
610  return std::vector<hdf5_hyperslab_spec<pattern_t::ndim()>>(
611  1, _get_hdf_slab_body(pattern, {}));
612  }
613 
614  template <typename value_t>
615  const static inline hdf5_filespace_spec<1> _get_container_extents(
616  dash::Array<value_t>& array) {
618  fs.extent[0] = array.size();
619  return fs;
620  }
621 
622  template <class Container_t>
624  _get_container_extents(Container_t& container) {
625  constexpr auto ndim = Container_t::pattern_type::ndim();
627  for (int i = 0; i < ndim; ++i) {
628  fs.extent[i] = container.extent(i);
629  }
630  return fs;
631  }
632 
633 #if 0
634  // new implementation using view traits
635  template < typename ViewType >
637  _get_container_extents(ViewType & container){
638  constexpr auto ndim = dash::ndim(ViewType);
640  for(int i=0; i<ndim; ++i){
641  fs.extent[i] = dash::extent<i>(container);
642  }
643  return fs;
644  }
645 #endif
646 
647  template <dim_t ndim, typename value_t, typename index_t, typename pattern_t>
648  static inline void _verify_container_dims(
650  static_assert(ndim == pattern_t::ndim(),
651  "Pattern dimension has to match matrix dimension");
652  }
653  template <class Container_t>
654  static inline void _verify_container_dims(const Container_t& container) {
655  return;
656  }
657 
658  template <typename Container_t>
659  typename std::enable_if<
660  _is_origin_view<Container_t>(),
661  void>::type static _store_pattern(Container_t& container, hid_t h5dset,
662  hdf5_options& foptions) {
663  using pattern_t = typename Container_t::pattern_type;
664  using extent_t = typename pattern_t::size_type;
665  constexpr auto ndim = pattern_t::ndim();
666 
667  auto& pattern = container.pattern();
668 
669  auto pat_key = foptions.pattern_metadata_key.c_str();
670  extent_t pattern_spec[ndim * 4];
671 
672  // Delete old attribute when overwriting dataset
673  if (foptions.modify_dataset) {
674  H5Adelete(h5dset, pat_key);
675  }
676  // Structure is
677  // sizespec, teamspec, blockspec, blocksize
678  for (int i = 0; i < ndim; ++i) {
679  pattern_spec[i] = pattern.sizespec().extent(i);
680  pattern_spec[i + ndim] = pattern.teamspec().extent(i);
681  pattern_spec[i + (ndim * 2)] = pattern.blockspec().extent(i);
682  pattern_spec[i + (ndim * 3)] = pattern.blocksize(i);
683  }
684 
685  hsize_t attr_len[] = {static_cast<hsize_t>(ndim * 4)};
686  hid_t attrspace = H5Screate_simple(1, attr_len, NULL);
687  hid_t attribute_id = H5Acreate(h5dset, pat_key, H5T_NATIVE_LONG, attrspace,
688  H5P_DEFAULT, H5P_DEFAULT);
689  H5Awrite(attribute_id, H5T_NATIVE_LONG, &pattern_spec);
690  H5Aclose(attribute_id);
691  H5Sclose(attrspace);
692  }
693 
694  template <typename Container_t>
695  typename std::enable_if<
696  !_is_origin_view<Container_t>(),
697  void>::type static _store_pattern(Container_t& container, hid_t h5dset,
698  hdf5_options& foptions) {}
699 
700  template <typename Container_t>
701  typename std::enable_if<
702  _is_origin_view<Container_t>(),
703  void>::type static _restore_pattern(Container_t& container, hid_t h5dset,
704  hdf5_options& foptions) {
705  using pattern_t = typename Container_t::pattern_type;
706  using extent_t = typename pattern_t::size_type;
707  constexpr auto ndim = pattern_t::ndim();
708 
709  std::array<extent_t, ndim> size_extents;
710  std::array<extent_t, ndim> team_extents;
711  std::array<dash::Distribution, ndim> dist_extents;
712  extent_t hdf_dash_pattern[ndim * 4];
713 
714  hsize_t attr_len[] = {ndim * 4};
715  hid_t attrspace = H5Screate_simple(1, attr_len, NULL);
716  hid_t attribute_id =
717  H5Aopen(h5dset, foptions.pattern_metadata_key.c_str(), H5P_DEFAULT);
718 
719  H5Aread(attribute_id, H5T_NATIVE_LONG, hdf_dash_pattern);
720  H5Aclose(attribute_id);
721  H5Sclose(attrspace);
722 
723  for (int i = 0; i < ndim; ++i) {
724  size_extents[i] = static_cast<extent_t>(hdf_dash_pattern[i]);
725  team_extents[i] = static_cast<extent_t>(hdf_dash_pattern[i + ndim]);
726  dist_extents[i] = dash::TILE(hdf_dash_pattern[i + (ndim * 3)]);
727  }
728  DASH_LOG_DEBUG("Created pattern according to metadata");
729 
730  const pattern_t pattern(dash::SizeSpec<ndim, typename pattern_t::size_type>(size_extents),
731  dash::DistributionSpec<ndim>(dist_extents),
733  dash::Team::All());
734 
735  // Allocate DASH Matrix
736  container.allocate(pattern);
737  }
738 
739  template <typename Container_t>
740  typename std::enable_if<
741  !_is_origin_view<Container_t>(),
742  void>::type static _restore_pattern(Container_t& container, hid_t h5dset,
743  hdf5_options& foptions) {}
744 
745  // -------------------------------------------------------------------------
746  // ------------ write dataset implementation specialisations ---------------
747  // -------------------------------------------------------------------------
748 
755  template <class Container_t>
756  typename std::enable_if<
757  _is_origin_view<Container_t>() &&
758  _compatible_pattern<typename Container_t::pattern_type>(),
759  void>::type static _write_dataset_impl(Container_t& container,
760  const hid_t& h5dset,
761  const hid_t& internal_type) {
762  _process_dataset_impl_zero_copy(StoreHDF::Mode::WRITE, container, h5dset,
763  internal_type);
764  }
765 
772  template <class Container_t>
773  typename std::enable_if<
774  !(_is_origin_view<Container_t>() &&
775  _compatible_pattern<typename Container_t::pattern_type>()),
776  void>::type static _write_dataset_impl(Container_t& container,
777  const hid_t& h5dset,
778  const hid_t& internal_type) {
779  _write_dataset_impl_buffered(container, h5dset, internal_type);
780  }
781 
782  template <class Container_t>
783  static void _process_dataset_impl_zero_copy(StoreHDF::Mode io_mode,
784  Container_t& container,
785  const hid_t& h5dset,
786  const hid_t& internal_type);
787 
788  template <class Container_t>
789  static void _write_dataset_impl_buffered(Container_t& container,
790  const hid_t& h5dset,
791  const hid_t& internal_type);
792 
793  template <
794  typename ElementT,
795  typename PatternT,
796  dim_t NDim,
797  dim_t NViewDim,
798  typename LocalMemT>
799  static void _write_dataset_impl_nd_block(
801  const hid_t& h5dset,
802  const hid_t& internal_type);
803 
804  // --------------------------------------------------------------------------
805  // --------------------- READ specializations -------------------------------
806  // --------------------------------------------------------------------------
807 
814  template <class Container_t>
815  typename std::enable_if<
816  _compatible_pattern<typename Container_t::pattern_type>() &&
817  _is_origin_view<Container_t>(),
818  void>::type static inline _read_dataset_impl(Container_t& container,
819  const hid_t& h5dset,
820  const hid_t& internal_type) {
821  _process_dataset_impl_zero_copy(StoreHDF::Mode::READ, container, h5dset,
822  internal_type);
823  }
824 };
825 
826 } // namespace hdf5
827 } // namespace io
828 } // namespace dash
829 
830 #include <dash/io/hdf5/internal/DriverImplZeroCopy.h>
831 #include <dash/io/hdf5/internal/DriverImplBuffered.h>
832 #include <dash/io/hdf5/internal/DriverImplNdBlock.h>
833 
834 #include <dash/io/hdf5/internal/StorageDriver-inl.h>
835 
836 #endif // DASH_ENABLE_HDF5
837 
838 #endif // DASH__IO__HDF5__STORAGEDRIVER_H__
constexpr dim_t rank(const DimensionalType &d)
Definition: Dimensional.h:64
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 >)
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.
Defines how a list of global indices is mapped to single units within a Team.
Definition: BlockPattern.h:42
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
bool modify_dataset
Modify an already existing HDF5 dataset.
Definition: StorageDriver.h:63
Signals success.
Definition: dart_types.h:33
Specifies cartesian extents in a specific number of dimensions.
Definition: Cartesian.h:197
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
Definition: Types.h:39
Stream manipulator class to set whether the selected dataset should be overwritten.
Definition: IOManip.h:72
Defines how a list of global indices is mapped to single units within a Team.
Definition: TilePattern.h:47
bool overwrite_file
Overwrite HDF5 file if already existing.
Definition: StorageDriver.h:58
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
std::string pattern_metadata_key
Metadata attribute key in HDF5 file.
Definition: StorageDriver.h:69
hdf5 pattern specification for parallel IO
A Team instance specifies a subset of all available units.
Definition: Team.h:41
View type traits.
Definition: ViewTraits.h:31
A set of utility routines used to provide parallel io support.
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
Stream manipulator class to set whether the pattern should be stored as metadata of the hdf5 dataset ...
Definition: IOManip.h:58
A distributed array.
Definition: Array.h:89
Stream manipulator class to specify the hdf5 dataset.
Definition: IOManip.h:20
constexpr size_type size() const noexcept
The size of the array.
Definition: Array.h:1173
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...
dart_ret_t dart__io__hdf5__prep_mpio(hid_t plist_id, dart_team_t teamid)
setup hdf5 for parallel io using mpi-io
DASH wrapper to store an dash::Array or dash::Matrix in an HDF5 file using parallel IO...
Definition: StorageDriver.h:77
GlobIter find(GlobIter first, GlobIter last, const ElementType &value)
Returns an iterator to the first element in the range [first,last) that compares equal to val...
Definition: Find.h:22
Stream manipulator class to set whether the pattern should be restored from the hdf5 dataset metadata...
Definition: IOManip.h:45
Forward-declaration.
constexpr DimensionalType::extent_type extent(const DimensionalType &d)
Definition: Dimensional.h:73
Shared access to a value in global memory across a team.
Definition: Shared.h:23
hdf5 pattern specification for parallel IO
static Team & All()
The invariant Team instance containing all available units.
Definition: Team.h:213
Options which can be passed to dash::io::StoreHDF::write to specify how existing structures are treat...
Definition: StorageDriver.h:56
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
DistributionSpec describes distribution patterns of all dimensions,.
Definition: Dimensional.h:222
Forward-declaration.
constexpr auto block(OffsetT block_idx, const ViewType &view) -> typename std::enable_if<(!dash::view_traits< ViewType >::is_local::value), ViewBlockMod< ViewType > >::type
Blocks view from global view.
Definition: Chunked.h:49