4 #ifndef ANDRES_MARRAY_HDF5_HXX
5 #define ANDRES_MARRAY_HDF5_HXX
14 "HDF5 up to at least version 1.8.16 does not support LastMajorOrder. "
15 "(Quote from the HDF5 1.8.16 manual: \"HDF5 uses C storage conventions, "
16 "assuming that the last listed dimension is the fastest-changing dimension "
17 "and the first-listed dimension is the slowest changing.\") "
18 "The indexing order of the Marray or View at hand is LastMajorOrder. "
19 "In order to avoid confusion, such Marrays and Views are not saved directly to HDF5. "
20 "Consider copying to an Marray in FirstMajorOrder or a one-dimensional Marray";
23 void save(
const hid_t&,
const std::string&,
const Marray<T>&);
24 template<
class T,
bool isConst>
26 template<
class T,
class BaseIterator,
class ShapeIterator>
28 BaseIterator, BaseIterator, ShapeIterator,
const Marray<T>&);
29 template<
class T,
class ShapeIterator>
30 void create(
const hid_t&,
const std::string&, ShapeIterator, ShapeIterator);
38 void loadShape(
const hid_t&,
const std::string&, std::vector<T>&);
39 template<
class T,
class BaseIterator,
class ShapeIterator>
41 BaseIterator, BaseIterator, ShapeIterator,
Marray<T>&);
52 template<
class T,
class ShapeIterator>
54 const hid_t& groupHandle,
55 const std::string& datasetName,
60 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
63 hid_t datatype = H5Tcopy(hdf5Type<T>());
64 std::size_t dimension = std::distance(begin, end);
65 std::vector<hsize_t> shape(dimension);
66 for(std::size_t j=0; j<dimension; ++j) {
67 shape[j] = hsize_t(*begin);
70 hid_t dataspace = H5Screate_simple(dimension, &shape[0], NULL);
73 throw std::runtime_error(
"Marray cannot create dataspace.");
77 hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
78 dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
82 throw std::runtime_error(
"Marray cannot create dataset.");
102 const hid_t& groupHandle,
103 const std::string& datasetName,
112 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
115 hid_t datatype = H5Tcopy(hdf5Type<T>());
116 std::vector<hsize_t> shape(in.
dimension());
117 for(std::size_t j=0; j<in.
dimension(); ++j) {
118 shape[j] = hsize_t(in.
shape(j));
120 hid_t dataspace = H5Screate_simple(in.
dimension(), &shape[0], NULL);
123 throw std::runtime_error(
"Marray cannot create dataspace.");
127 hid_t dataset = H5Dcreate(groupHandle, datasetName.c_str(), datatype,
128 dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
132 throw std::runtime_error(
"Marray cannot create dataset.");
136 herr_t status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &in(0));
141 throw std::runtime_error(
"Marray cannot write to dataset.");
155 template<
class T,
bool isConst>
157 const hid_t& groupHandle,
158 const std::string& datasetName,
162 save(groupHandle, datasetName, m);
180 const std::string& filename,
181 const std::string& datasetName,
186 load(file, datasetName, out);
202 const hid_t& groupHandle,
203 const std::string& datasetName,
208 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
210 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
212 throw std::runtime_error(
"Marray cannot open dataset.");
214 hid_t filespace = H5Dget_space(dataset);
215 hid_t type = H5Dget_type(dataset);
216 hid_t nativeType = H5Tget_native_type(type, H5T_DIR_DESCEND);
217 if(!H5Tequal(nativeType, hdf5Type<T>())) {
219 H5Tclose(nativeType);
222 throw std::runtime_error(
"Data types not equal error.");
224 int dimension = H5Sget_simple_extent_ndims(filespace);
225 std::vector<hsize_t> shape(dimension);
226 herr_t status = H5Sget_simple_extent_dims(filespace, &shape[0], NULL);
229 H5Tclose(nativeType);
232 throw std::runtime_error(
"H5Sget_simple_extent_dims error.");
234 hid_t memspace = H5Screate_simple(dimension, &shape[0], NULL);
237 std::vector<std::size_t> newShape((std::size_t)(dimension));
238 for(std::size_t j=0; j<newShape.size(); ++j) {
239 newShape[j] = (std::size_t)(shape[j]);
244 status = H5Dread(dataset, nativeType, memspace, filespace, H5P_DEFAULT, &out(0));
246 H5Tclose(nativeType);
251 throw std::runtime_error(
"Marray cannot read from dataset.");
267 const hid_t& groupHandle,
268 const std::string& datasetName,
272 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
275 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
277 throw std::runtime_error(
"Marray cannot open dataset.");
279 hid_t filespace = H5Dget_space(dataset);
280 hsize_t dimension = H5Sget_simple_extent_ndims(filespace);
281 hsize_t* shape =
new hsize_t[(std::size_t)(dimension)];
282 herr_t status = H5Sget_simple_extent_dims(filespace, shape, NULL);
287 throw std::runtime_error(
"Marray cannot get extension of dataset.");
291 out = std::vector<T>(dimension);
292 for(std::size_t j=0; j<out.size(); ++j) {
293 out[j] = T(shape[j]);
316 template<
class T,
class BaseIterator,
class ShapeIterator>
318 const hid_t& groupHandle,
319 const std::string& datasetName,
320 BaseIterator baseBegin,
321 BaseIterator baseEnd,
322 ShapeIterator shapeBegin,
326 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
329 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
331 throw std::runtime_error(
"Marray cannot open dataset.");
335 std::size_t size = std::distance(baseBegin, baseEnd);
336 std::vector<hsize_t> offset(size);
337 std::vector<hsize_t> slabShape(size);
338 std::vector<hsize_t> marrayShape(size);
340 for(std::size_t j=0; j<size; ++j) {
341 offset[j] = hsize_t(*baseBegin);
342 slabShape[j] = hsize_t(*shapeBegin);
343 marrayShape[j] = slabShape[j];
349 hid_t datatype = H5Dget_type(dataset);
351 if(!H5Tequal(datatype, hdf5Type<T>())) {
352 throw std::runtime_error(
"data type of stored hdf5 dataset and passed array do not match in loadHyperslab");
355 hid_t dataspace = H5Dget_space(dataset);
356 herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, &offset[0], NULL, &slabShape[0], NULL);
361 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
365 hid_t memspace = H5Screate_simple(
int(size), &marrayShape[0], NULL);
366 std::vector<hsize_t> offsetOut(size, 0);
367 status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &offsetOut[0], NULL, &marrayShape[0], NULL);
373 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
378 status = H5Dread(dataset, datatype, memspace, dataspace, H5P_DEFAULT, &(out(0)));
386 throw std::runtime_error(
"Marray cannot read from dataset.");
402 template<
class T,
class BaseIterator,
class ShapeIterator>
405 const hid_t& groupHandle,
406 const std::string& datasetName,
407 BaseIterator baseBegin,
408 BaseIterator baseEnd,
409 ShapeIterator shapeBegin,
418 HandleCheck<MARRAY_NO_DEBUG> handleCheck;
421 hid_t dataset = H5Dopen(groupHandle, datasetName.c_str(), H5P_DEFAULT);
423 throw std::runtime_error(
"Marray cannot open dataset.");
427 std::vector<hsize_t> memoryShape(in.
dimension());
428 for(std::size_t j=0; j<in.
dimension(); ++j) {
429 memoryShape[j] = in.
shape(j);
431 std::size_t size = std::distance(baseBegin, baseEnd);
432 std::vector<hsize_t> offset(size);
433 std::vector<hsize_t> slabShape(size);
434 for(std::size_t j=0; j<size; ++j) {
435 offset[j] = hsize_t(*baseBegin);
436 slabShape[j] = hsize_t(*shapeBegin);
442 hid_t datatype = H5Dget_type(dataset);
443 hid_t dataspace = H5Dget_space(dataset);
444 herr_t status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, &offset[0], NULL, &slabShape[0], NULL);
449 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
453 hid_t memspace = H5Screate_simple(
int(in.
dimension()), &memoryShape[0], NULL);
454 std::vector<hsize_t> memoryOffset(
int(in.
dimension()), 0);
455 status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, &memoryOffset[0], NULL, &memoryShape[0], NULL);
461 throw std::runtime_error(
"Marray cannot select hyperslab. Check offset and shape!");
465 status = H5Dwrite(dataset, datatype, memspace, dataspace, H5P_DEFAULT, &(in(0)));
473 throw std::runtime_error(
"Marray cannot write to dataset.");