Flow123d  DF_patch_fe_data_tables-da7858b
arena_resource.hh
Go to the documentation of this file.
1 #ifndef ARENA_RESOURCE_HH_
2 #define ARENA_RESOURCE_HH_
3 
4 #include <memory_resource>
5 #include <vector>
6 #include <iostream>
7 #include <new>
8 #include <stdexcept> // !! Use Flow exception mechanism
9 
10 #include "system/asserts.hh"
11 
12 #include <Eigen/Core>
13 #include <Eigen/Dense>
14 
15 
16 // Final proposal of Arena
17 template <class Resource>
18 class ArenaResource : public std::pmr::memory_resource {
19 public:
20  explicit ArenaResource(size_t buffer_size, size_t simd_alignment)
21  : buffer(new char[buffer_size]),
23 #ifdef FLOW123D_DEBUG
24  resource_(buffer.get(), buffer_size, std::pmr::null_memory_resource()),
25 #else
26  resource_(buffer.get(), buffer_size, std::pmr::get_default_resource()),
27 #endif
28  simd_alignment_(simd_alignment)
29  {}
30 
31 
32  ~ArenaResource() = default;
33 
34  /// Getter for resource
35  Resource &resource() {
36  return resource_;
37  }
38 
39  /// Allocate and return data pointer of n_item array of type T (alignment to length 8 bytes)
40  template <class T>
41  T* allocate_8(size_t n_items) {
42  size_t bytes = sizeof(T) * n_items;
43  return (T*)this->do_allocate(bytes, 8);
44  }
45 
46  /// Allocate and return data pointer of n_item array of type T (alignment to length given by simd_alignment constructor argument)
47  template <class T>
48  T* allocate_simd(size_t n_items) {
49  size_t bytes = sizeof(T) * n_items;
50  return (T*)this->do_allocate(bytes, simd_alignment_);
51  }
52 
53  // Reset allocated data
54  void reset() {
55  resource_.release();
56  }
57 
58 protected:
59  /// Override do_allocate to handle allocation logic
60  void* do_allocate(size_t bytes, size_t alignment) override {
61  void* p = resource_.allocate(bytes, alignment);
62  if (p == nullptr) { // test only in Debug when null_pointer_resource is in use
63  throw std::bad_alloc();
64  }
65  return p;
66  }
67 
68  /// Override do_deallocate (no-op for monotonic buffer)
69  void do_deallocate(FMT_UNUSED void* p, FMT_UNUSED size_t bytes, FMT_UNUSED size_t alignment) override {
70  // No-op
71  }
72 
73  /// Override do_is_equal for memory resource comparison
74  bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
75  return this == &other;
76  }
77 
78 private:
79  std::unique_ptr<char[]> buffer;
80  size_t buffer_size;
81  Resource resource_;
83 };
84 
85 
88 
89 
90 /**
91  * Define vector allocated in Arena and aligned to SIMD size.
92  */
93 template<class T>
94 class ArenaVec {
95 public:
96  /// Type definition
97  typedef Eigen::Matrix<T, Eigen::Dynamic, 1> VecData;
98 
99  /// Default constructor, set invalid data pointer
101  : data_ptr_(nullptr), data_size_(0), arena_(nullptr) {}
102 
103  /**
104  * Constructor. Set scalar value
105  */
106  ArenaVec(T scalar_val)
107  : data_ptr_(nullptr), data_size_(0), arena_(nullptr), scalar_val_(scalar_val) {}
108 
109  /**
110  * Constructor. Set sizes and allocate data pointer
111  */
113  : data_ptr_(nullptr), data_size_(data_size), arena_(&arena) {
115  }
116 
117  /**
118  * Maps data pointer to Eigen Map of dimensions given data_size_ and returns it.
119  */
120  inline Eigen::Map<VecData> eigen_map() {
122  return Eigen::Map<VecData>(data_ptr_, data_size_, 1);
123  }
124 
125  /// Return data pointer (development method)
126  T* data_ptr() {
127  return data_ptr_;
128  }
129 
130  /// Getter for data_size_
131  inline size_t data_size() const {
132  return data_size_;
133  }
134 
135  /// For development only. TODO remove
136  inline T & operator()(std::size_t item) {
137  ASSERT_LT(item, data_size_);
138  return data_ptr_[item];
139  }
140 
141  inline ArenaVec<T> operator+(const ArenaVec<T> &other) const {
142  ASSERT_EQ(data_size_, other.data_size());
144  Eigen::Map<VecData> result_map = res.eigen_map();
145  result_map = this->eigen_map() + other.eigen_map();
146  return res;
147  }
148 
149  inline ArenaVec<T> operator*(T multi) const {
151  Eigen::Map<VecData> result_map = res.eigen_map();
152  result_map = this->eigen_map() * multi;
153  return res;
154  }
155 
156 protected:
157  T* data_ptr_; ///< Pointer to data array
158  size_t data_size_; ///< Length of data array
159  AssemblyArena *arena_; ///< Pointer to Arena
160  T scalar_val_; ///< Scalar value of T type
161 };
162 
163 
164 
165 /// Outer product - only proposal of multi operator
166 //template<class T>
167 //class ArenaOVec {
168 //public:
169 // inline ArenaOVec<T> operator*(const ArenaOVec<T> &other) const {
170 // typedef Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> MatData;
171 //
172 // ArenaOVec<T> res(data_size_*other.data_size(), *arena_);
173 // Eigen::Map<MatData> result_map = Eigen::Map<MatData>(res.data_ptr(), data_size_, other.data_size());
174 // result_map = this->eigen_map() * other.eigen_map().transpose();
175 // return res;
176 // }
177 //};
178 
179 
180 
181 
182 #endif /* ARENA_RESOURCE_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
Resource resource_
std::unique_ptr< char[]> buffer
T * allocate_8(size_t n_items)
Allocate and return data pointer of n_item array of type T (alignment to length 8 bytes)
ArenaResource(size_t buffer_size, size_t simd_alignment)
~ArenaResource()=default
void * do_allocate(size_t bytes, size_t alignment) override
Override do_allocate to handle allocation logic.
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...
void do_deallocate(FMT_UNUSED void *p, FMT_UNUSED size_t bytes, FMT_UNUSED size_t alignment) override
Override do_deallocate (no-op for monotonic buffer)
bool do_is_equal(const std::pmr::memory_resource &other) const noexcept override
Override do_is_equal for memory resource comparison.
size_t simd_alignment_
Resource & resource()
Getter for resource.
ArenaVec(T scalar_val)
ArenaVec()
Default constructor, set invalid data pointer.
Eigen::Matrix< T, Eigen::Dynamic, 1 > VecData
Type definition.
ArenaVec(size_t data_size, AssemblyArena &arena)
T * data_ptr()
Return data pointer (development method)
ArenaVec< T > operator*(T multi) const
Eigen::Map< VecData > eigen_map()
size_t data_size_
Length of data array.
AssemblyArena * arena_
Pointer to Arena.
T & operator()(std::size_t item)
For development only. TODO remove.
ArenaVec< T > operator+(const ArenaVec< T > &other) const
size_t data_size() const
Getter for data_size_.
T scalar_val_
Scalar value of T type.
T * data_ptr_
Pointer to data array.
#define FMT_UNUSED
Definition: posix.h:75