1a4963045SJacob Faibussowitsch #pragma once 20e6b6b59SJacob Faibussowitsch 30e6b6b59SJacob Faibussowitsch #include <petsc/private/cpp/object_pool.hpp> 40e6b6b59SJacob Faibussowitsch 50e6b6b59SJacob Faibussowitsch #include "../segmentedmempool.hpp" 60e6b6b59SJacob Faibussowitsch #include "cupmthrustutility.hpp" 70e6b6b59SJacob Faibussowitsch 8f3146f24SJacob Faibussowitsch #include <thrust/device_ptr.h> 9f3146f24SJacob Faibussowitsch #include <thrust/fill.h> 10f3146f24SJacob Faibussowitsch 110e6b6b59SJacob Faibussowitsch #include <limits> // std::numeric_limits 120e6b6b59SJacob Faibussowitsch 13d71ae5a4SJacob Faibussowitsch namespace Petsc 14d71ae5a4SJacob Faibussowitsch { 150e6b6b59SJacob Faibussowitsch 16d71ae5a4SJacob Faibussowitsch namespace device 17d71ae5a4SJacob Faibussowitsch { 180e6b6b59SJacob Faibussowitsch 19d71ae5a4SJacob Faibussowitsch namespace cupm 20d71ae5a4SJacob Faibussowitsch { 210e6b6b59SJacob Faibussowitsch 220e6b6b59SJacob Faibussowitsch // ========================================================================================== 230e6b6b59SJacob Faibussowitsch // CUPM Host Allocator 240e6b6b59SJacob Faibussowitsch // ========================================================================================== 250e6b6b59SJacob Faibussowitsch 260e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType = char> 270e6b6b59SJacob Faibussowitsch class HostAllocator; 280e6b6b59SJacob Faibussowitsch 290e6b6b59SJacob Faibussowitsch // Allocator class to allocate pinned host memory for use with device 300e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType> 31*85f25e71SJed Brown class PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL HostAllocator : public memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>, impl::Interface<T> { 320e6b6b59SJacob Faibussowitsch public: 3396a4b4d9SJacob Faibussowitsch PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(T); 340e6b6b59SJacob Faibussowitsch using base_type = memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>; 35ff8f30bbSJacob Faibussowitsch using real_value_type = typename base_type::real_value_type; 36ff8f30bbSJacob Faibussowitsch using size_type = typename base_type::size_type; 37ff8f30bbSJacob Faibussowitsch using value_type = typename base_type::value_type; 380e6b6b59SJacob Faibussowitsch 390e6b6b59SJacob Faibussowitsch template <typename U> 40089fb57cSJacob Faibussowitsch static PetscErrorCode allocate(value_type **, size_type, const StreamBase<U> *) noexcept; 410e6b6b59SJacob Faibussowitsch template <typename U> 42089fb57cSJacob Faibussowitsch static PetscErrorCode deallocate(value_type *, const StreamBase<U> *) noexcept; 430e6b6b59SJacob Faibussowitsch template <typename U> 44089fb57cSJacob Faibussowitsch static PetscErrorCode uninitialized_copy(value_type *, const value_type *, size_type, const StreamBase<U> *) noexcept; 450e6b6b59SJacob Faibussowitsch }; 460e6b6b59SJacob Faibussowitsch 470e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 480e6b6b59SJacob Faibussowitsch template <typename U> 49d71ae5a4SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::allocate(value_type **ptr, size_type n, const StreamBase<U> *) noexcept 50d71ae5a4SJacob Faibussowitsch { 510e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 520e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMallocHost(ptr, n)); 533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 540e6b6b59SJacob Faibussowitsch } 550e6b6b59SJacob Faibussowitsch 560e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 570e6b6b59SJacob Faibussowitsch template <typename U> 58d71ae5a4SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::deallocate(value_type *ptr, const StreamBase<U> *) noexcept 59d71ae5a4SJacob Faibussowitsch { 600e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 610e6b6b59SJacob Faibussowitsch PetscCallCUPM(cupmFreeHost(ptr)); 623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 630e6b6b59SJacob Faibussowitsch } 640e6b6b59SJacob Faibussowitsch 650e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 660e6b6b59SJacob Faibussowitsch template <typename U> 67d71ae5a4SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::uninitialized_copy(value_type *dest, const value_type *src, size_type n, const StreamBase<U> *stream) noexcept 68d71ae5a4SJacob Faibussowitsch { 690e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 700e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemcpyAsync(dest, src, n, cupmMemcpyHostToHost, stream->get_stream(), true)); 713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 720e6b6b59SJacob Faibussowitsch } 730e6b6b59SJacob Faibussowitsch 740e6b6b59SJacob Faibussowitsch // ========================================================================================== 750e6b6b59SJacob Faibussowitsch // CUPM Device Allocator 760e6b6b59SJacob Faibussowitsch // ========================================================================================== 770e6b6b59SJacob Faibussowitsch 780e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType = char> 790e6b6b59SJacob Faibussowitsch class DeviceAllocator; 800e6b6b59SJacob Faibussowitsch 810e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType> 82*85f25e71SJed Brown class PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL DeviceAllocator : public memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>, impl::Interface<T> { 830e6b6b59SJacob Faibussowitsch public: 8496a4b4d9SJacob Faibussowitsch PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(T); 850e6b6b59SJacob Faibussowitsch using base_type = memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>; 86ff8f30bbSJacob Faibussowitsch using real_value_type = typename base_type::real_value_type; 87ff8f30bbSJacob Faibussowitsch using size_type = typename base_type::size_type; 88ff8f30bbSJacob Faibussowitsch using value_type = typename base_type::value_type; 890e6b6b59SJacob Faibussowitsch 900e6b6b59SJacob Faibussowitsch template <typename U> 91089fb57cSJacob Faibussowitsch static PetscErrorCode allocate(value_type **, size_type, const StreamBase<U> *) noexcept; 920e6b6b59SJacob Faibussowitsch template <typename U> 93089fb57cSJacob Faibussowitsch static PetscErrorCode deallocate(value_type *, const StreamBase<U> *) noexcept; 940e6b6b59SJacob Faibussowitsch template <typename U> 95089fb57cSJacob Faibussowitsch static PetscErrorCode zero(value_type *, size_type, const StreamBase<U> *) noexcept; 960e6b6b59SJacob Faibussowitsch template <typename U> 97089fb57cSJacob Faibussowitsch static PetscErrorCode uninitialized_copy(value_type *, const value_type *, size_type, const StreamBase<U> *) noexcept; 980e6b6b59SJacob Faibussowitsch template <typename U> 99089fb57cSJacob Faibussowitsch static PetscErrorCode set_canary(value_type *, size_type, const StreamBase<U> *) noexcept; 1000e6b6b59SJacob Faibussowitsch }; 1010e6b6b59SJacob Faibussowitsch 1020e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1030e6b6b59SJacob Faibussowitsch template <typename U> 104d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::allocate(value_type **ptr, size_type n, const StreamBase<U> *stream) noexcept 105d71ae5a4SJacob Faibussowitsch { 1060e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1070e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMallocAsync(ptr, n, stream->get_stream())); 1083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1090e6b6b59SJacob Faibussowitsch } 1100e6b6b59SJacob Faibussowitsch 1110e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1120e6b6b59SJacob Faibussowitsch template <typename U> 113d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::deallocate(value_type *ptr, const StreamBase<U> *stream) noexcept 114d71ae5a4SJacob Faibussowitsch { 1150e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1160e6b6b59SJacob Faibussowitsch PetscCallCUPM(cupmFreeAsync(ptr, stream->get_stream())); 1173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1180e6b6b59SJacob Faibussowitsch } 1190e6b6b59SJacob Faibussowitsch 1200e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1210e6b6b59SJacob Faibussowitsch template <typename U> 122d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::zero(value_type *ptr, size_type n, const StreamBase<U> *stream) noexcept 123d71ae5a4SJacob Faibussowitsch { 1240e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1250e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemsetAsync(ptr, 0, n, stream->get_stream(), true)); 1263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1270e6b6b59SJacob Faibussowitsch } 1280e6b6b59SJacob Faibussowitsch 1290e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1300e6b6b59SJacob Faibussowitsch template <typename U> 131d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::uninitialized_copy(value_type *dest, const value_type *src, size_type n, const StreamBase<U> *stream) noexcept 132d71ae5a4SJacob Faibussowitsch { 1330e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1340e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemcpyAsync(dest, src, n, cupmMemcpyDeviceToDevice, stream->get_stream(), true)); 1353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1360e6b6b59SJacob Faibussowitsch } 1370e6b6b59SJacob Faibussowitsch 1380e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1390e6b6b59SJacob Faibussowitsch template <typename U> 140d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::set_canary(value_type *ptr, size_type n, const StreamBase<U> *stream) noexcept 141d71ae5a4SJacob Faibussowitsch { 1420e6b6b59SJacob Faibussowitsch using limit_t = std::numeric_limits<real_value_type>; 1430e6b6b59SJacob Faibussowitsch const value_type canary = limit_t::has_signaling_NaN ? limit_t::signaling_NaN() : limit_t::max(); 144f3146f24SJacob Faibussowitsch const auto xptr = thrust::device_pointer_cast(ptr); 1450e6b6b59SJacob Faibussowitsch 1460e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 147f3146f24SJacob Faibussowitsch PetscCallThrust(THRUST_CALL(thrust::fill, stream->get_stream(), xptr, xptr + n, canary)); 1483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1490e6b6b59SJacob Faibussowitsch } 1500e6b6b59SJacob Faibussowitsch 1510e6b6b59SJacob Faibussowitsch } // namespace cupm 1520e6b6b59SJacob Faibussowitsch 1530e6b6b59SJacob Faibussowitsch } // namespace device 1540e6b6b59SJacob Faibussowitsch 1550e6b6b59SJacob Faibussowitsch } // namespace Petsc 156