12#ifndef MFEM_MEM_MANAGER_HPP
13#define MFEM_MEM_MANAGER_HPP
25#include <HYPRE_utilities.h>
26#if (21400 <= MFEM_HYPRE_VERSION) && (MFEM_HYPRE_VERSION < 21900)
27#include <_hypre_utilities.h>
230 if (
this == &orig) {
return *
this; }
257 explicit Memory(T *ptr,
int size,
bool own) {
Wrap(ptr, size, own); }
268 {
Wrap(ptr, size, mt, own); }
331 inline void New(
int size);
361 inline void Wrap(T *ptr,
int size,
bool own);
398 bool valid_host =
false,
bool valid_device =
true);
443 inline operator T*();
450 inline operator const T*()
const;
465 template <
typename U>
466 inline explicit operator U*();
476 template <
typename U>
477 inline explicit operator const U*()
const;
563 static constexpr std::size_t def_align_bytes_()
566 return alignof(max_align_t);
568 static constexpr std::size_t def_align_bytes = def_align_bytes_();
569 static constexpr std::size_t new_align_bytes =
570 alignof(T) > def_align_bytes ?
alignof(T) : def_align_bytes;
572 template <std::
size_t align_
bytes,
bool dummy = true>
struct Alloc
574#if __cplusplus < 201703L
575 static inline T *New(std::size_t)
578 MFEM_ASSERT(
false,
"overaligned type cannot use MemoryType::HOST");
582 static inline T *New(std::size_t size) {
return new T[size]; }
586#if __cplusplus < 201703L
587 template<
bool dummy>
struct Alloc<def_align_bytes,dummy>
589 static inline T *New(std::size_t size) {
return new T[size]; }
594 static inline T *NewHOST(std::size_t size)
596 return Alloc<new_align_bytes>::New(size);
611 template <
typename T>
friend class Memory;
614 MFEM_ENZYME_INACTIVE
static MemoryType host_mem_type;
617 MFEM_ENZYME_INACTIVE
static MemoryType device_mem_type;
620 MFEM_ENZYME_INACTIVE
static bool exists;
623 static bool Exists() {
return exists; }
634 MFEM_ENZYME_INACTIVE
static bool configured;
637#ifdef MFEM_USE_UMPIRE
638 static const char * h_umpire_name;
639 static const char * d_umpire_name;
640 static const char * d_umpire_2_name;
648 static void *New_(
void *h_tmp,
size_t bytes,
MemoryType mt,
unsigned &flags);
650 static void *New_(
void *h_tmp,
size_t bytes,
MemoryType h_mt,
651 MemoryType d_mt,
unsigned valid_flags,
unsigned &flags);
655 MFEM_ENZYME_INACTIVE
static void *Register_(
void *ptr,
void *h_ptr,
657 bool own,
bool alias,
unsigned &flags);
660 static void Register2_(
void *h_ptr,
void *d_ptr,
size_t bytes,
662 bool own,
bool alias,
unsigned &flags,
663 unsigned valid_flags);
666 static void Alias_(
void *base_h_ptr,
size_t offset,
size_t bytes,
667 unsigned base_flags,
unsigned &flags);
669 static void SetDeviceMemoryType_(
void *h_ptr,
unsigned flags,
673 MFEM_ENZYME_FN_LIKE_FREE
static void Delete_(
void *h_ptr,
MemoryType mt,
677 static void DeleteDevice_(
void *h_ptr,
unsigned & flags);
680 static bool MemoryClassCheck_(
MemoryClass mc,
void *h_ptr,
681 MemoryType h_mt,
size_t bytes,
unsigned flags);
685 MFEM_ENZYME_FN_LIKE_DYNCAST
static void *ReadWrite_(
void *h_ptr,
687 size_t bytes,
unsigned &flags);
689 MFEM_ENZYME_FN_LIKE_DYNCAST
static const void *Read_(
void *h_ptr,
691 size_t bytes,
unsigned &flags);
693 MFEM_ENZYME_FN_LIKE_DYNCAST
static void *Write_(
void *h_ptr,
MemoryType h_mt,
695 size_t bytes,
unsigned &flags);
697 static void SyncAlias_(
const void *base_h_ptr,
void *alias_h_ptr,
698 size_t alias_bytes,
unsigned base_flags,
699 unsigned &alias_flags);
703 MFEM_ENZYME_INACTIVE
static MemoryType GetDeviceMemoryType_(
void *h_ptr,
707 MFEM_ENZYME_INACTIVE
static MemoryType GetHostMemoryType_(
void *h_ptr);
710 static void CheckHostMemoryType_(
MemoryType h_mt,
void *h_ptr,
bool alias);
714 static void Copy_(
void *dest_h_ptr,
const void *src_h_ptr,
size_t bytes,
715 unsigned src_flags,
unsigned &dest_flags);
719 static void CopyToHost_(
void *dest_h_ptr,
const void *src_h_ptr,
720 size_t bytes,
unsigned src_flags);
724 static void CopyFromHost_(
void *dest_h_ptr,
const void *src_h_ptr,
725 size_t bytes,
unsigned &dest_flags);
728 static bool IsKnown_(
const void *h_ptr);
732 static bool IsAlias_(
const void *h_ptr);
735 static int CompareHostAndDevice_(
void *h_ptr,
size_t size,
unsigned flags);
744 void InsertDevice(
void *d_ptr,
void *h_ptr,
size_t bytes,
748 void InsertAlias(
const void *base_ptr,
void *alias_ptr,
749 const size_t bytes,
const bool base_is_alias);
752 void Erase(
void *h_ptr,
bool free_dev_ptr =
true);
755 void EraseDevice(
void *h_ptr);
758 void EraseAlias(
void *alias_ptr);
762 void *GetDevicePtr(
const void *h_ptr,
size_t bytes,
bool copy_data);
766 void *GetAliasDevicePtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
770 void *GetHostPtr(
const void *d_ptr,
size_t bytes,
bool copy_data);
774 void *GetAliasHostPtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
803 {
return dual_map[(int)mt]; }
822#ifdef MFEM_USE_UMPIRE
842 bool IsKnown(
const void *h_ptr) {
return IsKnown_(h_ptr); }
845 bool IsAlias(
const void *h_ptr) {
return IsAlias_(h_ptr); }
848 void RegisterCheck(
void *h_ptr);
852 int PrintPtrs(std::ostream &out =
mfem::out);
856 int PrintAliases(std::ostream &out =
mfem::out);
861#ifdef MFEM_USE_ENZYME
864 MemoryManager::Delete_(mem, MT, flags);
867 inline static void* __enzyme_allocation_like1[4] = {(
void*)
static_cast<void*(*)(
void*,
size_t,
MemoryType,
unsigned&)
>(MemoryManager::New_),
868 (
void*)1, (
void*)
"-1,2,3", (
void*)myfree
871 inline static void* __enzyme_allocation_like2[4] = {(
void*)
static_cast<void*(*)(
void*,
size_t,
MemoryType,
MemoryType,
unsigned,
unsigned&)
>(MemoryManager::New_),
872 (
void*)1, (
void*)
"-1,2,4", (
void*)MemoryManager::Delete_
880#if MFEM_HYPRE_VERSION < 21400
881#define HYPRE_MEMORY_DEVICE (0)
882#define HYPRE_MEMORY_HOST (1)
884#if MFEM_HYPRE_VERSION < 21900
891#if !defined(HYPRE_USING_GPU)
892 return HYPRE_MEMORY_HOST;
893#elif MFEM_HYPRE_VERSION < 23100
894 return HYPRE_MEMORY_DEVICE;
897 HYPRE_GetMemoryLocation(&loc);
905#if !defined(HYPRE_USING_GPU)
907#elif MFEM_HYPRE_VERSION < 23100
941 flags = OWNS_HOST | VALID_HOST;
944 (T*)MemoryManager::New_(
nullptr, size*
sizeof(T), h_mt, flags);
951 const size_t bytes = size*
sizeof(T);
953 if (mt_host) { flags = OWNS_HOST | VALID_HOST; }
956 h_ptr = (mt_host) ? h_tmp : (T*)MemoryManager::New_(h_tmp, bytes, mt, flags);
963 const size_t bytes = size*
sizeof(T);
964 this->h_mt = host_mt;
966 h_ptr = (T*)MemoryManager::New_(h_tmp, bytes, host_mt, device_mt,
975 flags = (own ? OWNS_HOST : 0) | VALID_HOST;
978 if (own && MemoryManager::Exists())
980 MemoryType h_ptr_mt = MemoryManager::GetHostMemoryType_(h_ptr);
981 MFEM_VERIFY(h_mt == h_ptr_mt,
982 "h_mt = " << (
int)h_mt <<
", h_ptr_mt = " << (
int)h_ptr_mt);
987 const size_t bytes = size*
sizeof(T);
988 MemoryManager::Register_(ptr, ptr, bytes, h_mt, own,
false, flags);
1003 flags = (own ? OWNS_HOST : 0) | VALID_HOST;
1013 h_ptr = (T*)MemoryManager::Register_(ptr, h_ptr, size*
sizeof(T), mt,
1017template <
typename T>
1019 bool own,
bool valid_host,
bool valid_device)
1026 MFEM_ASSERT(valid_host || valid_device,
"");
1027 const size_t bytes = size*
sizeof(T);
1029 MemoryManager::Register2_(h_ptr, d_ptr, bytes, h_mt, d_mt,
1031 valid_host*VALID_HOST|valid_device*VALID_DEVICE);
1034template <
typename T>
1037 MFEM_ASSERT(0 <= offset,
"invalid offset = " << offset);
1038 MFEM_ASSERT(0 <= size,
"invalid size = " << size);
1039 MFEM_ASSERT(offset + size <= base.
capacity,
1040 "invalid offset + size = " << offset + size
1041 <<
" > base capacity = " << base.
capacity);
1044 h_ptr = base.
h_ptr + offset;
1045 if (!(base.
flags & Registered))
1048#
if !defined(HYPRE_USING_GPU)
1052#elif MFEM_HYPRE_VERSION < 23100
1055 MemoryManager::Exists()
1062 MemoryManager::Register_(base.
h_ptr,
nullptr, base.
capacity*
sizeof(T),
1070 flags = (base.
flags | ALIAS) & ~(OWNS_HOST | OWNS_DEVICE);
1074 const size_t s_bytes = size*
sizeof(T);
1075 const size_t o_bytes = offset*
sizeof(T);
1076 MemoryManager::Alias_(base.
h_ptr, o_bytes, s_bytes, base.
flags, flags);
1079template <
typename T>
1083 if (!(flags & Registered))
1085 MemoryManager::Register_(h_ptr,
nullptr, capacity*
sizeof(T), h_mt,
1086 flags & OWNS_HOST, flags & ALIAS, flags);
1088 MemoryManager::SetDeviceMemoryType_(h_ptr, flags, d_mt);
1091template <
typename T>
1094 const bool registered = flags & Registered;
1096 const bool std_delete = !registered && mt_host;
1100 MemoryManager::Delete_((
void*)h_ptr, h_mt, flags);
1105 if (flags & OWNS_HOST) {
delete [] h_ptr; }
1110template <
typename T>
1113 if (flags & Registered)
1116 MemoryManager::DeleteDevice_((
void*)h_ptr, flags);
1120template <
typename T>
1123 MFEM_ASSERT((flags & VALID_HOST) && !(flags & VALID_DEVICE),
1124 "invalid host pointer access");
1128template <
typename T>
1131 MFEM_ASSERT((flags & VALID_HOST),
"invalid host pointer access");
1135template <
typename T>
1138 MFEM_ASSERT(Empty() ||
1139 ((flags & VALID_HOST) &&
1140 (std::is_const<T>::value || !(flags & VALID_DEVICE))),
1141 "invalid host pointer access");
1145template <
typename T>
1148 MFEM_ASSERT(Empty() || (flags & VALID_HOST),
"invalid host pointer access");
1152template <
typename T>
template <
typename U>
1155 MFEM_ASSERT(Empty() ||
1156 ((flags & VALID_HOST) &&
1157 (std::is_const<U>::value || !(flags & VALID_DEVICE))),
1158 "invalid host pointer access");
1159 return reinterpret_cast<U*
>(h_ptr);
1162template <
typename T>
template <
typename U>
1165 MFEM_ASSERT(Empty() || (flags & VALID_HOST),
"invalid host pointer access");
1166 return reinterpret_cast<U*
>(h_ptr);
1169template <
typename T>
1172 const size_t bytes = size *
sizeof(T);
1173 if (!(flags & Registered))
1176 MemoryManager::Register_(h_ptr,
nullptr, capacity*
sizeof(T), h_mt,
1177 flags & OWNS_HOST, flags & ALIAS, flags);
1179 return (T*)MemoryManager::ReadWrite_(h_ptr, h_mt, mc, bytes, flags);
1182template <
typename T>
1185 const size_t bytes = size *
sizeof(T);
1186 if (!(flags & Registered))
1189 MemoryManager::Register_(h_ptr,
nullptr, capacity*
sizeof(T), h_mt,
1190 flags & OWNS_HOST, flags & ALIAS, flags);
1192 return (
const T*)MemoryManager::Read_(h_ptr, h_mt, mc, bytes, flags);
1195template <
typename T>
1198 const size_t bytes = size *
sizeof(T);
1199 if (!(flags & Registered))
1202 MemoryManager::Register_(h_ptr,
nullptr, capacity*
sizeof(T), h_mt,
1203 flags & OWNS_HOST, flags & ALIAS, flags);
1205 return (T*)MemoryManager::Write_(h_ptr, h_mt, mc, bytes, flags);
1208template <
typename T>
1211 if (!(flags & Registered) && (other.
flags & Registered))
1213 MFEM_ASSERT(h_ptr == other.
h_ptr &&
1214 (flags & ALIAS) == (other.
flags & ALIAS),
1216 flags = (flags | Registered) & ~(OWNS_DEVICE | OWNS_INTERNAL);
1218 flags = (flags & ~(VALID_HOST | VALID_DEVICE)) |
1219 (other.
flags & (VALID_HOST | VALID_DEVICE));
1222template <
typename T>
1226 MFEM_ASSERT(!(flags & Registered) || (base.
flags & Registered),
1227 "invalid base state");
1228 if (!(base.
flags & Registered)) {
return; }
1229 MemoryManager::SyncAlias_(base.
h_ptr, h_ptr, alias_size*
sizeof(T),
1233template <
typename T>
1236 if (h_ptr ==
nullptr || !(flags & VALID_DEVICE)) {
return h_mt; }
1237 return MemoryManager::GetDeviceMemoryType_(h_ptr, flags & ALIAS);
1240template <
typename T>
1244 return MemoryManager::GetDeviceMemoryType_(h_ptr, flags & ALIAS);
1247template <
typename T>
1250 return flags & VALID_HOST ? true :
false;
1253template <
typename T>
1256 return flags & VALID_DEVICE ? true :
false;
1259template <
typename T>
1262 MFEM_VERIFY(src.
capacity>=size && capacity>=size,
"Incorrect size");
1263 if (size <= 0) {
return; }
1264 if (!(flags & Registered) && !(src.
flags & Registered))
1266 if (h_ptr != src.
h_ptr)
1268 MFEM_ASSERT(h_ptr + size <= src.
h_ptr || src.
h_ptr + size <= h_ptr,
1270 std::memcpy(h_ptr, src, size*
sizeof(T));
1276 MemoryManager::Copy_(h_ptr, src.
h_ptr, size*
sizeof(T), src.
flags, flags);
1280template <
typename T>
1283 MFEM_VERIFY(capacity>=size,
"Incorrect size");
1284 if (size <= 0) {
return; }
1285 if (!(flags & Registered))
1289 MFEM_ASSERT(h_ptr + size <= src || src + size <= h_ptr,
1291 std::memcpy(h_ptr, src, size*
sizeof(T));
1297 MemoryManager::CopyFromHost_(h_ptr, src, size*
sizeof(T), flags);
1301template <
typename T>
1307template <
typename T>
1310 MFEM_VERIFY(capacity>=size,
"Incorrect size");
1311 if (size <= 0) {
return; }
1312 if (!(flags & Registered))
1316 MFEM_ASSERT(h_ptr + size <= dest || dest + size <= h_ptr,
1318 std::memcpy(dest, h_ptr, size*
sizeof(T));
1323 MemoryManager::CopyToHost_(dest, h_ptr, size*
sizeof(T), flags);
1333template <
typename T>
1339template <
typename T>
1342 if (!(flags & VALID_HOST) || !(flags & VALID_DEVICE)) {
return 0; }
1343 return MemoryManager::CompareHostAndDevice_(h_ptr, size*
sizeof(T), flags);
A class to initialize the size of a Tensor.
bool IsKnown(const void *h_ptr)
Return true if the pointer is known by the memory manager.
static void SetUmpireDeviceAllocatorName(const char *d_name)
Set the device Umpire allocator name used with MemoryType::DEVICE_UMPIRE.
static void myfree(void *mem, MemoryType MT, unsigned &flags)
static const char * GetUmpireHostAllocatorName()
Get the host Umpire allocator name used with MemoryType::HOST_UMPIRE.
static void SetUmpireHostAllocatorName(const char *h_name)
Set the host Umpire allocator name used with MemoryType::HOST_UMPIRE.
static MemoryType GetHostMemoryType()
bool IsAlias(const void *h_ptr)
Return true if the pointer is known by the memory manager as an alias.
static const char * GetUmpireDevice2AllocatorName()
Get the device Umpire allocator name used with MemoryType::DEVICE_UMPIRE_2.
static void SetUmpireDevice2AllocatorName(const char *d_name)
Set the device Umpire allocator name used with MemoryType::DEVICE_UMPIRE_2.
static MemoryType GetDeviceMemoryType()
static MemoryType GetDualMemoryType(MemoryType mt)
Return the dual MemoryType of the given one, mt.
__attribute__((used)) inline static void *__enzyme_allocation_like2[4]
static const char * GetUmpireDeviceAllocatorName()
Get the device Umpire allocator name used with MemoryType::DEVICE_UMPIRE.
__attribute__((used)) inline static void *__enzyme_allocation_like1[4]
Class used by MFEM to store pointers to host and/or device memory.
void SetHostPtrOwner(bool own) const
Set/clear the ownership flag for the host pointer. Ownership indicates whether the pointer will be de...
void New(int size, MemoryType mt)
Allocate memory for size entries with the given MemoryType.
bool OwnsDevicePtr() const
Return true if the device pointer is owned. Ownership indicates whether the pointer will be deleted b...
T * Write(MemoryClass mc, int size)
Get write-only access to the memory with the given MemoryClass.
Memory(int size, MemoryType mt)
Allocate memory for size entries with the given MemoryType mt.
void Wrap(T *ptr, int size, MemoryType mt, bool own)
Wrap an externally allocated pointer, ptr, of the given MemoryType.
Memory(const Memory &base, int offset, int size)
Alias constructor. Create a Memory object that points inside the Memory object base.
MemoryType GetHostMemoryType() const
Return the host MemoryType of the Memory object.
bool DeviceIsValid() const
Return true if device pointer is valid.
Memory(int size, MemoryType h_mt, MemoryType d_mt)
Allocate memory for size entries with the given host MemoryType h_mt and device MemoryType d_mt.
void SetDeviceMemoryType(MemoryType d_mt)
Set the device MemoryType to be used by the Memory object.
void SetDevicePtrOwner(bool own) const
Set/clear the ownership flag for the device pointer. Ownership indicates whether the pointer will be ...
int Capacity() const
Return the size of the allocated memory.
void CopyFromHost(const T *src, int size)
Copy size entries from the host pointer src to *this.
T & operator[](int idx)
Array subscript operator for host memory.
void New(int size, MemoryType h_mt, MemoryType d_mt)
Allocate memory for size entries with the given host MemoryType h_mt and device MemoryType d_mt.
@ OWNS_INTERNAL
Ownership flag for internal Memory data.
@ VALID_HOST
Host pointer is valid.
@ OWNS_HOST
The host pointer will be deleted by Delete()
@ VALID_DEVICE
Device pointer is valid
@ ALIAS
Pointer is an alias.
MemoryType GetDeviceMemoryType() const
Return the device MemoryType of the Memory object. If the device MemoryType is not set,...
T * ReadWrite(MemoryClass mc, int size)
Get read-write access to the memory with the given MemoryClass.
MemoryType h_mt
Host memory type.
Memory & operator=(const Memory &orig)=default
Copy-assignment operator: default.
void Reset(MemoryType host_mt)
Reset the memory and set the host memory type.
void MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
bool HostIsValid() const
Return true if host pointer is valid.
~Memory()=default
Destructor: default.
bool UseDevice() const
Read the internal device flag.
void CopyToHost(T *dest, int size) const
Copy size entries from *this to the host pointer dest.
void SyncAlias(const Memory &base, int alias_size) const
Update the alias Memory *this to match the memory location (all valid locations) of its base Memory,...
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
friend void MemoryPrintFlags(unsigned flags)
Print the state of a Memory object based on its internal flags. Useful in a debugger....
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
bool Empty() const
Return true if the Memory object is empty, see Reset().
T * h_ptr
Pointer to host memory. Not owned.
void Sync(const Memory &other) const
Copy the host/device pointer validity flags from other to *this.
Memory(const Memory &orig)=default
Copy constructor: default.
void PrintFlags() const
Print the internal flags.
void DeleteDevice(bool copy_to_host=true)
Delete the device pointer, if owned. If copy_to_host is true and the data is valid only on device,...
unsigned flags
Bit flags defined from the FlagMask enum.
const T * Read(MemoryClass mc, int size) const
Get read-only access to the memory with the given MemoryClass.
void UseDevice(bool use_dev) const
Set the internal device flag.
int CompareHostAndDevice(int size) const
If both the host and the device data are valid, compare their contents.
void CopyFrom(const Memory &src, int size)
Copy size entries from src to *this.
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
Memory(int size)
Allocate host memory for size entries.
void Wrap(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with the current host memory type returned by MemoryMa...
void Delete()
Delete the owned pointers and reset the Memory object.
Memory(T *ptr, int size, MemoryType mt, bool own)
Wrap an externally allocated pointer, ptr, of the given MemoryType.
void CopyTo(Memory &dest, int size) const
Copy size entries from *this to dest.
void ClearOwnerFlags() const
Clear the ownership flags for the host and device pointers, as well as any internal data allocated by...
const T & operator[](int idx) const
Array subscript operator for host memory, const version.
void Wrap(T *h_ptr, T *d_ptr, int size, MemoryType h_mt, bool own, bool valid_host=false, bool valid_device=true)
int capacity
Size of the allocated memory.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
Memory & operator=(Memory &&orig)
Memory(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with the current host memory type returned by MemoryMa...
bool IsDeviceMemory(MemoryType mt)
Return true if the given memory type is in MemoryClass::DEVICE.
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
constexpr int DeviceMemoryType
MemoryClass operator*(MemoryClass mc1, MemoryClass mc2)
Return a suitable MemoryClass from a pair of MemoryClasses.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
MemoryClass
Memory classes identify sets of memory types.
constexpr int MemoryTypeSize
Static casts to 'int' and sizes of some useful memory types.
MemoryManager mm
The (single) global memory manager object.
MemoryType GetMemoryType(MemoryClass mc)
Return a suitable MemoryType for a given MemoryClass.
constexpr int HostMemoryTypeSize
bool IsHostMemory(MemoryType mt)
Return true if the given memory type is in MemoryClass::HOST.
const char * MemoryTypeName[MemoryTypeSize]
Memory type names, used during Device:: configuration.
constexpr int HostMemoryType
bool HypreUsingGPU()
Return true if HYPRE is configured to use GPU.
constexpr int DeviceMemoryTypeSize
MemoryType
Memory types supported by MFEM.
@ HOST_32
Host memory; aligned at 32 bytes.
@ SIZE
Number of host and device memory types.
@ HOST_64
Host memory; aligned at 64 bytes.
@ HOST
Host memory; using new[] and delete[].
@ HOST_PINNED
Host memory: pinned (page-locked)
@ HOST_DEBUG
Host memory; allocated from a "host-debug" pool.
@ DEVICE
Device memory; using CUDA or HIP *Malloc and *Free.
HYPRE_MemoryLocation GetHypreMemoryLocation()
Return the configured HYPRE_MemoryLocation.
void MemoryPrintFlags(unsigned flags)
Print the state of a Memory object based on its internal flags. Useful in a debugger....
bool MemoryClassContainsType(MemoryClass mc, MemoryType mt)
Return true iff the MemoryType mt is contained in the MemoryClass mc.