hops
H5ConverterEigen_misc.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c), 2020, EPFL - Blue Brain Project
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 <Eigen/Eigen>
12 
13 namespace HighFive {
14 
15 namespace details {
16 
17 
18 //compute size for single Eigen Matrix
19 template <typename T, int M, int N>
20 inline size_t compute_total_size(const Eigen::Matrix<T,M,N>& matrix) {
21  return matrix.rows() * matrix.cols();
22 }
23 
24 //compute size for std::vector of Eigens
25 template <typename T, int M, int N>
26 inline size_t compute_total_size(const std::vector<Eigen::Matrix<T,M,N>>& vec) {
27  return std::accumulate(vec.begin(), vec.end(), size_t{0u},
28  [](size_t so_far, const Eigen::Matrix<T,M,N>& v) {
29  return so_far + static_cast<size_t>(v.rows()) * static_cast<size_t>(v.cols());
30  });
31 }
32 
33 #ifdef H5_USE_BOOST
34 // compute size for boost::multi_array of Eigens
35 template <typename T, size_t Dims>
36 inline size_t compute_total_size(const boost::multi_array<T, Dims>& vec) {
37  return std::accumulate(vec.origin(), vec.origin() + vec.num_elements(), size_t{0u},
38  [](size_t so_far, const T& v) {
39  return so_far + static_cast<size_t>(v.rows()) * static_cast<size_t>(v.cols());
40  });
41 }
42 #endif
43 
44 //compute total row size for std::vector of Eigens
45 template <typename T, int M, int N>
46 inline size_t compute_total_row_size(const std::vector<Eigen::Matrix<T,M,N>>& vec) {
47  return std::accumulate(vec.begin(), vec.end(), size_t{0u},
48  [](size_t so_far, const Eigen::Matrix<T,M,N>& v) {
49  return so_far + static_cast<size_t>(v.rows());
50  });
51 }
52 
53 
54 // apply conversion to eigen matrix
55 template <typename T, int M, int N>
56 struct data_converter<Eigen::Matrix<T, M, N>, void> {
57 
58  typedef Eigen::Matrix<T, M, N> MatrixTMN;
59 
60  inline data_converter(const DataSpace& space)
61  : _dims(space.getDimensions()) {
62  assert(_dims.size() == 2);
63  }
64 
65  inline T* transform_read(MatrixTMN& array) {
66  if (_dims[0] != static_cast<size_t>(array.rows()) ||
67  _dims[1] != static_cast<size_t>(array.cols())) {
68  array.resize(static_cast<typename MatrixTMN::Index>(_dims[0]),
69  static_cast<typename MatrixTMN::Index>(_dims[1]));
70  }
71  return array.data();
72  }
73 
74  inline const T* transform_write(const MatrixTMN& array) {
75  return array.data();
76  }
77 
78  inline void process_result(MatrixTMN&) {}
79 
80  std::vector<size_t> _dims;
81 };
82 
83 
84 template <typename T, int M, int N>
85 inline void vectors_to_single_buffer(const std::vector<Eigen::Matrix<T,M,N>>& vec,
86  const std::vector<size_t>& dims,
87  const size_t current_dim,
88  std::vector<T>& buffer) {
89 
90  check_dimensions_vector(compute_total_row_size(vec), dims[current_dim], current_dim);
91  for (const auto& k : vec) {
92  std::copy(k.data(), k.data() + k.size(), std::back_inserter(buffer));
93  }
94 }
95 
96 // apply conversion to std::vector of eigen matrix
97 template <typename T, int M, int N>
98 struct data_converter<std::vector<Eigen::Matrix<T,M,N>>, void> {
99 
100  typedef Eigen::Matrix<T, M, N> MatrixTMN;
101 
102  inline data_converter(const DataSpace& space)
103  : _dims(space.getDimensions()), _space(space) {
104  assert(_dims.size() == 2);
105  }
106 
107  inline T * transform_read(std::vector<MatrixTMN>& /* vec */) {
108  _vec_align.resize(compute_total_size(_space.getDimensions()));
109  return _vec_align.data();
110  }
111 
112  inline const T* transform_write(const std::vector<MatrixTMN>& vec) {
113  _vec_align.reserve(compute_total_size(vec));
114  vectors_to_single_buffer<T, M, N>(vec, _dims, 0, _vec_align);
115  return _vec_align.data();
116  }
117 
118  inline void process_result(std::vector<MatrixTMN>& vec) {
119  T* start = _vec_align.data();
120  if (vec.size() > 0) {
121  for(auto& v : vec){
122  v = Eigen::Map<MatrixTMN>(start, v.rows(), v.cols());
123  start += v.rows()*v.cols();
124  }
125  }
126  else if (M == -1 || N == -1) {
127  std::ostringstream ss;
128  ss << "Dynamic size(-1) used without pre-defined vector data layout.\n"
129  << "Initiliaze vector elements using Zero, i.e.:\n"
130  << "\t vector<MatrixXd> vec(5, MatrixXd::Zero(20,5))";
131  throw DataSetException(ss.str());
132  }
133  else {
134  for (size_t i = 0; i < _dims[0] / static_cast<size_t>(M); ++i) {
135  vec.emplace_back(Eigen::Map<MatrixTMN>(start, M, N));
136  start += M * N;
137  }
138  }
139  }
140 
141  std::vector<size_t> _dims;
142  std::vector<typename type_of_array<T>::type> _vec_align;
144 };
145 
146 #ifdef H5_USE_BOOST
147 template <typename T, int M, int N, std::size_t Dims>
148 struct data_converter<boost::multi_array<Eigen::Matrix<T, M, N>, Dims>, void> {
149  typedef typename boost::multi_array<Eigen::Matrix<T, M, N>, Dims> MultiArrayEigen;
150 
151  inline data_converter(const DataSpace& space)
152  : _dims(space.getDimensions())
153  , _space(space) {
154  assert(_dims.size() == Dims);
155  }
156 
157  inline T* transform_read(const MultiArrayEigen& /*array*/) {
158  _vec_align.resize(compute_total_size(_space.getDimensions()));
159  return _vec_align.data();
160  }
161 
162  inline const T* transform_write(const MultiArrayEigen& array) {
163  _vec_align.reserve(compute_total_size(array));
164  for (auto e = array.origin(); e < array.origin() + array.num_elements(); ++e) {
165  std::copy(e->data(), e->data() + e->size(), std::back_inserter(_vec_align));
166  }
167  return _vec_align.data();
168  }
169 
170  inline void process_result(MultiArrayEigen& vec) {
171  T* start = _vec_align.data();
172  if (M != -1 && N != -1) {
173  for (auto v = vec.origin(); v < vec.origin() + vec.num_elements(); ++v) {
174  *v = Eigen::Map<Eigen::Matrix<T, M, N>>(start, v->rows(), v->cols());
175  start += v->rows() * v->cols();
176  }
177  } else {
178  if (vec.origin()->rows() > 0 && vec.origin()->cols() > 0) {
179  const auto VEC_M = vec.origin()->rows(), VEC_N = vec.origin()->cols();
180  for (auto v = vec.origin(); v < vec.origin() + vec.num_elements(); ++v) {
181  assert(v->rows() == VEC_M && v->cols() == VEC_N);
182  *v = Eigen::Map<Eigen::Matrix<T, M, N>>(start, VEC_M, VEC_N);
183  start += VEC_M * VEC_N;
184  }
185  } else {
186  throw DataSetException(
187  "Dynamic size(-1) used without pre-defined multi_array data layout.\n"
188  "Initialize vector elements using MatrixXd::Zero");
189  }
190  }
191  }
192 
193  std::vector<size_t> _dims;
194  const DataSpace& _space;
195  std::vector<typename type_of_array<T>::type> _vec_align;
196 };
197 #endif // H5_USE_BOOST
198 
199 } // namespace details
200 
201 } // namespace HighFive
HighFive::details::compute_total_size
size_t compute_total_size(const std::vector< size_t > &dims)
Definition: H5Converter_misc.hpp:41
HighFive::details::data_converter< Eigen::Matrix< T, M, N >, void >::transform_read
T * transform_read(MatrixTMN &array)
Definition: H5ConverterEigen_misc.hpp:65
HighFive::DataSpace::getDimensions
std::vector< size_t > getDimensions() const
getDimensions
Definition: H5Dataspace_misc.hpp:99
HighFive::details::data_converter< Eigen::Matrix< T, M, N >, void >::process_result
void process_result(MatrixTMN &)
Definition: H5ConverterEigen_misc.hpp:78
HighFive::details::data_converter< std::vector< Eigen::Matrix< T, M, N > >, void >::_space
const DataSpace & _space
Definition: H5ConverterEigen_misc.hpp:143
HighFive::details::data_converter< std::vector< Eigen::Matrix< T, M, N > >, void >::MatrixTMN
Eigen::Matrix< T, M, N > MatrixTMN
Definition: H5ConverterEigen_misc.hpp:100
HighFive::ObjectType::DataSpace
@ DataSpace
HighFive::details::data_converter::transform_write
const Scalar * transform_write(const Scalar &datamem) const noexcept
Definition: H5Converter_misc.hpp:137
HighFive::details::data_converter< std::vector< Eigen::Matrix< T, M, N > >, void >::process_result
void process_result(std::vector< MatrixTMN > &vec)
Definition: H5ConverterEigen_misc.hpp:118
HighFive::details::data_converter< std::vector< Eigen::Matrix< T, M, N > >, void >::_vec_align
std::vector< typename type_of_array< T >::type > _vec_align
Definition: H5ConverterEigen_misc.hpp:142
HighFive::details::data_converter< Eigen::Matrix< T, M, N >, void >::_dims
std::vector< size_t > _dims
Definition: H5ConverterEigen_misc.hpp:80
HighFive::details::vectors_to_single_buffer
void vectors_to_single_buffer(const std::vector< T > &vec_single_dim, const std::vector< size_t > &dims, const size_t current_dim, std::vector< T > &buffer)
Definition: H5Converter_misc.hpp:63
HighFive::details::data_converter::process_result
void process_result(Scalar &) const noexcept
Definition: H5Converter_misc.hpp:141
HighFive::details::data_converter::data_converter
data_converter(const DataSpace &) noexcept
Definition: H5Converter_misc.hpp:124
HighFive::details::data_converter< Eigen::Matrix< T, M, N >, void >::MatrixTMN
Eigen::Matrix< T, M, N > MatrixTMN
Definition: H5ConverterEigen_misc.hpp:58
HighFive::DataSetException
Exception specific to HighFive DataSet interface.
Definition: H5Exception.hpp:115
HighFive::details::data_converter< Eigen::Matrix< T, M, N >, void >::data_converter
data_converter(const DataSpace &space)
Definition: H5ConverterEigen_misc.hpp:60
HighFive::details::data_converter< std::vector< Eigen::Matrix< T, M, N > >, void >::_dims
std::vector< size_t > _dims
Definition: H5ConverterEigen_misc.hpp:141
HighFive::details::data_converter< std::vector< Eigen::Matrix< T, M, N > >, void >::data_converter
data_converter(const DataSpace &space)
Definition: H5ConverterEigen_misc.hpp:102
HighFive::details::data_converter::transform_read
Scalar * transform_read(Scalar &datamem) const noexcept
Definition: H5Converter_misc.hpp:133
HighFive::details::check_dimensions_vector
void check_dimensions_vector(size_t size_vec, size_t size_dataset, size_t dimension)
Definition: H5Converter_misc.hpp:46
copy
free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to copy
Definition: LICENSE.txt:6
HighFive::DataSpace
Class representing the space (dimensions) of a dataset.
Definition: H5DataSpace.hpp:37
HighFive::details::data_converter< std::vector< Eigen::Matrix< T, M, N > >, void >::transform_write
const T * transform_write(const std::vector< MatrixTMN > &vec)
Definition: H5ConverterEigen_misc.hpp:112
HighFive::details::data_converter< Eigen::Matrix< T, M, N >, void >::transform_write
const T * transform_write(const MatrixTMN &array)
Definition: H5ConverterEigen_misc.hpp:74
HighFive::details::compute_total_row_size
size_t compute_total_row_size(const std::vector< Eigen::Matrix< T, M, N >> &vec)
Definition: H5ConverterEigen_misc.hpp:46
HighFive::details::data_converter< std::vector< Eigen::Matrix< T, M, N > >, void >::transform_read
T * transform_read(std::vector< MatrixTMN > &)
Definition: H5ConverterEigen_misc.hpp:107
HighFive::details::data_converter
Definition: H5_definitions.hpp:57
HighFive
Definition: H5_definitions.hpp:15