Block-Structured AMR Software Framework
AMReX_Arena.H
Go to the documentation of this file.
1 #ifndef AMREX_ARENA_H_
2 #define AMREX_ARENA_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_BLassert.H>
6 #include <AMReX_INT.H>
7 
8 #ifdef AMREX_TINY_PROFILING
9 #include <AMReX_TinyProfiler.H>
10 #else
11 namespace amrex {
12  struct MemStat {};
13 }
14 #endif
15 
16 #include <cstddef>
17 #include <cstdlib>
18 #include <limits>
19 #include <map>
20 #include <mutex>
21 #include <unordered_map>
22 #include <utility>
23 
24 namespace amrex {
25 
30 inline std::size_t aligned_size (std::size_t align_requirement, std::size_t size) noexcept
31 {
32  return ((size + (align_requirement-1)) / align_requirement) * align_requirement;
33 }
34 
35 inline bool is_aligned (const void* p, std::size_t alignment) noexcept
36 {
37  auto* q = const_cast<void*>(p);
38  auto space = alignment;
39  return std::align(alignment, alignment, q, space) == p;
40 }
41 
42 class Arena;
43 
44 Arena* The_Arena ();
45 Arena* The_Async_Arena ();
46 Arena* The_Device_Arena ();
47 Arena* The_Managed_Arena ();
48 Arena* The_Pinned_Arena ();
49 Arena* The_Comms_Arena ();
50 Arena* The_Cpu_Arena ();
51 
52 struct ArenaInfo
53 {
55  bool use_cpu_memory = false;
57  bool device_set_readonly = false;
58  bool device_set_preferred = false;
59  bool device_use_hostalloc = false;
60  ArenaInfo& SetReleaseThreshold (Long rt) noexcept {
61  release_threshold = rt;
62  return *this;
63  }
64  ArenaInfo& SetDeviceMemory () noexcept {
66  device_use_hostalloc = false;
67  return *this;
68  }
69  ArenaInfo& SetReadOnly () noexcept {
71  device_set_readonly = true;
72  return *this;
73  }
74  ArenaInfo& SetPreferred () noexcept {
76  device_set_preferred = true;
77  return *this;
78  }
79  ArenaInfo& SetHostAlloc () noexcept {
80  device_use_hostalloc = true;
82  return *this;
83  }
84  ArenaInfo& SetCpuMemory () noexcept {
85  use_cpu_memory = true;
87  device_set_readonly = false;
88  device_set_preferred = false;
89  device_use_hostalloc = false;
90  return *this;
91  }
92 };
93 
99 class Arena
100 {
101 public:
102 
103  virtual ~Arena () = default;
104  Arena () noexcept = default;
105 
106  Arena (const Arena& rhs) = delete;
107  Arena (Arena&& rhs) = delete;
108  Arena& operator= (const Arena& rhs) = delete;
109  Arena& operator= (Arena&& rhs) = delete;
110 
116  [[nodiscard]] virtual void* alloc (std::size_t sz) = 0;
117 
121  [[nodiscard]] virtual std::pair<void*,std::size_t>
122  alloc_in_place (void* /*pt*/, std::size_t /*szmin*/, std::size_t szmax)
123  {
124  auto* p = alloc(szmax);
125  return std::make_pair(p, szmax);
126  }
127 
131  [[nodiscard]] virtual void*
132  shrink_in_place (void* /*pt*/, std::size_t sz)
133  {
134  return alloc(sz);
135  }
136 
140  virtual void free (void* pt) = 0;
141 
146  virtual std::size_t freeUnused () { return 0; }
147 
148  // isDeviceAccessible and isHostAccessible can both be true.
149  [[nodiscard]] virtual bool isDeviceAccessible () const;
150  [[nodiscard]] virtual bool isHostAccessible () const;
151 
152  // Note that isManaged, isDevice and isPinned are mutually exclusive.
153  // For memory allocated by cudaMalloc* etc., one of them returns true.
154  // Otherwise, neither is true.
155  [[nodiscard]] virtual bool isManaged () const;
156  [[nodiscard]] virtual bool isDevice () const;
157  [[nodiscard]] virtual bool isPinned () const;
158 
165  [[nodiscard]] virtual bool hasFreeDeviceMemory (std::size_t sz);
166 
171  void registerForProfiling (const std::string& memory_name);
172 
173 #ifdef AMREX_USE_GPU
175  [[nodiscard]] virtual bool isStreamOrderedArena () const { return false; }
176 #endif
177 
182  static std::size_t align (std::size_t sz);
183 
184  static void Initialize ();
185  static void PrintUsage ();
186  static void PrintUsageToFiles (std::string const& filename, std::string const& message);
187  static void Finalize ();
188 
189 #if 0
190  union Word
191  {
192  void* p;
193  long long ll;
194  long double ld;
195  void (*f) ();
196  };
197  static const std::size_t align_size = sizeof(Word);
198 #endif
199 
200  static const std::size_t align_size = 16;
201 
205  [[nodiscard]] const ArenaInfo& arenaInfo () const { return arena_info; }
206 
207 protected:
208 
210 
211  virtual std::size_t freeUnused_protected () { return 0; }
212  void* allocate_system (std::size_t nbytes);
213  void deallocate_system (void* p, std::size_t nbytes);
214 
215  struct ArenaProfiler {
217  bool m_do_profiling = false;
221  std::map<std::string, MemStat> m_profiling_stats;
223  std::unordered_map<void*, std::pair<MemStat*, std::size_t>> m_currently_allocated;
224 
226  ArenaProfiler () noexcept = default;
227  ArenaProfiler (const ArenaProfiler& rhs) = delete;
228  ArenaProfiler (ArenaProfiler&& rhs) = delete;
229  ArenaProfiler& operator= (const ArenaProfiler& rhs) = delete;
230  ArenaProfiler& operator= (ArenaProfiler&& rhs) = delete;
231 
232  void profile_alloc (void* ptr, std::size_t nbytes);
233 
234  void profile_free (void* ptr);
235 
237 };
238 
239 }
240 
241 #endif /*BL_ARENA_H*/
#define BL_ASSERT(EX)
Definition: AMReX_BLassert.H:39
A virtual base class for objects that manage their own dynamic memory allocation.
Definition: AMReX_Arena.H:100
static void Finalize()
Definition: AMReX_Arena.cpp:536
virtual void free(void *pt)=0
A pure virtual function for deleting the arena pointed to by pt.
const ArenaInfo & arenaInfo() const
Return the ArenaInfo object for querying.
Definition: AMReX_Arena.H:205
virtual void * shrink_in_place(void *, std::size_t sz)
Definition: AMReX_Arena.H:132
static std::size_t align(std::size_t sz)
Given a minimum required arena size of sz bytes, this returns the next largest arena size that will a...
Definition: AMReX_Arena.cpp:130
Arena() noexcept=default
virtual ~Arena()=default
virtual bool isPinned() const
Definition: AMReX_Arena.cpp:103
virtual bool isHostAccessible() const
Definition: AMReX_Arena.cpp:67
virtual bool isStreamOrderedArena() const
Is this GPU stream ordered memory allocator?
Definition: AMReX_Arena.H:175
virtual void * alloc(std::size_t sz)=0
static const std::size_t align_size
Definition: AMReX_Arena.H:200
static void PrintUsage()
Definition: AMReX_Arena.cpp:419
virtual bool isManaged() const
Definition: AMReX_Arena.cpp:79
virtual std::size_t freeUnused_protected()
Definition: AMReX_Arena.H:211
void registerForProfiling(const std::string &memory_name)
Add this Arena to the list of Arenas that are profiled by TinyProfiler.
Definition: AMReX_Arena.cpp:120
static void Initialize()
Definition: AMReX_Arena.cpp:270
static void PrintUsageToFiles(std::string const &filename, std::string const &message)
Definition: AMReX_Arena.cpp:482
virtual bool isDevice() const
Definition: AMReX_Arena.cpp:91
virtual std::pair< void *, std::size_t > alloc_in_place(void *, std::size_t, std::size_t szmax)
Definition: AMReX_Arena.H:122
virtual bool hasFreeDeviceMemory(std::size_t sz)
Does the device have enough free memory for allocating this much memory? For CPU builds,...
Definition: AMReX_Arena.cpp:114
void deallocate_system(void *p, std::size_t nbytes)
Definition: AMReX_Arena.cpp:219
struct amrex::Arena::ArenaProfiler m_profiler
virtual std::size_t freeUnused()
Free unused memory back to the system. Return value is the amount memory freed.
Definition: AMReX_Arena.H:146
ArenaInfo arena_info
Definition: AMReX_Arena.H:209
virtual bool isDeviceAccessible() const
Definition: AMReX_Arena.cpp:57
void * allocate_system(std::size_t nbytes)
Definition: AMReX_Arena.cpp:136
AMREX_GPU_HOST_DEVICE Long size(T const &b) noexcept
integer version
Definition: AMReX_GpuRange.H:26
static int f(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:44
@ max
Definition: AMReX_ParallelReduce.H:17
Definition: AMReX_Amr.cpp:49
bool is_aligned(const void *p, std::size_t alignment) noexcept
Definition: AMReX_Arena.H:35
Arena * The_Managed_Arena()
Definition: AMReX_Arena.cpp:624
Arena * The_Comms_Arena()
Definition: AMReX_Arena.cpp:654
Arena * The_Device_Arena()
Definition: AMReX_Arena.cpp:614
Arena * The_Pinned_Arena()
Definition: AMReX_Arena.cpp:634
Arena * The_Async_Arena()
Definition: AMReX_Arena.cpp:604
std::size_t aligned_size(std::size_t align_requirement, std::size_t size) noexcept
Given a minimum required size of size bytes, this returns the next largest arena size that will align...
Definition: AMReX_Arena.H:30
Arena * The_Cpu_Arena()
Definition: AMReX_Arena.cpp:644
Arena * The_Arena()
Definition: AMReX_Arena.cpp:594
Definition: AMReX_Arena.H:53
bool device_set_preferred
Definition: AMReX_Arena.H:58
bool device_set_readonly
Definition: AMReX_Arena.H:57
ArenaInfo & SetReadOnly() noexcept
Definition: AMReX_Arena.H:69
bool device_use_hostalloc
Definition: AMReX_Arena.H:59
Long release_threshold
Definition: AMReX_Arena.H:54
ArenaInfo & SetReleaseThreshold(Long rt) noexcept
Definition: AMReX_Arena.H:60
ArenaInfo & SetDeviceMemory() noexcept
Definition: AMReX_Arena.H:64
ArenaInfo & SetHostAlloc() noexcept
Definition: AMReX_Arena.H:79
ArenaInfo & SetPreferred() noexcept
Definition: AMReX_Arena.H:74
bool device_use_managed_memory
Definition: AMReX_Arena.H:56
bool use_cpu_memory
Definition: AMReX_Arena.H:55
ArenaInfo & SetCpuMemory() noexcept
Definition: AMReX_Arena.H:84
Definition: AMReX_Arena.H:215
std::map< std::string, MemStat > m_profiling_stats
Data structure used for profiling with TinyProfiler.
Definition: AMReX_Arena.H:221
void profile_alloc(void *ptr, std::size_t nbytes)
Definition: AMReX_Arena.cpp:678
void profile_free(void *ptr)
Definition: AMReX_Arena.cpp:691
std::unordered_map< void *, std::pair< MemStat *, std::size_t > > m_currently_allocated
Track the currently allocated memory, not used by CArena.
Definition: AMReX_Arena.H:223
bool m_do_profiling
If this arena is profiled by TinyProfiler.
Definition: AMReX_Arena.H:217
std::mutex m_arena_profiler_mutex
Mutex for the profiling.
Definition: AMReX_Arena.H:219
ArenaProfiler() noexcept=default
Definition: AMReX_Arena.H:12