H5Slice_traits_misc.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 #ifndef H5SLICE_TRAITS_MISC_HPP
10 #define H5SLICE_TRAITS_MISC_HPP
11 
12 #include "H5Slice_traits.hpp"
13 
14 #include <algorithm>
15 #include <cassert>
16 #include <functional>
17 #include <numeric>
18 #include <sstream>
19 #include <string>
20 
21 #ifdef H5_USE_BOOST
22 #include <boost/multi_array.hpp>
23 #include <boost/numeric/ublas/matrix.hpp>
24 #endif
25 
26 #include <H5Dpublic.h>
27 #include <H5Ppublic.h>
28 
29 #include "../H5DataSpace.hpp"
30 #include "../H5DataType.hpp"
31 #include "../H5Selection.hpp"
32 
33 #include "H5Converter_misc.hpp"
34 
35 namespace HighFive {
36 
37 namespace details {
38 
39 // map the correct reference to the dataset depending of the layout
40 // dataset -> itself
41 // subselection -> parent dataset
42 inline const DataSet& get_dataset(const Selection* ptr) {
43  return ptr->getDataset();
44 }
45 
46 inline const DataSet& get_dataset(const DataSet* ptr) { return *ptr; }
47 
48 // map the correct memspace identifier depending of the layout
49 // dataset -> entire memspace
50 // selection -> resolve space id
51 inline hid_t get_memspace_id(const Selection* ptr) {
52  return ptr->getMemSpace().getId();
53 }
54 
55 inline hid_t get_memspace_id(const DataSet* ptr) {
56  (void)ptr;
57  return H5S_ALL;
58 }
59 }
60 
61 inline ElementSet::ElementSet(const std::vector<std::size_t>& element_ids)
62  : _ids(element_ids) {}
63 
64 template <typename Derivate>
65 inline Selection
66 SliceTraits<Derivate>::select(const std::vector<size_t>& offset,
67  const std::vector<size_t>& count,
68  const std::vector<size_t>& stride) const {
69  // hsize_t type convertion
70  // TODO : normalize hsize_t type in HighFive namespace
71  std::vector<hsize_t> offset_local(offset.size());
72  std::vector<hsize_t> count_local(count.size());
73  std::vector<hsize_t> stride_local(stride.size());
74  std::copy(offset.begin(), offset.end(), offset_local.begin());
75  std::copy(count.begin(), count.end(), count_local.begin());
76  std::copy(stride.begin(), stride.end(), stride_local.begin());
77 
78  DataSpace space = static_cast<const Derivate*>(this)->getSpace().clone();
79  if (H5Sselect_hyperslab(space.getId(), H5S_SELECT_SET, offset_local.data(),
80  stride.empty() ? NULL : stride_local.data(),
81  count_local.data(), NULL) < 0) {
82  HDF5ErrMapper::ToException<DataSpaceException>(
83  "Unable to select hyperslap");
84  }
85 
86  return Selection(DataSpace(count), space,
87  details::get_dataset(static_cast<const Derivate*>(this)));
88 }
89 
90 template <typename Derivate>
91 inline Selection
92 SliceTraits<Derivate>::select(const std::vector<size_t>& columns) const {
93 
94  const DataSpace& space = static_cast<const Derivate*>(this)->getSpace();
95  const DataSet& dataset =
96  details::get_dataset(static_cast<const Derivate*>(this));
97  std::vector<size_t> dims = space.getDimensions();
98  std::vector<hsize_t> counts(dims.size());
99  std::copy(dims.begin(), dims.end(), counts.begin());
100  counts[dims.size() - 1] = 1;
101  std::vector<hsize_t> offsets(dims.size(), 0);
102 
103  H5Sselect_none(space.getId());
104  for (std::vector<size_t>::const_iterator i = columns.begin();
105  i != columns.end(); ++i) {
106 
107  offsets[offsets.size() - 1] = *i;
108  if (H5Sselect_hyperslab(space.getId(), H5S_SELECT_OR, offsets.data(),
109  0, counts.data(), 0) < 0) {
110  HDF5ErrMapper::ToException<DataSpaceException>(
111  "Unable to select hyperslap");
112  }
113  }
114 
115  dims[dims.size() - 1] = columns.size();
116  return Selection(DataSpace(dims), space, dataset);
117 }
118 
119 template <typename Derivate>
120 inline Selection
122  hsize_t* data = NULL;
123  const std::size_t length = elements._ids.size();
124  std::vector<hsize_t> raw_elements;
125 
126  // optimised at compile time
127  // switch for data conversion on 32bits platforms
128  if (std::is_same<std::size_t, hsize_t>::value) {
129  data = (hsize_t*)(&(elements._ids[0]));
130  } else {
131  raw_elements.resize(length);
132  std::copy(elements._ids.begin(), elements._ids.end(),
133  raw_elements.begin());
134  data = &(raw_elements[0]);
135  }
136 
137  DataSpace space = static_cast<const Derivate*>(this)->getSpace().clone();
138  if (H5Sselect_elements(space.getId(), H5S_SELECT_SET, length, data) < 0) {
139  HDF5ErrMapper::ToException<DataSpaceException>(
140  "Unable to select elements");
141  }
142 
143  return Selection(DataSpace(length), space,
144  details::get_dataset(static_cast<const Derivate*>(this)));
145 }
146 
147 template <typename Derivate>
148 template <typename T>
149 inline void SliceTraits<Derivate>::read(T& array) const {
150  typedef typename std::remove_const<T>::type type_no_const;
151 
152  type_no_const& nocv_array = const_cast<type_no_const&>(array);
153 
154  const size_t dim_array = details::array_dims<type_no_const>::value;
155  DataSpace space = static_cast<const Derivate*>(this)->getSpace();
156  DataSpace mem_space = static_cast<const Derivate*>(this)->getMemSpace();
157 
158  if (!details::checkDimensions(mem_space, dim_array)) {
159  std::ostringstream ss;
160  ss << "Impossible to read DataSet of dimensions "
161  << mem_space.getNumberDimensions() << " into arrays of dimensions "
162  << dim_array;
163  throw DataSpaceException(ss.str());
164  }
165 
166  // Create mem datatype
168  array_datatype;
169 
170  // Apply pre-read conversions
171  details::data_converter<type_no_const> converter(nocv_array, mem_space);
172 
173  if (H5Dread(
174  details::get_dataset(static_cast<const Derivate*>(this)).getId(),
175  array_datatype.getId(),
176  details::get_memspace_id((static_cast<const Derivate*>(this))),
177  space.getId(), H5P_DEFAULT,
178  static_cast<void*>(converter.transform_read(nocv_array))) < 0) {
179  HDF5ErrMapper::ToException<DataSetException>(
180  "Error during HDF5 Read: ");
181  }
182 
183  // re-arrange results
184  converter.process_result(array);
185 }
186 
187 template <typename Derivate>
188 template <typename T>
189 inline void SliceTraits<Derivate>::read(T* array) const {
190 
191  DataSpace space = static_cast<const Derivate*>(this)->getSpace();
192  DataSpace mem_space = static_cast<const Derivate*>(this)->getMemSpace();
193 
194  // Create mem datatype
196 
197  if (H5Dread(
198  details::get_dataset(static_cast<const Derivate*>(this)).getId(),
199  array_datatype.getId(),
200  details::get_memspace_id((static_cast<const Derivate*>(this))),
201  space.getId(), H5P_DEFAULT,
202  static_cast<void*>(array)) < 0) {
203  HDF5ErrMapper::ToException<DataSetException>(
204  "Error during HDF5 Read: ");
205  }
206 }
207 
208 template <typename Derivate>
209 template <typename T>
210 inline void SliceTraits<Derivate>::write(const T& buffer) {
211  typedef typename std::remove_const<T>::type type_no_const;
212 
213  type_no_const& nocv_buffer = const_cast<type_no_const&>(buffer);
214 
215  const size_t dim_buffer = details::array_dims<type_no_const>::value;
216  DataSpace space = static_cast<const Derivate*>(this)->getSpace();
217  DataSpace mem_space = static_cast<const Derivate*>(this)->getMemSpace();
218 
219  if (!details::checkDimensions(mem_space, dim_buffer)) {
220  std::ostringstream ss;
221  ss << "Impossible to write buffer of dimensions " << dim_buffer
222  << " into dataset of dimensions " << mem_space.getNumberDimensions();
223  throw DataSpaceException(ss.str());
224  }
225 
227  array_datatype;
228 
229  // Apply pre write conversions
230  details::data_converter<type_no_const> converter(nocv_buffer, mem_space);
231 
232  if (H5Dwrite(details::get_dataset(static_cast<Derivate*>(this)).getId(),
233  array_datatype.getId(),
234  details::get_memspace_id((static_cast<Derivate*>(this))),
235  space.getId(), H5P_DEFAULT,
236  static_cast<const void*>(
237  converter.transform_write(nocv_buffer))) < 0) {
238  HDF5ErrMapper::ToException<DataSetException>(
239  "Error during HDF5 Write: ");
240  }
241 }
242 
243 template <typename Derivate>
244 template <typename T>
245 inline void SliceTraits<Derivate>::write(const T* buffer) {
246 
247  DataSpace space = static_cast<const Derivate*>(this)->getSpace();
248  DataSpace mem_space = static_cast<const Derivate*>(this)->getMemSpace();
249 
251 
252  if (H5Dwrite(details::get_dataset(static_cast<Derivate*>(this)).getId(),
253  array_datatype.getId(),
254  details::get_memspace_id((static_cast<Derivate*>(this))),
255  space.getId(), H5P_DEFAULT,
256  static_cast<const void*>(buffer)) < 0) {
257  HDF5ErrMapper::ToException<DataSetException>(
258  "Error during HDF5 Write: ");
259  }
260 }
261 }
262 
263 #endif // H5SLICE_TRAITS_MISC_HPP
void read(T &array) const
size_t getNumberDimensions() const
getNumberDimensions
Exception specific to HighFive DataSpace interface.
Definition: H5Exception.hpp:98
std::vector< std::size_t > _ids
hid_t getId() const
getId
Scalar * transform_write(Scalar &datamem)
void write(const T &buffer)
hid_t get_memspace_id(const Selection *ptr)
Scalar * transform_read(Scalar &datamem)
ElementSet(const std::vector< std::size_t > &element_ids)
create an HDF5 DataType from a C++ type
Definition: H5DataType.hpp:41
DataSpace getMemSpace() const
getMemSpace
DataSet & getDataset()
getDataSet
Selection select(const std::vector< size_t > &offset, const std::vector< size_t > &count, const std::vector< size_t > &stride=std::vector< size_t >()) const
DataSpace clone() const
const DataSet & get_dataset(const Selection *ptr)
Selection: represent a view on a slice/part of a dataset.
Definition: H5Selection.hpp:27
#define NULL
Definition: mydefs.hpp:141
bool checkDimensions(const DataSpace &mem_space, size_t input_dims)
dimension checks
std::vector< size_t > getDimensions() const
getDimensions


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Mon Feb 28 2022 22:46:06