hops
H5Dataspace_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 H5DATASPACE_MISC_HPP
10 #define H5DATASPACE_MISC_HPP
11 
12 #include <array>
13 #include <initializer_list>
14 #include <vector>
15 #include <numeric>
16 
17 #include <H5Spublic.h>
18 
19 #include "H5Utils.hpp"
20 
21 namespace HighFive {
22 
23 inline DataSpace::DataSpace(const std::vector<size_t>& dims)
24  : DataSpace(dims.begin(), dims.end()) {}
25 
26 inline DataSpace::DataSpace(const std::initializer_list<size_t>& items)
27  : DataSpace(std::vector<size_t>(items)) {}
28 
29 template<typename... Args>
30  inline DataSpace::DataSpace(size_t dim1, Args... dims)
31  : DataSpace(std::vector<size_t>{dim1, static_cast<size_t>(dims)...}) {}
32 
33 template <class IT, typename>
34 inline DataSpace::DataSpace(const IT begin, const IT end) {
35  std::vector<hsize_t> real_dims(begin, end);
36 
37  if ((_hid = H5Screate_simple(int(real_dims.size()), real_dims.data(),
38  NULL)) < 0) {
39  throw DataSpaceException("Impossible to create dataspace");
40  }
41 }
42 
43 inline DataSpace::DataSpace(const std::vector<size_t>& dims,
44  const std::vector<size_t>& maxdims) {
45 
46  if (dims.size() != maxdims.size()) {
47  throw DataSpaceException("dims and maxdims must be the same length.");
48  }
49 
50  std::vector<hsize_t> real_dims(dims.begin(), dims.end());
51  std::vector<hsize_t> real_maxdims(maxdims.begin(), maxdims.end());
52 
53  // Replace unlimited flag with actual HDF one
54  std::replace(real_maxdims.begin(), real_maxdims.end(),
55  static_cast<hsize_t>(DataSpace::UNLIMITED), H5S_UNLIMITED);
56 
57  if ((_hid = H5Screate_simple(int(dims.size()), real_dims.data(),
58  real_maxdims.data())) < 0) {
59  throw DataSpaceException("Impossible to create dataspace");
60  }
61 } // namespace HighFive
62 
64  H5S_class_t h5_dataspace_type;
65  switch (dtype) {
67  h5_dataspace_type = H5S_SCALAR;
68  break;
70  h5_dataspace_type = H5S_NULL;
71  break;
72  default:
73  throw DataSpaceException("Invalid dataspace type: should be "
74  "datascape_scalar or datascape_null");
75  }
76 
77  if ((_hid = H5Screate(h5_dataspace_type)) < 0) {
78  throw DataSpaceException("Unable to create dataspace");
79  }
80 }
81 
82 inline DataSpace DataSpace::clone() const {
83  DataSpace res;
84  if ((res._hid = H5Scopy(_hid)) < 0) {
85  throw DataSpaceException("Unable to copy dataspace");
86  }
87  return res;
88 }
89 
90 inline size_t DataSpace::getNumberDimensions() const {
91  const int ndim = H5Sget_simple_extent_ndims(_hid);
92  if (ndim < 0) {
93  HDF5ErrMapper::ToException<DataSetException>(
94  "Unable to get dataspace number of dimensions");
95  }
96  return size_t(ndim);
97 }
98 
99 inline std::vector<size_t> DataSpace::getDimensions() const {
100  std::vector<hsize_t> dims(getNumberDimensions());
101  if (!dims.empty()) {
102  if (H5Sget_simple_extent_dims(_hid, dims.data(), NULL) < 0) {
103  HDF5ErrMapper::ToException<DataSetException>(
104  "Unable to get dataspace dimensions");
105  }
106  }
107  return details::to_vector_size_t(std::move(dims));
108 }
109 
110 inline size_t DataSpace::getElementCount() const {
111  const std::vector<size_t>& dims = getDimensions();
112  return std::accumulate(dims.begin(), dims.end(), size_t{1u},
113  std::multiplies<size_t>());
114 }
115 
116 inline std::vector<size_t> DataSpace::getMaxDimensions() const {
117  std::vector<hsize_t> maxdims(getNumberDimensions());
118  if (H5Sget_simple_extent_dims(_hid, NULL, maxdims.data()) < 0) {
119  HDF5ErrMapper::ToException<DataSetException>(
120  "Unable to get dataspace dimensions");
121  }
122 
123  std::replace(maxdims.begin(), maxdims.end(), H5S_UNLIMITED,
124  static_cast<hsize_t>(DataSpace::UNLIMITED));
125  return details::to_vector_size_t(maxdims);
126 }
127 
128 template <typename ScalarValue>
129 inline DataSpace DataSpace::From(const ScalarValue& scalar) {
130  (void)scalar;
131  static_assert(
132  (std::is_arithmetic<ScalarValue>::value ||
133  std::is_enum<ScalarValue>::value ||
134  std::is_same<std::string, ScalarValue>::value),
135  "Only the following types are supported by DataSpace::From: \n"
136  " signed_arithmetic_types = int | long | float | double \n"
137  " unsigned_arithmetic_types = unsigned signed_arithmetic_types \n"
138  " string_types = std::string \n"
139  " all_basic_types = string_types | unsigned_arithmetic_types | "
140  "signed_arithmetic_types \n "
141  " stl_container_types = std::vector<all_basic_types> "
142  " boost_container_types = "
143  "boost::numeric::ublas::matrix<all_basic_types> | "
144  "boost::multi_array<all_basic_types> \n"
145  " all_supported_types = all_basic_types | stl_container_types | "
146  "boost_container_types"
147  " eigen_matrix_type = Eigen::Matrix<signed_arithmetic_type> | Eigen::VectorXX");
149 }
150 
151 template <typename Value>
152 inline DataSpace DataSpace::From(const std::vector<Value>& container) {
153  return DataSpace(details::get_dim_vector<Value>(container));
154 }
155 
156 template <typename ValueT, std::size_t N>
157 inline DataSpace DataSpace::From(const ValueT(&container)[N]) {
158  return DataSpace(details::get_dim_vector(container));
159 }
160 
161 template <std::size_t N, std::size_t Width>
162 inline DataSpace DataSpace::FromCharArrayStrings(const char(&)[N][Width]) {
163  return DataSpace(N);
164 }
165 
167 template <typename Value, std::size_t N>
168 inline DataSpace DataSpace::From(const std::array<Value, N>& ) {
169  return DataSpace(N);
170 }
171 
172 #ifdef H5_USE_BOOST
173 template <typename Value, std::size_t Dims>
174 inline DataSpace
175 DataSpace::From(const boost::multi_array<Value, Dims>& container) {
176  std::vector<size_t> dims(container.shape(), container.shape() + Dims);
177  return DataSpace(dims);
178 }
179 
180 template <typename Value>
181 inline DataSpace
182 DataSpace::From(const boost::numeric::ublas::matrix<Value>& mat) {
183  std::vector<size_t> dims(2);
184  dims[0] = mat.size1();
185  dims[1] = mat.size2();
186  return DataSpace(dims);
187 }
188 #endif
189 
190 #ifdef H5_USE_EIGEN
191 template <typename Value, int M, int N>
192 inline DataSpace
193 DataSpace::From(const Eigen::Matrix<Value, M, N>& mat ) {
194  std::vector<size_t> dims{static_cast<size_t>(mat.rows()),
195  static_cast<size_t>(mat.cols())};
196  return DataSpace(dims);
197 }
198 
199 template <typename Value, int M, int N>
200 inline DataSpace
201 DataSpace::From(const std::vector<Eigen::Matrix<Value, M, N>>& vec) {
202  using elem_t = Eigen::Matrix<Value, M, N>;
203  std::vector<size_t> dims{
204  std::accumulate(vec.begin(), vec.end(), size_t{0u},
205  [](size_t so_far, const elem_t& v) {
206  return so_far + static_cast<size_t>(v.rows());
207  }),
208  static_cast<size_t>(vec[0].cols())};
209  return DataSpace(dims);
210 }
211 
212 #ifdef H5_USE_BOOST
213 template <typename Value, int M, int N, size_t Dims>
214 inline DataSpace DataSpace::
215 From(const boost::multi_array<Eigen::Matrix<Value, M, N>, Dims>& vec) {
216  std::vector<size_t> dims(vec.shape(), vec.shape() + Dims);
217  dims[Dims - 1] *= static_cast<size_t>(vec.origin()->rows() * vec.origin()->cols());
218  return DataSpace(dims);
219 }
220 #endif
221 
222 #endif
223 
224 namespace details {
225 
227 inline bool checkDimensions(const DataSpace& mem_space, size_t input_dims) {
228  size_t dataset_dims = mem_space.getNumberDimensions();
229  if (input_dims == dataset_dims)
230  return true;
231 
232  const std::vector<size_t>& dims = mem_space.getDimensions();
233  for (auto i = dims.crbegin(); i != --dims.crend() && *i == 1; ++i)
234  --dataset_dims;
235 
236  if (input_dims == dataset_dims)
237  return true;
238 
239  dataset_dims = dims.size();
240  for (auto i = dims.cbegin(); i != --dims.cend() && *i == 1; ++i)
241  --dataset_dims;
242 
243  if (input_dims == dataset_dims)
244  return true;
245 
246  // The final tests is for scalars
247  return input_dims == 0 && dataset_dims == 1 && dims[dims.size() - 1] == 1;
248 }
249 
250 } // namespace details
251 } // namespace HighFive
252 
253 #endif // H5DATASPACE_MISC_HPP
HighFive::DataSpace::DataspaceType
DataspaceType
dataspace type
Definition: H5DataSpace.hpp:45
HighFive::DataSpace::UNLIMITED
static const size_t UNLIMITED
Definition: H5DataSpace.hpp:42
HighFive::DataSpace::getDimensions
std::vector< size_t > getDimensions() const
getDimensions
Definition: H5Dataspace_misc.hpp:99
HighFive::DataSpace::datascape_null
@ datascape_null
Definition: H5DataSpace.hpp:47
HighFive::details::get_dim_vector
std::vector< size_t > get_dim_vector(const std::vector< T > &vec)
Definition: H5Utils.hpp:109
HighFive::DataSpace::DataSpace
DataSpace()=default
HighFive::ObjectType::DataSpace
@ DataSpace
HighFive::DataSpace::From
static DataSpace From(const ScalarValue &scalar_value)
Definition: H5Dataspace_misc.hpp:129
HighFive::details::to_vector_size_t
std::vector< std::size_t > to_vector_size_t(const std::vector< Size > &vec)
Definition: H5Utils.hpp:235
HighFive::DataSpace::getMaxDimensions
std::vector< size_t > getMaxDimensions() const
getMaxDimensions
Definition: H5Dataspace_misc.hpp:116
HighFive::DataSpace::FromCharArrayStrings
static DataSpace FromCharArrayStrings(const char(&)[N][Width])
Definition: H5Dataspace_misc.hpp:162
HighFive::DataSpace::getElementCount
size_t getElementCount() const
getElementCount
Definition: H5Dataspace_misc.hpp:110
HighFive::DataSpace::datascape_scalar
@ datascape_scalar
Definition: H5DataSpace.hpp:46
HighFive::Object::_hid
hid_t _hid
Definition: H5Object.hpp:81
HighFive::DataSpace
Class representing the space (dimensions) of a dataset.
Definition: H5DataSpace.hpp:37
HighFive::DataSpace::clone
DataSpace clone() const
Definition: H5Dataspace_misc.hpp:82
H5Utils.hpp
HighFive::details::checkDimensions
bool checkDimensions(const DataSpace &mem_space, size_t input_dims)
dimension checks
Definition: H5Dataspace_misc.hpp:227
HighFive::DataSpace::getNumberDimensions
size_t getNumberDimensions() const
getNumberDimensions
Definition: H5Dataspace_misc.hpp:90
HighFive
Definition: H5_definitions.hpp:15
HighFive::DataSpaceException
Exception specific to HighFive DataSpace interface.
Definition: H5Exception.hpp:99