alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
BufGenericSycl.hpp
Go to the documentation of this file.
1/* Copyright 2024 Jan Stephan, Luca Ferragina, Aurora Perego, Andrea Bocci
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
11#include "alpaka/dim/Traits.hpp"
15#include "alpaka/vec/Vec.hpp"
16
17#include <memory>
18#include <type_traits>
19
20#ifdef ALPAKA_ACC_SYCL_ENABLED
21
22# include <sycl/sycl.hpp>
23
24namespace alpaka
25{
26 //! The SYCL memory buffer.
27 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
28 class BufGenericSycl : public internal::ViewAccessOps<BufGenericSycl<TElem, TDim, TIdx, TTag>>
29 {
30 public:
31 static_assert(
32 !std::is_const_v<TElem>,
33 "The elem type of the buffer can not be const because the C++ Standard forbids containers of const "
34 "elements!");
35 static_assert(!std::is_const_v<TIdx>, "The idx type of the buffer can not be const!");
36
37 //! Constructor
38 template<typename TExtent, typename Deleter>
39 BufGenericSycl(DevGenericSycl<TTag> const& dev, TElem* const pMem, Deleter deleter, TExtent const& extent)
40 : m_dev{dev}
41 , m_extentElements{getExtentVecEnd<TDim>(extent)}
42 , m_spMem(pMem, std::move(deleter))
43 {
45
46 static_assert(
47 TDim::value == Dim<TExtent>::value,
48 "The dimensionality of TExtent and the dimensionality of the TDim template parameter have to be "
49 "identical!");
50
51 static_assert(
52 std::is_same_v<TIdx, Idx<TExtent>>,
53 "The idx type of TExtent and the TIdx template parameter have to be identical!");
54 }
55
56 DevGenericSycl<TTag> m_dev;
57 Vec<TDim, TIdx> m_extentElements;
58 std::shared_ptr<TElem> m_spMem;
59 };
60} // namespace alpaka
61
62namespace alpaka::trait
63{
64 //! The BufGenericSycl device type trait specialization.
65 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
66 struct DevType<BufGenericSycl<TElem, TDim, TIdx, TTag>>
67 {
68 using type = DevGenericSycl<TTag>;
69 };
70
71 //! The BufGenericSycl device get trait specialization.
72 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
73 struct GetDev<BufGenericSycl<TElem, TDim, TIdx, TTag>>
74 {
75 static auto getDev(BufGenericSycl<TElem, TDim, TIdx, TTag> const& buf)
76 {
77 return buf.m_dev;
78 }
79 };
80
81 //! The BufGenericSycl dimension getter trait specialization.
82 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
83 struct DimType<BufGenericSycl<TElem, TDim, TIdx, TTag>>
84 {
85 using type = TDim;
86 };
87
88 //! The BufGenericSycl memory element type get trait specialization.
89 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
90 struct ElemType<BufGenericSycl<TElem, TDim, TIdx, TTag>>
91 {
92 using type = TElem;
93 };
94
95 //! The BufGenericSycl extent get trait specialization.
96 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
97 struct GetExtents<BufGenericSycl<TElem, TDim, TIdx, TTag>>
98 {
99 auto operator()(BufGenericSycl<TElem, TDim, TIdx, TTag> const& buf) const
100 {
101 return buf.m_extentElements;
102 }
103 };
104
105 //! The BufGenericSycl native pointer get trait specialization.
106 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
107 struct GetPtrNative<BufGenericSycl<TElem, TDim, TIdx, TTag>>
108 {
109 static auto getPtrNative(BufGenericSycl<TElem, TDim, TIdx, TTag> const& buf) -> TElem const*
110 {
111 return buf.m_spMem.get();
112 }
113
114 static auto getPtrNative(BufGenericSycl<TElem, TDim, TIdx, TTag>& buf) -> TElem*
115 {
116 return buf.m_spMem.get();
117 }
118 };
119
120 //! The BufGenericSycl pointer on device get trait specialization.
121 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
122 struct GetPtrDev<BufGenericSycl<TElem, TDim, TIdx, TTag>, DevGenericSycl<TTag>>
123 {
124 static auto getPtrDev(BufGenericSycl<TElem, TDim, TIdx, TTag> const& buf, DevGenericSycl<TTag> const& dev)
125 -> TElem const*
126 {
127 if(dev == getDev(buf))
128 {
129 return buf.m_spMem.get();
130 }
131 else
132 {
133 throw std::runtime_error("The buffer is not accessible from the given device!");
134 }
135 }
136
137 static auto getPtrDev(BufGenericSycl<TElem, TDim, TIdx, TTag>& buf, DevGenericSycl<TTag> const& dev) -> TElem*
138 {
139 if(dev == getDev(buf))
140 {
141 return buf.m_spMem.get();
142 }
143 else
144 {
145 throw std::runtime_error("The buffer is not accessible from the given device!");
146 }
147 }
148 };
149
150 //! The SYCL memory allocation trait specialization.
151 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
152 struct BufAlloc<TElem, TDim, TIdx, DevGenericSycl<TTag>>
153 {
154 template<typename TExtent>
155 static auto allocBuf(DevGenericSycl<TTag> const& dev, TExtent const& extent)
156 -> BufGenericSycl<TElem, TDim, TIdx, TTag>
157 {
159
160# if ALPAKA_DEBUG >= ALPAKA_DEBUG_FULL
161 if constexpr(TDim::value == 0)
162 std::cout << __func__ << " ewb: " << sizeof(TElem) << '\n';
163 else if constexpr(TDim::value == 1)
164 {
165 auto const width = getWidth(extent);
166
167 auto const widthBytes = width * static_cast<TIdx>(sizeof(TElem));
168 std::cout << __func__ << " ew: " << width << " ewb: " << widthBytes << '\n';
169 }
170 else if constexpr(TDim::value == 2)
171 {
172 auto const width = getWidth(extent);
173 auto const height = getHeight(extent);
174
175 auto const widthBytes = width * static_cast<TIdx>(sizeof(TElem));
176 std::cout << __func__ << " ew: " << width << " eh: " << height << " ewb: " << widthBytes
177 << " pitch: " << widthBytes << '\n';
178 }
179 else if constexpr(TDim::value == 3)
180 {
181 auto const width = getWidth(extent);
182 auto const height = getHeight(extent);
183 auto const depth = getDepth(extent);
184
185 auto const widthBytes = width * static_cast<TIdx>(sizeof(TElem));
186 std::cout << __func__ << " ew: " << width << " eh: " << height << " ed: " << depth
187 << " ewb: " << widthBytes << " pitch: " << widthBytes << '\n';
188 }
189# endif
190
191 auto const& [nativeDev, nativeContext] = dev.getNativeHandle();
192 TElem* memPtr = sycl::malloc_device<TElem>(
193 static_cast<std::size_t>(getExtentProduct(extent)),
194 nativeDev,
195 nativeContext);
196 auto deleter = [ctx = nativeContext](TElem* ptr) { sycl::free(ptr, ctx); };
197
198 return BufGenericSycl<TElem, TDim, TIdx, TTag>(dev, memPtr, std::move(deleter), extent);
199 }
200 };
201
202 //! The BufGenericSycl stream-ordered memory allocation capability trait specialization.
203 template<typename TDim, concepts::Tag TTag>
204 struct HasAsyncBufSupport<TDim, DevGenericSycl<TTag>> : std::false_type
205 {
206 };
207
208 //! The BufGenericSycl offset get trait specialization.
209 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
210 struct GetOffsets<BufGenericSycl<TElem, TDim, TIdx, TTag>>
211 {
212 auto operator()(BufGenericSycl<TElem, TDim, TIdx, TTag> const&) const -> Vec<TDim, TIdx>
213 {
214 return Vec<TDim, TIdx>::zeros();
215 }
216 };
217
218 //! The pinned/mapped memory allocation trait specialization for the SYCL devices.
219 template<concepts::Tag TTag, typename TElem, typename TDim, typename TIdx>
220 struct BufAllocMapped<PlatformGenericSycl<TTag>, TElem, TDim, TIdx>
221 {
222 template<typename TExtent>
223 static auto allocMappedBuf(
224 DevCpu const& host,
225 PlatformGenericSycl<TTag> const& platform,
226 TExtent const& extent) -> BufCpu<TElem, TDim, TIdx>
227 {
229
230 // Allocate SYCL page-locked memory on the host, mapped into the SYCL platform's address space and
231 // accessible to all devices in the SYCL platform.
232 auto ctx = platform.syclContext();
233 TElem* memPtr = sycl::malloc_host<TElem>(static_cast<std::size_t>(getExtentProduct(extent)), ctx);
234 auto deleter = [ctx](TElem* ptr) { sycl::free(ptr, ctx); };
235
236 return BufCpu<TElem, TDim, TIdx>(host, memPtr, std::move(deleter), extent);
237 }
238 };
239
240 //! The pinned/mapped memory allocation capability trait specialization.
241 template<concepts::Tag TTag>
242 struct HasMappedBufSupport<PlatformGenericSycl<TTag>> : public std::true_type
243 {
244 };
245
246 //! The BufGenericSycl idx type trait specialization.
247 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
248 struct IdxType<BufGenericSycl<TElem, TDim, TIdx, TTag>>
249 {
250 using type = TIdx;
251 };
252
253 //! The BufCpu pointer on SYCL device get trait specialization.
254 template<typename TElem, typename TDim, typename TIdx, concepts::Tag TTag>
255 struct GetPtrDev<BufCpu<TElem, TDim, TIdx>, DevGenericSycl<TTag>>
256 {
257 static auto getPtrDev(BufCpu<TElem, TDim, TIdx> const& buf, DevGenericSycl<TTag> const&) -> TElem const*
258 {
259 return getPtrNative(buf);
260 }
261
262 static auto getPtrDev(BufCpu<TElem, TDim, TIdx>& buf, DevGenericSycl<TTag> const&) -> TElem*
263 {
264 return getPtrNative(buf);
265 }
266 };
267} // namespace alpaka::trait
268
271
272#endif
#define ALPAKA_DEBUG_MINIMAL_LOG_SCOPE
Definition Debug.hpp:55
ALPAKA_NO_HOST_ACC_WARNING static ALPAKA_FN_HOST_ACC constexpr auto zeros() -> Vec< TDim, TVal >
Zero value constructor.
Definition Vec.hpp:99
The accelerator traits.
The alpaka accelerator library.
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto getExtentProduct(T const &object) -> Idx< T >
Definition Traits.hpp:134
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto getHeight(TExtent const &extent=TExtent()) -> Idx< TExtent >
Definition Traits.hpp:108
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC constexpr auto getExtentVecEnd(T const &object={}) -> Vec< TDim, Idx< T > >
Definition Traits.hpp:78
ALPAKA_FN_HOST auto allocMappedBuf(DevCpu const &host, TPlatform const &platform, TExtent const &extent=TExtent())
Allocates pinned/mapped host memory, accessible by all devices in the given platform.
Definition Traits.hpp:138
ALPAKA_FN_HOST auto getPtrNative(TView const &view) -> Elem< TView > const *
Gets the native pointer of the memory view.
Definition Traits.hpp:136
ALPAKA_FN_HOST auto allocBuf(TDev const &dev, TExtent const &extent=TExtent())
Allocates memory on the given device.
Definition Traits.hpp:64
ALPAKA_FN_HOST auto getDev(T const &t)
Definition Traits.hpp:68
ALPAKA_FN_HOST auto getPtrDev(TView const &view, TDev const &dev) -> Elem< TView > const *
Gets the pointer to the view on the given device.
Definition Traits.hpp:157
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto getDepth(TExtent const &extent=TExtent()) -> Idx< TExtent >
Definition Traits.hpp:121
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto getWidth(TExtent const &extent=TExtent()) -> Idx< TExtent >
Definition Traits.hpp:95
STL namespace.