mirror of
https://git.gfz-potsdam.de/naaice/poet.git
synced 2025-12-16 12:54:50 +01:00
162 lines
5.7 KiB
C++
162 lines
5.7 KiB
C++
#pragma once
|
|
|
|
#include "bits/H5Inspector_decl.hpp"
|
|
#include "H5Exception.hpp"
|
|
|
|
#include <Eigen/Core>
|
|
#include <Eigen/Dense>
|
|
|
|
namespace HighFive {
|
|
namespace details {
|
|
|
|
template <class EigenType>
|
|
struct eigen_inspector {
|
|
using type = EigenType;
|
|
using value_type = typename EigenType::Scalar;
|
|
using base_type = typename inspector<value_type>::base_type;
|
|
using hdf5_type = base_type;
|
|
|
|
|
|
static_assert(int(EigenType::ColsAtCompileTime) == int(EigenType::MaxColsAtCompileTime),
|
|
"Padding isn't supported.");
|
|
static_assert(int(EigenType::RowsAtCompileTime) == int(EigenType::MaxRowsAtCompileTime),
|
|
"Padding isn't supported.");
|
|
|
|
static constexpr bool is_row_major() {
|
|
return EigenType::ColsAtCompileTime == 1 || EigenType::RowsAtCompileTime == 1 ||
|
|
EigenType::IsRowMajor;
|
|
}
|
|
|
|
|
|
static constexpr size_t ndim = 2;
|
|
static constexpr size_t min_ndim = ndim + inspector<value_type>::min_ndim;
|
|
static constexpr size_t max_ndim = ndim + inspector<value_type>::max_ndim;
|
|
static constexpr bool is_trivially_copyable = is_row_major() &&
|
|
std::is_trivially_copyable<value_type>::value &&
|
|
inspector<value_type>::is_trivially_nestable;
|
|
static constexpr bool is_trivially_nestable = false;
|
|
|
|
static size_t getRank(const type& val) {
|
|
return ndim + inspector<value_type>::getRank(val.data()[0]);
|
|
}
|
|
|
|
static std::vector<size_t> getDimensions(const type& val) {
|
|
std::vector<size_t> sizes{static_cast<size_t>(val.rows()), static_cast<size_t>(val.cols())};
|
|
auto s = inspector<value_type>::getDimensions(val.data()[0]);
|
|
sizes.insert(sizes.end(), s.begin(), s.end());
|
|
return sizes;
|
|
}
|
|
|
|
static void prepare(type& val, const std::vector<size_t>& dims) {
|
|
if (dims[0] != static_cast<size_t>(val.rows()) ||
|
|
dims[1] != static_cast<size_t>(val.cols())) {
|
|
val.resize(static_cast<typename type::Index>(dims[0]),
|
|
static_cast<typename type::Index>(dims[1]));
|
|
}
|
|
}
|
|
|
|
static hdf5_type* data(type& val) {
|
|
if (!is_trivially_copyable) {
|
|
throw DataSetException("Invalid used of `inspector<Eigen::Matrix<...>>::data`.");
|
|
}
|
|
|
|
return inspector<value_type>::data(*val.data());
|
|
}
|
|
|
|
static const hdf5_type* data(const type& val) {
|
|
if (!is_trivially_copyable) {
|
|
throw DataSetException("Invalid used of `inspector<Eigen::Matrix<...>>::data`.");
|
|
}
|
|
|
|
return inspector<value_type>::data(*val.data());
|
|
}
|
|
|
|
static void serialize(const type& val, const std::vector<size_t>& dims, hdf5_type* m) {
|
|
Eigen::Index n_rows = val.rows();
|
|
Eigen::Index n_cols = val.cols();
|
|
|
|
auto subdims = std::vector<size_t>(dims.begin() + ndim, dims.end());
|
|
auto subsize = compute_total_size(subdims);
|
|
for (Eigen::Index i = 0; i < n_rows; ++i) {
|
|
for (Eigen::Index j = 0; j < n_cols; ++j) {
|
|
inspector<value_type>::serialize(val(i, j), dims, m);
|
|
m += subsize;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void unserialize(const hdf5_type* vec_align,
|
|
const std::vector<size_t>& dims,
|
|
type& val) {
|
|
if (dims.size() < 2) {
|
|
std::ostringstream os;
|
|
os << "Impossible to pair DataSet with " << dims.size()
|
|
<< " dimensions into an eigen-matrix.";
|
|
throw DataSpaceException(os.str());
|
|
}
|
|
|
|
auto n_rows = static_cast<Eigen::Index>(dims[0]);
|
|
auto n_cols = static_cast<Eigen::Index>(dims[1]);
|
|
|
|
auto subdims = std::vector<size_t>(dims.begin() + ndim, dims.end());
|
|
auto subsize = compute_total_size(subdims);
|
|
for (Eigen::Index i = 0; i < n_rows; ++i) {
|
|
for (Eigen::Index j = 0; j < n_cols; ++j) {
|
|
inspector<value_type>::unserialize(vec_align, subdims, val(i, j));
|
|
vec_align += subsize;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
template <typename T, int M, int N, int Options>
|
|
struct inspector<Eigen::Matrix<T, M, N, Options>>
|
|
: public eigen_inspector<Eigen::Matrix<T, M, N, Options>> {
|
|
private:
|
|
using super = eigen_inspector<Eigen::Matrix<T, M, N, Options>>;
|
|
|
|
public:
|
|
using type = typename super::type;
|
|
using value_type = typename super::value_type;
|
|
using base_type = typename super::base_type;
|
|
using hdf5_type = typename super::hdf5_type;
|
|
};
|
|
|
|
template <typename T, int M, int N, int Options>
|
|
struct inspector<Eigen::Array<T, M, N, Options>>
|
|
: public eigen_inspector<Eigen::Array<T, M, N, Options>> {
|
|
private:
|
|
using super = eigen_inspector<Eigen::Array<T, M, N, Options>>;
|
|
|
|
public:
|
|
using type = typename super::type;
|
|
using value_type = typename super::value_type;
|
|
using base_type = typename super::base_type;
|
|
using hdf5_type = typename super::hdf5_type;
|
|
};
|
|
|
|
|
|
template <typename PlainObjectType, int MapOptions>
|
|
struct inspector<Eigen::Map<PlainObjectType, MapOptions>>
|
|
: public eigen_inspector<Eigen::Map<PlainObjectType, MapOptions>> {
|
|
private:
|
|
using super = eigen_inspector<Eigen::Map<PlainObjectType, MapOptions>>;
|
|
|
|
public:
|
|
using type = typename super::type;
|
|
using value_type = typename super::value_type;
|
|
using base_type = typename super::base_type;
|
|
using hdf5_type = typename super::hdf5_type;
|
|
|
|
static void prepare(type& val, const std::vector<size_t>& dims) {
|
|
if (dims[0] != static_cast<size_t>(val.rows()) ||
|
|
dims[1] != static_cast<size_t>(val.cols())) {
|
|
throw DataSetException("Eigen::Map has invalid shape and can't be resized.");
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
} // namespace details
|
|
} // namespace HighFive
|