32 #ifndef MCKL_UTILITY_HDF5_HPP 33 #define MCKL_UTILITY_HDF5_HPP 40 ::
hid_t,
const char *name, const ::H5L_info_t *,
void *opdata)
42 auto links =
reinterpret_cast<std::vector<std::string> *
>(opdata);
43 links->emplace_back(name);
49 ::
hid_t,
const char *, const ::H5L_info_t *,
void *opdata)
51 auto links =
reinterpret_cast<std::size_t *
>(opdata);
61 template <
typename Derived>
90 std::swap(
id_, other.id_);
104 explicit operator bool()
const {
return good(); }
127 ::H5E_auto2_t f =
nullptr;
128 ::H5Eget_auto2(H5E_DEFAULT, &f,
nullptr);
131 H5E_DEFAULT, reinterpret_cast<::H5E_auto2_t>(::H5Eprint2), stderr);
133 ::H5Eset_auto2(H5E_DEFAULT,
nullptr,
nullptr);
152 id_ = ::H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
156 filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
167 ::H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT) :
168 ::H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT,
179 HDF5File(
const std::string &filename,
bool append,
bool read_only)
181 ::H5Fopen(filename.c_str(),
182 (read_only ? H5F_ACC_RDONLY : H5F_ACC_RDWR),
184 ::H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT,
189 static ::hid_t copy(::
hid_t) =
delete;
211 id_ = ::H5Gopen2(file.
id(), groupname.c_str(), H5P_DEFAULT);
214 id_ = ::H5Gcreate2(file.
id(), groupname.c_str(), H5P_DEFAULT,
215 H5P_DEFAULT, H5P_DEFAULT);
227 id_ = ::H5Gopen2(group.
id(), groupname.c_str(), H5P_DEFAULT);
230 id_ = ::H5Gcreate2(group.
id(), groupname.c_str(), H5P_DEFAULT,
231 H5P_DEFAULT, H5P_DEFAULT);
236 std::vector<std::string>
links()
const 238 std::vector<std::string> links;
239 ::H5Literate(
id_, H5_INDEX_NAME, H5_ITER_INC,
nullptr,
248 std::size_t links = 0;
249 ::H5Literate(
id_, H5_INDEX_NAME, H5_ITER_INC,
nullptr,
255 static ::hid_t copy(::
hid_t) =
delete;
273 return ::H5Tcommit2(file.
id(), name.c_str(),
id_, H5P_DEFAULT,
274 H5P_DEFAULT, H5P_DEFAULT);
279 return ::H5Tcommit2(group.
id(), name.c_str(),
id_, H5P_DEFAULT,
280 H5P_DEFAULT, H5P_DEFAULT);
283 void size(std::size_t s)
const { ::H5Tset_size(
id_, s); }
285 std::size_t
size()
const { return ::H5Tget_size(
id_); }
287 static ::hid_t
copy(::
hid_t id) { return ::H5Tcopy(
id); }
302 int rank, ::hsize_t *dim, ::hsize_t *maxdims =
nullptr)
309 return static_cast<std::size_t
>(::H5Sget_simple_extent_npoints(
id_));
314 return static_cast<std::size_t
>(::H5Sget_simple_extent_ndims(
id_));
317 std::size_t
dims(::hsize_t *dest)
const 319 return static_cast<std::size_t
>(
320 ::H5Sget_simple_extent_dims(
id_, dest,
nullptr));
323 static ::hid_t copy(::
hid_t) =
delete;
339 ::H5Aopen(file.
id(), name.c_str(), H5P_DEFAULT))
345 ::H5Aopen(group.
id(), name.c_str(), H5P_DEFAULT))
352 type.
id(), space.
id(), H5P_DEFAULT, H5P_DEFAULT))
359 type.
id(), space.
id(), H5P_DEFAULT, H5P_DEFAULT))
369 if (this->space().npoints() == 0) {
373 return ::H5Awrite(
id_, type.
id(), mem) >= 0;
378 if (this->space().npoints() == 0) {
382 return ::H5Aread(
id_, type.
id(), mem) >= 0;
385 static ::hid_t copy(::
hid_t) =
delete;
406 ::H5Dopen2(group.
id(), name.c_str(), H5P_DEFAULT))
413 space.
id(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))
420 space.
id(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))
430 if (this->space().npoints() == 0) {
435 id_, type.
id(), H5S_ALL, H5S_ALL, H5P_DEFAULT, mem) >= 0;
440 if (this->space().npoints() == 0) {
444 return ::H5Dread(
id_, type.
id(), H5S_ALL, H5S_ALL, H5P_DEFAULT, mem) >=
448 static ::hid_t copy(::
hid_t) =
delete;
474 inline ::hid_t
hdf5typeid(
char *) { return ::H5Tcopy(H5T_NATIVE_CHAR); }
480 return ::H5Tcopy(H5T_NATIVE_SCHAR);
487 return ::H5Tcopy(H5T_NATIVE_UCHAR);
492 inline ::hid_t
hdf5typeid(
short *) { return ::H5Tcopy(H5T_NATIVE_SHORT); }
498 return ::H5Tcopy(H5T_NATIVE_UCHAR);
503 inline ::hid_t
hdf5typeid(
int *) { return ::H5Tcopy(H5T_NATIVE_INT); }
509 return ::H5Tcopy(H5T_NATIVE_UINT);
514 inline ::hid_t
hdf5typeid(
long *) { return ::H5Tcopy(H5T_NATIVE_LONG); }
520 return ::H5Tcopy(H5T_NATIVE_ULONG);
525 inline ::hid_t
hdf5typeid(
long long *) { return ::H5Tcopy(H5T_NATIVE_LLONG); }
531 return ::H5Tcopy(H5T_NATIVE_ULLONG);
536 inline ::hid_t
hdf5typeid(
float *) { return ::H5Tcopy(H5T_NATIVE_FLOAT); }
540 inline ::hid_t
hdf5typeid(
double *) { return ::H5Tcopy(H5T_NATIVE_DOUBLE); }
546 return ::H5Tcopy(H5T_NATIVE_LDOUBLE);
550 template <
typename T>
558 template <
typename Location,
typename T>
559 inline bool hdf5store(Location &&location,
const std::string &name,
560 const T &value,
bool isattr =
false, decltype(hdf5type<T>()) * =
nullptr)
562 auto type = hdf5type<T>();
567 ::hsize_t dims[] = {1};
578 return attr.
write(type, &value);
585 return data.
write(type, &value);
590 template <
typename Location>
591 inline bool hdf5store(Location &&location,
const std::string &name,
592 const std::string &str,
bool isattr =
false)
595 std::string empty_str;
596 empty_str.push_back(
'\0');
597 return hdf5store(location, name, empty_str, isattr);
605 type.
size(str.size());
610 ::hsize_t dims[] = {1};
621 return attr.
write(type, str.c_str());
629 return data.
write(type, str.c_str());
634 template <
typename Location,
typename T,
typename Alloc>
635 inline bool hdf5store(Location &&location,
const std::string &name,
637 std::size_t chunk_size = 1024)
639 auto type = hdf5type<T>();
644 auto ext = extensible && !isattr;
645 ::hsize_t dims[] = {vec.size()};
646 ::hsize_t maxdims[] = {ext ? H5S_UNLIMITED : vec.size()};
657 return attr.
write(type, vec.data());
667 if (::H5Pset_layout(plist.
id(), H5D_CHUNKED) != 0) {
671 ::hsize_t chunk_dims[] = {chunk_size};
672 if (::H5Pset_chunk(plist.
id(), 1, chunk_dims) != 0) {
676 data =
HDF5DataSet(::H5Dcreate2(location.id(), name.c_str(), type.id(),
677 space.
id(), H5P_DEFAULT, plist.
id(), H5P_DEFAULT));
686 return data.
write(type, vec.data());
691 template <
typename Location,
typename T,
typename Alloc>
699 auto type = hdf5type<T>();
709 auto space = data.
space();
714 ::hsize_t offset[] = {space.
npoints()};
715 ::hsize_t exts[] = {vec.size()};
716 ::hsize_t dims[] = {offset[0] + exts[0]};
717 if (::H5Dset_extent(data.
id(), dims) != 0) {
721 space = data.
space();
726 if (::H5Sselect_hyperslab(
727 space.id(), H5S_SELECT_SET, offset,
nullptr, exts,
nullptr) != 0) {
736 if (::H5Dwrite(data.
id(), type.id(), mspace.
id(), space.id(), H5P_DEFAULT,
746 template <
typename Location,
typename T, MatrixLayout Layout,
typename Alloc>
747 inline bool hdf5store(Location &&location,
const std::string &name,
750 auto type = hdf5type<T>();
757 dims[0] = mat.
nrow();
758 dims[1] = mat.
ncol();
761 dims[0] = mat.
ncol();
762 dims[1] = mat.
nrow();
786 template <
typename Location,
typename T>
787 inline bool hdf5load(Location &&location,
const std::string &name, T *value,
788 bool isattr =
false, decltype(hdf5type<T>()) * =
nullptr)
790 auto type = hdf5type<T>();
800 return attr.
read(type, value);
807 return data.
read(type, value);
812 template <
typename Location>
813 inline bool hdf5load(Location &&location,
const std::string &name,
814 std::string *str,
bool isattr =
false)
822 auto type = attr.
type();
827 str->resize(type.size());
829 return attr.
read(type, const_cast<char *>(str->data()));
837 auto type = data.
type();
842 str->resize(type.size());
844 return data.
read(type, const_cast<char *>(str->data()));
849 template <
typename Location,
typename T,
typename Alloc>
850 inline bool hdf5load(Location &&location,
const std::string &name,
853 auto type = hdf5type<T>();
864 auto space = attr.
space();
869 vec->resize(space.npoints());
874 return attr.
read(type, vec->data());
882 auto space = data.
space();
887 vec->resize(space.npoints());
892 return data.
read(type, vec->data());
897 template <
typename Location,
typename T, MatrixLayout Layout,
typename Alloc>
898 inline bool hdf5load(Location &&location,
const std::string &name,
901 auto type = hdf5type<T>();
912 auto space = attr.
space();
917 if (space.ndims() != 2) {
922 if (space.dims(dims) != 2) {
927 mat->
resize(dims[0], dims[1]);
930 mat->
resize(dims[1], dims[0]);
936 return attr.
read(type, mat->
data());
944 auto space = data.
space();
949 if (space.ndims() != 2) {
954 if (space.dims(dims) != 2) {
959 mat->
resize(dims[0], dims[1]);
962 mat->
resize(dims[1], dims[0]);
968 return data.
read(type, mat->
data());
973 #endif // MCKL_UTILITY_HDF5_HPP
void size(std::size_t s) const
inline ::herr_t mckl_hdf5_inc_link(::hid_t, const char *, const ::H5L_info_t *, void *opdata)
size_type ncol() const
The number of columns.
void resize(size_type nrow, size_type ncol)
Resize the matrix.
std::size_t ndims() const
HDF5DataSet(const HDF5File &file, const std::string &name)
RAII class for HDF5 data type.
inline ::hid_t hdf5typeid(char *)
HDF5 data type id overload for char.
HDF5Attribute(const HDF5File &file, const std::string &name)
bool write(const HDF5DataType &type, const void *mem) const
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
HDF5Attribute(const HDF5Group &group, const std::string &name, const HDF5DataType &type, const HDF5DataSpace &space)
bool empty() const
If the matrix is empty, i.e., nrow() * ncol() == 0
bool hdf5store(Location &&location, const std::string &name, const T &value, bool isattr=false, decltype(hdf5type< T >()) *=nullptr)
Store a value in HDF5 format.
static void close(::hid_t id)
HDF5ID & operator=(HDF5ID &&other)
bool write(const HDF5DataType &type, const void *mem) const
RAII class for HDF5 attribute.
std::vector< std::string > links() const
Get the names of all links in the group.
HDF5File(const std::string &filename, bool append, bool read_only)
Open or create an HDF5 file.
std::size_t size() const
Get the number of links in the group.
bool commit(const HDF5Group &group, const std::string &name) const
static void close(::hid_t id)
pointer data()
Pointer to the upper left corner of the matrix.
HDF5DataSet(const HDF5File &file, const std::string &name, const HDF5DataType &type, const HDF5DataSpace &space)
bool read(const HDF5DataType &type, void *mem) const
RAII class for HDF5 group.
static void close(::hid_t id)
std::size_t dims(::hsize_t *dest) const
HDF5DataSpace space() const
HDF5ID(const HDF5ID &other)
static void close(::hid_t id)
RAII class for HDF5 data space.
HDF5Group(const HDF5File &file, const std::string &groupname)
Open a group if possible, otherwise create a new one.
bool read(const HDF5DataType &type, void *mem) const
bool hdf5_error_printing(bool enabled)
Enable and disable HDF5 low level error printing.
bool commit(const HDF5File &file, const std::string &name) const
static void close(::hid_t id)
HDF5DataType type() const
HDF5DataSet(const HDF5Group &group, const std::string &name)
inline ::herr_t mckl_hdf5_add_link(::hid_t, const char *name, const ::H5L_info_t *, void *opdata)
HDF5Attribute(const HDF5File &file, const std::string &name, const HDF5DataType &type, const HDF5DataSpace &space)
size_type nrow() const
The number of rows.
HDF5DataSet(const HDF5Group &group, const std::string &name, const HDF5DataType &type, const HDF5DataSpace &space)
HDF5ID & operator=(const HDF5ID &other)
HDF5DataType type() const
bool hdf5append(Location &&location, const std::string &name, const Vector< T, Alloc > &vec)
Append a vector in HDF5 format.
HDF5DataSpace space() const
RAII class for HDF5 property list.
RAII class for HDF5 file object.
HDF5File(const std::string &filename)
Open an HDF5 file if it possible, otherwise create a new one.
static void close(::hid_t id)
HDF5DataSpace(int rank, ::hsize_t *dim, ::hsize_t *maxdims=nullptr)
RAII class for HDF5 data set.
static void close(::hid_t id)
HDF5File(const std::string &filename, bool append)
Open or create an HDF5 file.
HDF5Attribute(const HDF5Group &group, const std::string &name)
HDF5Group(const HDF5Group &group, const std::string &groupname)
Open a group if possible, otherwise create a new one.
std::size_t npoints() const
HDF5DataType hdf5type()
HDF5 data type.
bool hdf5load(Location &&location, const std::string &name, T *value, bool isattr=false, decltype(hdf5type< T >()) *=nullptr)
Load a value form HDF5 format.