12 #ifndef MFEM_MEM_MANAGER_HPP
13 #define MFEM_MEM_MANAGER_HPP
18 #include <type_traits>
21 #include <HYPRE_config.h>
159 template <
typename T>
240 explicit Memory(T *ptr,
int size,
bool own) {
Wrap(ptr, size, own); }
251 {
Wrap(ptr, size, mt, own); }
314 inline void New(
int size);
344 inline void Wrap(T *ptr,
int size,
bool own);
420 inline operator T*();
427 inline operator const T*()
const;
442 template <
typename U>
443 inline explicit operator U*();
453 template <
typename U>
454 inline explicit operator const U*()
const;
526 inline void CopyToHost(T *dest,
int size)
const;
540 static constexpr std::size_t def_align_bytes_()
543 return alignof(max_align_t);
545 static constexpr std::size_t def_align_bytes = def_align_bytes_();
546 static constexpr std::size_t new_align_bytes =
547 alignof(T) > def_align_bytes ?
alignof(T) : def_align_bytes;
549 template <std::
size_t align_bytes,
bool dummy = true>
struct Alloc
551 #if __cplusplus < 201703L
552 static inline T *
New(std::size_t)
555 MFEM_ASSERT(
false,
"overaligned type cannot use MemoryType::HOST");
559 static inline T *
New(std::size_t size) {
return new T[size]; }
563 #if __cplusplus < 201703L
564 template<
bool dummy>
struct Alloc<def_align_bytes,dummy>
566 static inline T *
New(std::size_t size) {
return new T[size]; }
571 static inline T *NewHOST(std::size_t size)
573 return Alloc<new_align_bytes>::New(size);
588 template <
typename T>
friend class Memory;
600 static bool Exists() {
return exists; }
611 static bool configured;
614 #ifdef MFEM_USE_UMPIRE
615 static const char * h_umpire_name;
616 static const char * d_umpire_name;
617 static const char * d_umpire_2_name;
625 static void *New_(
void *h_tmp,
size_t bytes,
MemoryType mt,
unsigned &
flags);
632 static void *Register_(
void *ptr,
void *
h_ptr,
size_t bytes,
MemoryType mt,
633 bool own,
bool alias,
unsigned &
flags);
636 static void Register2_(
void *
h_ptr,
void *d_ptr,
size_t bytes,
638 bool own,
bool alias,
unsigned &
flags);
641 static void Alias_(
void *base_h_ptr,
size_t offset,
size_t bytes,
642 unsigned base_flags,
unsigned &
flags);
644 static void SetDeviceMemoryType_(
void *
h_ptr,
unsigned flags,
652 static void DeleteDevice_(
void *
h_ptr,
unsigned &
flags);
661 size_t bytes,
unsigned &
flags);
664 size_t bytes,
unsigned &
flags);
667 size_t bytes,
unsigned &
flags);
669 static void SyncAlias_(
const void *base_h_ptr,
void *alias_h_ptr,
670 size_t alias_bytes,
unsigned base_flags,
671 unsigned &alias_flags);
685 static void Copy_(
void *dest_h_ptr,
const void *src_h_ptr,
size_t bytes,
686 unsigned src_flags,
unsigned &dest_flags);
690 static void CopyToHost_(
void *dest_h_ptr,
const void *src_h_ptr,
691 size_t bytes,
unsigned src_flags);
695 static void CopyFromHost_(
void *dest_h_ptr,
const void *src_h_ptr,
696 size_t bytes,
unsigned &dest_flags);
699 static bool IsKnown_(
const void *
h_ptr);
703 static bool IsAlias_(
const void *
h_ptr);
706 static int CompareHostAndDevice_(
void *
h_ptr,
size_t size,
unsigned flags);
715 void InsertDevice(
void *d_ptr,
void *
h_ptr,
size_t bytes,
719 void InsertAlias(
const void *base_ptr,
void *alias_ptr,
720 const size_t bytes,
const bool base_is_alias);
723 void Erase(
void *
h_ptr,
bool free_dev_ptr =
true);
726 void EraseDevice(
void *
h_ptr);
729 void EraseAlias(
void *alias_ptr);
733 void *GetDevicePtr(
const void *
h_ptr,
size_t bytes,
bool copy_data);
737 void *GetAliasDevicePtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
741 void *GetHostPtr(
const void *d_ptr,
size_t bytes,
bool copy_data);
745 void *GetAliasHostPtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
774 {
return dual_map[(int)mt]; }
793 #ifdef MFEM_USE_UMPIRE
819 void RegisterCheck(
void *
h_ptr);
836 template <
typename T>
845 template <
typename T>
854 template <
typename T>
861 (T*)MemoryManager::New_(
nullptr, size*
sizeof(T),
h_mt,
flags);
864 template <
typename T>
868 const size_t bytes = size*
sizeof(T);
873 h_ptr = (mt_host) ? h_tmp : (T*)MemoryManager::New_(h_tmp, bytes, mt,
flags);
876 template <
typename T>
880 const size_t bytes = size*
sizeof(T);
881 this->
h_mt = host_mt;
883 h_ptr = (T*)MemoryManager::New_(h_tmp, bytes, host_mt, device_mt,
887 template <
typename T>
895 if (own && MemoryManager::Exists())
898 MFEM_VERIFY(
h_mt == h_ptr_mt,
899 "h_mt = " << (
int)
h_mt <<
", h_ptr_mt = " << (
int)h_ptr_mt);
904 const size_t bytes = size*
sizeof(T);
905 MemoryManager::Register_(ptr, ptr, bytes,
h_mt, own,
false,
flags);
909 template <
typename T>
930 h_ptr = (T*)MemoryManager::Register_(ptr,
h_ptr, size*
sizeof(T), mt,
934 template <
typename T>
942 const size_t bytes = size*
sizeof(T);
944 MemoryManager::Register2_(
h_ptr, d_ptr, bytes,
h_mt, d_mt,
948 template <
typename T>
951 MFEM_ASSERT(0 <= offset,
"invalid offset = " << offset);
952 MFEM_ASSERT(0 <= size,
"invalid size = " << size);
953 MFEM_ASSERT(offset + size <= base.
capacity,
954 "invalid offset + size = " << offset + size
955 <<
" > base capacity = " << base.
capacity);
969 MemoryManager::Exists()
974 MemoryManager::Register_(base.
h_ptr,
nullptr, base.
capacity*
sizeof(T),
986 const size_t s_bytes = size*
sizeof(T);
987 const size_t o_bytes = offset*
sizeof(T);
988 MemoryManager::Alias_(base.
h_ptr, o_bytes, s_bytes, base.
flags,
flags);
991 template <
typename T>
1000 MemoryManager::SetDeviceMemoryType_(
h_ptr,
flags, d_mt);
1003 template <
typename T>
1008 const bool std_delete = !registered && mt_host;
1018 template <
typename T>
1024 MemoryManager::DeleteDevice_((
void*)
h_ptr,
flags);
1028 template <
typename T>
1032 "invalid host pointer access");
1036 template <
typename T>
1043 template <
typename T>
1046 MFEM_ASSERT(
Empty() ||
1049 "invalid host pointer access");
1053 template <
typename T>
1060 template <
typename T>
template <
typename U>
1063 MFEM_ASSERT(
Empty() ||
1066 "invalid host pointer access");
1067 return reinterpret_cast<U*
>(
h_ptr);
1070 template <
typename T>
template <
typename U>
1074 return reinterpret_cast<U*
>(
h_ptr);
1077 template <
typename T>
1080 const size_t bytes = size *
sizeof(T);
1087 return (T*)MemoryManager::ReadWrite_(
h_ptr,
h_mt, mc, bytes,
flags);
1090 template <
typename T>
1093 const size_t bytes = size *
sizeof(T);
1100 return (
const T*)MemoryManager::Read_(
h_ptr,
h_mt, mc, bytes,
flags);
1103 template <
typename T>
1106 const size_t bytes = size *
sizeof(T);
1116 template <
typename T>
1130 template <
typename T>
1135 "invalid base state");
1136 if (!(base.
flags & REGISTERED)) {
return; }
1137 MemoryManager::SyncAlias_(base.
h_ptr,
h_ptr, alias_size*
sizeof(T),
1141 template <
typename T>
1148 template <
typename T>
1155 template <
typename T>
1161 template <
typename T>
1167 template <
typename T>
1177 std::memcpy(
h_ptr, src, size*
sizeof(T));
1187 template <
typename T>
1190 MFEM_VERIFY(
capacity>=size,
"Incorrect size");
1193 if (
h_ptr != src && size != 0)
1195 MFEM_ASSERT(
h_ptr + size <= src || src + size <=
h_ptr,
1197 std::memcpy(
h_ptr, src, size*
sizeof(T));
1203 MemoryManager::CopyFromHost_(
h_ptr, src, size*
sizeof(T),
flags);
1207 template <
typename T>
1210 MFEM_VERIFY(
capacity>=size,
"Incorrect size");
1214 template <
typename T>
1217 MFEM_VERIFY(
capacity>=size,
"Incorrect size");
1220 if (
h_ptr != dest && size != 0)
1222 MFEM_ASSERT(
h_ptr + size <= dest || dest + size <=
h_ptr,
1224 std::memcpy(dest,
h_ptr, size*
sizeof(T));
1229 MemoryManager::CopyToHost_(dest,
h_ptr, size*
sizeof(T),
flags);
1239 template <
typename T>
1245 template <
typename T>
1249 return MemoryManager::CompareHostAndDevice_(
h_ptr, size*
sizeof(T),
flags);
1258 #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.
Memory & operator=(Memory &&orig)
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.