HighFive 2.9.0
HighFive - Header-only C++ HDF5 interface
Loading...
Searching...
No Matches
boost.hpp
Go to the documentation of this file.
1#pragma once
2#ifdef H5_USE_BOOST
3
5#include "H5Exception.hpp"
6
7#include <boost/multi_array.hpp>
8// starting Boost 1.64, serialization header must come before ublas
9#include <boost/serialization/vector.hpp>
10#include <boost/numeric/ublas/matrix.hpp>
11
12namespace HighFive {
13namespace details {
14
15template <typename T, size_t Dims>
16struct inspector<boost::multi_array<T, Dims>> {
17 using type = boost::multi_array<T, Dims>;
18 using value_type = T;
19 using base_type = typename inspector<value_type>::base_type;
20 using hdf5_type = typename inspector<value_type>::hdf5_type;
21
22 static constexpr size_t ndim = Dims;
23 static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
24 static constexpr bool is_trivially_copyable = std::is_trivially_copyable<value_type>::value &&
25 inspector<value_type>::is_trivially_copyable;
26
27 static std::vector<size_t> getDimensions(const type& val) {
28 std::vector<size_t> sizes;
29 for (size_t i = 0; i < ndim; ++i) {
30 sizes.push_back(val.shape()[i]);
31 }
32 auto s = inspector<value_type>::getDimensions(val.data()[0]);
33 sizes.insert(sizes.end(), s.begin(), s.end());
34 return sizes;
35 }
36
37 static size_t getSizeVal(const type& val) {
38 return compute_total_size(getDimensions(val));
39 }
40
41 static size_t getSize(const std::vector<size_t>& dims) {
42 return compute_total_size(dims);
43 }
44
45 static void prepare(type& val, const std::vector<size_t>& dims) {
46 if (dims.size() < ndim) {
47 std::ostringstream os;
48 os << "Only '" << dims.size() << "' given but boost::multi_array is of size '" << ndim
49 << "'.";
50 throw DataSpaceException(os.str());
51 }
52 boost::array<typename type::index, Dims> ext;
53 std::copy(dims.begin(), dims.begin() + ndim, ext.begin());
54 val.resize(ext);
55 std::vector<size_t> next_dims(dims.begin() + Dims, dims.end());
56 std::size_t size = std::accumulate(dims.begin(),
57 dims.begin() + Dims,
58 std::size_t{1},
59 std::multiplies<size_t>());
60 for (size_t i = 0; i < size; ++i) {
61 inspector<value_type>::prepare(*(val.origin() + i), next_dims);
62 }
63 }
64
65 static hdf5_type* data(type& val) {
66 return inspector<value_type>::data(*val.data());
67 }
68
69 static const hdf5_type* data(const type& val) {
70 return inspector<value_type>::data(*val.data());
71 }
72
73 template <class It>
74 static void serialize(const type& val, It m) {
75 size_t size = val.num_elements();
76 size_t subsize = inspector<value_type>::getSizeVal(*val.origin());
77 for (size_t i = 0; i < size; ++i) {
78 inspector<value_type>::serialize(*(val.origin() + i), m + i * subsize);
79 }
80 }
81
82 template <class It>
83 static void unserialize(It vec_align, const std::vector<size_t>& dims, type& val) {
84 std::vector<size_t> next_dims(dims.begin() + ndim, dims.end());
85 size_t subsize = compute_total_size(next_dims);
86 for (size_t i = 0; i < val.num_elements(); ++i) {
87 inspector<value_type>::unserialize(vec_align + i * subsize,
88 next_dims,
89 *(val.origin() + i));
90 }
91 }
92};
93
94template <typename T>
95struct inspector<boost::numeric::ublas::matrix<T>> {
96 using type = boost::numeric::ublas::matrix<T>;
97 using value_type = unqualified_t<T>;
98 using base_type = typename inspector<value_type>::base_type;
99 using hdf5_type = typename inspector<value_type>::hdf5_type;
100
101 static constexpr size_t ndim = 2;
102 static constexpr size_t recursive_ndim = ndim + inspector<value_type>::recursive_ndim;
103 static constexpr bool is_trivially_copyable = std::is_trivially_copyable<value_type>::value &&
104 inspector<value_type>::is_trivially_copyable;
105
106 static std::vector<size_t> getDimensions(const type& val) {
107 std::vector<size_t> sizes{val.size1(), val.size2()};
108 auto s = inspector<value_type>::getDimensions(val(0, 0));
109 sizes.insert(sizes.end(), s.begin(), s.end());
110 return sizes;
111 }
112
113 static size_t getSizeVal(const type& val) {
114 return compute_total_size(getDimensions(val));
115 }
116
117 static size_t getSize(const std::vector<size_t>& dims) {
118 return compute_total_size(dims);
119 }
120
121 static void prepare(type& val, const std::vector<size_t>& dims) {
122 if (dims.size() < ndim) {
123 std::ostringstream os;
124 os << "Impossible to pair DataSet with " << dims.size() << " dimensions into a " << ndim
125 << " boost::numeric::ublas::matrix";
126 throw DataSpaceException(os.str());
127 }
128 val.resize(dims[0], dims[1], false);
129 }
130
131 static hdf5_type* data(type& val) {
132 return inspector<value_type>::data(val(0, 0));
133 }
134
135 static const hdf5_type* data(const type& val) {
136 return inspector<value_type>::data(val(0, 0));
137 }
138
139 static void serialize(const type& val, hdf5_type* m) {
140 size_t size = val.size1() * val.size2();
141 size_t subsize = inspector<value_type>::getSizeVal(val(0, 0));
142 for (size_t i = 0; i < size; ++i) {
143 inspector<value_type>::serialize(*(&val(0, 0) + i), m + i * subsize);
144 }
145 }
146
147 static void unserialize(const hdf5_type* vec_align,
148 const std::vector<size_t>& dims,
149 type& val) {
150 std::vector<size_t> next_dims(dims.begin() + ndim, dims.end());
151 size_t subsize = compute_total_size(next_dims);
152 size_t size = val.size1() * val.size2();
153 for (size_t i = 0; i < size; ++i) {
154 inspector<value_type>::unserialize(vec_align + i * subsize,
155 next_dims,
156 *(&val(0, 0) + i));
157 }
158 }
159};
160
161} // namespace details
162} // namespace HighFive
163
164#endif
size_t getSize(const File &file, const std::string &path)
Get the size of an existing DataSet in an open HDF5 file.
Definition H5Easy_public.hpp:82
Definition H5_definitions.hpp:22
size_t compute_total_size(const std::vector< size_t > &dims)
Definition H5Inspector_decl.hpp:10