QMCPACK
OMPallocator< T, HostAllocator > Struct Template Reference

OMPallocator is an allocator with fused device and dualspace allocator functionality. More...

+ Inheritance diagram for OMPallocator< T, HostAllocator >:
+ Collaboration diagram for OMPallocator< T, HostAllocator >:

Classes

struct  rebind
 

Public Types

using value_type = typename HostAllocator::value_type
 
using size_type = typename HostAllocator::size_type
 
using pointer = typename HostAllocator::pointer
 
using const_pointer = typename HostAllocator::const_pointer
 

Public Member Functions

 OMPallocator ()=default
 
 OMPallocator (const OMPallocator &)
 Gives you a OMPallocator with no state. More...
 
template<class U , class V >
 OMPallocator (const OMPallocator< U, V > &)
 
value_typeallocate (std::size_t n)
 
void deallocate (value_type *pt, std::size_t n)
 
void attachReference (const OMPallocator &from, std::ptrdiff_t ptr_offset)
 
T * get_device_ptr ()
 
const T * get_device_ptr () const
 

Private Attributes

T * device_ptr_ = nullptr
 

Detailed Description

template<typename T, class HostAllocator = std::allocator<T>>
struct qmcplusplus::OMPallocator< T, HostAllocator >

OMPallocator is an allocator with fused device and dualspace allocator functionality.

it is mostly c++03 style but is stateful with respect to the bond between the returned pt on the host and the device_ptr_. While many containers may need a copy only one can own the memory it returns and it can only service one owner. i.e. only one object should call the allocate and deallocate methods.

Note: in the style of openmp portability this class always thinks its dual space even when its not, this happens through the magic of openmp ignoring target pragmas when target isn't enabled. i.e. -fopenmp-targets=... isn't passed at compile time. This makes the code "simpler" and more "portable" since its the same code you would write for openmp CPU implementation exploding head and that is the same implementation + pragmas as the serial implementation. This definitely isn't true for all QMCPACK code using offload but it is true for OMPAllocator so we do test it that way.

Definition at line 60 of file OMPallocator.hpp.


Class Documentation

◆ qmcplusplus::OMPallocator::rebind

struct qmcplusplus::OMPallocator::rebind

template<typename T, class HostAllocator = std::allocator<T>>
template<class U, class V>
struct qmcplusplus::OMPallocator< T, HostAllocator >::rebind< U, V >

Definition at line 79 of file OMPallocator.hpp.

+ Collaboration diagram for OMPallocator< T, HostAllocator >::rebind< U, V >:
Class Members
typedef OMPallocator< U, V > other

Member Typedef Documentation

◆ const_pointer

using const_pointer = typename HostAllocator::const_pointer

Definition at line 65 of file OMPallocator.hpp.

◆ pointer

using pointer = typename HostAllocator::pointer

Definition at line 64 of file OMPallocator.hpp.

◆ size_type

using size_type = typename HostAllocator::size_type

Definition at line 63 of file OMPallocator.hpp.

◆ value_type

using value_type = typename HostAllocator::value_type

Definition at line 62 of file OMPallocator.hpp.

Constructor & Destructor Documentation

◆ OMPallocator() [1/3]

OMPallocator ( )
default

◆ OMPallocator() [2/3]

OMPallocator ( const OMPallocator< T, HostAllocator > &  )
inline

Gives you a OMPallocator with no state.

But OMPallocoator is stateful so this copy constructor is a lie. However until allocators are correct > c++11 this is retained since our < c++11 compliant containers may expect it.

Definition at line 73 of file OMPallocator.hpp.

73 : device_ptr_(nullptr) {}

◆ OMPallocator() [3/3]

OMPallocator ( const OMPallocator< U, V > &  )
inline

Definition at line 75 of file OMPallocator.hpp.

75  : device_ptr_(nullptr)
76  {}

Member Function Documentation

◆ allocate()

value_type* allocate ( std::size_t  n)
inline

Definition at line 84 of file OMPallocator.hpp.

Referenced by qmcplusplus::TEST_CASE().

85  {
86  static_assert(std::is_same<T, value_type>::value, "OMPallocator and HostAllocator data types must agree!");
87  value_type* pt = HostAllocator::allocate(n);
88 #if defined(QMC_OFFLOAD_MEM_ASSOCIATED)
89  cudaErrorCheck(cudaMalloc(&device_ptr_, n * sizeof(T)), "cudaMalloc failed in OMPallocator!");
90  const int status = omp_target_associate_ptr(pt, device_ptr_, n * sizeof(T), 0, omp_get_default_device());
91  if (status != 0)
92  throw std::runtime_error("omp_target_associate_ptr failed in OMPallocator!");
93 #else
94  PRAGMA_OFFLOAD("omp target enter data map(alloc:pt[0:n])")
96 #endif
97  OMPallocator_device_mem_allocated += n * sizeof(T);
98  return pt;
99  }
T * getOffloadDevicePtr(T *host_ptr)
cudaErrorCheck(cudaMemcpyAsync(dev_lu.data(), lu.data(), sizeof(decltype(lu)::value_type) *lu.size(), cudaMemcpyHostToDevice, hstream), "cudaMemcpyAsync failed copying log_values to device")
#define cudaMalloc
Definition: cuda2hip.h:119
typename HostAllocator::value_type value_type
std::atomic< size_t > OMPallocator_device_mem_allocated

◆ attachReference()

void attachReference ( const OMPallocator< T, HostAllocator > &  from,
std::ptrdiff_t  ptr_offset 
)
inline

Definition at line 116 of file OMPallocator.hpp.

Referenced by qmc_allocator_traits< OMPallocator< T, HostAllocator > >::attachReference().

117  {
118  device_ptr_ = const_cast<typename OMPallocator::pointer>(from.get_device_ptr()) + ptr_offset;
119  }
typename HostAllocator::pointer pointer

◆ deallocate()

void deallocate ( value_type pt,
std::size_t  n 
)
inline

Definition at line 101 of file OMPallocator.hpp.

Referenced by qmcplusplus::TEST_CASE().

102  {
103  OMPallocator_device_mem_allocated -= n * sizeof(T);
104 #if defined(QMC_OFFLOAD_MEM_ASSOCIATED)
105  T* device_ptr_from_omp = getOffloadDevicePtr(pt);
106  const int status = omp_target_disassociate_ptr(pt, omp_get_default_device());
107  if (status != 0)
108  throw std::runtime_error("omp_target_disassociate_ptr failed in OMPallocator!");
109  cudaErrorCheck(cudaFree(device_ptr_from_omp), "cudaFree failed in OMPallocator!");
110 #else
111  PRAGMA_OFFLOAD("omp target exit data map(delete:pt[0:n])")
112 #endif
113  HostAllocator::deallocate(pt, n);
114  }
T * getOffloadDevicePtr(T *host_ptr)
cudaErrorCheck(cudaMemcpyAsync(dev_lu.data(), lu.data(), sizeof(decltype(lu)::value_type) *lu.size(), cudaMemcpyHostToDevice, hstream), "cudaMemcpyAsync failed copying log_values to device")
#define cudaFree
Definition: cuda2hip.h:99
std::atomic< size_t > OMPallocator_device_mem_allocated

◆ get_device_ptr() [1/2]

◆ get_device_ptr() [2/2]

const T* get_device_ptr ( ) const
inline

Definition at line 122 of file OMPallocator.hpp.

122 { return device_ptr_; }

Member Data Documentation

◆ device_ptr_

T* device_ptr_ = nullptr
private

The documentation for this struct was generated from the following file: