12 #ifndef MFEM_MEM_MANAGER_HPP
13 #define MFEM_MEM_MANAGER_HPP
18 #include <type_traits>
101 template <
typename T>
160 explicit Memory(T *ptr,
int size,
bool own) {
Wrap(ptr, size, own); }
171 {
Wrap(ptr, size, mt, own); }
246 inline void Wrap(T *ptr,
int size,
bool own)
285 inline operator T*();
292 inline operator const T*()
const;
307 template <
typename U>
308 inline explicit operator U*();
318 template <
typename U>
319 inline explicit operator const U*()
const;
379 inline void CopyToHost(T *dest,
int size)
const;
387 template <
typename T>
friend class Memory;
399 static void *New_(
void *h_ptr, std::size_t size,
MemoryType mt,
404 static void *Register_(
void *ptr,
void *h_ptr, std::size_t capacity,
405 MemoryType mt,
bool own,
bool alias,
unsigned &flags);
409 static void Alias_(
void *base_h_ptr, std::size_t offset, std::size_t size,
410 unsigned base_flags,
unsigned &flags);
414 static MemoryType Delete_(
void *h_ptr,
unsigned flags);
418 static void *ReadWrite_(
void *h_ptr,
MemoryClass mc, std::size_t size,
421 static const void *Read_(
void *h_ptr,
MemoryClass mc, std::size_t size,
424 static void *Write_(
void *h_ptr,
MemoryClass mc, std::size_t size,
427 static void SyncAlias_(
const void *base_h_ptr,
void *alias_h_ptr,
428 size_t alias_size,
unsigned base_flags,
429 unsigned &alias_flags);
433 static MemoryType GetMemoryType_(
void *h_ptr,
unsigned flags);
437 static void Copy_(
void *dest_h_ptr,
const void *src_h_ptr, std::size_t size,
438 unsigned src_flags,
unsigned &dest_flags);
442 static void CopyToHost_(
void *dest_h_ptr,
const void *src_h_ptr,
443 std::size_t size,
unsigned src_flags);
447 static void CopyFromHost_(
void *dest_h_ptr,
const void *src_h_ptr,
448 std::size_t size,
unsigned &dest_flags);
451 void *Insert(
void *ptr,
const std::size_t bytes);
453 void InsertDevice(
void *ptr,
void *h_ptr,
size_t bytes);
456 void *Erase(
void *ptr,
bool free_dev_ptr =
true);
460 void *GetDevicePtr(
const void *ptr,
size_t bytes,
bool copy_data);
462 void InsertAlias(
const void *base_ptr,
void *alias_ptr,
bool base_is_alias);
464 void EraseAlias(
void *alias_ptr);
466 void *GetAliasDevicePtr(
const void *alias_ptr,
size_t bytes,
bool copy_data);
469 bool IsKnown(
const void *ptr);
490 template <
typename T>
502 h_ptr = (T*)MemoryManager::New_(tmp, size*
sizeof(T), mt, flags);
507 template <
typename T>
512 Wrap(ptr, size, own);
519 h_ptr = (T*)MemoryManager::Register_(ptr, tmp, size*
sizeof(T), mt, own,
525 template <
typename T>
528 h_ptr = base.
h_ptr + offset;
530 if (!(base.
flags & REGISTERED))
532 flags = (base.
flags | ALIAS) & ~(OWNS_HOST | OWNS_DEVICE);
536 MemoryManager::Alias_(base.
h_ptr, offset*
sizeof(T), size*
sizeof(T),
541 template <
typename T>
544 if (!(flags & REGISTERED) ||
547 if (flags & OWNS_HOST) {
delete [] h_ptr; }
551 template <
typename T>
554 MFEM_ASSERT((flags & VALID_HOST) && !(flags & VALID_DEVICE),
555 "invalid host pointer access");
559 template <
typename T>
562 MFEM_ASSERT((flags & VALID_HOST),
"invalid host pointer access");
566 template <
typename T>
569 MFEM_ASSERT(Empty() ||
570 ((flags & VALID_HOST) &&
571 (std::is_const<T>::value || !(flags & VALID_DEVICE))),
572 "invalid host pointer access");
576 template <
typename T>
579 MFEM_ASSERT(Empty() || (flags & VALID_HOST),
"invalid host pointer access");
583 template <
typename T>
template <
typename U>
586 MFEM_ASSERT(Empty() ||
587 ((flags & VALID_HOST) &&
588 (std::is_const<U>::value || !(flags & VALID_DEVICE))),
589 "invalid host pointer access");
590 return reinterpret_cast<U*
>(h_ptr);
593 template <
typename T>
template <
typename U>
596 MFEM_ASSERT(Empty() || (flags & VALID_HOST),
"invalid host pointer access");
597 return reinterpret_cast<U*
>(h_ptr);
600 template <
typename T>
603 if (!(flags & REGISTERED))
606 MemoryManager::Register_(h_ptr, NULL, capacity*
sizeof(T),
608 flags & ALIAS, flags);
610 return (T*)MemoryManager::ReadWrite_(h_ptr, mc, size*
sizeof(T), flags);
613 template <
typename T>
616 if (!(flags & REGISTERED))
619 MemoryManager::Register_((
void*)h_ptr, NULL, capacity*
sizeof(T),
621 flags & ALIAS, flags);
623 return (
const T *)MemoryManager::Read_(
624 (
void*)h_ptr, mc, size*
sizeof(T), flags);
627 template <
typename T>
630 if (!(flags & REGISTERED))
633 MemoryManager::Register_(h_ptr, NULL, capacity*
sizeof(T),
635 flags & ALIAS, flags);
637 return (T*)MemoryManager::Write_(h_ptr, mc, size*
sizeof(T), flags);
640 template <
typename T>
643 if (!(flags & REGISTERED) && (other.
flags & REGISTERED))
645 MFEM_ASSERT(h_ptr == other.
h_ptr &&
646 (flags & ALIAS) == (other.
flags & ALIAS),
648 flags = (flags | REGISTERED) & ~(OWNS_DEVICE | OWNS_INTERNAL);
650 flags = (flags & ~(VALID_HOST | VALID_DEVICE)) |
651 (other.
flags & (VALID_HOST | VALID_DEVICE));
654 template <
typename T>
658 MFEM_ASSERT(!(flags & REGISTERED) || (base.
flags & REGISTERED),
659 "invalid base state");
660 if (!(base.
flags & REGISTERED)) {
return; }
661 MemoryManager::SyncAlias_(base.
h_ptr, h_ptr, alias_size*
sizeof(T),
665 template <
typename T>
669 return MemoryManager::GetMemoryType_(h_ptr, flags);
672 template <
typename T>
675 if (!(flags & REGISTERED) && !(src.
flags & REGISTERED))
677 if (h_ptr != src.
h_ptr && size != 0)
679 MFEM_ASSERT(h_ptr + size <= src || src + size <= h_ptr,
681 std::memcpy(h_ptr, src, size*
sizeof(T));
687 MemoryManager::Copy_(h_ptr, src.
h_ptr, size*
sizeof(T), src.
flags, flags);
691 template <
typename T>
694 if (!(flags & REGISTERED))
696 if (h_ptr != src && size != 0)
698 MFEM_ASSERT(h_ptr + size <= src || src + size <= h_ptr,
700 std::memcpy(h_ptr, src, size*
sizeof(T));
706 MemoryManager::CopyFromHost_(h_ptr, src, size*
sizeof(T), flags);
710 template <
typename T>
713 if (!(flags & REGISTERED))
715 if (h_ptr != dest && size != 0)
717 MFEM_ASSERT(h_ptr + size <= dest || dest + size <= h_ptr,
719 std::memcpy(dest, h_ptr, size*
sizeof(T));
724 MemoryManager::CopyToHost_(dest, h_ptr, size*
sizeof(T), flags);
739 #endif // MFEM_MEM_MANAGER_HPP
Host memory aligned at 64 bytes (not supported yet)
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.
The device pointer will be deleted by Delete()
void Delete()
Delete the owned pointers. The Memory is not reset by this method.
Memory(T *ptr, int size, MemoryType mt, bool own)
Wrap an externally allocated pointer, ptr, of the given MemoryType.
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 ...
Memory types: { CUDA, CUDA_UVM }.
T * Write(MemoryClass mc, int size)
Get write-only access to the memory with the given MemoryClass.
Internal device flag, see e.g. Vector::UseDevice()
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.
int Capacity() const
Return the size of the allocated memory.
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...
Host memory aligned at 32 bytes (not supported yet)
void Wrap(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with type MemoryType::HOST.
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.
The memory manager class.
Memory(const Memory &base, int offset, int size)
Alias constructor. Create a Memory object that points inside the Memory object base.
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
h_ptr is registered with the MemoryManager
The host pointer will be deleted by Delete()
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.
Ownership flag for internal Memory data.
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 RegisterCheck(void *ptr)
Check if pointer has been registered in the memory manager.
void Sync(const Memory &other) const
Copy the host/device pointer validity flags from other to *this.
void MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
MemoryManager mm
The (single) global memory manager object.
T * h_ptr
Pointer to host memory. Not owned.
Host memory; using new[] and delete[].
void PrintPtrs(void)
Prints all pointers known by the memory manager.
void New(int size)
Allocate host memory for size entries with type MemoryType::HOST.
bool Empty() const
Return true if the Memory object is empty, see Reset().
cudaMallocManaged, cudaFree (not supported yet)
T * ReadWrite(MemoryClass mc, int size)
Get read-write access to the memory with the given MemoryClass.
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.
Memory(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with type MemoryType::HOST.
T & operator[](int idx)
Array subscript operator for host memory.
static bool Exists()
Return true if a global memory manager instance exists.
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 subsets of memory types.
void MemoryPrintFlags(unsigned flags)
Print the state of a Memory object based on its internal flags. Useful in a debugger.