HighFive 2.10.1
HighFive - Header-only C++ HDF5 interface
Loading...
Searching...
No Matches
H5Slice_traits.hpp
Go to the documentation of this file.
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#pragma once
10
11#include <cstdlib>
12#include <vector>
13
14#include "H5_definitions.hpp"
15#include "H5Utils.hpp"
16
17#include "../H5PropertyList.hpp"
18#include "h5s_wrapper.hpp"
19
20namespace HighFive {
21
23 public:
29 explicit ElementSet(std::initializer_list<std::size_t> list);
34 explicit ElementSet(std::initializer_list<std::vector<std::size_t>> list);
40 explicit ElementSet(const std::vector<std::size_t>& element_ids);
45 explicit ElementSet(const std::vector<std::vector<std::size_t>>& element_ids);
46
47 private:
48 std::vector<std::size_t> _ids;
49
50 template <typename Derivate>
51 friend class SliceTraits;
52};
53
54namespace detail {
55
56template <class To, class From>
57inline std::vector<To> convertSizeVector(const std::vector<From>& from) {
58 std::vector<To> to(from.size());
59 std::copy(from.cbegin(), from.cend(), to.begin());
60
61 return to;
62}
63} // namespace detail
64
65inline std::vector<hsize_t> toHDF5SizeVector(const std::vector<size_t>& from) {
66 return detail::convertSizeVector<hsize_t>(from);
67}
68
69inline std::vector<size_t> toSTLSizeVector(const std::vector<hsize_t>& from) {
70 return detail::convertSizeVector<size_t>(from);
71}
72
74 RegularHyperSlab() = default;
75
76 RegularHyperSlab(std::vector<size_t> offset_,
77 std::vector<size_t> count_ = {},
78 std::vector<size_t> stride_ = {},
79 std::vector<size_t> block_ = {})
80 : offset(toHDF5SizeVector(offset_))
81 , count(toHDF5SizeVector(count_))
82 , stride(toHDF5SizeVector(stride_))
83 , block(toHDF5SizeVector(block_)) {}
84
85 static RegularHyperSlab fromHDF5Sizes(std::vector<hsize_t> offset_,
86 std::vector<hsize_t> count_ = {},
87 std::vector<hsize_t> stride_ = {},
88 std::vector<hsize_t> block_ = {}) {
90 slab.offset = offset_;
91 slab.count = count_;
92 slab.stride = stride_;
93 slab.block = block_;
94
95 return slab;
96 }
97
98 size_t rank() const {
99 return std::max(std::max(offset.size(), count.size()),
100 std::max(stride.size(), block.size()));
101 }
102
104 std::vector<size_t> packedDims() const {
105 auto n_dims = rank();
106 auto dims = std::vector<size_t>(n_dims, 0);
107
108 for (size_t i = 0; i < n_dims; ++i) {
109 dims[i] = count[i] * (block.empty() ? 1 : block[i]);
110 }
111
112 return dims;
113 }
114
115 std::vector<hsize_t> offset;
116 std::vector<hsize_t> count;
117 std::vector<hsize_t> stride;
118 std::vector<hsize_t> block;
119};
120
122 public:
124 selects.emplace_back(RegularHyperSlab{}, Op::None);
125 };
126
127 explicit HyperSlab(const RegularHyperSlab& sel) {
128 selects.emplace_back(sel, Op::Set);
129 }
130
132 auto ret = *this;
133 ret |= sel;
134 return ret;
135 }
136
138 selects.emplace_back(sel, Op::Or);
139 return *this;
140 }
141
143 auto ret = *this;
144 ret &= sel;
145 return ret;
146 }
147
149 selects.emplace_back(sel, Op::And);
150 return *this;
151 }
152
154 auto ret = *this;
155 ret ^= sel;
156 return ret;
157 }
158
160 selects.emplace_back(sel, Op::Xor);
161 return *this;
162 }
163
165 selects.emplace_back(sel, Op::NotA);
166 return *this;
167 }
168
170 selects.emplace_back(sel, Op::NotB);
171 return *this;
172 }
173
174 DataSpace apply(const DataSpace& space_) const {
175 return apply_impl(space_);
176 }
177
178 private:
179 enum class Op {
180 Noop,
181 Set,
182 Or,
183 And,
184 Xor,
185 NotB,
186 NotA,
187 Append,
188 Prepend,
189 Invalid,
190 None,
191 };
192
193 H5S_seloper_t convert(Op op) const {
194 switch (op) {
195 case Op::Noop:
196 return H5S_SELECT_NOOP;
197 case Op::Set:
198 return H5S_SELECT_SET;
199 case Op::Or:
200 return H5S_SELECT_OR;
201 case Op::And:
202 return H5S_SELECT_AND;
203 case Op::Xor:
204 return H5S_SELECT_XOR;
205 case Op::NotB:
206 return H5S_SELECT_NOTB;
207 case Op::NotA:
208 return H5S_SELECT_NOTA;
209 case Op::Append:
210 return H5S_SELECT_APPEND;
211 case Op::Prepend:
212 return H5S_SELECT_PREPEND;
213 case Op::Invalid:
214 return H5S_SELECT_INVALID;
215 default:
216 throw DataSpaceException("Invalid HyperSlab operation.");
217 }
218 }
219
220 struct Select_: public RegularHyperSlab {
221 Select_(const RegularHyperSlab& sel, Op op_)
222 : RegularHyperSlab(sel)
223 , op(op_) {}
224
225 Op op;
226 };
227
228 std::vector<Select_> selects;
229
230 protected:
231 DataSpace select_none(const DataSpace& outer_space) const {
232 auto space = outer_space.clone();
233 detail::h5s_select_none(space.getId());
234 return space;
235 }
236
237 void select_hyperslab(DataSpace& space, const Select_& sel) const {
238 detail::h5s_select_hyperslab(space.getId(),
239 convert(sel.op),
240 sel.offset.empty() ? nullptr : sel.offset.data(),
241 sel.stride.empty() ? nullptr : sel.stride.data(),
242 sel.count.empty() ? nullptr : sel.count.data(),
243 sel.block.empty() ? nullptr : sel.block.data());
244 }
245
246#if H5_VERSION_GE(1, 10, 6)
248 size_t detect_streak(Select_ const* begin, Select_ const* end, Op op) const {
249 assert(op == Op::Or);
250 auto it = std::find_if(begin, end, [op](const Select_& sel) { return sel.op != op; });
251 return static_cast<size_t>(it - begin);
252 }
253
254 DataSpace combine_selections(const DataSpace& left_space,
255 Op op,
256 const DataSpace& right_space) const {
257 assert(op == Op::Or);
258
259 auto left_type = detail::h5s_get_select_type(left_space.getId());
260 auto right_type = detail::h5s_get_select_type(right_space.getId());
261
262 // Since HDF5 doesn't allow `combine_selections` with a None
263 // selection, we need to avoid the issue:
264 if (left_type == H5S_SEL_NONE) {
265 return right_space;
266 } else if (right_type == H5S_SEL_NONE) {
267 return left_space;
268 } else if (left_type == H5S_SEL_ALL) {
269 return left_space;
270 } else if (right_type == H5S_SEL_ALL) {
271 return right_space;
272 } else {
273 return detail::make_data_space(
274 detail::h5s_combine_select(left_space.getId(), convert(op), right_space.getId()));
275 }
276 }
277
289 DataSpace reduce_streak(const DataSpace& outer_space,
290 Select_ const* begin,
291 Select_ const* end,
292 Op op) const {
293 assert(op == Op::Or);
294
295 if (begin == end) {
296 throw std::runtime_error("Broken logic in 'DataSpace::reduce_streak'.");
297 }
298
299 std::ptrdiff_t distance = end - begin;
300 if (distance == 1) {
301 auto space = select_none(outer_space);
302 select_hyperslab(space, *begin);
303 return space;
304 }
305
306 Select_ const* mid = begin + distance / 2;
307 auto right_space = reduce_streak(outer_space, begin, mid, op);
308 auto left_space = reduce_streak(outer_space, mid, end, op);
309
310 return combine_selections(left_space, op, right_space);
311 }
312
313 DataSpace apply_impl(const DataSpace& space_) const {
314 auto space = space_.clone();
315 auto n_selects = selects.size();
316 for (size_t i = 0; i < n_selects; ++i) {
317 auto begin = selects.data() + i;
318 auto end = selects.data() + n_selects;
319
320 auto n_ors = detect_streak(begin, end, Op::Or);
321
322 if (n_ors > 1) {
323 auto right_space = reduce_streak(space_, begin, begin + n_ors, Op::Or);
324 space = combine_selections(space, Op::Or, right_space);
325 i += n_ors - 1;
326 } else if (selects[i].op == Op::None) {
327 detail::h5s_select_none(space.getId());
328 } else {
329 select_hyperslab(space, selects[i]);
330 }
331 }
332 return space;
333 }
334#else
335 DataSpace apply_impl(const DataSpace& space_) const {
336 auto space = space_.clone();
337 for (const auto& sel: selects) {
338 if (sel.op == Op::None) {
339 detail::h5s_select_none(space.getId());
340 } else {
341 select_hyperslab(space, sel);
342 }
343 }
344 return space;
345 }
346#endif
347};
348
349template <typename Derivate>
351 public:
360 Selection select(const HyperSlab& hyperslab) const;
361
369 Selection select(const HyperSlab& hyperslab, const DataSpace& memspace) const;
370
378 Selection select(const std::vector<size_t>& offset,
379 const std::vector<size_t>& count,
380 const std::vector<size_t>& stride = {},
381 const std::vector<size_t>& block = {}) const;
382
388 Selection select(const std::vector<size_t>& columns) const;
389
393 Selection select(const ElementSet& elements) const;
394
395 template <typename T>
396 T read(const DataTransferProps& xfer_props = DataTransferProps()) const;
397
408 template <typename T>
409 void read(T& array, const DataTransferProps& xfer_props = DataTransferProps()) const;
410
422 template <typename T>
423 void read(T* array,
424 const DataType& dtype,
425 const DataTransferProps& xfer_props = DataTransferProps()) const;
426
438 template <typename T>
439 void read(T* array, const DataTransferProps& xfer_props = DataTransferProps()) const;
440
450 template <typename T>
451 void read_raw(T* array,
452 const DataType& dtype,
453 const DataTransferProps& xfer_props = DataTransferProps()) const;
454
464 template <typename T>
465 void read_raw(T* array, const DataTransferProps& xfer_props = DataTransferProps()) const;
466
467
475 template <typename T>
476 void write(const T& buffer, const DataTransferProps& xfer_props = DataTransferProps());
477
492 template <typename T>
493 void write_raw(const T* buffer,
494 const DataType& mem_datatype,
495 const DataTransferProps& xfer_props = DataTransferProps());
496
504 template <typename T>
505 void write_raw(const T* buffer, const DataTransferProps& xfer_props = DataTransferProps());
506};
507
508} // namespace HighFive
Class representing the space (dimensions) of a DataSet.
Definition H5DataSpace.hpp:39
DataSpace clone() const
Create a copy of the DataSpace which will have different id.
Definition H5Dataspace_misc.hpp:94
HDF5 Data Type.
Definition H5DataType.hpp:61
Definition H5Slice_traits.hpp:22
ElementSet(std::initializer_list< std::size_t > list)
Create a list of points of N-dimension for selection.
Definition H5Slice_traits_misc.hpp:51
Definition H5Slice_traits.hpp:121
HyperSlab & notA(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:164
DataSpace apply_impl(const DataSpace &space_) const
Definition H5Slice_traits.hpp:335
HyperSlab & notB(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:169
HyperSlab operator&(const RegularHyperSlab &sel) const
Definition H5Slice_traits.hpp:142
HyperSlab operator^(const RegularHyperSlab &sel) const
Definition H5Slice_traits.hpp:153
HyperSlab operator|(const RegularHyperSlab &sel) const
Definition H5Slice_traits.hpp:131
HyperSlab & operator&=(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:148
HyperSlab()
Definition H5Slice_traits.hpp:123
void select_hyperslab(DataSpace &space, const Select_ &sel) const
Definition H5Slice_traits.hpp:237
HyperSlab & operator^=(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:159
DataSpace select_none(const DataSpace &outer_space) const
Definition H5Slice_traits.hpp:231
HyperSlab(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:127
HyperSlab & operator|=(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:137
DataSpace apply(const DataSpace &space_) const
Definition H5Slice_traits.hpp:174
hid_t getId() const noexcept
getId
Definition H5Object_misc.hpp:69
HDF5 property Lists.
Definition H5PropertyList.hpp:160
Selection: represent a view on a slice/part of a dataset.
Definition H5Selection.hpp:27
Definition H5Slice_traits.hpp:350
T read(const DataTransferProps &xfer_props=DataTransferProps()) const
Definition H5Slice_traits_misc.hpp:160
void write(const T &buffer, const DataTransferProps &xfer_props=DataTransferProps())
Definition H5Slice_traits_misc.hpp:256
Selection select(const HyperSlab &hyperslab) const
Select an hyperslab in the current Slice/Dataset.
Definition H5Slice_traits_misc.hpp:82
void read_raw(T *array, const DataType &dtype, const DataTransferProps &xfer_props=DataTransferProps()) const
Definition H5Slice_traits_misc.hpp:227
void write_raw(const T *buffer, const DataType &mem_datatype, const DataTransferProps &xfer_props=DataTransferProps())
Definition H5Slice_traits_misc.hpp:281
PropertyList< PropertyType::DATASET_XFER > DataTransferProps
Definition H5PropertyList.hpp:203
Definition H5_definitions.hpp:22
std::vector< size_t > toSTLSizeVector(const std::vector< hsize_t > &from)
Definition H5Slice_traits.hpp:69
std::vector< hsize_t > toHDF5SizeVector(const std::vector< size_t > &from)
Definition H5Slice_traits.hpp:65
Definition H5Slice_traits.hpp:73
size_t rank() const
Definition H5Slice_traits.hpp:98
std::vector< hsize_t > offset
Definition H5Slice_traits.hpp:115
std::vector< hsize_t > block
Definition H5Slice_traits.hpp:118
std::vector< size_t > packedDims() const
Dimensions when all gaps are removed.
Definition H5Slice_traits.hpp:104
RegularHyperSlab(std::vector< size_t > offset_, std::vector< size_t > count_={}, std::vector< size_t > stride_={}, std::vector< size_t > block_={})
Definition H5Slice_traits.hpp:76
std::vector< hsize_t > count
Definition H5Slice_traits.hpp:116
static RegularHyperSlab fromHDF5Sizes(std::vector< hsize_t > offset_, std::vector< hsize_t > count_={}, std::vector< hsize_t > stride_={}, std::vector< hsize_t > block_={})
Definition H5Slice_traits.hpp:85
std::vector< hsize_t > stride
Definition H5Slice_traits.hpp:117