HighFive 3.0.0
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"
17
18#include "../H5PropertyList.hpp"
19#include "h5s_wrapper.hpp"
20
21namespace HighFive {
22
24 public:
30 explicit ElementSet(std::initializer_list<std::size_t> list);
35 explicit ElementSet(std::initializer_list<std::vector<std::size_t>> list);
41 explicit ElementSet(const std::vector<std::size_t>& element_ids);
46 explicit ElementSet(const std::vector<std::vector<std::size_t>>& element_ids);
47
48 private:
49 std::vector<std::size_t> _ids;
50
51 template <typename Derivate>
52 friend class SliceTraits;
53};
54
55inline std::vector<hsize_t> toHDF5SizeVector(const std::vector<size_t>& from) {
56 return detail::convertSizeVector<hsize_t>(from);
57}
58
59inline std::vector<size_t> toSTLSizeVector(const std::vector<hsize_t>& from) {
60 return detail::convertSizeVector<size_t>(from);
61}
62
64 RegularHyperSlab() = default;
65
66 RegularHyperSlab(const std::vector<size_t>& offset_,
67 const std::vector<size_t>& count_ = {},
68 const std::vector<size_t>& stride_ = {},
69 const std::vector<size_t>& block_ = {})
70 : offset(toHDF5SizeVector(offset_))
71 , count(toHDF5SizeVector(count_))
72 , stride(toHDF5SizeVector(stride_))
73 , block(toHDF5SizeVector(block_)) {}
74
75 static RegularHyperSlab fromHDF5Sizes(std::vector<hsize_t> offset_,
76 std::vector<hsize_t> count_ = {},
77 std::vector<hsize_t> stride_ = {},
78 std::vector<hsize_t> block_ = {}) {
80 slab.offset = std::move(offset_);
81 slab.count = std::move(count_);
82 slab.stride = std::move(stride_);
83 slab.block = std::move(block_);
84
85 return slab;
86 }
87
88 size_t rank() const {
89 return std::max(std::max(offset.size(), count.size()),
90 std::max(stride.size(), block.size()));
91 }
92
94 std::vector<size_t> packedDims() const {
95 auto n_dims = rank();
96 auto dims = std::vector<size_t>(n_dims, 0);
97
98 for (size_t i = 0; i < n_dims; ++i) {
99 dims[i] = count[i] * (block.empty() ? 1 : block[i]);
100 }
101
102 return dims;
103 }
104
105 std::vector<hsize_t> offset;
106 std::vector<hsize_t> count;
107 std::vector<hsize_t> stride;
108 std::vector<hsize_t> block;
109};
110
112 public:
114 selects.emplace_back(RegularHyperSlab{}, Op::None);
115 };
116
117 explicit HyperSlab(const RegularHyperSlab& sel) {
118 selects.emplace_back(sel, Op::Set);
119 }
120
122 auto ret = *this;
123 ret |= sel;
124 return ret;
125 }
126
128 selects.emplace_back(sel, Op::Or);
129 return *this;
130 }
131
133 auto ret = *this;
134 ret &= sel;
135 return ret;
136 }
137
139 selects.emplace_back(sel, Op::And);
140 return *this;
141 }
142
144 auto ret = *this;
145 ret ^= sel;
146 return ret;
147 }
148
150 selects.emplace_back(sel, Op::Xor);
151 return *this;
152 }
153
155 selects.emplace_back(sel, Op::NotA);
156 return *this;
157 }
158
160 selects.emplace_back(sel, Op::NotB);
161 return *this;
162 }
163
164 DataSpace apply(const DataSpace& space_) const {
165 return apply_impl(space_);
166 }
167
168 private:
169 enum class Op {
170 Noop,
171 Set,
172 Or,
173 And,
174 Xor,
175 NotB,
176 NotA,
177 Append,
178 Prepend,
179 Invalid,
180 None,
181 };
182
183 H5S_seloper_t convert(Op op) const {
184 switch (op) {
185 case Op::Noop:
186 return H5S_SELECT_NOOP;
187 case Op::Set:
188 return H5S_SELECT_SET;
189 case Op::Or:
190 return H5S_SELECT_OR;
191 case Op::And:
192 return H5S_SELECT_AND;
193 case Op::Xor:
194 return H5S_SELECT_XOR;
195 case Op::NotB:
196 return H5S_SELECT_NOTB;
197 case Op::NotA:
198 return H5S_SELECT_NOTA;
199 case Op::Append:
200 return H5S_SELECT_APPEND;
201 case Op::Prepend:
202 return H5S_SELECT_PREPEND;
203 case Op::Invalid:
204 return H5S_SELECT_INVALID;
205 default:
206 throw DataSpaceException("Invalid HyperSlab operation.");
207 }
208 }
209
210 struct Select_: public RegularHyperSlab {
211 Select_(const RegularHyperSlab& sel, Op op_)
212 : RegularHyperSlab(sel)
213 , op(op_) {}
214
215 Op op;
216 };
217
218 std::vector<Select_> selects;
219
220 protected:
221 DataSpace select_none(const DataSpace& outer_space) const {
222 auto space = outer_space.clone();
223 detail::h5s_select_none(space.getId());
224 return space;
225 }
226
227 void select_hyperslab(DataSpace& space, const Select_& sel) const {
228 detail::h5s_select_hyperslab(space.getId(),
229 convert(sel.op),
230 sel.offset.empty() ? nullptr : sel.offset.data(),
231 sel.stride.empty() ? nullptr : sel.stride.data(),
232 sel.count.empty() ? nullptr : sel.count.data(),
233 sel.block.empty() ? nullptr : sel.block.data());
234 }
235
236#if H5_VERSION_GE(1, 10, 6)
238 size_t detect_streak(Select_ const* begin, Select_ const* end, Op op) const {
239 assert(op == Op::Or);
240 auto it = std::find_if(begin, end, [op](const Select_& sel) { return sel.op != op; });
241 return static_cast<size_t>(it - begin);
242 }
243
244 DataSpace combine_selections(const DataSpace& left_space,
245 Op op,
246 const DataSpace& right_space) const {
247 assert(op == Op::Or);
248
249 auto left_type = detail::h5s_get_select_type(left_space.getId());
250 auto right_type = detail::h5s_get_select_type(right_space.getId());
251
252 // Since HDF5 doesn't allow `combine_selections` with a None
253 // selection, we need to avoid the issue:
254 if (left_type == H5S_SEL_NONE) {
255 return right_space;
256 } else if (right_type == H5S_SEL_NONE) {
257 return left_space;
258 } else if (left_type == H5S_SEL_ALL) {
259 return left_space;
260 } else if (right_type == H5S_SEL_ALL) {
261 return right_space;
262 } else {
263 return detail::make_data_space(
264 detail::h5s_combine_select(left_space.getId(), convert(op), right_space.getId()));
265 }
266 }
267
279 DataSpace reduce_streak(const DataSpace& outer_space,
280 Select_ const* begin,
281 Select_ const* end,
282 Op op) const {
283 assert(op == Op::Or);
284
285 if (begin == end) {
286 throw std::runtime_error("Broken logic in 'DataSpace::reduce_streak'.");
287 }
288
289 std::ptrdiff_t distance = end - begin;
290 if (distance == 1) {
291 auto space = select_none(outer_space);
292 select_hyperslab(space, *begin);
293 return space;
294 }
295
296 Select_ const* mid = begin + distance / 2;
297 auto right_space = reduce_streak(outer_space, begin, mid, op);
298 auto left_space = reduce_streak(outer_space, mid, end, op);
299
300 return combine_selections(left_space, op, right_space);
301 }
302
303 DataSpace apply_impl(const DataSpace& space_) const {
304 auto space = space_.clone();
305 auto n_selects = selects.size();
306 for (size_t i = 0; i < n_selects; ++i) {
307 auto begin = selects.data() + i;
308 auto end = selects.data() + n_selects;
309
310 auto n_ors = detect_streak(begin, end, Op::Or);
311
312 if (n_ors > 1) {
313 auto right_space = reduce_streak(space_, begin, begin + n_ors, Op::Or);
314 space = combine_selections(space, Op::Or, right_space);
315 i += n_ors - 1;
316 } else if (selects[i].op == Op::None) {
317 detail::h5s_select_none(space.getId());
318 } else {
319 select_hyperslab(space, selects[i]);
320 }
321 }
322 return space;
323 }
324#else
325 DataSpace apply_impl(const DataSpace& space_) const {
326 auto space = space_.clone();
327 for (const auto& sel: selects) {
328 if (sel.op == Op::None) {
329 detail::h5s_select_none(space.getId());
330 } else {
331 select_hyperslab(space, sel);
332 }
333 }
334 return space;
335 }
336#endif
337};
338
406 public:
407 template <class... Slices>
408 explicit ProductSet(const Slices&... slices);
409
410 private:
411 HyperSlab slab;
412 std::vector<size_t> shape;
413
414 template <typename Derivate>
415 friend class SliceTraits;
416};
417
418
419template <typename Derivate>
421 public:
430 Selection select(const HyperSlab& hyperslab) const;
431
439 Selection select(const HyperSlab& hyperslab, const DataSpace& memspace) const;
440
448 Selection select(const std::vector<size_t>& offset,
449 const std::vector<size_t>& count,
450 const std::vector<size_t>& stride = {},
451 const std::vector<size_t>& block = {}) const;
452
458 Selection select(const std::vector<size_t>& columns) const;
459
463 Selection select(const ElementSet& elements) const;
464
470 Selection select(const ProductSet& product_set) const;
471
472 template <typename T>
473 T read(const DataTransferProps& xfer_props = DataTransferProps()) const;
474
485 template <typename T>
486 void read(T& array, const DataTransferProps& xfer_props = DataTransferProps()) const;
487
497 template <typename T>
498 void read_raw(T* array,
499 const DataType& dtype,
500 const DataTransferProps& xfer_props = DataTransferProps()) const;
501
511 template <typename T>
512 void read_raw(T* array, const DataTransferProps& xfer_props = DataTransferProps()) const;
513
514
522 template <typename T>
523 void write(const T& buffer, const DataTransferProps& xfer_props = DataTransferProps());
524
539 template <typename T>
540 void write_raw(const T* buffer,
541 const DataType& mem_datatype,
542 const DataTransferProps& xfer_props = DataTransferProps());
543
551 template <typename T>
552 void write_raw(const T* buffer, const DataTransferProps& xfer_props = DataTransferProps());
553
563 Selection squeezeMemSpace(const std::vector<size_t>& axes) const;
564
574 Selection reshapeMemSpace(const std::vector<size_t>& dims) const;
575};
576
577} // 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:23
Definition H5Slice_traits.hpp:111
HyperSlab & notA(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:154
DataSpace apply_impl(const DataSpace &space_) const
Definition H5Slice_traits.hpp:325
HyperSlab & notB(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:159
HyperSlab operator&(const RegularHyperSlab &sel) const
Definition H5Slice_traits.hpp:132
HyperSlab operator^(const RegularHyperSlab &sel) const
Definition H5Slice_traits.hpp:143
HyperSlab operator|(const RegularHyperSlab &sel) const
Definition H5Slice_traits.hpp:121
HyperSlab & operator&=(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:138
HyperSlab()
Definition H5Slice_traits.hpp:113
void select_hyperslab(DataSpace &space, const Select_ &sel) const
Definition H5Slice_traits.hpp:227
HyperSlab & operator^=(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:149
DataSpace select_none(const DataSpace &outer_space) const
Definition H5Slice_traits.hpp:221
HyperSlab(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:117
HyperSlab & operator|=(const RegularHyperSlab &sel)
Definition H5Slice_traits.hpp:127
DataSpace apply(const DataSpace &space_) const
Definition H5Slice_traits.hpp:164
hid_t getId() const noexcept
getId
Definition H5Object_misc.hpp:63
Selects the Cartesian product of slices.
Definition H5Slice_traits.hpp:405
HDF5 property Lists.
Definition H5PropertyList.hpp:158
Selection: represent a view on a slice/part of a dataset.
Definition H5Selection.hpp:27
Definition H5Slice_traits.hpp:420
Selection squeezeMemSpace(const std::vector< size_t > &axes) const
Return a Selection with axes squeezed from the memspace.
Definition H5Slice_traits_misc.hpp:465
T read(const DataTransferProps &xfer_props=DataTransferProps()) const
Definition H5Slice_traits_misc.hpp:321
void write(const T &buffer, const DataTransferProps &xfer_props=DataTransferProps())
Definition H5Slice_traits_misc.hpp:404
Selection select(const HyperSlab &hyperslab) const
Select an hyperslab in the current Slice/Dataset.
Definition H5Slice_traits_misc.hpp:232
Selection reshapeMemSpace(const std::vector< size_t > &dims) const
Return a Selection with a simple memspace with dims.
Definition H5Slice_traits_misc.hpp:476
void read_raw(T *array, const DataType &dtype, const DataTransferProps &xfer_props=DataTransferProps()) const
Definition H5Slice_traits_misc.hpp:375
void write_raw(const T *buffer, const DataType &mem_datatype, const DataTransferProps &xfer_props=DataTransferProps())
Definition H5Slice_traits_misc.hpp:430
PropertyList< PropertyType::DATASET_XFER > DataTransferProps
Definition H5PropertyList.hpp:200
Definition assert_compatible_spaces.hpp:15
std::vector< size_t > toSTLSizeVector(const std::vector< hsize_t > &from)
Definition H5Slice_traits.hpp:59
std::vector< hsize_t > toHDF5SizeVector(const std::vector< size_t > &from)
Definition H5Slice_traits.hpp:55
Definition H5Slice_traits.hpp:63
size_t rank() const
Definition H5Slice_traits.hpp:88
std::vector< hsize_t > offset
Definition H5Slice_traits.hpp:105
RegularHyperSlab(const std::vector< size_t > &offset_, const std::vector< size_t > &count_={}, const std::vector< size_t > &stride_={}, const std::vector< size_t > &block_={})
Definition H5Slice_traits.hpp:66
std::vector< hsize_t > block
Definition H5Slice_traits.hpp:108
std::vector< size_t > packedDims() const
Dimensions when all gaps are removed.
Definition H5Slice_traits.hpp:94
std::vector< hsize_t > count
Definition H5Slice_traits.hpp:106
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:75
std::vector< hsize_t > stride
Definition H5Slice_traits.hpp:107