Flow123d  DF_patch_fe_data_tables-b828b90
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 template <class Resource> class ArenaResource; // forward declaration
17 
18 
19 // Helper class of ArenaResource, allows allocate aligned blocks of data
20 template <class Upstream>
21 class AlignedMemoryResource : public std::pmr::memory_resource {
22 public:
23  explicit AlignedMemoryResource(std::pmr::monotonic_buffer_resource& upstream, size_t alignment)
24  : upstream_(upstream), alignment_(alignment) {}
25 
26 protected:
27  void* do_allocate(size_t bytes, size_t alignment) override {
28  if (alignment_ > alignment) {
29  alignment = alignment_;
30  }
31  void* p = upstream_.allocate(bytes, alignment);
32  if (p == nullptr) { // test only in Debug when null_pointer_resource is in use
33  throw std::bad_alloc();
34  }
35  return p;
36  }
37 
38  void do_deallocate(void* p, size_t bytes, size_t alignment) override {
39  upstream_.deallocate(p, bytes, alignment);
40  }
41 
42  bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
43  return this == &other;
44  }
45 
46 private:
47  Upstream& upstream_;
48  size_t alignment_;
49 
50  friend class ArenaResource<Upstream>;
51 };
52 
53 
54 // Final proposal of Arena
55 template <class Resource>
56 class ArenaResource : public std::pmr::memory_resource {
57 public:
58  explicit ArenaResource(size_t buffer_size, size_t simd_alignment)
59  : buffer(new char[buffer_size]),
61 #ifdef FLOW123D_DEBUG
62  resource_(buffer.get(), buffer_size, std::pmr::null_memory_resource()),
63 #else
64  resource_(buffer.get(), buffer_size, std::pmr::get_default_resource()),
65 #endif
66  simd_alignment_(simd_alignment)
67  {}
68 
69 
70  ~ArenaResource() = default;
71 
72  /// Getter for resource
73  Resource &resource() {
74  return resource_;
75  }
76 
77  /// Allocate and return data pointer of n_item array of type T (alignment to length 8 bytes)
78  template <class T>
79  T* allocate_8(size_t n_items) {
80  size_t bytes = sizeof(T) * n_items;
82  return (T*)a_res.do_allocate(bytes, a_res.alignment_);
83  }
84 
85  /// Allocate and return data pointer of n_item array of type T (alignment to length given by simd_alignment constructor argument)
86  template <class T>
87  T* allocate_simd(size_t n_items) {
88  size_t bytes = sizeof(T) * n_items;
90  return (T*)a_res.do_allocate(bytes, a_res.alignment_);
91  }
92 
93  // Reset allocated data
94  void reset() {
95  resource_.release();
96  }
97 
98 protected:
99  /// Override do_allocate to handle allocation logic
100  void* do_allocate(size_t bytes, size_t alignment) override {
101  // No-op
102  return nullptr;
103  }
104 
105  /// Override do_deallocate (no-op for monotonic buffer)
106  void do_deallocate(void* p, size_t bytes, size_t alignment) override {
107  // No-op
108  }
109 
110  /// Override do_is_equal for memory resource comparison
111  bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
112  return this == &other;
113  }
114 
115 private:
116  std::unique_ptr<char[]> buffer;
117  size_t buffer_size;
118  Resource resource_;
120 };
121 
124 
125 
126 
127 #endif /* ARENA_RESOURCE_HH_ */
Definitions of ASSERTS.
void * do_allocate(size_t bytes, size_t alignment) override
AlignedMemoryResource(std::pmr::monotonic_buffer_resource &upstream, size_t alignment)
bool do_is_equal(const std::pmr::memory_resource &other) const noexcept override
void do_deallocate(void *p, size_t bytes, size_t alignment) override
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(void *p, size_t bytes, 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.