OpenGM  2.3.x
Discrete Graphical Model Library
marray_hdf5.hxx
Go to the documentation of this file.
1 #pragma once
2 #ifndef MARRAY_HDF5_HXX
3 #define MARRAY_HDF5_HXX
4 
5 // compat fix for buggy hdf5 1.8 versions
6 #include <H5version.h>
7 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR >= 8 && defined(H5_USE_16_API_DEFAULT))
8 #define H5Gcreate_vers 2
9 #define H5Gopen_vers 2
10 #define H5Dopen_vers 2
11 #define H5Dcreate_vers 2
12 #define H5Acreate_vers 2
13 #endif
14 
15 #include <cstring>
16 
17 #include "marray.hxx"
18 #include "hdf5.h"
19 
20 namespace marray {
22 namespace hdf5 {
23 
24 // assertion testing
25 
26 // \cond suppress doxygen
27 template<bool B> class HandleCheck;
28 template<> class HandleCheck<false> {
29 public:
30  HandleCheck()
31  { counter_ = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL); }
32  void check()
33  { marray_detail::Assert( counter_ == H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL)); }
34 private:
35  ssize_t counter_;
36 };
37 template<> class HandleCheck<true> {
38 public:
39  void check() {}
40 };
41 // \endcond
42 
43 // namespace variables
44 
45 const char reverseShapeAttributeName[14] = "reverse-shape";
46 
47 // prototypes
48 
51 
52 inline hid_t createFile(const std::string&, HDF5Version = DEFAULT_HDF5_VERSION);
53 inline hid_t openFile(const std::string&, FileAccessMode = READ_ONLY, HDF5Version = DEFAULT_HDF5_VERSION);
54 inline void closeFile(const hid_t&);
55 
56 inline hid_t createGroup(const hid_t&, const std::string&);
57 inline hid_t openGroup(const hid_t&, const std::string&);
58 inline void closeGroup(const hid_t&);
59 
60 template<class T>
61  void save(const hid_t&, const std::string&, const Marray<T>&);
62 template<class T, bool isConst>
63  void save(const hid_t&, const std::string&, const View<T, isConst>&);
64 template<class T>
65  void save(const hid_t&, const std::string&, const std::vector<T>&);
66 template<class T, class BaseIterator, class ShapeIterator>
67  void saveHyperslab(const hid_t&, const std::string&,
68  BaseIterator, BaseIterator, ShapeIterator, const Marray<T>&);
69 template<class T, class ShapeIterator>
70  void create(const hid_t&, const std::string&, ShapeIterator,
71  ShapeIterator, CoordinateOrder);
72 
73 template<class T>
74  void load(const hid_t&, const std::string&, Marray<T>&);
75 template<class T>
76  void loadShape(const hid_t&, const std::string&, Vector<T>&);
77 template<class T, class BaseIterator, class ShapeIterator>
78  void loadHyperslab(const hid_t&, const std::string&,
79  BaseIterator, BaseIterator, ShapeIterator, Marray<T>&);
80 
81 // type conversion from C++ to HDF5
82 
83 // \cond suppress doxygen
84 template<class T>
85 inline hid_t uintTypeHelper() {
86  switch(sizeof(T)) {
87  case 1:
88  return H5T_STD_U8LE;
89  case 2:
90  return H5T_STD_U16LE;
91  case 4:
92  return H5T_STD_U32LE;
93  case 8:
94  return H5T_STD_U64LE;
95  default:
96  throw std::runtime_error("No matching HDF5 type.");
97  }
98 }
99 
100 template<class T>
101 inline hid_t intTypeHelper() {
102  switch(sizeof(T)) {
103  case 1:
104  return H5T_STD_I8LE;
105  case 2:
106  return H5T_STD_I16LE;
107  case 4:
108  return H5T_STD_I32LE;
109  case 8:
110  return H5T_STD_I64LE;
111  default:
112  throw std::runtime_error("No matching HDF5 type.");
113  }
114 }
115 
116 template<class T>
117 inline hid_t floatingTypeHelper() {
118  switch(sizeof(T)) {
119  case 4:
120  return H5T_IEEE_F32LE;
121  case 8:
122  return H5T_IEEE_F64LE;
123  default:
124  throw std::runtime_error("No matching HDF5 type.");
125  }
126 }
127 
128 template<class T>
129 inline hid_t hdf5Type();
130 
131 template<> inline hid_t hdf5Type<unsigned char>()
132  { return uintTypeHelper<unsigned char>(); }
133 template<> inline hid_t hdf5Type<unsigned short>()
134  { return uintTypeHelper<unsigned short>(); }
135 template<> inline hid_t hdf5Type<unsigned int>()
136  { return uintTypeHelper<unsigned int>(); }
137 template<> inline hid_t hdf5Type<unsigned long>()
138  { return uintTypeHelper<unsigned long>(); }
139 template<> inline hid_t hdf5Type<unsigned long long>()
140  { return uintTypeHelper<unsigned long long>(); }
141 
142 template<> inline hid_t hdf5Type<char>()
143  { return uintTypeHelper<char>(); }
144 template<> inline hid_t hdf5Type<signed char>()
145  { return intTypeHelper<signed char>(); }
146 template<> inline hid_t hdf5Type<short>()
147  { return intTypeHelper<short>(); }
148 template<> inline hid_t hdf5Type<int>()
149  { return intTypeHelper<int>(); }
150 template<> inline hid_t hdf5Type<long>()
151  { return intTypeHelper<long>(); }
152 template<> inline hid_t hdf5Type<long long>()
153  { return intTypeHelper<long long>(); }
154 
155 template<> inline hid_t hdf5Type<float>()
156  { return floatingTypeHelper<float>(); }
157 template<> inline hid_t hdf5Type<double>()
158  { return floatingTypeHelper<double>(); }
159 // \endcond
160 
161 // implementation
162 
173 template<class T, class ShapeIterator>
174 void create(
175  const hid_t& groupHandle,
176  const std::string& datasetName,
177  ShapeIterator begin,
178  ShapeIterator end,
179  CoordinateOrder coordinateOrder
180 ) {
181  marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
182  HandleCheck<MARRAY_NO_DEBUG> handleCheck;
183 
184  // build dataspace
185  hid_t datatype = H5Tcopy(hdf5Type<T>());
186  size_t dimension = std::distance(begin, end);
187  Vector<hsize_t> shape((size_t)(dimension));
188  if(coordinateOrder == FirstMajorOrder) {
189  // copy shape as is
190  for(size_t j=0; j<dimension; ++j) {
191  shape[j] = hsize_t(*begin);
192  ++begin;
193  }
194  }
195  else {
196  // reverse shape
197  for(size_t j=0; j<dimension; ++j) {
198  shape[dimension-j-1] = hsize_t(*begin);
199  ++begin;
200  }
201  }
202  hid_t dataspace = H5Screate_simple(dimension, &shape[0], NULL);
203  if(dataspace < 0) {
204  H5Tclose(datatype);
205  throw std::runtime_error("Marray cannot create dataspace.");
206  }
207 
208 
209  // create new dataset
210  hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
211  dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
212  if(dataset < 0) {
213  H5Sclose(dataspace);
214  H5Tclose(datatype);
215  throw std::runtime_error("Marray cannot create dataset.");
216  }
217 
218  // write attribute to indicate whether shape is reversed
219  if(coordinateOrder == LastMajorOrder) {
220  hsize_t attributeShape[1] = {1};
221  hid_t attributeDataspace = H5Screate_simple(1, attributeShape, NULL);
222  if(attributeDataspace < 0) {
223  H5Dclose(dataset);
224  H5Sclose(dataspace);
225  H5Tclose(datatype);
226  throw std::runtime_error("Marray cannot create dataspace.");
227  }
228  hid_t attribute = H5Acreate(dataset, reverseShapeAttributeName,
229  H5T_STD_U8LE, attributeDataspace, H5P_DEFAULT, H5P_DEFAULT);
230  if(attribute < 0) {
231  H5Sclose(attributeDataspace);
232  H5Dclose(dataset);
233  H5Sclose(dataspace);
234  H5Tclose(datatype);
235  throw std::runtime_error("Marray cannot create attribute.");
236  }
237  unsigned int data = 1;
238  herr_t err = H5Awrite(attribute, H5T_STD_U8LE, &data);
239  H5Aclose(attribute);
240  H5Sclose(attributeDataspace);
241  if(err < 0) {
242  H5Dclose(dataset);
243  H5Sclose(dataspace);
244  H5Tclose(datatype);
245  throw std::runtime_error("Marray cannot create write to attribute.");
246  }
247  }
248 
249  // clean up
250  H5Dclose(dataset);
251  H5Sclose(dataspace);
252  H5Tclose(datatype);
253  handleCheck.check();
254 }
255 
264 template<class T>
265 void save(
266  const hid_t& groupHandle,
267  const std::string& datasetName,
268  const Marray<T>& in
269 ) {
270  marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
271  HandleCheck<MARRAY_NO_DEBUG> handleCheck;
272 
273  // build dataspace
274  hid_t datatype = H5Tcopy(hdf5Type<T>());
275  Vector<hsize_t> shape(in.dimension());
276  if(in.coordinateOrder() == FirstMajorOrder) {
277  // copy shape as is
278  for(size_t j=0; j<in.dimension(); ++j) {
279  shape[j] = hsize_t(in.shape(j));
280  }
281  }
282  else {
283  // reverse shape
284  for(size_t j=0; j<in.dimension(); ++j) {
285  shape[size_t(in.dimension()-j-1)] = hsize_t(in.shape(j));
286  }
287  }
288  hid_t dataspace = H5Screate_simple(in.dimension(), &shape[0], NULL);
289  if(dataspace < 0) {
290  H5Tclose(datatype);
291  throw std::runtime_error("Marray cannot create dataspace.");
292  }
293 
294  // create new dataset
295  hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
296  dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
297  if(dataset < 0) {
298  H5Sclose(dataspace);
299  H5Tclose(datatype);
300  throw std::runtime_error("Marray cannot create dataset.");
301  }
302 
303  // write attribute to indicate whether shape is reversed
304  if(in.coordinateOrder() == LastMajorOrder) {
305  hsize_t attributeShape[1] = {1};
306  hid_t attributeDataspace = H5Screate_simple(1, attributeShape, NULL);
307  if(attributeDataspace < 0) {
308  H5Dclose(dataset);
309  H5Sclose(dataspace);
310  H5Tclose(datatype);
311  throw std::runtime_error("Marray cannot create dataspace.");
312  }
313  hid_t attribute = H5Acreate(dataset, reverseShapeAttributeName,
314  H5T_STD_U8LE, attributeDataspace, H5P_DEFAULT, H5P_DEFAULT);
315  if(attribute < 0) {
316  H5Sclose(attributeDataspace);
317  H5Dclose(dataset);
318  H5Sclose(dataspace);
319  H5Tclose(datatype);
320  throw std::runtime_error("Marray cannot create attribute.");
321  }
322  unsigned int data = 1;
323  herr_t err = H5Awrite(attribute, H5T_STD_U8LE, &data);
324  H5Aclose(attribute);
325  H5Sclose(attributeDataspace);
326  if(err < 0) {
327  H5Dclose(dataset);
328  H5Sclose(dataspace);
329  H5Tclose(datatype);
330  throw std::runtime_error("Marray cannot create write to attribute.");
331  }
332  }
333 
334  // write
335  herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL,
336  H5P_DEFAULT, &in(0));
337  H5Dclose(dataset);
338  H5Sclose(dataspace);
339  H5Tclose(datatype);
340  if(status < 0) {
341  throw std::runtime_error("Marray cannot write to dataset.");
342  }
343 
344  handleCheck.check();
345 }
346 
355 template<class T, bool isConst>
356 inline void save(
357  const hid_t& groupHandle,
358  const std::string& datasetName,
359  const View<T, isConst>& in
360 ) {
361  Marray<T> m = in;
362  save(groupHandle, datasetName, m);
363 }
364 
373 template<class T>
374 void save(
375  const hid_t& groupHandle,
376  const std::string& datasetName,
377  const std::vector<T>& in
378 )
379 {
380  marray::Vector<T> v(in.size());
381  for(size_t j=0; j<in.size(); ++j) {
382  v[j] = in[j];
383  }
384  save(groupHandle, datasetName, v);
385 }
386 
395 template<class T>
396 void load(
397  const hid_t& groupHandle,
398  const std::string& datasetName,
399  Marray<T>& out
400 ) {
401  marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
402  HandleCheck<MARRAY_NO_DEBUG> handleCheck;
403 
404  hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
405  if(dataset < 0) {
406  throw std::runtime_error("Marray cannot open dataset.");
407  }
408  hid_t filespace = H5Dget_space(dataset);
409  hid_t type = H5Dget_type(dataset);
410  hid_t nativeType = H5Tget_native_type(type, H5T_DIR_DESCEND);
411  if(!H5Tequal(nativeType, hdf5Type<T>())) {
412  H5Dclose(dataset);
413  H5Tclose(nativeType);
414  H5Tclose(type);
415  H5Sclose(filespace);
416  throw std::runtime_error("Data types not equal error.");
417  }
418  int dimension = H5Sget_simple_extent_ndims(filespace);
419  Vector<hsize_t> shape(dimension);
420  herr_t status = H5Sget_simple_extent_dims(filespace, &shape[0], NULL);
421  if(status < 0) {
422  H5Dclose(dataset);
423  H5Tclose(nativeType);
424  H5Tclose(type);
425  H5Sclose(filespace);
426  throw std::runtime_error("H5Sget_simple_extent_dims error.");
427  }
428  hid_t memspace = H5Screate_simple(dimension, &shape[0], NULL);
429 
430  // resize marray
431  marray::Vector<size_t> newShape((size_t)(dimension));
432  for(size_t j=0; j<newShape.size(); ++j) {
433  newShape(j) = (size_t)(shape[j]);
434  }
435  if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
436  // reverse shape
437  out = Marray<T>(SkipInitialization, newShape.rbegin(),
438  newShape.rend(), LastMajorOrder);
439  }
440  else {
441  // don't reverse shape
442  out = Marray<T>(SkipInitialization, newShape.begin(),
443  newShape.end(), FirstMajorOrder);
444  }
445 
446  // read
447  status = H5Dread(dataset, nativeType, memspace, filespace,
448  H5P_DEFAULT, &out(0));
449  H5Dclose(dataset);
450  H5Tclose(nativeType);
451  H5Tclose(type);
452  H5Sclose(memspace);
453  H5Sclose(filespace);
454  if(status < 0) {
455  throw std::runtime_error("Marray cannot read from dataset.");
456  }
457 
458  handleCheck.check();
459 }
460 
469 template<class T>
471  const hid_t& groupHandle,
472  const std::string& datasetName,
473  Vector<T>& out
474 ) {
475  marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
476  HandleCheck<MARRAY_NO_DEBUG> handleCheck;
477 
478  // load shape from HDF5 file
479  hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
480  if(dataset < 0) {
481  throw std::runtime_error("Marray cannot open dataset.");
482  }
483  hid_t filespace = H5Dget_space(dataset);
484  hsize_t dimension = H5Sget_simple_extent_ndims(filespace);
485  hsize_t* shape = new hsize_t[(size_t)(dimension)];
486  herr_t status = H5Sget_simple_extent_dims(filespace, shape, NULL);
487  if(status < 0) {
488  H5Dclose(dataset);
489  H5Sclose(filespace);
490  delete[] shape;
491  throw std::runtime_error("Marray cannot get extension of dataset.");
492  }
493 
494  // write shape to out
495  out = Vector<T>((size_t)(dimension));
496  if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
497  for(size_t j=0; j<out.size(); ++j) {
498  out[out.size()-j-1] = T(shape[j]);
499  }
500  }
501  else {
502  for(size_t j=0; j<out.size(); ++j) {
503  out[j] = T(shape[j]);
504  }
505  }
506 
507  // clean up
508  delete[] shape;
509  H5Dclose(dataset);
510  H5Sclose(filespace);
511  handleCheck.check();
512 }
513 
525 template<class T, class BaseIterator, class ShapeIterator>
527  const hid_t& groupHandle,
528  const std::string& datasetName,
529  BaseIterator baseBegin,
530  BaseIterator baseEnd,
531  ShapeIterator shapeBegin,
532  Marray<T>& out
533 ) {
534  marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
535  HandleCheck<MARRAY_NO_DEBUG> handleCheck;
536 
537  // open dataset
538  hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
539  if(dataset < 0) {
540  throw std::runtime_error("Marray cannot open dataset.");
541  }
542 
543  // determine shape of hyperslab and array
544  size_t size = std::distance(baseBegin, baseEnd);
545  Vector<hsize_t> offset(size);
546  Vector<hsize_t> slabShape(size);
547  Vector<hsize_t> marrayShape(size);
548  CoordinateOrder coordinateOrder;
549  if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
550  // reverse base and shape
551  coordinateOrder = LastMajorOrder;
552  size_t j = size-1;
553  size_t k = 0;
554  for(;;) {
555  offset[j] = hsize_t(*baseBegin);
556  slabShape[j] = hsize_t(*shapeBegin);
557  marrayShape[k] = slabShape[j];
558  if(j == 0) {
559  break;
560  }
561  else {
562  ++baseBegin;
563  ++shapeBegin;
564  ++k;
565  --j;
566  }
567  }
568  }
569  else {
570  // don't reverse base and shape
571  coordinateOrder = FirstMajorOrder;
572  for(size_t j=0; j<size; ++j) {
573  offset[j] = hsize_t(*baseBegin);
574  slabShape[j] = hsize_t(*shapeBegin);
575  marrayShape[j] = slabShape[j];
576  ++baseBegin;
577  ++shapeBegin;
578  }
579  }
580 
581  // select dataspace hyperslab
582  hid_t datatype = H5Dget_type(dataset);
583 
584  if(!H5Tequal(datatype, hdf5Type<T>())) {
585  throw std::runtime_error("data type of stored hdf5 dataset and passed array do not match in loadHyperslab");
586  }
587 
588  hid_t dataspace = H5Dget_space(dataset);
589  herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
590  &offset[0], NULL, &slabShape[0], NULL);
591  if(status < 0) {
592  H5Tclose(datatype);
593  H5Sclose(dataspace);
594  H5Dclose(dataset);
595  throw std::runtime_error("Marray cannot select hyperslab. Check offset and shape!");
596  }
597 
598  // select memspace hyperslab
599  hid_t memspace = H5Screate_simple(int(size), &marrayShape[0], NULL);
600  Vector<hsize_t> offsetOut(size, 0); // no offset
601  status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &offsetOut[0],
602  NULL, &marrayShape[0], NULL);
603  if(status < 0) {
604  H5Sclose(memspace);
605  H5Tclose(datatype);
606  H5Sclose(dataspace);
607  H5Dclose(dataset);
608  throw std::runtime_error("Marray cannot select hyperslab. Check offset and shape!");
609  }
610 
611  // read from dataspace into memspace
612  out = Marray<T>(SkipInitialization, &marrayShape[0],
613  (&marrayShape[0])+size, coordinateOrder);
614  status = H5Dread(dataset, datatype, memspace, dataspace,
615  H5P_DEFAULT, &(out(0)));
616 
617  // clean up
618  H5Sclose(memspace);
619  H5Tclose(datatype);
620  H5Sclose(dataspace);
621  H5Dclose(dataset);
622  if(status < 0) {
623  throw std::runtime_error("Marray cannot read from dataset.");
624  }
625  handleCheck.check();
626 }
627 
639 template<class T, class BaseIterator, class ShapeIterator>
640 void
642  const hid_t& groupHandle,
643  const std::string& datasetName,
644  BaseIterator baseBegin,
645  BaseIterator baseEnd,
646  ShapeIterator shapeBegin,
647  const Marray<T>& in
648 ) {
649  marray_detail::Assert(MARRAY_NO_ARG_TEST || groupHandle >= 0);
650  HandleCheck<MARRAY_NO_DEBUG> handleCheck;
651 
652  // open dataset
653  hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
654  if(dataset < 0) {
655  throw std::runtime_error("Marray cannot open dataset.");
656  }
657 
658  // determine hyperslab shape
659  Vector<hsize_t> memoryShape(in.dimension());
660  for(size_t j=0; j<in.dimension(); ++j) {
661  memoryShape[j] = in.shape(j);
662  }
663  size_t size = std::distance(baseBegin, baseEnd);
664  Vector<hsize_t> offset(size);
665  Vector<hsize_t> slabShape(size);
666  bool reverseShapeAttribute =
667  (H5Aexists(dataset, reverseShapeAttributeName) > 0);
668  if(reverseShapeAttribute && in.coordinateOrder() == LastMajorOrder) {
669  // reverse base and shape
670  size_t j = size-1;
671  for(;;) {
672  offset[j] = hsize_t(*baseBegin);
673  slabShape[j] = hsize_t(*shapeBegin);
674  if(j == 0) {
675  break;
676  }
677  else {
678  ++baseBegin;
679  ++shapeBegin;
680  --j;
681  }
682  }
683  }
684  else if(!reverseShapeAttribute && in.coordinateOrder() == FirstMajorOrder) {
685  for(size_t j=0; j<size; ++j) {
686  offset[j] = hsize_t(*baseBegin);
687  slabShape[j] = hsize_t(*shapeBegin);
688  ++baseBegin;
689  ++shapeBegin;
690  }
691  }
692  else {
693  H5Dclose(dataset);
694  throw std::runtime_error("Marray cannot write to HDF5 file. A different order was used when the file was created.");
695  }
696 
697  // select dataspace hyperslab
698  hid_t datatype = H5Dget_type(dataset);
699  hid_t dataspace = H5Dget_space(dataset);
700  herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
701  &offset[0], NULL, &slabShape[0], NULL);
702  if(status < 0) {
703  H5Tclose(datatype);
704  H5Sclose(dataspace);
705  H5Dclose(dataset);
706  throw std::runtime_error("Marray cannot select hyperslab. Check offset and shape!");
707  }
708 
709  // select memspace hyperslab
710  hid_t memspace = H5Screate_simple(int(in.dimension()), &memoryShape[0], NULL);
711  Vector<hsize_t> memoryOffset(int(in.dimension()), 0); // no offset
712  status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &memoryOffset[0], NULL,
713  &memoryShape[0], NULL);
714  if(status < 0) {
715  H5Sclose(memspace);
716  H5Tclose(datatype);
717  H5Sclose(dataspace);
718  H5Dclose(dataset);
719  throw std::runtime_error("Marray cannot select hyperslab. Check offset and shape!");
720  }
721 
722  // write from memspace to dataspace
723  status = H5Dwrite(dataset, datatype, memspace, dataspace, H5P_DEFAULT, &(in(0)));
724 
725  // clean up
726  H5Sclose(memspace);
727  H5Tclose(datatype);
728  H5Sclose(dataspace);
729  H5Dclose(dataset);
730  if(status < 0) {
731  throw std::runtime_error("Marray cannot write to dataset.");
732  }
733  handleCheck.check();
734 }
735 
745 inline hid_t
747 (
748  const std::string& filename,
749  HDF5Version hdf5version
750 )
751 {
752  hid_t version = H5P_DEFAULT;
753  if(hdf5version == LATEST_HDF5_VERSION) {
754  version = H5Pcreate(H5P_FILE_ACCESS);
755  H5Pset_libver_bounds(version, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
756  }
757 
758  hid_t fileHandle = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, version);
759  if(fileHandle < 0) {
760  throw std::runtime_error("Could not create HDF5 file: " + filename);
761  }
762 
763  return fileHandle;
764 }
765 
776 inline hid_t
777 openFile
778 (
779  const std::string& filename,
780  FileAccessMode fileAccessMode,
781  HDF5Version hdf5version
782 )
783 {
784  hid_t access = H5F_ACC_RDONLY;
785  if(fileAccessMode == READ_WRITE) {
786  access = H5F_ACC_RDWR;
787  }
788 
789  hid_t version = H5P_DEFAULT;
790  if(hdf5version == LATEST_HDF5_VERSION) {
791  version = H5Pcreate(H5P_FILE_ACCESS);
792  H5Pset_libver_bounds(version, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
793  }
794 
795  hid_t fileHandle = H5Fopen(filename.c_str(), access, version);
796  if(fileHandle < 0) {
797  throw std::runtime_error("Could not open HDF5 file: " + filename);
798  }
799 
800  return fileHandle;
801 }
802 
809 inline void closeFile
810 (
811  const hid_t& handle
812 )
813 {
814  H5Fclose(handle);
815 }
816 
825 inline hid_t
827 (
828  const hid_t& parentHandle,
829  const std::string& groupName
830 )
831 {
832  hid_t groupHandle = H5Gcreate(parentHandle, groupName.c_str(),
833  H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
834  if(groupHandle < 0) {
835  throw std::runtime_error("Could not create HDF5 group.");
836  }
837  return groupHandle;
838 }
839 
848 inline hid_t
849 openGroup
850 (
851  const hid_t& parentHandle,
852  const std::string& groupName
853 )
854 {
855  hid_t groupHandle = H5Gopen(parentHandle, groupName.c_str(), H5P_DEFAULT);
856  if(groupHandle < 0) {
857  throw std::runtime_error("Could not open HDF5 group.");
858  }
859  return groupHandle;
860 }
861 
868 inline void
870 (
871  const hid_t& handle
872 )
873 {
874  H5Gclose(handle);
875 }
876 
877 } // namespace hdf5
878 } // namespace marray
879 
880 #endif // #ifndef MARRAY_HDF5_HXX
881 
hid_t createFile(const std::string &, HDF5Version=DEFAULT_HDF5_VERSION)
Create an HDF5 file.
const char reverseShapeAttributeName[14]
Definition: marray_hdf5.hxx:45
Runtime-flexible multi-dimensional views and arrays.
Definition: marray.hxx:20
const size_t shape(const size_t) const
Get the shape in one dimension.
Definition: marray.hxx:1725
reverse_iterator rbegin()
Array-Interface to an interval of memory.
Definition: marray.hxx:44
void create(const hid_t &, const std::string &, ShapeIterator, ShapeIterator, CoordinateOrder)
Create and close an HDF5 dataset to store Marray data.
hid_t createGroup(const hid_t &, const std::string &)
Create an HDF5 group.
void load(const hid_t &, const std::string &, Marray< T > &)
Load an Marray from an HDF5 dataset.
One-dimensional Marray.
Definition: marray.hxx:50
const size_t dimension() const
Get the dimension.
Definition: marray.hxx:1711
void loadHyperslab(const hid_t &, const std::string &, BaseIterator, BaseIterator, ShapeIterator, Marray< T > &)
Load a hyperslab from an HDF5 dataset into an Marray.
const bool MARRAY_NO_ARG_TEST
Argument testing enabled.
Definition: marray.hxx:60
void loadShape(const hid_t &, const std::string &, Vector< T > &)
Load the shape of an HDF5 dataset.
CoordinateOrder
Definition: marray.hxx:23
const size_t size() const
void closeFile(const hid_t &)
Close an HDF5 file.
void save(const hid_t &, const std::string &, const Marray< T > &)
Save an Marray as an HDF5 dataset.
void closeGroup(const hid_t &)
Close an HDF5 group.
reverse_iterator rend()
static const InitializationSkipping SkipInitialization
Flag to indicate initialization skipping.
Definition: marray.hxx:29
void saveHyperslab(const hid_t &, const std::string &, BaseIterator, BaseIterator, ShapeIterator, const Marray< T > &)
Save an Marray as a hyperslab into an HDF5 dataset.
const CoordinateOrder & coordinateOrder() const
Get the coordinate order used for scalar indexing and iterators.
Definition: marray.hxx:1815
hid_t openFile(const std::string &, FileAccessMode=READ_ONLY, HDF5Version=DEFAULT_HDF5_VERSION)
Open an HDF5 file.
hid_t openGroup(const hid_t &, const std::string &)
Open an HDF5 group.