2 #ifndef MARRAY_HDF5_HXX
3 #define MARRAY_HDF5_HXX
7 #if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR >= 8 && defined(H5_USE_16_API_DEFAULT))
8 #define H5Gcreate_vers 2
10 #define H5Dopen_vers 2
11 #define H5Dcreate_vers 2
12 #define H5Acreate_vers 2
27 template<
bool B>
class HandleCheck;
28 template<>
class HandleCheck<false> {
31 { counter_ = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL); }
33 { marray_detail::Assert( counter_ == H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL)); }
37 template<>
class HandleCheck<true> {
56 inline hid_t
createGroup(
const hid_t&,
const std::string&);
57 inline hid_t
openGroup(
const hid_t&,
const std::string&);
61 void save(
const hid_t&,
const std::string&,
const Marray<T>&);
62 template<
class T,
bool isConst>
65 void save(
const hid_t&,
const std::string&,
const std::vector<T>&);
66 template<
class T,
class BaseIterator,
class ShapeIterator>
68 BaseIterator, BaseIterator, ShapeIterator,
const Marray<T>&);
69 template<
class T,
class ShapeIterator>
70 void create(
const hid_t&,
const std::string&, ShapeIterator,
77 template<
class T,
class BaseIterator,
class ShapeIterator>
79 BaseIterator, BaseIterator, ShapeIterator,
Marray<T>&);
85 inline hid_t uintTypeHelper() {
96 throw std::runtime_error(
"No matching HDF5 type.");
101 inline hid_t intTypeHelper() {
106 return H5T_STD_I16LE;
108 return H5T_STD_I32LE;
110 return H5T_STD_I64LE;
112 throw std::runtime_error(
"No matching HDF5 type.");
117 inline hid_t floatingTypeHelper() {
120 return H5T_IEEE_F32LE;
122 return H5T_IEEE_F64LE;
124 throw std::runtime_error(
"No matching HDF5 type.");
129 inline hid_t hdf5Type();
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>(); }
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>(); }
155 template<>
inline hid_t hdf5Type<float>()
156 {
return floatingTypeHelper<float>(); }
157 template<>
inline hid_t hdf5Type<double>()
158 {
return floatingTypeHelper<double>(); }
173 template<
class T,
class ShapeIterator>
175 const hid_t& groupHandle,
176 const std::string& datasetName,
182 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
185 hid_t datatype = H5Tcopy(hdf5Type<T>());
186 size_t dimension = std::distance(begin, end);
190 for(
size_t j=0; j<dimension; ++j) {
191 shape[j] = hsize_t(*begin);
197 for(
size_t j=0; j<dimension; ++j) {
198 shape[dimension-j-1] = hsize_t(*begin);
202 hid_t dataspace = H5Screate_simple(dimension, &shape[0], NULL);
205 throw std::runtime_error(
"Marray cannot create dataspace.");
210 hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
211 dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
215 throw std::runtime_error(
"Marray cannot create dataset.");
220 hsize_t attributeShape[1] = {1};
221 hid_t attributeDataspace = H5Screate_simple(1, attributeShape, NULL);
222 if(attributeDataspace < 0) {
226 throw std::runtime_error(
"Marray cannot create dataspace.");
228 hid_t attribute = H5Acreate(dataset, reverseShapeAttributeName,
229 H5T_STD_U8LE, attributeDataspace, H5P_DEFAULT, H5P_DEFAULT);
231 H5Sclose(attributeDataspace);
235 throw std::runtime_error(
"Marray cannot create attribute.");
237 unsigned int data = 1;
238 herr_t err = H5Awrite(attribute, H5T_STD_U8LE, &data);
240 H5Sclose(attributeDataspace);
245 throw std::runtime_error(
"Marray cannot create write to attribute.");
266 const hid_t& groupHandle,
267 const std::string& datasetName,
271 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
274 hid_t datatype = H5Tcopy(hdf5Type<T>());
279 shape[j] = hsize_t(in.
shape(j));
288 hid_t dataspace = H5Screate_simple(in.
dimension(), &shape[0], NULL);
291 throw std::runtime_error(
"Marray cannot create dataspace.");
295 hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
296 dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
300 throw std::runtime_error(
"Marray cannot create dataset.");
305 hsize_t attributeShape[1] = {1};
306 hid_t attributeDataspace = H5Screate_simple(1, attributeShape, NULL);
307 if(attributeDataspace < 0) {
311 throw std::runtime_error(
"Marray cannot create dataspace.");
313 hid_t attribute = H5Acreate(dataset, reverseShapeAttributeName,
314 H5T_STD_U8LE, attributeDataspace, H5P_DEFAULT, H5P_DEFAULT);
316 H5Sclose(attributeDataspace);
320 throw std::runtime_error(
"Marray cannot create attribute.");
322 unsigned int data = 1;
323 herr_t err = H5Awrite(attribute, H5T_STD_U8LE, &data);
325 H5Sclose(attributeDataspace);
330 throw std::runtime_error(
"Marray cannot create write to attribute.");
335 herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL,
336 H5P_DEFAULT, &in(0));
341 throw std::runtime_error(
"Marray cannot write to dataset.");
355 template<
class T,
bool isConst>
357 const hid_t& groupHandle,
358 const std::string& datasetName,
362 save(groupHandle, datasetName, m);
375 const hid_t& groupHandle,
376 const std::string& datasetName,
377 const std::vector<T>& in
381 for(
size_t j=0; j<in.size(); ++j) {
384 save(groupHandle, datasetName, v);
397 const hid_t& groupHandle,
398 const std::string& datasetName,
402 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
404 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
406 throw std::runtime_error(
"Marray cannot open dataset.");
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>())) {
413 H5Tclose(nativeType);
416 throw std::runtime_error(
"Data types not equal error.");
418 int dimension = H5Sget_simple_extent_ndims(filespace);
420 herr_t status = H5Sget_simple_extent_dims(filespace, &shape[0], NULL);
423 H5Tclose(nativeType);
426 throw std::runtime_error(
"H5Sget_simple_extent_dims error.");
428 hid_t memspace = H5Screate_simple(dimension, &shape[0], NULL);
432 for(
size_t j=0; j<newShape.
size(); ++j) {
433 newShape(j) = (
size_t)(shape[j]);
435 if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
447 status = H5Dread(dataset, nativeType, memspace, filespace,
448 H5P_DEFAULT, &out(0));
450 H5Tclose(nativeType);
455 throw std::runtime_error(
"Marray cannot read from dataset.");
471 const hid_t& groupHandle,
472 const std::string& datasetName,
476 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
479 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
481 throw std::runtime_error(
"Marray cannot open dataset.");
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);
491 throw std::runtime_error(
"Marray cannot get extension of dataset.");
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]);
502 for(
size_t j=0; j<out.
size(); ++j) {
503 out[j] = T(shape[j]);
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,
535 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
538 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
540 throw std::runtime_error(
"Marray cannot open dataset.");
544 size_t size = std::distance(baseBegin, baseEnd);
549 if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
555 offset[j] = hsize_t(*baseBegin);
556 slabShape[j] = hsize_t(*shapeBegin);
557 marrayShape[k] = slabShape[j];
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];
582 hid_t datatype = H5Dget_type(dataset);
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");
588 hid_t dataspace = H5Dget_space(dataset);
589 herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
590 &offset[0], NULL, &slabShape[0], NULL);
595 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
599 hid_t memspace = H5Screate_simple(
int(size), &marrayShape[0], NULL);
601 status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &offsetOut[0],
602 NULL, &marrayShape[0], NULL);
608 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
613 (&marrayShape[0])+size, coordinateOrder);
614 status = H5Dread(dataset, datatype, memspace, dataspace,
615 H5P_DEFAULT, &(out(0)));
623 throw std::runtime_error(
"Marray cannot read from dataset.");
639 template<
class T,
class BaseIterator,
class ShapeIterator>
642 const hid_t& groupHandle,
643 const std::string& datasetName,
644 BaseIterator baseBegin,
645 BaseIterator baseEnd,
646 ShapeIterator shapeBegin,
650 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
653 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
655 throw std::runtime_error(
"Marray cannot open dataset.");
661 memoryShape[j] = in.
shape(j);
663 size_t size = std::distance(baseBegin, baseEnd);
666 bool reverseShapeAttribute =
667 (H5Aexists(dataset, reverseShapeAttributeName) > 0);
672 offset[j] = hsize_t(*baseBegin);
673 slabShape[j] = hsize_t(*shapeBegin);
685 for(
size_t j=0; j<size; ++j) {
686 offset[j] = hsize_t(*baseBegin);
687 slabShape[j] = hsize_t(*shapeBegin);
694 throw std::runtime_error(
"Marray cannot write to HDF5 file. A different order was used when the file was created.");
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);
706 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
710 hid_t memspace = H5Screate_simple(
int(in.
dimension()), &memoryShape[0], NULL);
712 status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &memoryOffset[0], NULL,
713 &memoryShape[0], NULL);
719 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
723 status = H5Dwrite(dataset, datatype, memspace, dataspace, H5P_DEFAULT, &(in(0)));
731 throw std::runtime_error(
"Marray cannot write to dataset.");
748 const std::string& filename,
752 hid_t version = H5P_DEFAULT;
754 version = H5Pcreate(H5P_FILE_ACCESS);
755 H5Pset_libver_bounds(version, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
758 hid_t fileHandle = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, version);
760 throw std::runtime_error(
"Could not create HDF5 file: " + filename);
779 const std::string& filename,
784 hid_t access = H5F_ACC_RDONLY;
786 access = H5F_ACC_RDWR;
789 hid_t version = H5P_DEFAULT;
791 version = H5Pcreate(H5P_FILE_ACCESS);
792 H5Pset_libver_bounds(version, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
795 hid_t fileHandle = H5Fopen(filename.c_str(), access, version);
797 throw std::runtime_error(
"Could not open HDF5 file: " + filename);
828 const hid_t& parentHandle,
829 const std::string& groupName
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.");
851 const hid_t& parentHandle,
852 const std::string& groupName
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.");
880 #endif // #ifndef MARRAY_HDF5_HXX
hid_t createFile(const std::string &, HDF5Version=DEFAULT_HDF5_VERSION)
Create an HDF5 file.
const char reverseShapeAttributeName[14]
Runtime-flexible multi-dimensional views and arrays.
const size_t shape(const size_t) const
Get the shape in one dimension.
reverse_iterator rbegin()
Array-Interface to an interval of memory.
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.
const size_t dimension() const
Get the dimension.
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.
void loadShape(const hid_t &, const std::string &, Vector< T > &)
Load the shape of an HDF5 dataset.
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.
static const InitializationSkipping SkipInitialization
Flag to indicate initialization skipping.
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.
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.