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>
214 explicit Memory(T *ptr,
int size,
bool own) {
Wrap(ptr, size, own); }
225 {
Wrap(ptr, size, mt, own); }
288 inline void New(
int size);
318 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;
502 inline void CopyToHost(T *dest,
int size)
const;
516 static constexpr std::size_t def_align_bytes_()
519 return alignof(max_align_t);
521 static constexpr std::size_t def_align_bytes = def_align_bytes_();
522 static constexpr std::size_t new_align_bytes =
523 alignof(T) > def_align_bytes ?
alignof(T) : def_align_bytes;
525 template <std::
size_t align_bytes,
bool dummy = true>
struct Alloc
527 #if __cplusplus < 201703L
528 static inline T *
New(std::size_t)
531 MFEM_ASSERT(
false,
"overaligned type cannot use MemoryType::HOST");
535 static inline T *
New(std::size_t size) {
return new T[size]; }
539 #if __cplusplus < 201703L
540 template<
bool dummy>
struct Alloc<def_align_bytes,dummy>
542 static inline T *
New(std::size_t size) {
return new T[size]; }
547 static inline T *NewHOST(std::size_t size)
549 return Alloc<new_align_bytes>::New(size);
564 template <
typename T>
friend class Memory;
576 static bool Exists() {
return exists; }
587 static bool configured;
590 #ifdef MFEM_USE_UMPIRE
591 static const char * h_umpire_name;
592 static const char * d_umpire_name;
593 static const char * d_umpire_2_name;
601 static void *New_(
void *h_tmp,
size_t bytes,
MemoryType mt,
unsigned &
flags);
608 static void *Register_(
void *ptr,
void *
h_ptr,
size_t bytes,
MemoryType mt,
609 bool own,
bool alias,
unsigned &
flags);
612 static void Register2_(
void *
h_ptr,
void *d_ptr,
size_t bytes,
614 bool own,
bool alias,
unsigned &
flags);
617 static void Alias_(
void *base_h_ptr,
size_t offset,
size_t bytes,
618 unsigned base_flags,
unsigned &
flags);
620 static void SetDeviceMemoryType_(
void *
h_ptr,
unsigned flags,
628 static void DeleteDevice_(
void *
h_ptr,
unsigned &
flags);
637 size_t bytes,
unsigned &
flags);
640 size_t bytes,
unsigned &
flags);
643 size_t bytes,
unsigned &
flags);
645 static void SyncAlias_(
const void *base_h_ptr,
void *alias_h_ptr,
646 size_t alias_bytes,
unsigned base_flags,
647 unsigned &alias_flags);
661 static void Copy_(
void *dest_h_ptr,
const void *src_h_ptr,
size_t bytes,
662 unsigned src_flags,
unsigned &dest_flags);
666 static void CopyToHost_(
void *dest_h_ptr,
const void *src_h_ptr,
667 size_t bytes,
unsigned src_flags);
671 static void CopyFromHost_(
void *dest_h_ptr,
const void *src_h_ptr,
672 size_t bytes,
unsigned &dest_flags);
675 static bool IsKnown_(
const void *
h_ptr);
679 static bool IsAlias_(
const void *
h_ptr);
682 static int CompareHostAndDevice_(
void *
h_ptr,
size_t size,
unsigned flags);
691 void InsertDevice(
void *d_ptr,
void *
h_ptr,
size_t bytes,
695 void InsertAlias(
const void *base_ptr,
void *alias_ptr,
696 const size_t bytes,
const bool base_is_alias);
699 void Erase(
void *
h_ptr,
bool free_dev_ptr =
true);
702 void EraseDevice(
void *
h_ptr);
705 void EraseAlias(
void *alias_ptr);
709 void *GetDevicePtr(
const void *
h_ptr,
size_t bytes,
bool copy_data);
713 void *GetAliasDevicePtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
717 void *GetHostPtr(
const void *d_ptr,
size_t bytes,
bool copy_data);
721 void *GetAliasHostPtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
750 {
return dual_map[(int)mt]; }
769 #ifdef MFEM_USE_UMPIRE
795 void RegisterCheck(
void *
h_ptr);
812 template <
typename T>
821 template <
typename T>
830 template <
typename T>
837 (T*)MemoryManager::New_(
nullptr, size*
sizeof(T),
h_mt,
flags);
840 template <
typename T>
844 const size_t bytes = size*
sizeof(T);
849 h_ptr = (mt_host) ? h_tmp : (T*)MemoryManager::New_(h_tmp, bytes, mt,
flags);
852 template <
typename T>
856 const size_t bytes = size*
sizeof(T);
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>
932 #ifndef HYPRE_USING_CUDA
939 MemoryManager::Exists()
944 MemoryManager::Register_(base.
h_ptr,
nullptr, base.
capacity*
sizeof(T),
956 const size_t s_bytes = size*
sizeof(T);
957 const size_t o_bytes = offset*
sizeof(T);
958 MemoryManager::Alias_(base.
h_ptr, o_bytes, s_bytes, base.
flags,
flags);
961 template <
typename T>
970 MemoryManager::SetDeviceMemoryType_(
h_ptr,
flags, d_mt);
973 template <
typename T>
978 const bool std_delete = !registered && mt_host;
987 template <
typename T>
993 MemoryManager::DeleteDevice_((
void*)
h_ptr,
flags);
997 template <
typename T>
1001 "invalid host pointer access");
1005 template <
typename T>
1012 template <
typename T>
1015 MFEM_ASSERT(
Empty() ||
1018 "invalid host pointer access");
1022 template <
typename T>
1029 template <
typename T>
template <
typename U>
1032 MFEM_ASSERT(
Empty() ||
1035 "invalid host pointer access");
1036 return reinterpret_cast<U*
>(
h_ptr);
1039 template <
typename T>
template <
typename U>
1043 return reinterpret_cast<U*
>(
h_ptr);
1046 template <
typename T>
1049 const size_t bytes = size *
sizeof(T);
1056 return (T*)MemoryManager::ReadWrite_(
h_ptr,
h_mt, mc, bytes,
flags);
1059 template <
typename T>
1062 const size_t bytes = size *
sizeof(T);
1069 return (
const T*)MemoryManager::Read_(
h_ptr,
h_mt, mc, bytes,
flags);
1072 template <
typename T>
1075 const size_t bytes = size *
sizeof(T);
1085 template <
typename T>
1099 template <
typename T>
1104 "invalid base state");
1105 if (!(base.
flags & REGISTERED)) {
return; }
1106 MemoryManager::SyncAlias_(base.
h_ptr,
h_ptr, alias_size*
sizeof(T),
1110 template <
typename T>
1117 template <
typename T>
1124 template <
typename T>
1130 template <
typename T>
1136 template <
typename T>
1145 std::memcpy(
h_ptr, src, size*
sizeof(T));
1155 template <
typename T>
1160 if (
h_ptr != src && size != 0)
1162 MFEM_ASSERT(
h_ptr + size <= src || src + size <=
h_ptr,
1164 std::memcpy(
h_ptr, src, size*
sizeof(T));
1170 MemoryManager::CopyFromHost_(
h_ptr, src, size*
sizeof(T),
flags);
1174 template <
typename T>
1179 if (
h_ptr != dest && size != 0)
1181 MFEM_ASSERT(
h_ptr + size <= dest || dest + size <=
h_ptr,
1183 std::memcpy(dest,
h_ptr, size*
sizeof(T));
1188 MemoryManager::CopyToHost_(dest,
h_ptr, size*
sizeof(T),
flags);
1198 template <
typename T>
1204 template <
typename T>
1208 return MemoryManager::CompareHostAndDevice_(
h_ptr, size*
sizeof(T),
flags);
1217 #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. The Memory is not reset by this method, i.e. it will, generally, not be Empty() after this call.
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.
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.
Memory()
Default constructor: no initialization.
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.