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 100e6b6b59SJacob Faibussowitsch #include <limits> // std::numeric_limits 110e6b6b59SJacob Faibussowitsch 12d71ae5a4SJacob Faibussowitsch namespace Petsc 13d71ae5a4SJacob Faibussowitsch { 140e6b6b59SJacob Faibussowitsch 15d71ae5a4SJacob Faibussowitsch namespace device 16d71ae5a4SJacob Faibussowitsch { 170e6b6b59SJacob Faibussowitsch 18d71ae5a4SJacob Faibussowitsch namespace cupm 19d71ae5a4SJacob Faibussowitsch { 200e6b6b59SJacob Faibussowitsch 210e6b6b59SJacob Faibussowitsch // ========================================================================================== 220e6b6b59SJacob Faibussowitsch // CUPM Host Allocator 230e6b6b59SJacob Faibussowitsch // ========================================================================================== 240e6b6b59SJacob Faibussowitsch 250e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType = char> 260e6b6b59SJacob Faibussowitsch class HostAllocator; 270e6b6b59SJacob Faibussowitsch 280e6b6b59SJacob Faibussowitsch // Allocator class to allocate pinned host memory for use with device 290e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType> 300e6b6b59SJacob Faibussowitsch class HostAllocator : public memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>, impl::Interface<T> { 310e6b6b59SJacob Faibussowitsch public: 320e6b6b59SJacob Faibussowitsch PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(interface_type, T); 330e6b6b59SJacob Faibussowitsch using base_type = memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>; 34*ff8f30bbSJacob Faibussowitsch using real_value_type = typename base_type::real_value_type; 35*ff8f30bbSJacob Faibussowitsch using size_type = typename base_type::size_type; 36*ff8f30bbSJacob Faibussowitsch using value_type = typename base_type::value_type; 370e6b6b59SJacob Faibussowitsch 380e6b6b59SJacob Faibussowitsch template <typename U> 390e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode allocate(value_type **, size_type, const StreamBase<U> *) noexcept; 400e6b6b59SJacob Faibussowitsch template <typename U> 410e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode deallocate(value_type *, const StreamBase<U> *) noexcept; 420e6b6b59SJacob Faibussowitsch template <typename U> 430e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode uninitialized_copy(value_type *, const value_type *, size_type, const StreamBase<U> *) noexcept; 440e6b6b59SJacob Faibussowitsch }; 450e6b6b59SJacob Faibussowitsch 460e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 470e6b6b59SJacob Faibussowitsch template <typename U> 48d71ae5a4SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::allocate(value_type **ptr, size_type n, const StreamBase<U> *) noexcept 49d71ae5a4SJacob Faibussowitsch { 500e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 510e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMallocHost(ptr, n)); 520e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 530e6b6b59SJacob Faibussowitsch } 540e6b6b59SJacob Faibussowitsch 550e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 560e6b6b59SJacob Faibussowitsch template <typename U> 57d71ae5a4SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::deallocate(value_type *ptr, const StreamBase<U> *) noexcept 58d71ae5a4SJacob Faibussowitsch { 590e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 600e6b6b59SJacob Faibussowitsch PetscCallCUPM(cupmFreeHost(ptr)); 610e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 620e6b6b59SJacob Faibussowitsch } 630e6b6b59SJacob Faibussowitsch 640e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 650e6b6b59SJacob Faibussowitsch template <typename U> 66d71ae5a4SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::uninitialized_copy(value_type *dest, const value_type *src, size_type n, const StreamBase<U> *stream) noexcept 67d71ae5a4SJacob Faibussowitsch { 680e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 690e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemcpyAsync(dest, src, n, cupmMemcpyHostToHost, stream->get_stream(), true)); 700e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 710e6b6b59SJacob Faibussowitsch } 720e6b6b59SJacob Faibussowitsch 730e6b6b59SJacob Faibussowitsch // ========================================================================================== 740e6b6b59SJacob Faibussowitsch // CUPM Device Allocator 750e6b6b59SJacob Faibussowitsch // ========================================================================================== 760e6b6b59SJacob Faibussowitsch 770e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType = char> 780e6b6b59SJacob Faibussowitsch class DeviceAllocator; 790e6b6b59SJacob Faibussowitsch 800e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType> 810e6b6b59SJacob Faibussowitsch class DeviceAllocator : public memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>, impl::Interface<T> { 820e6b6b59SJacob Faibussowitsch public: 830e6b6b59SJacob Faibussowitsch PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(interface_type, T); 840e6b6b59SJacob Faibussowitsch using base_type = memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>; 85*ff8f30bbSJacob Faibussowitsch using real_value_type = typename base_type::real_value_type; 86*ff8f30bbSJacob Faibussowitsch using size_type = typename base_type::size_type; 87*ff8f30bbSJacob Faibussowitsch using value_type = typename base_type::value_type; 880e6b6b59SJacob Faibussowitsch 890e6b6b59SJacob Faibussowitsch template <typename U> 900e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode allocate(value_type **, size_type, const StreamBase<U> *) noexcept; 910e6b6b59SJacob Faibussowitsch template <typename U> 920e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode deallocate(value_type *, const StreamBase<U> *) noexcept; 930e6b6b59SJacob Faibussowitsch template <typename U> 940e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode zero(value_type *, size_type, const StreamBase<U> *) noexcept; 950e6b6b59SJacob Faibussowitsch template <typename U> 960e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode uninitialized_copy(value_type *, const value_type *, size_type, const StreamBase<U> *) noexcept; 970e6b6b59SJacob Faibussowitsch template <typename U> 980e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode set_canary(value_type *, size_type, const StreamBase<U> *) noexcept; 990e6b6b59SJacob Faibussowitsch }; 1000e6b6b59SJacob Faibussowitsch 1010e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1020e6b6b59SJacob Faibussowitsch template <typename U> 103d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::allocate(value_type **ptr, size_type n, const StreamBase<U> *stream) noexcept 104d71ae5a4SJacob Faibussowitsch { 1050e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1060e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMallocAsync(ptr, n, stream->get_stream())); 1070e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 1080e6b6b59SJacob Faibussowitsch } 1090e6b6b59SJacob Faibussowitsch 1100e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1110e6b6b59SJacob Faibussowitsch template <typename U> 112d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::deallocate(value_type *ptr, const StreamBase<U> *stream) noexcept 113d71ae5a4SJacob Faibussowitsch { 1140e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1150e6b6b59SJacob Faibussowitsch PetscCallCUPM(cupmFreeAsync(ptr, stream->get_stream())); 1160e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 1170e6b6b59SJacob Faibussowitsch } 1180e6b6b59SJacob Faibussowitsch 1190e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1200e6b6b59SJacob Faibussowitsch template <typename U> 121d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::zero(value_type *ptr, size_type n, const StreamBase<U> *stream) noexcept 122d71ae5a4SJacob Faibussowitsch { 1230e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1240e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemsetAsync(ptr, 0, n, stream->get_stream(), true)); 1250e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 1260e6b6b59SJacob Faibussowitsch } 1270e6b6b59SJacob Faibussowitsch 1280e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1290e6b6b59SJacob Faibussowitsch template <typename U> 130d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::uninitialized_copy(value_type *dest, const value_type *src, size_type n, const StreamBase<U> *stream) noexcept 131d71ae5a4SJacob Faibussowitsch { 1320e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1330e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemcpyAsync(dest, src, n, cupmMemcpyDeviceToDevice, stream->get_stream(), true)); 1340e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 1350e6b6b59SJacob Faibussowitsch } 1360e6b6b59SJacob Faibussowitsch 1370e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 1380e6b6b59SJacob Faibussowitsch template <typename U> 139d71ae5a4SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::set_canary(value_type *ptr, size_type n, const StreamBase<U> *stream) noexcept 140d71ae5a4SJacob Faibussowitsch { 1410e6b6b59SJacob Faibussowitsch using limit_t = std::numeric_limits<real_value_type>; 1420e6b6b59SJacob Faibussowitsch const value_type canary = limit_t::has_signaling_NaN ? limit_t::signaling_NaN() : limit_t::max(); 1430e6b6b59SJacob Faibussowitsch 1440e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 1450e6b6b59SJacob Faibussowitsch PetscCall(impl::ThrustSet<T>(stream->get_stream(), n, ptr, &canary)); 1460e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 1470e6b6b59SJacob Faibussowitsch } 1480e6b6b59SJacob Faibussowitsch 1490e6b6b59SJacob Faibussowitsch } // namespace cupm 1500e6b6b59SJacob Faibussowitsch 1510e6b6b59SJacob Faibussowitsch } // namespace device 1520e6b6b59SJacob Faibussowitsch 1530e6b6b59SJacob Faibussowitsch } // namespace Petsc 1540e6b6b59SJacob Faibussowitsch 1550e6b6b59SJacob Faibussowitsch #endif // __cplusplus 1560e6b6b59SJacob Faibussowitsch 1570e6b6b59SJacob Faibussowitsch #endif // CUPMALLOCATOR_HPP 158