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,
78 void loadVec(
const hid_t&,
const std::string&, std::vector<T>&);
79 template<
class T,
class BaseIterator,
class ShapeIterator>
81 BaseIterator, BaseIterator, ShapeIterator,
Marray<T>&);
88 inline hid_t uintTypeHelper() {
99 throw std::runtime_error(
"No matching HDF5 type.");
104 inline hid_t intTypeHelper() {
109 return H5T_STD_I16BE;
111 return H5T_STD_I32BE;
113 return H5T_STD_I64BE;
115 throw std::runtime_error(
"No matching HDF5 type.");
120 inline hid_t floatingTypeHelper() {
123 return H5T_IEEE_F32BE;
125 return H5T_IEEE_F64BE;
127 throw std::runtime_error(
"No matching HDF5 type.");
133 inline hid_t uintTypeHelper() {
138 return H5T_STD_U16LE;
140 return H5T_STD_U32LE;
142 return H5T_STD_U64LE;
144 throw std::runtime_error(
"No matching HDF5 type.");
149 inline hid_t intTypeHelper() {
154 return H5T_STD_I16LE;
156 return H5T_STD_I32LE;
158 return H5T_STD_I64LE;
160 throw std::runtime_error(
"No matching HDF5 type.");
165 inline hid_t floatingTypeHelper() {
168 return H5T_IEEE_F32LE;
170 return H5T_IEEE_F64LE;
172 throw std::runtime_error(
"No matching HDF5 type.");
178 inline hid_t hdf5Type();
180 template<>
inline hid_t hdf5Type<unsigned char>()
181 {
return uintTypeHelper<unsigned char>(); }
182 template<>
inline hid_t hdf5Type<unsigned short>()
183 {
return uintTypeHelper<unsigned short>(); }
184 template<>
inline hid_t hdf5Type<unsigned int>()
185 {
return uintTypeHelper<unsigned int>(); }
186 template<>
inline hid_t hdf5Type<unsigned long>()
187 {
return uintTypeHelper<unsigned long>(); }
188 template<>
inline hid_t hdf5Type<unsigned long long>()
189 {
return uintTypeHelper<unsigned long long>(); }
191 template<>
inline hid_t hdf5Type<char>()
192 {
return uintTypeHelper<char>(); }
193 template<>
inline hid_t hdf5Type<signed char>()
194 {
return intTypeHelper<signed char>(); }
195 template<>
inline hid_t hdf5Type<short>()
196 {
return intTypeHelper<short>(); }
197 template<>
inline hid_t hdf5Type<int>()
198 {
return intTypeHelper<int>(); }
199 template<>
inline hid_t hdf5Type<long>()
200 {
return intTypeHelper<long>(); }
201 template<>
inline hid_t hdf5Type<long long>()
202 {
return intTypeHelper<long long>(); }
204 template<>
inline hid_t hdf5Type<float>()
205 {
return floatingTypeHelper<float>(); }
206 template<>
inline hid_t hdf5Type<double>()
207 {
return floatingTypeHelper<double>(); }
222 template<
class T,
class ShapeIterator>
224 const hid_t& groupHandle,
225 const std::string& datasetName,
231 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
234 hid_t datatype = H5Tcopy(hdf5Type<T>());
235 size_t dimension = std::distance(begin, end);
239 for(
size_t j=0; j<dimension; ++j) {
240 shape[j] = hsize_t(*begin);
246 for(
size_t j=0; j<dimension; ++j) {
247 shape[dimension-j-1] = hsize_t(*begin);
251 hid_t dataspace = H5Screate_simple(dimension, &shape[0], NULL);
254 throw std::runtime_error(
"Marray cannot create dataspace.");
259 hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
260 dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
264 throw std::runtime_error(
"Marray cannot create dataset.");
269 hsize_t attributeShape[1] = {1};
270 hid_t attributeDataspace = H5Screate_simple(1, attributeShape, NULL);
271 if(attributeDataspace < 0) {
275 throw std::runtime_error(
"Marray cannot create dataspace.");
277 hid_t attribute = H5Acreate(dataset, reverseShapeAttributeName,
278 H5T_STD_U8LE, attributeDataspace, H5P_DEFAULT, H5P_DEFAULT);
280 H5Sclose(attributeDataspace);
284 throw std::runtime_error(
"Marray cannot create attribute.");
286 unsigned int data = 1;
287 herr_t err = H5Awrite(attribute, H5T_STD_U8LE, &data);
289 H5Sclose(attributeDataspace);
294 throw std::runtime_error(
"Marray cannot create write to attribute.");
315 const hid_t& groupHandle,
316 const std::string& datasetName,
320 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
323 hid_t datatype = H5Tcopy(hdf5Type<T>());
328 shape[j] = hsize_t(in.
shape(j));
337 hid_t dataspace = H5Screate_simple(in.
dimension(), &shape[0], NULL);
340 throw std::runtime_error(
"Marray cannot create dataspace.");
344 hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
345 dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
349 throw std::runtime_error(
"Marray cannot create dataset.");
354 hsize_t attributeShape[1] = {1};
355 hid_t attributeDataspace = H5Screate_simple(1, attributeShape, NULL);
356 if(attributeDataspace < 0) {
360 throw std::runtime_error(
"Marray cannot create dataspace.");
362 hid_t attribute = H5Acreate(dataset, reverseShapeAttributeName,
363 H5T_STD_U8LE, attributeDataspace, H5P_DEFAULT, H5P_DEFAULT);
365 H5Sclose(attributeDataspace);
369 throw std::runtime_error(
"Marray cannot create attribute.");
371 unsigned int data = 1;
372 herr_t err = H5Awrite(attribute, H5T_STD_U8LE, &data);
374 H5Sclose(attributeDataspace);
379 throw std::runtime_error(
"Marray cannot create write to attribute.");
384 herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL,
385 H5P_DEFAULT, &in(0));
390 throw std::runtime_error(
"Marray cannot write to dataset.");
404 template<
class T,
bool isConst>
406 const hid_t& groupHandle,
407 const std::string& datasetName,
411 save(groupHandle, datasetName, m);
424 const hid_t& groupHandle,
425 const std::string& datasetName,
426 const std::vector<T>& in
430 for(
size_t j=0; j<in.size(); ++j) {
433 save(groupHandle, datasetName, v);
446 const hid_t& groupHandle,
447 const std::string& datasetName,
451 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
453 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
455 throw std::runtime_error(
"Marray cannot open dataset.");
457 hid_t filespace = H5Dget_space(dataset);
458 hid_t type = H5Dget_type(dataset);
459 hid_t nativeType = H5Tget_native_type(type, H5T_DIR_DESCEND);
460 if(!H5Tequal(nativeType, hdf5Type<T>())) {
462 H5Tclose(nativeType);
465 throw std::runtime_error(
"Data types not equal error.");
467 int dimension = H5Sget_simple_extent_ndims(filespace);
469 herr_t status = H5Sget_simple_extent_dims(filespace, &shape[0], NULL);
472 H5Tclose(nativeType);
475 throw std::runtime_error(
"H5Sget_simple_extent_dims error.");
477 hid_t memspace = H5Screate_simple(dimension, &shape[0], NULL);
481 for(
size_t j=0; j<newShape.
size(); ++j) {
482 newShape(j) = (
size_t)(shape[j]);
484 if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
496 status = H5Dread(dataset, nativeType, memspace, filespace,
497 H5P_DEFAULT, &out(0));
499 H5Tclose(nativeType);
504 throw std::runtime_error(
"Marray cannot read from dataset.");
520 const hid_t& groupHandle,
521 const std::string& datasetName,
525 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
528 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
530 throw std::runtime_error(
"Marray cannot open dataset.");
532 hid_t filespace = H5Dget_space(dataset);
533 hsize_t dimension = H5Sget_simple_extent_ndims(filespace);
534 hsize_t* shape =
new hsize_t[(
size_t)(dimension)];
535 herr_t status = H5Sget_simple_extent_dims(filespace, shape, NULL);
540 throw std::runtime_error(
"Marray cannot get extension of dataset.");
545 if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
546 for(
size_t j=0; j<out.
size(); ++j) {
547 out[out.
size()-j-1] = T(shape[j]);
551 for(
size_t j=0; j<out.
size(); ++j) {
552 out[j] = T(shape[j]);
573 const hid_t& groupHandle,
574 const std::string& datasetName,
579 load( groupHandle,datasetName,v);
580 out.resize(v.
size());
581 for(
size_t j=0; j<v.
size(); ++j) {
597 template<
class T,
class BaseIterator,
class ShapeIterator>
599 const hid_t& groupHandle,
600 const std::string& datasetName,
601 BaseIterator baseBegin,
602 BaseIterator baseEnd,
603 ShapeIterator shapeBegin,
607 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
610 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
612 throw std::runtime_error(
"Marray cannot open dataset.");
616 size_t size = std::distance(baseBegin, baseEnd);
621 if(H5Aexists(dataset, reverseShapeAttributeName) > 0) {
627 offset[j] = hsize_t(*baseBegin);
628 slabShape[j] = hsize_t(*shapeBegin);
629 marrayShape[k] = slabShape[j];
644 for(
size_t j=0; j<size; ++j) {
645 offset[j] = hsize_t(*baseBegin);
646 slabShape[j] = hsize_t(*shapeBegin);
647 marrayShape[j] = slabShape[j];
654 hid_t datatype = H5Dget_type(dataset);
656 if(!H5Tequal(datatype, hdf5Type<T>())) {
657 throw std::runtime_error(
"data type of stored hdf5 dataset and passed array do not match in loadHyperslab");
660 hid_t dataspace = H5Dget_space(dataset);
661 herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
662 &offset[0], NULL, &slabShape[0], NULL);
667 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
671 hid_t memspace = H5Screate_simple(
int(size), &marrayShape[0], NULL);
673 status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &offsetOut[0],
674 NULL, &marrayShape[0], NULL);
680 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
685 (&marrayShape[0])+size, coordinateOrder);
686 status = H5Dread(dataset, datatype, memspace, dataspace,
687 H5P_DEFAULT, &(out(0)));
695 throw std::runtime_error(
"Marray cannot read from dataset.");
711 template<
class T,
class BaseIterator,
class ShapeIterator>
714 const hid_t& groupHandle,
715 const std::string& datasetName,
716 BaseIterator baseBegin,
717 BaseIterator baseEnd,
718 ShapeIterator shapeBegin,
722 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
725 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
727 throw std::runtime_error(
"Marray cannot open dataset.");
733 memoryShape[j] = in.
shape(j);
735 size_t size = std::distance(baseBegin, baseEnd);
738 bool reverseShapeAttribute =
739 (H5Aexists(dataset, reverseShapeAttributeName) > 0);
744 offset[j] = hsize_t(*baseBegin);
745 slabShape[j] = hsize_t(*shapeBegin);
757 for(
size_t j=0; j<size; ++j) {
758 offset[j] = hsize_t(*baseBegin);
759 slabShape[j] = hsize_t(*shapeBegin);
766 throw std::runtime_error(
"Marray cannot write to HDF5 file. A different order was used when the file was created.");
770 hid_t datatype = H5Dget_type(dataset);
771 hid_t dataspace = H5Dget_space(dataset);
772 herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET,
773 &offset[0], NULL, &slabShape[0], NULL);
778 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
782 hid_t memspace = H5Screate_simple(
int(in.
dimension()), &memoryShape[0], NULL);
784 status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &memoryOffset[0], NULL,
785 &memoryShape[0], NULL);
791 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
795 status = H5Dwrite(dataset, datatype, memspace, dataspace, H5P_DEFAULT, &(in(0)));
803 throw std::runtime_error(
"Marray cannot write to dataset.");
820 const std::string& filename,
824 hid_t version = H5P_DEFAULT;
825 if(hdf5version == LATEST_HDF5_VERSION) {
826 version = H5Pcreate(H5P_FILE_ACCESS);
827 H5Pset_libver_bounds(version, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
830 hid_t fileHandle = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, version);
832 throw std::runtime_error(
"Could not create HDF5 file: " + filename);
851 const std::string& filename,
856 hid_t access = H5F_ACC_RDONLY;
857 if(fileAccessMode == READ_WRITE) {
858 access = H5F_ACC_RDWR;
861 hid_t version = H5P_DEFAULT;
862 if(hdf5version == LATEST_HDF5_VERSION) {
863 version = H5Pcreate(H5P_FILE_ACCESS);
864 H5Pset_libver_bounds(version, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
867 hid_t fileHandle = H5Fopen(filename.c_str(), access, version);
869 throw std::runtime_error(
"Could not open HDF5 file: " + filename);
900 const hid_t& parentHandle,
901 const std::string& groupName
904 hid_t groupHandle = H5Gcreate(parentHandle, groupName.c_str(),
905 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
906 if(groupHandle < 0) {
907 throw std::runtime_error(
"Could not create HDF5 group.");
923 const hid_t& parentHandle,
924 const std::string& groupName
927 hid_t groupHandle = H5Gopen(parentHandle, groupName.c_str(), H5P_DEFAULT);
928 if(groupHandle < 0) {
929 throw std::runtime_error(
"Could not open HDF5 group.");
952 #endif // #ifndef MARRAY_HDF5_HXX void loadVec(const hid_t &, const std::string &, std::vector< T > &)
Load a vector of an HDF5 dataset.
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 CoordinateOrder & coordinateOrder() const
Get the coordinate order used for scalar indexing and iterators.
iterator end()
Get the end-iterator.
reverse_iterator rbegin()
Get a reserve iterator to the beginning.
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.
iterator begin()
Get an iterator to the beginning.
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.
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.
const size_t dimension() const
Get the dimension.
void closeGroup(const hid_t &)
Close an HDF5 group.
reverse_iterator rend()
Get the reverse end-iterator.
const size_t shape(const size_t) const
Get the shape in one dimension.
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.
hid_t openFile(const std::string &, FileAccessMode=READ_ONLY, HDF5Version=DEFAULT_HDF5_VERSION)
Open an HDF5 file.
const size_t size() const
Get the number of data items.
hid_t openGroup(const hid_t &, const std::string &)
Open an HDF5 group.