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 ElementSet(std::initializer_list<std::size_t> list);
35 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 explicit 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 const* it =
241 std::find_if(begin, end, [op](const Select_& sel) { return sel.op != op; });
242 return static_cast<size_t>(it - begin);
243 }
244
245 DataSpace combine_selections(const DataSpace& left_space,
246 Op op,
247 const DataSpace& right_space) const {
248 assert(op == Op::Or);
249
250 auto left_type = detail::h5s_get_select_type(left_space.getId());
251 auto right_type = detail::h5s_get_select_type(right_space.getId());
252
253 // Since HDF5 doesn't allow `combine_selections` with a None
254 // selection, we need to avoid the issue:
255 if (left_type == H5S_SEL_NONE) {
256 return right_space;
257 } else if (right_type == H5S_SEL_NONE) {
258 return left_space;
259 } else if (left_type == H5S_SEL_ALL) {
260 return left_space;
261 } else if (right_type == H5S_SEL_ALL) {
262 return right_space;
263 } else {
264 return detail::make_data_space(
265 detail::h5s_combine_select(left_space.getId(), convert(op), right_space.getId()));
266 }
267 }
268
280 DataSpace reduce_streak(const DataSpace& outer_space,
281 Select_ const* begin,
282 Select_ const* end,
283 Op op) const {
284 assert(op == Op::Or);
285
286 if (begin == end) {
287 throw std::runtime_error("Broken logic in 'DataSpace::reduce_streak'.");
288 }
289
290 std::ptrdiff_t distance = end - begin;
291 if (distance == 1) {
292 auto space = select_none(outer_space);
293 select_hyperslab(space, *begin);
294 return space;
295 }
296
297 Select_ const* mid = begin + distance / 2;
298 auto right_space = reduce_streak(outer_space, begin, mid, op);
299 auto left_space = reduce_streak(outer_space, mid, end, op);
300
301 return combine_selections(left_space, op, right_space);
302 }
303
304 DataSpace apply_impl(const DataSpace& space_) const {
305 auto space = space_.clone();
306 auto n_selects = selects.size();
307 for (size_t i = 0; i < n_selects; ++i) {
308 auto const* const begin = selects.data() + i;
309 auto const* const end = selects.data() + n_selects;
310
311 auto n_ors = detect_streak(begin, end, Op::Or);
312
313 if (n_ors > 1) {
314 auto right_space = reduce_streak(space_, begin, begin + n_ors, Op::Or);
315 space = combine_selections(space, Op::Or, right_space);
316 i += n_ors - 1;
317 } else if (selects[i].op == Op::None) {
318 detail::h5s_select_none(space.getId());
319 } else {
320 select_hyperslab(space, selects[i]);
321 }
322 }
323 return space;
324 }
325#else
326 DataSpace apply_impl(const DataSpace& space_) const {
327 auto space = space_.clone();
328 for (const auto& sel: selects) {
329 if (sel.op == Op::None) {
330 detail::h5s_select_none(space.getId());
331 } else {
332 select_hyperslab(space, sel);
333 }
334 }
335 return space;
336 }
337#endif
338};
339
407 public:
408 template <class... Slices>
409 explicit ProductSet(const Slices&... slices);
410
411 private:
412 HyperSlab slab;
413 std::vector<size_t> shape;
414
415 template <typename Derivate>
416 friend class SliceTraits;
417};
418
419
420template <typename Derivate>
422 public:
431 Selection select(const HyperSlab& hyper_slab) const;
432
440 Selection select(const HyperSlab& hyper_slab, const DataSpace& memspace) const;
441
449 Selection select(const std::vector<size_t>& offset,
450 const std::vector<size_t>& count,
451 const std::vector<size_t>& stride = {},
452 const std::vector<size_t>& block = {}) const;
453
459 Selection select(const std::vector<size_t>& columns) const;
460
464 Selection select(const ElementSet& elements) const;
465
471 Selection select(const ProductSet& product_set) const;
472
473 template <typename T>
474 T read(const DataTransferProps& xfer_props = DataTransferProps()) const;
475
486 template <typename T>
487 void read(T& array, const DataTransferProps& xfer_props = DataTransferProps()) const;
488
498 template <typename T>
499 void read_raw(T* array,
500 const DataType& mem_datatype,
501 const DataTransferProps& xfer_props = DataTransferProps()) const;
502
512 template <typename T>
513 void read_raw(T* array, const DataTransferProps& xfer_props = DataTransferProps()) const;
514
515
523 template <typename T>
524 void write(const T& buffer, const DataTransferProps& xfer_props = DataTransferProps());
525
540 template <typename T>
541 void write_raw(const T* buffer,
542 const DataType& mem_datatype,
543 const DataTransferProps& xfer_props = DataTransferProps());
544
552 template <typename T>
553 void write_raw(const T* buffer, const DataTransferProps& xfer_props = DataTransferProps());
554
564 Selection squeezeMemSpace(const std::vector<size_t>& axes) const;
565
575 Selection reshapeMemSpace(const std::vector<size_t>& dims) const;
576};
577
578} // 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:93
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:326
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:75
Selects the Cartesian product of slices.
Definition H5Slice_traits.hpp:406
HDF5 property Lists.
Definition H5PropertyList.hpp:138
Selection: represent a view on a slice/part of a dataset.
Definition H5Selection.hpp:27
Definition H5Slice_traits.hpp:421
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
Selection select(const HyperSlab &hyper_slab) const
Select an hyper_slab in the current Slice/Dataset.
Definition H5Slice_traits_misc.hpp:232
void write(const T &buffer, const DataTransferProps &xfer_props=DataTransferProps())
Definition H5Slice_traits_misc.hpp:404
void read_raw(T *array, const DataType &mem_datatype, const DataTransferProps &xfer_props=DataTransferProps()) const
Definition H5Slice_traits_misc.hpp:375
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 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:179
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