12 #ifndef MFEM_MEM_MANAGER_HPP
13 #define MFEM_MEM_MANAGER_HPP
18 #include <type_traits>
121 template <
typename T>
184 explicit Memory(T *ptr,
int size,
bool own) {
Wrap(ptr, size, own); }
195 {
Wrap(ptr, size, mt, own); }
258 inline void New(
int size);
273 inline void Wrap(T *ptr,
int size,
bool own);
334 inline operator T*();
341 inline operator const T*()
const;
356 template <
typename U>
357 inline explicit operator U*();
367 template <
typename U>
368 inline explicit operator const U*()
const;
428 inline void CopyToHost(T *dest,
int size)
const;
442 static constexpr std::size_t def_align_bytes_()
445 return alignof(max_align_t);
447 static constexpr std::size_t def_align_bytes = def_align_bytes_();
448 static constexpr std::size_t new_align_bytes =
449 alignof(T) > def_align_bytes ?
alignof(T) : def_align_bytes;
451 template <std::
size_t align_bytes,
bool dummy = true>
struct Alloc
453 #if __cplusplus < 201703L
454 static inline T *
New(std::size_t)
457 MFEM_ASSERT(
false,
"overaligned type cannot use MemoryType::HOST");
461 static inline T *
New(std::size_t size) {
return new T[size]; }
465 #if __cplusplus < 201703L
466 template<
bool dummy>
struct Alloc<def_align_bytes,dummy>
468 static inline T *
New(std::size_t size) {
return new T[size]; }
484 template <
typename T>
friend class Memory;
496 static bool Exists() {
return exists; }
499 #ifdef MFEM_USE_UMPIRE
500 static const char *h_umpire_name;
501 static const char *d_umpire_name;
509 static void *New_(
void *h_tmp,
size_t bytes,
MemoryType mt,
unsigned &
flags);
513 static void *Register_(
void *ptr,
void *
h_ptr,
size_t bytes,
MemoryType mt,
514 bool own,
bool alias,
unsigned &
flags);
517 static void Alias_(
void *base_h_ptr,
size_t offset,
size_t bytes,
518 unsigned base_flags,
unsigned &
flags);
534 size_t bytes,
unsigned &
flags);
537 size_t bytes,
unsigned &
flags);
540 size_t bytes,
unsigned &
flags);
542 static void SyncAlias_(
const void *base_h_ptr,
void *alias_h_ptr,
543 size_t alias_bytes,
unsigned base_flags,
544 unsigned &alias_flags);
558 static void Copy_(
void *dest_h_ptr,
const void *src_h_ptr,
size_t bytes,
559 unsigned src_flags,
unsigned &dest_flags);
563 static void CopyToHost_(
void *dest_h_ptr,
const void *src_h_ptr,
564 size_t bytes,
unsigned src_flags);
568 static void CopyFromHost_(
void *dest_h_ptr,
const void *src_h_ptr,
569 size_t bytes,
unsigned &dest_flags);
572 static bool IsKnown_(
const void *
h_ptr);
576 static bool IsAlias_(
const void *
h_ptr);
579 static int CompareHostAndDevice_(
void *
h_ptr,
size_t size,
unsigned flags);
588 void InsertDevice(
void *d_ptr,
void *
h_ptr,
size_t bytes,
592 void InsertAlias(
const void *base_ptr,
void *alias_ptr,
593 const size_t bytes,
const bool base_is_alias);
596 void Erase(
void *
h_ptr,
bool free_dev_ptr =
true);
599 void EraseAlias(
void *alias_ptr);
603 void *GetDevicePtr(
const void *
h_ptr,
size_t bytes,
bool copy_data);
607 void *GetAliasDevicePtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
611 void *GetHostPtr(
const void *d_ptr,
size_t bytes,
bool copy_data);
615 void *GetAliasHostPtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
628 #ifdef MFEM_USE_UMPIRE
630 void SetUmpireAllocatorNames(
const char *h_name,
const char *d_name);
645 void RegisterCheck(
void *
h_ptr);
662 template <
typename T>
666 h_mt = MemoryManager::host_mem_type;
671 template <
typename T>
680 template <
typename T>
685 h_mt = MemoryManager::host_mem_type;
687 (T*)MemoryManager::New_(
nullptr, size*
sizeof(T),
h_mt,
flags);
690 template <
typename T>
694 const size_t bytes = size*
sizeof(T);
699 Alloc<new_align_bytes>::New(size) :
nullptr;
700 h_ptr = (mt_host) ? h_tmp : (T*)MemoryManager::New_(h_tmp, bytes, mt,
flags);
703 template <
typename T>
708 const size_t bytes = size*
sizeof(T);
710 h_mt = MemoryManager::host_mem_type;
712 if (own && MemoryManager::Exists())
713 { MFEM_VERIFY(
h_mt == MemoryManager::GetHostMemoryType_(
h_ptr),
""); }
716 { MemoryManager::Register_(ptr, ptr, bytes,
h_mt, own,
false, flags); }
719 template <
typename T>
736 h_mt = MemoryManager::GetDualMemoryType_(mt);
740 h_ptr = (T*)MemoryManager::Register_(ptr,
h_ptr, size*
sizeof(T), mt,
744 template <
typename T>
752 const size_t bytes = size*
sizeof(T);
754 MemoryManager::Register_(d_ptr,
h_ptr, bytes, d_mt, own,
false,
flags);
757 template <
typename T>
767 const size_t s_bytes = size*
sizeof(T);
768 const size_t o_bytes = offset*
sizeof(T);
769 MemoryManager::Alias_(base.
h_ptr, o_bytes, s_bytes, base.
flags,
flags);
773 template <
typename T>
778 const bool std_delete = !registered && mt_host;
787 template <
typename T>
791 "invalid host pointer access");
795 template <
typename T>
802 template <
typename T>
805 MFEM_ASSERT(
Empty() ||
808 "invalid host pointer access");
812 template <
typename T>
819 template <
typename T>
template <
typename U>
822 MFEM_ASSERT(
Empty() ||
825 "invalid host pointer access");
826 return reinterpret_cast<U*
>(
h_ptr);
829 template <
typename T>
template <
typename U>
833 return reinterpret_cast<U*
>(
h_ptr);
836 template <
typename T>
839 const size_t bytes = size *
sizeof(T);
846 return (T*)MemoryManager::ReadWrite_(
h_ptr,
h_mt, mc, bytes,
flags);
849 template <
typename T>
852 const size_t bytes = size *
sizeof(T);
859 return (
const T*)MemoryManager::Read_(
h_ptr,
h_mt, mc, bytes,
flags);
862 template <
typename T>
865 const size_t bytes = size *
sizeof(T);
875 template <
typename T>
889 template <
typename T>
894 "invalid base state");
895 if (!(base.
flags & REGISTERED)) {
return; }
896 MemoryManager::SyncAlias_(base.
h_ptr,
h_ptr, alias_size*
sizeof(T),
900 template <
typename T>
904 return MemoryManager::GetDeviceMemoryType_(
h_ptr);
907 template <
typename T>
914 MFEM_ASSERT(
h_ptr + size <= src || src + size <=
h_ptr,
916 std::memcpy(
h_ptr, src, size*
sizeof(T));
926 template <
typename T>
931 if (
h_ptr != src && size != 0)
933 MFEM_ASSERT(
h_ptr + size <= src || src + size <=
h_ptr,
935 std::memcpy(
h_ptr, src, size*
sizeof(T));
941 MemoryManager::CopyFromHost_(
h_ptr, src, size*
sizeof(T),
flags);
945 template <
typename T>
950 if (
h_ptr != dest && size != 0)
952 MFEM_ASSERT(
h_ptr + size <= dest || dest + size <=
h_ptr,
954 std::memcpy(dest,
h_ptr, size*
sizeof(T));
959 MemoryManager::CopyToHost_(dest,
h_ptr, size*
sizeof(T),
flags);
969 template <
typename T>
975 template <
typename T>
979 return MemoryManager::CompareHostAndDevice_(
h_ptr, size*
sizeof(T),
flags);
988 #endif // MFEM_MEM_MANAGER_HPP
MemoryType h_mt
Host memory type.
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.
const char * GetUmpireAllocatorHostName()
void PrintFlags() const
Print the internal flags.
Device memory; using 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.
const char * GetUmpireAllocatorDeviceName()
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.
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.
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...
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
constexpr int HostMemoryType
static MemoryType GetDeviceMemoryType()
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.
void ClearOwnerFlags() const
Clear the ownership flags for the host and device pointers, as well as any internal data allocated by...
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.
bool IsKnown(const void *h_ptr)
Return true if the pointer is known by the memory manager.
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)
MemoryManager mm
The (single) global memory manager object.
T * h_ptr
Pointer to host memory. Not owned.
int capacity
Size of the allocated memory.
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.
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...
Host memory; using Umpire.
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.
MemoryClass
Memory classes identify sets of memory types.