Flow123d  DF_patch_fe_data_tables-92632e6
arena_vec.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file arena_vec.hh
15  */
16 
17 #ifndef ARENA_VEC_HH_
18 #define ARENA_VEC_HH_
19 
20 #include "fem/arena_resource.hh"
21 #include "system/asserts.hh"
22 
23 #include <Eigen/Core>
24 #include <Eigen/Dense>
25 
26 
27 
28 template<class T> class ArenaOVec;
29 
30 
31 /**
32  * Define vector allocated in ArenaResource and aligned to SIMD size.
33  */
34 template<class T>
35 class ArenaVec {
36 public:
37  /// Type definition
38  typedef Eigen::Matrix<T, Eigen::Dynamic, 1> VecData;
39  typedef Eigen::Array<T, Eigen::Dynamic, 1> ArrayData;
40 
41  /// Default constructor, set invalid data pointer
43  : data_ptr_(nullptr), data_size_(0), arena_(nullptr), scalar_val_( (T)0 ) {}
44 
45  /**
46  * Constructor. Set scalar value
47  */
48  ArenaVec(T scalar_val)
49  : data_ptr_(nullptr), data_size_(0), arena_(nullptr), scalar_val_(scalar_val) {}
50 
51  /**
52  * Constructor. Set sizes and allocate data pointer
53  */
55  : data_ptr_(nullptr), data_size_(data_size), arena_(&arena), scalar_val_( (T)0 ) {
57  }
58 
59  /// Copy constructor
60  ArenaVec(const ArenaVec<T> &other)
61  : data_ptr_(other.data_ptr_), data_size_(other.data_size_),
62  arena_(other.arena_), scalar_val_(other.scalar_val_)
63  {}
64 
65  /**
66  * Maps data pointer to Eigen Map of dimensions given data_size_ and returns it.
67  */
68  inline Eigen::Map<VecData> eigen_map() {
70  return Eigen::Map<VecData>(data_ptr_, data_size_, 1);
71  }
72 
73  /// Smae as previous but with const modifier
74  inline const Eigen::Map<VecData> eigen_map() const {
76  return Eigen::Map<VecData>(data_ptr_, data_size_, 1);
77  }
78 
79  /**
80  * Maps data pointer to Eigen Map of dimensions given data_size_ and returns it.
81  */
82  inline Eigen::Map<ArrayData> array_map() {
84  return Eigen::Map<ArrayData>(data_ptr_, data_size_, 1);
85  }
86 
87  /// Smae as previous but with const modifier
88  inline const Eigen::Map<ArrayData> array_map() const {
90  return Eigen::Map<ArrayData>(data_ptr_, data_size_, 1);
91  }
92 
93  /// Return data pointer (development method)
94  T* data_ptr() {
95  return data_ptr_;
96  }
97 
98  /// Smae as previous but return const pointer
99  const T* data_ptr() const {
100  return data_ptr_;
101  }
102 
103  /// Getter for data_size_
104  inline size_t data_size() const {
105  return data_size_;
106  }
107 
108  /// Getter for arena_
110  return *arena_;
111  }
112 
113  /// Set pointer to PatchArena
116  this->arena_ = &arena;
117  }
118 
119  inline ArenaVec<T> sqrt() const {
122  Eigen::Map<ArrayData> result_map = res.array_map();
123  result_map = this->array_map().sqrt();
124  return res;
125  }
126 
127  inline ArenaVec<T> inverse() const {
130  Eigen::Map<ArrayData> result_map = res.array_map();
131  result_map = this->array_map().inverse();
132  return res;
133  }
134 
135  inline ArenaVec<T> abs() const {
138  Eigen::Map<ArrayData> result_map = res.array_map();
139  result_map = this->array_map().abs();
140  return res;
141  }
142 
143  /// For development only. TODO remove
144  inline T & operator()(std::size_t item) {
146  ASSERT_LT(item, data_size_);
147  return data_ptr_[item];
148  }
149 
150  /// For development only. TODO remove
151  inline const T & operator()(std::size_t item) const {
152  ASSERT_LT(item, data_size_);
153  return data_ptr_[item];
154  }
155 
156  inline ArenaVec<T> &operator=(const ArenaVec<T> &other) {
157  data_ptr_ = other.data_ptr_;
158  data_size_ = other.data_size_;
159  arena_ = other.arena_;
160  scalar_val_ = other.scalar_val_;
161  return *this;
162  }
163 
164  inline ArenaVec<T> operator+(const ArenaVec<T> &other) const {
166  ASSERT_PTR(other.data_ptr());
167  ASSERT_EQ(data_size_, other.data_size());
169  Eigen::Map<VecData> result_map = res.eigen_map();
170  result_map = this->eigen_map() + other.eigen_map();
171  return res;
172  }
173 
174  inline ArenaVec<T> operator-(const ArenaVec<T> &other) const {
176  ASSERT_PTR(other.data_ptr());
177  ASSERT_EQ(data_size_, other.data_size());
179  Eigen::Map<ArrayData> result_map = res.array_map();
180  result_map = this->array_map() - other.array_map();
181  return res;
182  }
183 
184  inline ArenaVec<T> operator*(T multi) const {
187  Eigen::Map<ArrayData> result_map = res.array_map();
188  result_map = this->array_map() * multi;
189  return res;
190  }
191 
192  inline ArenaVec<T> operator*(const ArenaVec<T> &other) const {
194  ASSERT_PTR(other.data_ptr());
195  ASSERT_EQ(data_size_, other.data_size());
197  Eigen::Map<ArrayData> result_map = res.array_map();
198  result_map = this->array_map() * other.array_map();
199  return res;
200  }
201 
202  inline ArenaVec<T> operator/(T div_by) const {
205  Eigen::Map<ArrayData> result_map = res.array_map();
206  result_map = this->array_map() / div_by;
207  return res;
208  }
209 
210  inline ArenaVec<T> operator/(const ArenaVec<T> &other) const {
212  ASSERT_PTR(other.data_ptr());
213  ASSERT_EQ(data_size_, other.data_size());
215  Eigen::Map<ArrayData> result_map = res.array_map();
216  result_map = this->array_map() / other.array_map();
217  return res;
218  }
219 
220 protected:
221  /// Constructor. Allows create ArenaVec from ArenaOVec
224 
225  T* data_ptr_; ///< Pointer to data array
226  size_t data_size_; ///< Length of data array
227  PatchArena *arena_; ///< Pointer to Arena where intermediate calculations and results are stored, should be changed by set_patch_arena
228  T scalar_val_; ///< Scalar value of T type
229 
230  friend class ArenaOVec<T>;
231 };
232 
233 
234 
235 /**
236  * Define vector allocated in ArenaResource based on ArenaVec with overwrite
237  * multiplication operator that executes outer product.
238  *
239  * Example of usage with conversions between ArenaVec and ArenaOVec:
240  @code
241  ArenaVec<double> outer_product(ArenaVec<double> a, ArenaVec<double> b) {
242  // Convert ArenaVec inputs to ArenaOVec variables
243  ArenaOVec<double> a_ovec(a);
244  ArenaOVec<double> b_ovec(b);
245 
246  // performs outer product
247  ArenaOVec<double> result_ovec = a * b;
248 
249  // reverse conversion to ArenaVec
250  return result_ovec.get_vec();
251  }
252  @endcode
253  *
254  * If we consider that size of input vector 'a' is 'M' and size of input vector 'b' is 'N'
255  * then size of returned vector is 'M*N'.
256  */
257 template<class T>
258 class ArenaOVec : public ArenaVec<T> {
259 public:
260  /// Default constructor
262  : ArenaVec<T>() {}
263 
264  /// Copy constructor
265  ArenaOVec(const ArenaOVec<T> &other)
266  : ArenaVec<T>(other) {}
267 
268  /// Constructor. Set scalar_val
269  ArenaOVec(T scalar_val)
270  : ArenaVec<T>(scalar_val) {}
271 
272  /**
273  * Constructor creates ArenaOVec on data of ArenaVec
274  */
276  ASSERT_PTR(vec.data_ptr());
277 
278  this->data_ptr_ = vec.data_ptr_;
279  this->data_size_ = vec.data_size_;
280  this->arena_ = vec.arena_;
281  }
282 
283  /// Convert ArenaOVec to ArenaVec and its
285  return ArenaVec<T>(*this);
286  }
287 
288  inline ArenaOVec<T> &operator=(const ArenaOVec<T> &other) {
289  ArenaVec<T>::operator=(other);
290  return *this;
291  }
292 
293 
294  inline ArenaOVec<T> operator+(const ArenaOVec<T> &other) const {
295  // Test of valid data_ptr is in constructor
296  ASSERT_EQ(this->data_size_, other.data_size());
297  ArenaVec<T> res_vec(this->data_size_, *this->arena_);
298  ArenaOVec<T> res(res_vec);
299  Eigen::Map<typename ArenaVec<T>::VecData> result_map = res.eigen_map();
300  result_map = this->eigen_map() + other.eigen_map();
301  return res;
302  }
303 
304 
305  inline ArenaOVec<T> operator*(const ArenaOVec<T> &other) const {
306  typedef Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> MatData;
307 
308  ArenaVec<T> res_vec(this->data_size_*other.data_size(), *this->arena_);
309  ArenaOVec<T> res(res_vec);
310  Eigen::Map<MatData> result_map = Eigen::Map<MatData>(res.data_ptr(), this->data_size_, other.data_size());
311  result_map = this->eigen_map() * other.eigen_map().transpose();
312  return res;
313  }
314 };
315 
316 
317 #endif /* ARENA_VEC_HH_ */
Definitions of ASSERTS.
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:301
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Definition: asserts.hh:341
ArenaOVec< T > operator+(const ArenaOVec< T > &other) const
Definition: arena_vec.hh:294
ArenaVec< T > get_vec() const
Convert ArenaOVec to ArenaVec and its.
Definition: arena_vec.hh:284
ArenaOVec(const ArenaVec< T > &vec)
Definition: arena_vec.hh:275
ArenaOVec< T > & operator=(const ArenaOVec< T > &other)
Definition: arena_vec.hh:288
ArenaOVec(const ArenaOVec< T > &other)
Copy constructor.
Definition: arena_vec.hh:265
ArenaOVec(T scalar_val)
Constructor. Set scalar_val.
Definition: arena_vec.hh:269
ArenaOVec()
Default constructor.
Definition: arena_vec.hh:261
ArenaOVec< T > operator*(const ArenaOVec< T > &other) const
Definition: arena_vec.hh:305
ArenaVec(T scalar_val)
Definition: arena_vec.hh:48
Eigen::Array< T, Eigen::Dynamic, 1 > ArrayData
Definition: arena_vec.hh:39
ArenaVec()
Default constructor, set invalid data pointer.
Definition: arena_vec.hh:42
Eigen::Matrix< T, Eigen::Dynamic, 1 > VecData
Type definition.
Definition: arena_vec.hh:38
ArenaVec< T > operator/(const ArenaVec< T > &other) const
Definition: arena_vec.hh:210
const T * data_ptr() const
Smae as previous but return const pointer.
Definition: arena_vec.hh:99
PatchArena & arena()
Getter for arena_.
Definition: arena_vec.hh:109
T * data_ptr()
Return data pointer (development method)
Definition: arena_vec.hh:94
const T & operator()(std::size_t item) const
For development only. TODO remove.
Definition: arena_vec.hh:151
const Eigen::Map< ArrayData > array_map() const
Smae as previous but with const modifier.
Definition: arena_vec.hh:88
ArenaVec< T > sqrt() const
Definition: arena_vec.hh:119
ArenaVec< T > operator*(T multi) const
Definition: arena_vec.hh:184
ArenaVec< T > operator*(const ArenaVec< T > &other) const
Definition: arena_vec.hh:192
Eigen::Map< VecData > eigen_map()
Definition: arena_vec.hh:68
ArenaVec< T > abs() const
Definition: arena_vec.hh:135
Eigen::Map< ArrayData > array_map()
Definition: arena_vec.hh:82
size_t data_size_
Length of data array.
Definition: arena_vec.hh:226
const Eigen::Map< VecData > eigen_map() const
Smae as previous but with const modifier.
Definition: arena_vec.hh:74
ArenaVec< T > operator/(T div_by) const
Definition: arena_vec.hh:202
ArenaVec< T > inverse() const
Definition: arena_vec.hh:127
ArenaVec< T > & operator=(const ArenaVec< T > &other)
Definition: arena_vec.hh:156
void set_patch_arena(PatchArena &arena)
Set pointer to PatchArena.
Definition: arena_vec.hh:114
ArenaVec< T > operator-(const ArenaVec< T > &other) const
Definition: arena_vec.hh:174
PatchArena * arena_
Pointer to Arena where intermediate calculations and results are stored, should be changed by set_pat...
Definition: arena_vec.hh:227
T & operator()(std::size_t item)
For development only. TODO remove.
Definition: arena_vec.hh:144
ArenaVec< T > operator+(const ArenaVec< T > &other) const
Definition: arena_vec.hh:164
ArenaVec(size_t data_size, PatchArena &arena)
Definition: arena_vec.hh:54
ArenaVec(const ArenaVec< T > &other)
Copy constructor.
Definition: arena_vec.hh:60
ArenaVec(T *data_ptr, size_t data_size, PatchArena &arena)
Constructor. Allows create ArenaVec from ArenaOVec.
Definition: arena_vec.hh:222
size_t data_size() const
Getter for data_size_.
Definition: arena_vec.hh:104
T scalar_val_
Scalar value of T type.
Definition: arena_vec.hh:228
T * data_ptr_
Pointer to data array.
Definition: arena_vec.hh:225
T * allocate_simd(size_t n_items)
Allocate and return data pointer of n_item array of type T (alignment to length given by simd_alignme...
ArmaVec< double, N > vec
Definition: armor.hh:933