1*0e6b6b59SJacob Faibussowitsch #ifndef CUPMALLOCATOR_HPP 2*0e6b6b59SJacob Faibussowitsch #define CUPMALLOCATOR_HPP 3*0e6b6b59SJacob Faibussowitsch 4*0e6b6b59SJacob Faibussowitsch #if defined(__cplusplus) 5*0e6b6b59SJacob Faibussowitsch #include <petsc/private/cpp/object_pool.hpp> 6*0e6b6b59SJacob Faibussowitsch 7*0e6b6b59SJacob Faibussowitsch #include "../segmentedmempool.hpp" 8*0e6b6b59SJacob Faibussowitsch #include "cupmthrustutility.hpp" 9*0e6b6b59SJacob Faibussowitsch 10*0e6b6b59SJacob Faibussowitsch #include <limits> // std::numeric_limits 11*0e6b6b59SJacob Faibussowitsch 12*0e6b6b59SJacob Faibussowitsch namespace Petsc { 13*0e6b6b59SJacob Faibussowitsch 14*0e6b6b59SJacob Faibussowitsch namespace device { 15*0e6b6b59SJacob Faibussowitsch 16*0e6b6b59SJacob Faibussowitsch namespace cupm { 17*0e6b6b59SJacob Faibussowitsch 18*0e6b6b59SJacob Faibussowitsch // ========================================================================================== 19*0e6b6b59SJacob Faibussowitsch // CUPM Host Allocator 20*0e6b6b59SJacob Faibussowitsch // ========================================================================================== 21*0e6b6b59SJacob Faibussowitsch 22*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType = char> 23*0e6b6b59SJacob Faibussowitsch class HostAllocator; 24*0e6b6b59SJacob Faibussowitsch 25*0e6b6b59SJacob Faibussowitsch // Allocator class to allocate pinned host memory for use with device 26*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType> 27*0e6b6b59SJacob Faibussowitsch class HostAllocator : public memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>, impl::Interface<T> { 28*0e6b6b59SJacob Faibussowitsch public: 29*0e6b6b59SJacob Faibussowitsch PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(interface_type, T); 30*0e6b6b59SJacob Faibussowitsch using base_type = memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>; 31*0e6b6b59SJacob Faibussowitsch using typename base_type::real_value_type; 32*0e6b6b59SJacob Faibussowitsch using typename base_type::size_type; 33*0e6b6b59SJacob Faibussowitsch using typename base_type::value_type; 34*0e6b6b59SJacob Faibussowitsch 35*0e6b6b59SJacob Faibussowitsch template <typename U> 36*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode allocate(value_type **, size_type, const StreamBase<U> *) noexcept; 37*0e6b6b59SJacob Faibussowitsch template <typename U> 38*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode deallocate(value_type *, const StreamBase<U> *) noexcept; 39*0e6b6b59SJacob Faibussowitsch template <typename U> 40*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode uninitialized_copy(value_type *, const value_type *, size_type, const StreamBase<U> *) noexcept; 41*0e6b6b59SJacob Faibussowitsch }; 42*0e6b6b59SJacob Faibussowitsch 43*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 44*0e6b6b59SJacob Faibussowitsch template <typename U> 45*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::allocate(value_type **ptr, size_type n, const StreamBase<U> *) noexcept { 46*0e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 47*0e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMallocHost(ptr, n)); 48*0e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 49*0e6b6b59SJacob Faibussowitsch } 50*0e6b6b59SJacob Faibussowitsch 51*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 52*0e6b6b59SJacob Faibussowitsch template <typename U> 53*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::deallocate(value_type *ptr, const StreamBase<U> *) noexcept { 54*0e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 55*0e6b6b59SJacob Faibussowitsch PetscCallCUPM(cupmFreeHost(ptr)); 56*0e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 57*0e6b6b59SJacob Faibussowitsch } 58*0e6b6b59SJacob Faibussowitsch 59*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 60*0e6b6b59SJacob Faibussowitsch template <typename U> 61*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode HostAllocator<T, P>::uninitialized_copy(value_type *dest, const value_type *src, size_type n, const StreamBase<U> *stream) noexcept { 62*0e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 63*0e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemcpyAsync(dest, src, n, cupmMemcpyHostToHost, stream->get_stream(), true)); 64*0e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 65*0e6b6b59SJacob Faibussowitsch } 66*0e6b6b59SJacob Faibussowitsch 67*0e6b6b59SJacob Faibussowitsch // ========================================================================================== 68*0e6b6b59SJacob Faibussowitsch // CUPM Device Allocator 69*0e6b6b59SJacob Faibussowitsch // ========================================================================================== 70*0e6b6b59SJacob Faibussowitsch 71*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType = char> 72*0e6b6b59SJacob Faibussowitsch class DeviceAllocator; 73*0e6b6b59SJacob Faibussowitsch 74*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename PetscType> 75*0e6b6b59SJacob Faibussowitsch class DeviceAllocator : public memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>, impl::Interface<T> { 76*0e6b6b59SJacob Faibussowitsch public: 77*0e6b6b59SJacob Faibussowitsch PETSC_CUPM_INHERIT_INTERFACE_TYPEDEFS_USING(interface_type, T); 78*0e6b6b59SJacob Faibussowitsch using base_type = memory::impl::SegmentedMemoryPoolAllocatorBase<PetscType>; 79*0e6b6b59SJacob Faibussowitsch using typename base_type::real_value_type; 80*0e6b6b59SJacob Faibussowitsch using typename base_type::size_type; 81*0e6b6b59SJacob Faibussowitsch using typename base_type::value_type; 82*0e6b6b59SJacob Faibussowitsch 83*0e6b6b59SJacob Faibussowitsch template <typename U> 84*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode allocate(value_type **, size_type, const StreamBase<U> *) noexcept; 85*0e6b6b59SJacob Faibussowitsch template <typename U> 86*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode deallocate(value_type *, const StreamBase<U> *) noexcept; 87*0e6b6b59SJacob Faibussowitsch template <typename U> 88*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode zero(value_type *, size_type, const StreamBase<U> *) noexcept; 89*0e6b6b59SJacob Faibussowitsch template <typename U> 90*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode uninitialized_copy(value_type *, const value_type *, size_type, const StreamBase<U> *) noexcept; 91*0e6b6b59SJacob Faibussowitsch template <typename U> 92*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD static PetscErrorCode set_canary(value_type *, size_type, const StreamBase<U> *) noexcept; 93*0e6b6b59SJacob Faibussowitsch }; 94*0e6b6b59SJacob Faibussowitsch 95*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 96*0e6b6b59SJacob Faibussowitsch template <typename U> 97*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::allocate(value_type **ptr, size_type n, const StreamBase<U> *stream) noexcept { 98*0e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 99*0e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMallocAsync(ptr, n, stream->get_stream())); 100*0e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 101*0e6b6b59SJacob Faibussowitsch } 102*0e6b6b59SJacob Faibussowitsch 103*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 104*0e6b6b59SJacob Faibussowitsch template <typename U> 105*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::deallocate(value_type *ptr, const StreamBase<U> *stream) noexcept { 106*0e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 107*0e6b6b59SJacob Faibussowitsch PetscCallCUPM(cupmFreeAsync(ptr, stream->get_stream())); 108*0e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 109*0e6b6b59SJacob Faibussowitsch } 110*0e6b6b59SJacob Faibussowitsch 111*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 112*0e6b6b59SJacob Faibussowitsch template <typename U> 113*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::zero(value_type *ptr, size_type n, const StreamBase<U> *stream) noexcept { 114*0e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 115*0e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemsetAsync(ptr, 0, n, stream->get_stream(), true)); 116*0e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 117*0e6b6b59SJacob Faibussowitsch } 118*0e6b6b59SJacob Faibussowitsch 119*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 120*0e6b6b59SJacob Faibussowitsch template <typename U> 121*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::uninitialized_copy(value_type *dest, const value_type *src, size_type n, const StreamBase<U> *stream) noexcept { 122*0e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 123*0e6b6b59SJacob Faibussowitsch PetscCall(PetscCUPMMemcpyAsync(dest, src, n, cupmMemcpyDeviceToDevice, stream->get_stream(), true)); 124*0e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 125*0e6b6b59SJacob Faibussowitsch } 126*0e6b6b59SJacob Faibussowitsch 127*0e6b6b59SJacob Faibussowitsch template <DeviceType T, typename P> 128*0e6b6b59SJacob Faibussowitsch template <typename U> 129*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode DeviceAllocator<T, P>::set_canary(value_type *ptr, size_type n, const StreamBase<U> *stream) noexcept { 130*0e6b6b59SJacob Faibussowitsch using limit_t = std::numeric_limits<real_value_type>; 131*0e6b6b59SJacob Faibussowitsch const value_type canary = limit_t::has_signaling_NaN ? limit_t::signaling_NaN() : limit_t::max(); 132*0e6b6b59SJacob Faibussowitsch 133*0e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 134*0e6b6b59SJacob Faibussowitsch PetscCall(impl::ThrustSet<T>(stream->get_stream(), n, ptr, &canary)); 135*0e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 136*0e6b6b59SJacob Faibussowitsch } 137*0e6b6b59SJacob Faibussowitsch 138*0e6b6b59SJacob Faibussowitsch } // namespace cupm 139*0e6b6b59SJacob Faibussowitsch 140*0e6b6b59SJacob Faibussowitsch } // namespace device 141*0e6b6b59SJacob Faibussowitsch 142*0e6b6b59SJacob Faibussowitsch } // namespace Petsc 143*0e6b6b59SJacob Faibussowitsch 144*0e6b6b59SJacob Faibussowitsch #endif // __cplusplus 145*0e6b6b59SJacob Faibussowitsch 146*0e6b6b59SJacob Faibussowitsch #endif // CUPMALLOCATOR_HPP 147