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