h5gt 0.2.0
C++ wrapper for HDF5 library (based on HighFive project)
Loading...
Searching...
No Matches
H5Easy_Eigen.hpp
1/*
2 * Copyright (c), 2017, Adrien Devresse <adrien.devresse@epfl.ch>
3 *
4 * Distributed under the Boost Software License, Version 1.0.
5 * (See accompanying file LICENSE_1_0.txt or copy at
6 * http://www.boost.org/LICENSE_1_0.txt)
7 *
8 */
9#ifndef H5EASY_BITS_EIGEN_HPP
10#define H5EASY_BITS_EIGEN_HPP
11
12#include "../H5Easy.hpp"
13#include "H5Easy_misc.hpp"
14#include "H5Easy_scalar.hpp"
15
16#ifdef H5GT_USE_EIGEN
17
18namespace H5Easy {
19
20namespace detail {
21
22template <typename T>
23struct io_impl<
24 T,
25 typename std::enable_if<std::is_base_of<Eigen::DenseBase<T>, T>::value>::type> {
26
27 // abbreviate row-major <-> col-major conversions
28 template <typename S>
29 struct types
30 {
31 using row_major = Eigen::Ref<
32 const Eigen::Array<
33 typename std::decay<T>::type::Scalar,
34 std::decay<T>::type::RowsAtCompileTime,
35 std::decay<T>::type::ColsAtCompileTime,
36 std::decay<T>::type::ColsAtCompileTime == 1 ? Eigen::ColMajor : Eigen::RowMajor,
37 std::decay<T>::type::MaxRowsAtCompileTime,
38 std::decay<T>::type::MaxColsAtCompileTime>,
39 0,
40 Eigen::InnerStride<1>>;
41
42 using col_major = Eigen::Map<
43 Eigen::Array<
44 typename std::decay<T>::type::Scalar,
45 std::decay<T>::type::RowsAtCompileTime,
46 std::decay<T>::type::ColsAtCompileTime,
47 std::decay<T>::type::ColsAtCompileTime == 1 ? Eigen::ColMajor : Eigen::RowMajor,
48 std::decay<T>::type::MaxRowsAtCompileTime,
49 std::decay<T>::type::MaxColsAtCompileTime>>;
50 };
51
52 // return the shape of Eigen::DenseBase<T> object as size 1 or 2 "std::vector<size_t>"
53 inline static std::vector<size_t> shape(const T& data) {
54 if (std::decay<T>::type::RowsAtCompileTime == 1) {
55 return {static_cast<size_t>(data.cols())};
56 }
57 if (std::decay<T>::type::ColsAtCompileTime == 1) {
58 return {static_cast<size_t>(data.rows())};
59 }
60 return {static_cast<size_t>(data.rows()), static_cast<size_t>(data.cols())};
61 }
62
63 using EigenIndex = Eigen::DenseIndex;
64
65 // get the shape of a "DataSet" as size 2 "std::vector<Eigen::Index>"
66 template <class D>
67 inline static std::vector<EigenIndex> shape(const File& file,
68 const std::string& path,
69 const D& dataset,
70 int RowsAtCompileTime) {
71 std::vector<size_t> dims = dataset.getDimensions();
72
73 if (dims.size() == 1 && RowsAtCompileTime == 1) {
74 return std::vector<EigenIndex>{1u, static_cast<EigenIndex>(dims[0])};
75 }
76 if (dims.size() == 1) {
77 return std::vector<EigenIndex>{static_cast<EigenIndex>(dims[0]), 1u};
78 }
79 if (dims.size() == 2) {
80 return std::vector<EigenIndex>{static_cast<EigenIndex>(dims[0]),
81 static_cast<EigenIndex>(dims[1])};
82 }
83
84 throw detail::error(file, path, "H5Easy::load: Inconsistent rank");
85 }
86
87 inline static DataSet dump(File& file,
88 const std::string& path,
89 const T& data,
90 const DumpOptions& options) {
91 using row_major_type = typename types<T>::row_major;
92 using value_type = typename std::decay<T>::type::Scalar;
93 row_major_type row_major(data);
94 DataSet dataset = initDataset<value_type>(file, path, shape(data), options);
95 dataset.write_raw(row_major.data());
96 if (options.flush()) {
97 file.flush();
98 }
99 return dataset;
100 }
101
102 inline static T load(const File& file, const std::string& path) {
103 DataSet dataset = file.getDataSet(path);
104 std::vector<typename T::Index> dims = shape(file, path, dataset, T::RowsAtCompileTime);
105 T data(dims[0], dims[1]);
106 dataset.read(data.data());
107 if (data.IsVectorAtCompileTime || data.IsRowMajor) {
108 return data;
109 }
110 using col_major = typename types<T>::col_major;
111 return col_major(data.data(), dims[0], dims[1]);
112 }
113
114 inline static Attribute dumpAttribute(File& file,
115 const std::string& path,
116 const std::string& key,
117 const T& data,
118 const DumpOptions& options) {
119 using row_major_type = typename types<T>::row_major;
120 using value_type = typename std::decay<T>::type::Scalar;
121 row_major_type row_major(data);
122 Attribute attribute = initAttribute<value_type>(file, path, key, shape(data), options);
123 attribute.write_raw(row_major.data());
124 if (options.flush()) {
125 file.flush();
126 }
127 return attribute;
128 }
129
130 inline static T loadAttribute(const File& file,
131 const std::string& path,
132 const std::string& key) {
133 DataSet dataset = file.getDataSet(path);
134 Attribute attribute = dataset.getAttribute(key);
135 DataSpace dataspace = attribute.getSpace();
136 std::vector<typename T::Index> dims = shape(file, path, dataspace, T::RowsAtCompileTime);
137 T data(dims[0], dims[1]);
138 attribute.read(data.data());
139 if (data.IsVectorAtCompileTime || data.IsRowMajor) {
140 return data;
141 }
142 using col_major = typename types<T>::col_major;
143 return col_major(data.data(), dims[0], dims[1]);
144 }
145};
146
147} // namespace detail
148} // namespace H5Easy
149
150#endif // H5GT_USE_EIGEN
151#endif // H5EASY_BITS_EIGEN_HPP