Block-Structured AMR Software Framework
AMReX_GpuAllocators.H
Go to the documentation of this file.
1 #ifndef AMREX_GPUALLOCATORS_H_
2 #define AMREX_GPUALLOCATORS_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_Print.H>
6 #include <AMReX_Arena.H>
7 #include <AMReX_GpuDevice.H>
8 
9 #ifdef AMREX_USE_CUDA
10 #include <cuda.h>
11 #include <driver_types.h>
12 #include <cuda_runtime.h>
13 #endif // AMREX_USE_CUDA
14 
15 #include <limits>
16 #include <map>
17 #include <memory>
18 #include <type_traits>
19 
20 namespace amrex {
21 
22  template <typename T>
23  struct FatPtr
24  {
25  T* m_ptr = nullptr;
26  std::size_t m_size = 0;
27  [[nodiscard]] constexpr T* ptr () const noexcept { return m_ptr; }
28  [[nodiscard]] constexpr std::size_t size () const noexcept { return m_size; }
29  };
30 
31  template <class T, class AR>
33  {
34  using value_type = T;
35  using arena_wrapper_type = AR;
36 
37  constexpr ArenaAllocatorBase () = default;
38  explicit constexpr ArenaAllocatorBase (AR a_ar) : m_ar(a_ar) {}
39 
40  [[nodiscard]] T* allocate (std::size_t n)
41  {
42  return (T*) arena()->alloc(n * sizeof(T));
43  }
44 
45  [[nodiscard]] FatPtr<T>
46  allocate_in_place (T* p, std::size_t nmin, std::size_t nmax)
47  {
48  auto pn = arena()->alloc_in_place(p, nmin*sizeof(T), nmax*sizeof(T));
49  return FatPtr<T>{(T*)pn.first, pn.second/sizeof(T)};
50  }
51 
52  [[nodiscard]] T*
53  shrink_in_place (T* p, std::size_t n)
54  {
55  return (T*) arena()->shrink_in_place(p,n*sizeof(T));
56  }
57 
58  void deallocate (T* ptr, std::size_t)
59  {
60  if (ptr != nullptr) { arena()->free(ptr); }
61  }
62 
63  [[nodiscard]] Arena* arena () const noexcept {
64  return m_ar.arena();
65  }
66 
67  private:
68  AR m_ar{};
69  };
70 
71  struct ArenaWrapper {
72  [[nodiscard]] static Arena* arena () noexcept {
73  return The_Arena();
74  }
75  };
76 
78  [[nodiscard]] static Arena* arena () noexcept {
79  return The_Device_Arena();
80  }
81  };
82 
84  [[nodiscard]] static Arena* arena () noexcept {
85  return The_Pinned_Arena();
86  }
87  };
88 
90  [[nodiscard]] static Arena* arena () noexcept {
91  return The_Managed_Arena();
92  }
93  };
94 
96  [[nodiscard]] static Arena* arena () noexcept {
97  return The_Async_Arena();
98  }
99  };
100 
102  constexpr PolymorphicArenaWrapper () = default;
103  explicit constexpr PolymorphicArenaWrapper (Arena* a_arena)
104  : m_arena(a_arena) {}
105  [[nodiscard]] Arena* arena () const noexcept {
106  return (m_arena) ? m_arena : The_Arena();
107  }
108  Arena* m_arena = nullptr;
109  };
110 
111  template<typename T>
113  : public ArenaAllocatorBase<T,ArenaWrapper>
114  {
115  };
116 
117  template<typename T>
119  : public ArenaAllocatorBase<T,DeviceArenaWrapper>
120  {
121  };
122 
123  template<typename T>
125  : public ArenaAllocatorBase<T,PinnedArenaWrapper>
126  {
127  };
128 
129  template<typename T>
131  : public ArenaAllocatorBase<T,ManagedArenaWrapper>
132  {
133  };
134 
135  template<typename T>
137  : public ArenaAllocatorBase<T,AsyncArenaWrapper>
138  {
139  };
140 
141  template<typename T>
143  : public ArenaAllocatorBase<T,PolymorphicArenaWrapper>
144  {
145  public :
146  constexpr PolymorphicArenaAllocator () = default;
147  explicit constexpr PolymorphicArenaAllocator (Arena* a_arena)
149  (PolymorphicArenaWrapper(a_arena))
150  {}
151  void setArena (Arena* a_ar) noexcept
152  {
153  *this = PolymorphicArenaAllocator<T>(a_ar);
154  }
155  };
156 
157  template <typename T>
158  struct RunOnGpu : std::false_type {};
159 
160  template <class T, class Enable = void>
161  struct IsArenaAllocator : std::false_type {};
162  //
163  template <class T>
165  <T,std::enable_if_t<std::is_base_of_v
166  <ArenaAllocatorBase<typename T::value_type,
167  typename T::arena_wrapper_type>,
168  T>>>
169  : std::true_type {};
170 
171  template <typename T>
172  struct IsPolymorphicArenaAllocator : std::false_type {};
173 
174 #ifdef AMREX_USE_GPU
175  template <typename T>
176  struct RunOnGpu<ArenaAllocator<T> > : std::true_type {};
177 
178  template <typename T>
179  struct RunOnGpu<DeviceArenaAllocator<T> > : std::true_type {};
180 
181  template <typename T>
182  struct RunOnGpu<ManagedArenaAllocator<T> > : std::true_type {};
183 
184  template <typename T>
185  struct RunOnGpu<AsyncArenaAllocator<T> > : std::true_type {};
186 
187  template <typename T>
189 
190 #endif // AMREX_USE_GPU
191 
192 #ifdef AMREX_USE_GPU
193  template <class T>
195 #else
196  template <class T>
197  using DefaultAllocator = std::allocator<T>;
198 #endif // AMREX_USE_GPU
199 
200  template <typename A1, typename A2,
201  std::enable_if_t<IsArenaAllocator<A1>::value &&
202  IsArenaAllocator<A2>::value, int> = 0>
203  bool operator== (A1 const& a1, A2 const& a2)
204  {
205  return a1.arena() == a2.arena();
206  }
207 
208  template <typename A1, typename A2,
209  std::enable_if_t<IsArenaAllocator<A1>::value &&
210  IsArenaAllocator<A2>::value, int> = 0>
211  bool operator!= (A1 const& a1, A2 const& a2)
212  {
213  return a1.arena() != a2.arena();
214  }
215 
216 } // namespace amrex
217 
218 #endif // AMREX_GPUALLOCATORS_H_
Definition: AMReX_GpuAllocators.H:114
A virtual base class for objects that manage their own dynamic memory allocation.
Definition: AMReX_Arena.H:100
virtual void free(void *pt)=0
A pure virtual function for deleting the arena pointed to by pt.
virtual void * shrink_in_place(void *, std::size_t sz)
Definition: AMReX_Arena.H:132
virtual void * alloc(std::size_t sz)=0
virtual std::pair< void *, std::size_t > alloc_in_place(void *, std::size_t, std::size_t szmax)
Definition: AMReX_Arena.H:122
Definition: AMReX_GpuAllocators.H:138
Definition: AMReX_GpuAllocators.H:120
Definition: AMReX_GpuAllocators.H:132
Definition: AMReX_GpuAllocators.H:126
Definition: AMReX_GpuAllocators.H:144
void setArena(Arena *a_ar) noexcept
Definition: AMReX_GpuAllocators.H:151
constexpr PolymorphicArenaAllocator(Arena *a_arena)
Definition: AMReX_GpuAllocators.H:147
constexpr PolymorphicArenaAllocator()=default
Definition: AMReX_Amr.cpp:49
Arena * The_Managed_Arena()
Definition: AMReX_Arena.cpp:624
bool operator!=(A1 const &a1, A2 const &a2)
Definition: AMReX_GpuAllocators.H:211
Arena * The_Device_Arena()
Definition: AMReX_Arena.cpp:614
bool operator==(A1 const &a1, A2 const &a2)
Definition: AMReX_GpuAllocators.H:203
Arena * The_Pinned_Arena()
Definition: AMReX_Arena.cpp:634
Arena * The_Async_Arena()
Definition: AMReX_Arena.cpp:604
Arena * The_Arena()
Definition: AMReX_Arena.cpp:594
Definition: AMReX_GpuAllocators.H:33
FatPtr< T > allocate_in_place(T *p, std::size_t nmin, std::size_t nmax)
Definition: AMReX_GpuAllocators.H:46
T value_type
Definition: AMReX_GpuAllocators.H:34
constexpr ArenaAllocatorBase()=default
AR arena_wrapper_type
Definition: AMReX_GpuAllocators.H:35
AR m_ar
Definition: AMReX_GpuAllocators.H:68
T * allocate(std::size_t n)
Definition: AMReX_GpuAllocators.H:40
constexpr ArenaAllocatorBase(AR a_ar)
Definition: AMReX_GpuAllocators.H:38
Arena * arena() const noexcept
Definition: AMReX_GpuAllocators.H:63
T * shrink_in_place(T *p, std::size_t n)
Definition: AMReX_GpuAllocators.H:53
void deallocate(T *ptr, std::size_t)
Definition: AMReX_GpuAllocators.H:58
Definition: AMReX_GpuAllocators.H:71
static Arena * arena() noexcept
Definition: AMReX_GpuAllocators.H:72
Definition: AMReX_GpuAllocators.H:95
static Arena * arena() noexcept
Definition: AMReX_GpuAllocators.H:96
Definition: AMReX_GpuAllocators.H:77
static Arena * arena() noexcept
Definition: AMReX_GpuAllocators.H:78
Definition: AMReX_GpuAllocators.H:24
constexpr T * ptr() const noexcept
Definition: AMReX_GpuAllocators.H:27
std::size_t m_size
Definition: AMReX_GpuAllocators.H:26
T * m_ptr
Definition: AMReX_GpuAllocators.H:25
constexpr std::size_t size() const noexcept
Definition: AMReX_GpuAllocators.H:28
Definition: AMReX_GpuAllocators.H:161
Definition: AMReX_GpuAllocators.H:172
Definition: AMReX_GpuAllocators.H:89
static Arena * arena() noexcept
Definition: AMReX_GpuAllocators.H:90
Definition: AMReX_GpuAllocators.H:83
static Arena * arena() noexcept
Definition: AMReX_GpuAllocators.H:84
Definition: AMReX_GpuAllocators.H:101
constexpr PolymorphicArenaWrapper()=default
Arena * arena() const noexcept
Definition: AMReX_GpuAllocators.H:105
constexpr PolymorphicArenaWrapper(Arena *a_arena)
Definition: AMReX_GpuAllocators.H:103
Arena * m_arena
Definition: AMReX_GpuAllocators.H:108
Definition: AMReX_GpuAllocators.H:158