xref: /petsc/src/sys/objects/device/impls/cupm/cupmallocator.hpp (revision ff8f30bb06d5b42f7b1ac49b776a11794d476fa2)
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