12 #ifndef MFEM_MEM_MANAGER_HPP
13 #define MFEM_MEM_MANAGER_HPP
18 #include <type_traits>
21 #include <HYPRE_config.h>
145 template <
typename T>
215 explicit Memory(T *ptr,
int size,
bool own) {
Wrap(ptr, size, own); }
226 {
Wrap(ptr, size, mt, own); }
289 inline void New(
int size);
319 inline void Wrap(T *ptr,
int size,
bool own);
395 inline operator T*();
402 inline operator const T*()
const;
417 template <
typename U>
418 inline explicit operator U*();
428 template <
typename U>
429 inline explicit operator const U*()
const;
501 inline void CopyToHost(T *dest,
int size)
const;
515 static constexpr std::size_t def_align_bytes_()
518 return alignof(max_align_t);
520 static constexpr std::size_t def_align_bytes = def_align_bytes_();
521 static constexpr std::size_t new_align_bytes =
522 alignof(T) > def_align_bytes ?
alignof(T) : def_align_bytes;
524 template <std::
size_t align_bytes,
bool dummy = true>
struct Alloc
526 #if __cplusplus < 201703L
527 static inline T *
New(std::size_t)
530 MFEM_ASSERT(
false,
"overaligned type cannot use MemoryType::HOST");
534 static inline T *
New(std::size_t size) {
return new T[size]; }
538 #if __cplusplus < 201703L
539 template<
bool dummy>
struct Alloc<def_align_bytes,dummy>
541 static inline T *
New(std::size_t size) {
return new T[size]; }
546 static inline T *NewHOST(std::size_t size)
548 return Alloc<new_align_bytes>::New(size);
563 template <
typename T>
friend class Memory;
575 static bool Exists() {
return exists; }
586 static bool configured;
589 #ifdef MFEM_USE_UMPIRE
590 static const char * h_umpire_name;
591 static const char * d_umpire_name;
592 static const char * d_umpire_2_name;
600 static void *New_(
void *h_tmp,
size_t bytes,
MemoryType mt,
unsigned &
flags);
607 static void *Register_(
void *ptr,
void *
h_ptr,
size_t bytes,
MemoryType mt,
608 bool own,
bool alias,
unsigned &
flags);
611 static void Register2_(
void *
h_ptr,
void *d_ptr,
size_t bytes,
613 bool own,
bool alias,
unsigned &
flags);
616 static void Alias_(
void *base_h_ptr,
size_t offset,
size_t bytes,
617 unsigned base_flags,
unsigned &
flags);
619 static void SetDeviceMemoryType_(
void *
h_ptr,
unsigned flags,
627 static void DeleteDevice_(
void *
h_ptr,
unsigned &
flags);
636 size_t bytes,
unsigned &
flags);
639 size_t bytes,
unsigned &
flags);
642 size_t bytes,
unsigned &
flags);
644 static void SyncAlias_(
const void *base_h_ptr,
void *alias_h_ptr,
645 size_t alias_bytes,
unsigned base_flags,
646 unsigned &alias_flags);
660 static void Copy_(
void *dest_h_ptr,
const void *src_h_ptr,
size_t bytes,
661 unsigned src_flags,
unsigned &dest_flags);
665 static void CopyToHost_(
void *dest_h_ptr,
const void *src_h_ptr,
666 size_t bytes,
unsigned src_flags);
670 static void CopyFromHost_(
void *dest_h_ptr,
const void *src_h_ptr,
671 size_t bytes,
unsigned &dest_flags);
674 static bool IsKnown_(
const void *
h_ptr);
678 static bool IsAlias_(
const void *
h_ptr);
681 static int CompareHostAndDevice_(
void *
h_ptr,
size_t size,
unsigned flags);
690 void InsertDevice(
void *d_ptr,
void *
h_ptr,
size_t bytes,
694 void InsertAlias(
const void *base_ptr,
void *alias_ptr,
695 const size_t bytes,
const bool base_is_alias);
698 void Erase(
void *
h_ptr,
bool free_dev_ptr =
true);
701 void EraseDevice(
void *
h_ptr);
704 void EraseAlias(
void *alias_ptr);
708 void *GetDevicePtr(
const void *
h_ptr,
size_t bytes,
bool copy_data);
712 void *GetAliasDevicePtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
716 void *GetHostPtr(
const void *d_ptr,
size_t bytes,
bool copy_data);
720 void *GetAliasHostPtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
749 {
return dual_map[(int)mt]; }
768 #ifdef MFEM_USE_UMPIRE
794 void RegisterCheck(
void *
h_ptr);
811 template <
typename T>
820 template <
typename T>
829 template <
typename T>
836 (T*)MemoryManager::New_(
nullptr, size*
sizeof(T),
h_mt,
flags);
839 template <
typename T>
843 const size_t bytes = size*
sizeof(T);
848 h_ptr = (mt_host) ? h_tmp : (T*)MemoryManager::New_(h_tmp, bytes, mt,
flags);
851 template <
typename T>
855 const size_t bytes = size*
sizeof(T);
856 this->
h_mt = host_mt;
858 h_ptr = (T*)MemoryManager::New_(h_tmp, bytes, host_mt, device_mt,
862 template <
typename T>
870 if (own && MemoryManager::Exists())
873 MFEM_VERIFY(
h_mt == h_ptr_mt,
874 "h_mt = " << (
int)
h_mt <<
", h_ptr_mt = " << (
int)h_ptr_mt);
879 const size_t bytes = size*
sizeof(T);
880 MemoryManager::Register_(ptr, ptr, bytes,
h_mt, own,
false,
flags);
884 template <
typename T>
905 h_ptr = (T*)MemoryManager::Register_(ptr,
h_ptr, size*
sizeof(T), mt,
909 template <
typename T>
917 const size_t bytes = size*
sizeof(T);
919 MemoryManager::Register2_(
h_ptr, d_ptr, bytes,
h_mt, d_mt,
923 template <
typename T>
926 MFEM_ASSERT(0 <= offset,
"invalid offset = " << offset);
927 MFEM_ASSERT(0 <= size,
"invalid size = " << size);
928 MFEM_ASSERT(offset + size <= base.
capacity,
929 "invalid offset + size = " << offset + size
930 <<
" > base capacity = " << base.
capacity);
944 MemoryManager::Exists()
949 MemoryManager::Register_(base.
h_ptr,
nullptr, base.
capacity*
sizeof(T),
961 const size_t s_bytes = size*
sizeof(T);
962 const size_t o_bytes = offset*
sizeof(T);
963 MemoryManager::Alias_(base.
h_ptr, o_bytes, s_bytes, base.
flags,
flags);
966 template <
typename T>
975 MemoryManager::SetDeviceMemoryType_(
h_ptr,
flags, d_mt);
978 template <
typename T>
983 const bool std_delete = !registered && mt_host;
993 template <
typename T>
999 MemoryManager::DeleteDevice_((
void*)
h_ptr,
flags);
1003 template <
typename T>
1007 "invalid host pointer access");
1011 template <
typename T>
1018 template <
typename T>
1021 MFEM_ASSERT(
Empty() ||
1024 "invalid host pointer access");
1028 template <
typename T>
1035 template <
typename T>
template <
typename U>
1038 MFEM_ASSERT(
Empty() ||
1041 "invalid host pointer access");
1042 return reinterpret_cast<U*
>(
h_ptr);
1045 template <
typename T>
template <
typename U>
1049 return reinterpret_cast<U*
>(
h_ptr);
1052 template <
typename T>
1055 const size_t bytes = size *
sizeof(T);
1062 return (T*)MemoryManager::ReadWrite_(
h_ptr,
h_mt, mc, bytes,
flags);
1065 template <
typename T>
1068 const size_t bytes = size *
sizeof(T);
1075 return (
const T*)MemoryManager::Read_(
h_ptr,
h_mt, mc, bytes,
flags);
1078 template <
typename T>
1081 const size_t bytes = size *
sizeof(T);
1091 template <
typename T>
1105 template <
typename T>
1110 "invalid base state");
1111 if (!(base.
flags & REGISTERED)) {
return; }
1112 MemoryManager::SyncAlias_(base.
h_ptr,
h_ptr, alias_size*
sizeof(T),
1116 template <
typename T>
1123 template <
typename T>
1130 template <
typename T>
1136 template <
typename T>
1142 template <
typename T>
1152 std::memcpy(
h_ptr, src, size*
sizeof(T));
1162 template <
typename T>
1165 MFEM_VERIFY(
capacity>=size,
"Incorrect size");
1168 if (
h_ptr != src && size != 0)
1170 MFEM_ASSERT(
h_ptr + size <= src || src + size <=
h_ptr,
1172 std::memcpy(
h_ptr, src, size*
sizeof(T));
1178 MemoryManager::CopyFromHost_(
h_ptr, src, size*
sizeof(T),
flags);
1182 template <
typename T>
1185 MFEM_VERIFY(
capacity>=size,
"Incorrect size");
1189 template <
typename T>
1192 MFEM_VERIFY(
capacity>=size,
"Incorrect size");
1195 if (
h_ptr != dest && size != 0)
1197 MFEM_ASSERT(
h_ptr + size <= dest || dest + size <=
h_ptr,
1199 std::memcpy(dest,
h_ptr, size*
sizeof(T));
1204 MemoryManager::CopyToHost_(dest,
h_ptr, size*
sizeof(T),
flags);
1214 template <
typename T>
1220 template <
typename T>
1224 return MemoryManager::CompareHostAndDevice_(
h_ptr, size*
sizeof(T),
flags);
1233 #endif // MFEM_MEM_MANAGER_HPP
MemoryType h_mt
Host memory type.
bool HostIsValid() const
Return true if host pointer is valid.
Host memory; aligned at 64 bytes.
bool IsHostMemory(MemoryType mt)
Return true if the given memory type is in MemoryClass::HOST.
~Memory()=default
Destructor: default.
friend void MemoryPrintFlags(unsigned flags)
Print the state of a Memory object based on its internal flags. Useful in a debugger. See also Memory<T>::PrintFlags().
Device memory; using CUDA or HIP *Malloc and *Free.
void PrintFlags() const
Print the internal flags.
static const char * GetUmpireHostAllocatorName()
Get the host Umpire allocator name used with MemoryType::HOST_UMPIRE.
const char * MemoryTypeName[MemoryTypeSize]
Memory type names, used during Device:: configuration.
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.
static MemoryType GetHostMemoryType()
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...
void SetDevicePtrOwner(bool own) const
Set/clear the ownership flag for the device pointer. Ownership indicates whether the pointer will be ...
Host memory; allocated from a "host-debug" pool.
T * Write(MemoryClass mc, int size)
Get write-only access to the memory with the given MemoryClass.
Memory(int size)
Allocate host memory for size entries.
void UseDevice(bool use_dev) const
Set the internal device flag.
Host memory: pinned (page-locked)
void CopyFrom(const Memory &src, int size)
Copy size entries from src to *this.
Number of host and device memory types.
int Capacity() const
Return the size of the allocated memory.
int CompareHostAndDevice(int size) const
If both the host and the device data are valid, compare their contents.
Memory(int size, MemoryType mt)
Allocate memory for size entries with the given MemoryType mt.
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
unsigned flags
Bit flags defined from the FlagMask enum.
bool IsAlias(const void *h_ptr)
Return true if the pointer is known by the memory manager as an alias.
class if defined(__alignas_is_defined) alignas(double) RowNode
bool MemoryClassContainsType(MemoryClass mc, MemoryType mt)
Return true iff the MemoryType mt is contained in the MemoryClass mc.
Host memory; aligned at 32 bytes.
void Wrap(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with the current host memory type returned by MemoryMa...
static MemoryType GetDualMemoryType(MemoryType mt)
Return the dual MemoryType of the given one, mt.
void CopyFromHost(const T *src, int size)
Copy size entries from the host pointer src to *this.
void CopyTo(Memory &dest, int size) const
Copy size entries from *this to dest.
constexpr int DeviceMemoryType
static const char * GetUmpireDeviceAllocatorName()
Get the device Umpire allocator name used with MemoryType::DEVICE_UMPIRE.
constexpr int HostMemoryType
static MemoryType GetDeviceMemoryType()
bool DeviceIsValid() const
Return true if device pointer is valid.
Memory(const Memory &base, int offset, int size)
Alias constructor. Create a Memory object that points inside the Memory object base.
Ownership flag for internal Memory data.
The host pointer will be deleted by Delete()
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
constexpr int MemoryTypeSize
Static casts to 'int' and sizes of some useful memory types.
Memory & operator=(const Memory &orig)=default
Copy-assignment operator: default.
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
static const char * GetUmpireDevice2AllocatorName()
Get the device Umpire allocator name used with MemoryType::DEVICE_UMPIRE_2.
void ClearOwnerFlags() const
Clear the ownership flags for the host and device pointers, as well as any internal data allocated by...
MemoryType GetDeviceMemoryType() const
Return the device MemoryType of the Memory object. If the device MemoryType is not set...
MemoryType
Memory types supported by MFEM.
void SetHostPtrOwner(bool own) const
Set/clear the ownership flag for the host pointer. Ownership indicates whether the pointer will be de...
void Sync(const Memory &other) const
Copy the host/device pointer validity flags from other to *this.
void SetDeviceMemoryType(MemoryType d_mt)
Set the device MemoryType to be used by the Memory object.
bool IsKnown(const void *h_ptr)
Return true if the pointer is known by the memory manager.
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...
A class to initialize the size of a Tensor.
constexpr int HostMemoryTypeSize
void MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
bool IsDeviceMemory(MemoryType mt)
Return true if the given memory type is in MemoryClass::DEVICE.
static void SetUmpireDevice2AllocatorName(const char *d_name)
Set the device Umpire allocator name used with MemoryType::DEVICE_UMPIRE_2.
MemoryManager mm
The (single) global memory manager object.
T * h_ptr
Pointer to host memory. Not owned.
int capacity
Size of the allocated memory.
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...
Host memory; using new[] and delete[].
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
bool Empty() const
Return true if the Memory object is empty, see Reset().
T * ReadWrite(MemoryClass mc, int size)
Get read-write access to the memory with the given MemoryClass.
friend class MemoryManager
MemoryType GetMemoryType(MemoryClass mc)
Return a suitable MemoryType for a given MemoryClass.
void CopyToHost(T *dest, int size) const
Copy size entries from *this to the host pointer dest.
Class used by MFEM to store pointers to host and/or device memory.
static void SetUmpireHostAllocatorName(const char *h_name)
Set the host Umpire allocator name used with MemoryType::HOST_UMPIRE.
bool OwnsDevicePtr() const
Return true if the device pointer is owned. Ownership indicates whether the pointer will be deleted b...
bool UseDevice() const
Read the internal device flag.
constexpr int DeviceMemoryTypeSize
Memory(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with the current host memory type returned by MemoryMa...
T & operator[](int idx)
Array subscript operator for host memory.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
MemoryClass operator*(MemoryClass mc1, MemoryClass mc2)
Return a suitable MemoryClass from a pair of MemoryClasses.
const T * Read(MemoryClass mc, int size) const
Get read-only access to the memory with the given MemoryClass.
static void SetUmpireDeviceAllocatorName(const char *d_name)
Set the device Umpire allocator name used with MemoryType::DEVICE_UMPIRE.
MemoryType GetHostMemoryType() const
Return the host MemoryType of the Memory object.
MemoryClass
Memory classes identify sets of memory types.