Skip to content

Commit

Permalink
Refactor H5Easy to use core. (#1016)
Browse files Browse the repository at this point in the history
  • Loading branch information
1uc authored Jun 21, 2024
1 parent cb77ede commit 20fbd4c
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 340 deletions.
6 changes: 3 additions & 3 deletions include/highfive/H5Easy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#ifdef H5_USE_XTENSOR
#include <xtensor/xarray.hpp>
#include <xtensor/xtensor.hpp>
#include "xtensor.hpp"
#endif

// optionally enable Eigen plug-in and load the library
Expand All @@ -41,6 +42,7 @@

#ifdef H5_USE_EIGEN
#include <Eigen/Eigen>
#include "eigen.hpp"
#endif

// optionally enable OpenCV plug-in and load the library
Expand All @@ -52,6 +54,7 @@

#ifdef H5_USE_OPENCV
#include <opencv2/opencv.hpp>
#include "experimental/opencv.hpp"
#endif

#include "H5File.hpp"
Expand Down Expand Up @@ -393,8 +396,5 @@ inline T loadAttribute(const File& file, const std::string& path, const std::str

#include "h5easy_bits/H5Easy_Eigen.hpp"
#include "h5easy_bits/H5Easy_misc.hpp"
#include "h5easy_bits/H5Easy_opencv.hpp"
#include "h5easy_bits/H5Easy_public.hpp"
#include "h5easy_bits/H5Easy_scalar.hpp"
#include "h5easy_bits/H5Easy_vector.hpp"
#include "h5easy_bits/H5Easy_xtensor.hpp"
96 changes: 34 additions & 62 deletions include/highfive/h5easy_bits/H5Easy_Eigen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,66 +14,48 @@

#ifdef H5_USE_EIGEN

#include "../eigen.hpp"

namespace H5Easy {

namespace detail {

template <typename T>
struct io_impl<T, typename std::enable_if<std::is_base_of<Eigen::DenseBase<T>, T>::value>::type> {
// abbreviate row-major <-> col-major conversions
template <typename S>
struct types {
using row_major = Eigen::Ref<
const Eigen::Array<typename std::decay<T>::type::Scalar,
std::decay<T>::type::RowsAtCompileTime,
std::decay<T>::type::ColsAtCompileTime,
std::decay<T>::type::ColsAtCompileTime == 1 ? Eigen::ColMajor
: Eigen::RowMajor,
std::decay<T>::type::MaxRowsAtCompileTime,
std::decay<T>::type::MaxColsAtCompileTime>,
0,
Eigen::InnerStride<1>>;

using col_major =
Eigen::Map<Eigen::Array<typename std::decay<T>::type::Scalar,
std::decay<T>::type::RowsAtCompileTime,
std::decay<T>::type::ColsAtCompileTime,
std::decay<T>::type::ColsAtCompileTime == 1 ? Eigen::ColMajor
: Eigen::RowMajor,
std::decay<T>::type::MaxRowsAtCompileTime,
std::decay<T>::type::MaxColsAtCompileTime>>;
};

// return the shape of Eigen::DenseBase<T> object as size 1 or 2 "std::vector<size_t>"
inline static std::vector<size_t> shape(const T& data) {
using EigenIndex = Eigen::DenseIndex;

// When creating a dataset for an Eigen object, the shape of the dataset is
// 1D for vectors. (legacy reasons)
inline static std::vector<size_t> file_shape(const T& data) {
if (std::decay<T>::type::RowsAtCompileTime == 1) {
return {static_cast<size_t>(data.cols())};
}
if (std::decay<T>::type::ColsAtCompileTime == 1) {
return {static_cast<size_t>(data.rows())};
}
return {static_cast<size_t>(data.rows()), static_cast<size_t>(data.cols())};
return inspector<T>::getDimensions(data);
}

using EigenIndex = Eigen::DenseIndex;
// The shape of an Eigen object as used in HighFive core.
inline static std::vector<size_t> mem_shape(const T& data) {
return inspector<T>::getDimensions(data);
}

// get the shape of a "DataSet" as size 2 "std::vector<Eigen::Index>"
// The shape of an Eigen object as used in HighFive core.
template <class D>
inline static std::vector<EigenIndex> shape(const File& file,
inline static std::vector<size_t> mem_shape(const File& file,
const std::string& path,
const D& dataset,
int RowsAtCompileTime) {
const D& dataset) {
std::vector<size_t> dims = dataset.getDimensions();

if (dims.size() == 1 && RowsAtCompileTime == 1) {
return std::vector<EigenIndex>{1u, static_cast<EigenIndex>(dims[0])};
if (dims.size() == 1 && T::RowsAtCompileTime == 1) {
return std::vector<size_t>{1, dims[0]};
}
if (dims.size() == 1) {
return std::vector<EigenIndex>{static_cast<EigenIndex>(dims[0]), 1u};
if (dims.size() == 1 && T::ColsAtCompileTime == 1) {
return std::vector<size_t>{dims[0], 1};
}
if (dims.size() == 2) {
return std::vector<EigenIndex>{static_cast<EigenIndex>(dims[0]),
static_cast<EigenIndex>(dims[1])};
return dims;
}

throw detail::error(file, path, "H5Easy::load: Inconsistent rank");
Expand All @@ -83,11 +65,12 @@ struct io_impl<T, typename std::enable_if<std::is_base_of<Eigen::DenseBase<T>, T
const std::string& path,
const T& data,
const DumpOptions& options) {
using row_major_type = typename types<T>::row_major;
using value_type = typename std::decay<T>::type::Scalar;
row_major_type row_major(data);
DataSet dataset = initDataset<value_type>(file, path, shape(data), options);
dataset.write_raw(row_major.data());

std::vector<size_t> file_dims = file_shape(data);
std::vector<size_t> mem_dims = mem_shape(data);
DataSet dataset = initDataset<value_type>(file, path, file_dims, options);
dataset.reshapeMemSpace(mem_dims).write(data);
if (options.flush()) {
file.flush();
}
Expand All @@ -96,26 +79,21 @@ struct io_impl<T, typename std::enable_if<std::is_base_of<Eigen::DenseBase<T>, T

inline static T load(const File& file, const std::string& path) {
DataSet dataset = file.getDataSet(path);
std::vector<typename T::Index> dims = shape(file, path, dataset, T::RowsAtCompileTime);
T data(dims[0], dims[1]);
dataset.read_raw(data.data());
if (data.IsVectorAtCompileTime || data.IsRowMajor) {
return data;
}
using col_major = typename types<T>::col_major;
return col_major(data.data(), dims[0], dims[1]);
std::vector<size_t> dims = mem_shape(file, path, dataset);
return dataset.reshapeMemSpace(dims).template read<T>();
}

inline static Attribute dumpAttribute(File& file,
const std::string& path,
const std::string& key,
const T& data,
const DumpOptions& options) {
using row_major_type = typename types<T>::row_major;
using value_type = typename std::decay<T>::type::Scalar;
row_major_type row_major(data);
Attribute attribute = initAttribute<value_type>(file, path, key, shape(data), options);
attribute.write_raw(row_major.data());

std::vector<size_t> file_dims = file_shape(data);
std::vector<size_t> mem_dims = mem_shape(data);
Attribute attribute = initAttribute<value_type>(file, path, key, file_dims, options);
attribute.reshapeMemSpace(mem_dims).write(data);
if (options.flush()) {
file.flush();
}
Expand All @@ -128,14 +106,8 @@ struct io_impl<T, typename std::enable_if<std::is_base_of<Eigen::DenseBase<T>, T
DataSet dataset = file.getDataSet(path);
Attribute attribute = dataset.getAttribute(key);
DataSpace dataspace = attribute.getSpace();
std::vector<typename T::Index> dims = shape(file, path, dataspace, T::RowsAtCompileTime);
T data(dims[0], dims[1]);
attribute.read_raw(data.data());
if (data.IsVectorAtCompileTime || data.IsRowMajor) {
return data;
}
using col_major = typename types<T>::col_major;
return col_major(data.data(), dims[0], dims[1]);
std::vector<size_t> dims = mem_shape(file, path, dataspace);
return attribute.reshapeMemSpace(dims).template read<T>();
}
};

Expand Down
100 changes: 0 additions & 100 deletions include/highfive/h5easy_bits/H5Easy_opencv.hpp

This file was deleted.

56 changes: 6 additions & 50 deletions include/highfive/h5easy_bits/H5Easy_scalar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "../H5Easy.hpp"
#include "H5Easy_misc.hpp"
#include "default_io_impl.hpp"

namespace H5Easy {

Expand All @@ -20,49 +21,7 @@ Base template for partial specialization: the fallback if specialized templates
Used e.g. for scalars.
*/
template <typename T, typename = void>
struct io_impl {
inline static DataSet dump(File& file,
const std::string& path,
const T& data,
const DumpOptions& options) {
DataSet dataset = initScalarDataset(file, path, data, options);
dataset.write(data);
if (options.flush()) {
file.flush();
}
return dataset;
}

inline static T load(const File& file, const std::string& path) {
DataSet dataset = file.getDataSet(path);
T data;
dataset.read(data);
return data;
}

inline static Attribute dumpAttribute(File& file,
const std::string& path,
const std::string& key,
const T& data,
const DumpOptions& options) {
Attribute attribute = initScalarAttribute(file, path, key, data, options);
attribute.write(data);
if (options.flush()) {
file.flush();
}
return attribute;
}

inline static T loadAttribute(const File& file,
const std::string& path,
const std::string& key) {
DataSet dataset = file.getDataSet(path);
Attribute attribute = dataset.getAttribute(key);
T data;
attribute.read(data);
return data;
}

struct io_impl: public default_io_impl<T> {
inline static DataSet dump_extend(File& file,
const std::string& path,
const T& data,
Expand Down Expand Up @@ -93,7 +52,6 @@ struct io_impl {
return dataset;
}

std::vector<size_t> shape = idx;
const size_t unlim = DataSpace::UNLIMITED;
std::vector<size_t> unlim_shape(idx.size(), unlim);
std::vector<hsize_t> chunks(idx.size(), 10);
Expand All @@ -103,8 +61,9 @@ struct io_impl {
throw error(file, path, "H5Easy::dump: Incorrect dimension ChunkSize");
}
}
for (size_t& i: shape) {
i++;
std::vector<size_t> shape(idx.size());
for (size_t i = 0; i < idx.size(); ++i) {
shape[i] = idx[i] + 1;
}
DataSpace dataspace = DataSpace(shape, unlim_shape);
DataSetCreateProps props;
Expand All @@ -121,10 +80,7 @@ struct io_impl {
const std::string& path,
const std::vector<size_t>& idx) {
std::vector<size_t> ones(idx.size(), 1);
DataSet dataset = file.getDataSet(path);
T data;
dataset.select(idx, ones).read(data);
return data;
return file.getDataSet(path).select(idx, ones).read<T>();
}
};

Expand Down
Loading

0 comments on commit 20fbd4c

Please sign in to comment.