10e6b6b59SJacob Faibussowitsch #ifndef CUPMALLOCATOR_HPP 20e6b6b59SJacob Faibussowitsch #define CUPMALLOCATOR_HPP 30e6b6b59SJacob Faibussowitsch 40e6b6b59SJacob Faibussowitsch #if defined(__cplusplus) 50e6b6b59SJacob Faibussowitsch #include <petsc/private/cpp/object_pool.hpp> 60e6b6b59SJacob Faibussowitsch 70e6b6b59SJacob Faibussowitsch #include "../segmentedmempool.hpp" 80e6b6b59SJacob Faibussowitsch #include "cupmthrustutility.hpp" 90e6b6b59SJacob Faibussowitsch 10f3146f24SJacob Faibussowitsch #include <thrust/device_ptr.h> 11f3146f24SJacob Faibussowitsch #include <thrust/fill.h> 12f3146f24SJacob Faibussowitsch 130e6b6b59SJacob Faibussowitsch #include <limits> // std::numeric_limits 140e6b6b59SJacob Faibussowitsch 15d71ae5a4SJacob Faibussowitsch namespace Petsc 16d71ae5a4SJacob Faibussowitsch { 170e6b6b59SJacob Faibussowitsch 18d71ae5a4SJacob Faibussowitsch namespace device 19d71ae5a4SJacob Faibussowitsch { 200e6b6b59SJacob Faibussowitsch 21d71ae5a4SJacob Faibussowitsch namespace cupm 22d71ae5a4SJacob Faibussowitsch { 230e6b6b59SJacob Faibussowitsch 240e6b6b59SJacob Faibussowitsch // ========================================================================================== 250e6b6b59SJacob Faibussowitsch // CUPM Host Allocator 260e6b6b59SJacob Faibussowitsch // ========================================================================================== 270e6b6b59SJacob Faibussowitsch 280e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType = char> 290e6b6b59SJacob Faibussowitsch class HostAllocator; 300e6b6b59SJacob Faibussowitsch 310e6b6b59SJacob Faibussowitsch // Allocator class to allocate pinned host memory for use with device 320e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType> 330e6b6b59SJacob Faibussowitsch class HostAllocator : public memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>, impl::Interface<T> { 340e6b6b59SJacob Faibussowitsch public: 35*96a4b4d9SJacob Faibussowitsch PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(T); 360e6b6b59SJacob Faibussowitsch using base_type = memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>; 37ff8f30bbSJacob Faibussowitsch using real_value_type = typename base_type::real_value_type; 38ff8f30bbSJacob Faibussowitsch using size_type = typename base_type::size_type; 39ff8f30bbSJacob Faibussowitsch using value_type = typename base_type::value_type; 400e6b6b59SJacob Faibussowitsch 410e6b6b59SJacob Faibussowitsch template <typename U> 42089fb57cSJacob Faibussowitsch static PetscErrorCode allocate(value_type **, size_type, const StreamBase<U> *) noexcept; 430e6b6b59SJacob Faibussowitsch template <typename U> 44089fb57cSJacob Faibussowitsch static PetscErrorCode deallocate(value_type *, const StreamBase<U> *) noexcept; 450e6b6b59SJacob Faibussowitsch template <typename U> 46089fb57cSJacob Faibussowitsch static PetscErrorCode uninitialized_copy(value_type *, const value_type *, size_type, const StreamBase<U> *) noexcept; 470e6b6b59SJacob Faibussowitsch }; 480e6b6b59SJacob Faibussowitsch 490e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 500e6b6b59SJacob Faibussowitsch template <typename U> 51d71ae5a4SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::allocate(value_type **ptr, size_type n, const StreamBase<U> *) noexcept 52d71ae5a4SJacob Faibussowitsch { 530e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 540e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMallocHost(ptr, n)); 553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 560e6b6b59SJacob Faibussowitsch } 570e6b6b59SJacob Faibussowitsch 580e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 590e6b6b59SJacob Faibussowitsch template <typename U> 60d71ae5a4SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::deallocate(value_type *ptr, const StreamBase<U> *) noexcept 61d71ae5a4SJacob Faibussowitsch { 620e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 630e6b6b59SJacob Faibussowitsch PetscCallCUPM(cupmFreeHost(ptr)); 643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 650e6b6b59SJacob Faibussowitsch } 660e6b6b59SJacob Faibussowitsch 670e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 680e6b6b59SJacob Faibussowitsch template <typename U> 69d71ae5a4SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::uninitialized_copy(value_type *dest, const value_type *src, size_type n, const StreamBase<U> *stream) noexcept 70d71ae5a4SJacob Faibussowitsch { 710e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 720e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemcpyAsync(dest, src, n, cupmMemcpyHostToHost, stream->get_stream(), true)); 733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 740e6b6b59SJacob Faibussowitsch } 750e6b6b59SJacob Faibussowitsch 760e6b6b59SJacob Faibussowitsch // ========================================================================================== 770e6b6b59SJacob Faibussowitsch // CUPM Device Allocator 780e6b6b59SJacob Faibussowitsch // ========================================================================================== 790e6b6b59SJacob Faibussowitsch 800e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType = char> 810e6b6b59SJacob Faibussowitsch class DeviceAllocator; 820e6b6b59SJacob Faibussowitsch 830e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType> 840e6b6b59SJacob Faibussowitsch class DeviceAllocator : public memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>, impl::Interface<T> { 850e6b6b59SJacob Faibussowitsch public: 86*96a4b4d9SJacob Faibussowitsch PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(T); 870e6b6b59SJacob Faibussowitsch using base_type = memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>; 88ff8f30bbSJacob Faibussowitsch using real_value_type = typename base_type::real_value_type; 89ff8f30bbSJacob Faibussowitsch using size_type = typename base_type::size_type; 90ff8f30bbSJacob Faibussowitsch using value_type = typename base_type::value_type; 910e6b6b59SJacob Faibussowitsch 920e6b6b59SJacob Faibussowitsch template <typename U> 93089fb57cSJacob Faibussowitsch static PetscErrorCode allocate(value_type **, size_type, const StreamBase<U> *) noexcept; 940e6b6b59SJacob Faibussowitsch template <typename U> 95089fb57cSJacob Faibussowitsch static PetscErrorCode deallocate(value_type *, const StreamBase<U> *) noexcept; 960e6b6b59SJacob Faibussowitsch template <typename U> 97089fb57cSJacob Faibussowitsch static PetscErrorCode zero(value_type *, size_type, const StreamBase<U> *) noexcept; 980e6b6b59SJacob Faibussowitsch template <typename U> 99089fb57cSJacob Faibussowitsch static PetscErrorCode uninitialized_copy(value_type *, const value_type *, size_type, const StreamBase<U> *) noexcept; 1000e6b6b59SJacob Faibussowitsch template <typename U> 101089fb57cSJacob Faibussowitsch static PetscErrorCode set_canary(value_type *, size_type, const StreamBase<U> *) noexcept; 1020e6b6b59SJacob Faibussowitsch }; 1030e6b6b59SJacob Faibussowitsch 1040e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1050e6b6b59SJacob Faibussowitsch template <typename U> 106d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::allocate(value_type **ptr, size_type n, const StreamBase<U> *stream) noexcept 107d71ae5a4SJacob Faibussowitsch { 1080e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1090e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMallocAsync(ptr, n, stream->get_stream())); 1103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1110e6b6b59SJacob Faibussowitsch } 1120e6b6b59SJacob Faibussowitsch 1130e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1140e6b6b59SJacob Faibussowitsch template <typename U> 115d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::deallocate(value_type *ptr, const StreamBase<U> *stream) noexcept 116d71ae5a4SJacob Faibussowitsch { 1170e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1180e6b6b59SJacob Faibussowitsch PetscCallCUPM(cupmFreeAsync(ptr, stream->get_stream())); 1193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1200e6b6b59SJacob Faibussowitsch } 1210e6b6b59SJacob Faibussowitsch 1220e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1230e6b6b59SJacob Faibussowitsch template <typename U> 124d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::zero(value_type *ptr, size_type n, const StreamBase<U> *stream) noexcept 125d71ae5a4SJacob Faibussowitsch { 1260e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1270e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemsetAsync(ptr, 0, n, stream->get_stream(), true)); 1283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1290e6b6b59SJacob Faibussowitsch } 1300e6b6b59SJacob Faibussowitsch 1310e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1320e6b6b59SJacob Faibussowitsch template <typename U> 133d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::uninitialized_copy(value_type *dest, const value_type *src, size_type n, const StreamBase<U> *stream) noexcept 134d71ae5a4SJacob Faibussowitsch { 1350e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1360e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemcpyAsync(dest, src, n, cupmMemcpyDeviceToDevice, stream->get_stream(), true)); 1373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1380e6b6b59SJacob Faibussowitsch } 1390e6b6b59SJacob Faibussowitsch 1400e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1410e6b6b59SJacob Faibussowitsch template <typename U> 142d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::set_canary(value_type *ptr, size_type n, const StreamBase<U> *stream) noexcept 143d71ae5a4SJacob Faibussowitsch { 1440e6b6b59SJacob Faibussowitsch using limit_t = std::numeric_limits<real_value_type>; 1450e6b6b59SJacob Faibussowitsch const value_type canary = limit_t::has_signaling_NaN ? limit_t::signaling_NaN() : limit_t::max(); 146f3146f24SJacob Faibussowitsch const auto xptr = thrust::device_pointer_cast(ptr); 1470e6b6b59SJacob Faibussowitsch 1480e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 149f3146f24SJacob Faibussowitsch PetscCallThrust(THRUST_CALL(thrust::fill, stream->get_stream(), xptr, xptr + n, canary)); 1503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1510e6b6b59SJacob Faibussowitsch } 1520e6b6b59SJacob Faibussowitsch 1530e6b6b59SJacob Faibussowitsch } // namespace cupm 1540e6b6b59SJacob Faibussowitsch 1550e6b6b59SJacob Faibussowitsch } // namespace device 1560e6b6b59SJacob Faibussowitsch 1570e6b6b59SJacob Faibussowitsch } // namespace Petsc 1580e6b6b59SJacob Faibussowitsch 1590e6b6b59SJacob Faibussowitsch #endif // __cplusplus 1600e6b6b59SJacob Faibussowitsch 1610e6b6b59SJacob Faibussowitsch #endif // CUPMALLOCATOR_HPP 162