alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
AccGenericSycl.hpp
Go to the documentation of this file.
1/* Copyright 2026 Jan Stephan, Antonio Di Pilato, Andrea Bocci, Luca Ferragina, Aurora Perego
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
7// Base classes.
25
26// Specialized traits.
27#include "alpaka/acc/Traits.hpp"
28#include "alpaka/dev/Traits.hpp"
29#include "alpaka/idx/Traits.hpp"
32#include "alpaka/vec/Vec.hpp"
33
34// Implementation details.
38#include "alpaka/core/Sycl.hpp"
39
40#include <algorithm>
41#include <cstddef>
42#ifdef __cpp_lib_format
43# include <format>
44#endif
45#include <string>
46#include <type_traits>
47
48#ifdef ALPAKA_ACC_SYCL_ENABLED
49
50# include <sycl/sycl.hpp>
51
52namespace alpaka
53{
54 template<
55 concepts::Tag TTag,
56 typename TAcc,
57 typename TDim,
58 typename TIdx,
59 typename TKernelFnObj,
60 bool TCooperative,
61 typename... TArgs>
62 class TaskKernelGenericSycl;
63
64 //! The SYCL accelerator.
65 //!
66 //! This accelerator allows parallel kernel execution on SYCL devices.
67 template<concepts::Tag TTag, typename TDim, typename TIdx>
68 class AccGenericSycl
69 : public WorkDivGenericSycl<TDim, TIdx>
70 , public gb::IdxGbGenericSycl<TDim, TIdx>
71 , public bt::IdxBtGenericSycl<TDim, TIdx>
72 , public AtomicHierarchy<AtomicGenericSycl, AtomicGenericSycl, AtomicGenericSycl>
73 , public math::MathGenericSycl
74 , public BlockSharedMemDynGenericSycl
75 , public BlockSharedMemStGenericSycl
76 , public BlockSyncGenericSycl<TDim>
77 , public GridSyncGenericSycl<TDim>
78 , public IntrinsicGenericSycl
79 , public MemFenceGenericSycl
80# ifdef ALPAKA_DISABLE_VENDOR_RNG
81 , public rand::RandDefault
82# else
83 , public rand::RandGenericSycl<TDim>
84# endif
85 , public warp::WarpGenericSycl<TDim>
86 , public interface::Implements<InterfaceAcc, AccGenericSycl<TTag, TDim, TIdx>>
87 {
88 static_assert(TDim::value > 0, "The SYCL accelerator must have a dimension greater than zero.");
89
90 public:
91 AccGenericSycl(AccGenericSycl const&) = delete;
92 AccGenericSycl(AccGenericSycl&&) = delete;
93 auto operator=(AccGenericSycl const&) -> AccGenericSycl& = delete;
94 auto operator=(AccGenericSycl&&) -> AccGenericSycl& = delete;
95
96 AccGenericSycl(
97 Vec<TDim, TIdx> const& threadElemExtent,
98 sycl::nd_item<TDim::value> work_item,
99 sycl::local_accessor<std::byte> dyn_shared_acc,
100 sycl::local_accessor<std::byte> st_shared_acc)
101 : WorkDivGenericSycl<TDim, TIdx>{threadElemExtent, work_item}
102 , gb::IdxGbGenericSycl<TDim, TIdx>{work_item}
103 , bt::IdxBtGenericSycl<TDim, TIdx>{work_item}
104 , BlockSharedMemDynGenericSycl{dyn_shared_acc}
105 , BlockSharedMemStGenericSycl{st_shared_acc}
106 , BlockSyncGenericSycl<TDim>{work_item}
107 , GridSyncGenericSycl<TDim>{work_item}
108# ifndef ALPAKA_DISABLE_VENDOR_RNG
109 , rand::RandGenericSycl<TDim>{work_item}
110# endif
111 , warp::WarpGenericSycl<TDim>{work_item}
112 {
113 }
114 };
115} // namespace alpaka
116
117namespace alpaka::detail
118{
119 //! Whether the SYCL device can run cooperative kernels, i.e. kernels that synchronise all the work-items in the
120 //! grid: this requires the work-groups in the root group to make concurrent forward progress.
121 template<concepts::Tag TTag>
122 auto syclCooperativeLaunch([[maybe_unused]] sycl::device const& device) -> bool
123 {
124 if constexpr(std::is_same_v<TTag, TagFpgaSyclIntel>)
125 {
126 // cooperative kernels are not supported by the FPGA back-end
127 return false;
128 }
129 else
130 {
131# ifdef SYCL_EXT_ONEAPI_FORWARD_PROGRESS
132 namespace syclex = sycl::ext::oneapi::experimental;
133 auto const caps = device.template get_info<
134 syclex::info::device::work_group_progress_capabilities<syclex::execution_scope::root_group>>();
135 return std::find(caps.begin(), caps.end(), syclex::forward_progress_guarantee::concurrent) != caps.end();
136# else
137 // without the forward progress extension there is no way to check if the device supports it
138 return false;
139# endif
140 }
141 }
142} // namespace alpaka::detail
143
144namespace alpaka::trait
145{
146 //! The SYCL accelerator type trait specialization.
147 template<concepts::Tag TTag, typename TDim, typename TIdx>
148 struct AccType<AccGenericSycl<TTag, TDim, TIdx>>
149 {
150 using type = AccGenericSycl<TTag, TDim, TIdx>;
151 };
152
153 //! The SYCL single thread accelerator type trait specialization.
154 template<concepts::Tag TTag, typename TDim, typename TIdx>
155 struct IsSingleThreadAcc<AccGenericSycl<TTag, TDim, TIdx>> : std::false_type
156 {
157 };
158
159 //! The SYCL multi thread accelerator type trait specialization.
160 template<concepts::Tag TTag, typename TDim, typename TIdx>
161 struct IsMultiThreadAcc<AccGenericSycl<TTag, TDim, TIdx>> : std::true_type
162 {
163 };
164
165 //! The SYCL accelerator device properties get trait specialization.
166 template<concepts::Tag TTag, typename TDim, typename TIdx>
167 struct GetAccDevProps<AccGenericSycl<TTag, TDim, TIdx>>
168 {
169 static auto getAccDevProps(DevGenericSycl<TTag> const& dev) -> AccDevProps<TDim, TIdx>
170 {
171 auto const device = dev.getNativeHandle().first;
172 auto const max_threads_dim
173 = device.template get_info<sycl::info::device::max_work_item_sizes<TDim::value>>();
174 Vec<TDim, TIdx> max_threads_dim_vec{};
175 for(int i = 0; i < static_cast<int>(TDim::value); i++)
176 max_threads_dim_vec[i] = alpaka::core::clipCast<TIdx>(max_threads_dim[i]);
177 return {// m_multiProcessorCount
178 alpaka::core::clipCast<TIdx>(device.template get_info<sycl::info::device::max_compute_units>()),
179 // m_gridBlockExtentMax
181 // WARNING: There is no SYCL way to determine these values
182 std::numeric_limits<TIdx>::max(),
183 std::numeric_limits<TIdx>::max(),
184 std::numeric_limits<TIdx>::max())),
185 // m_gridBlockCountMax
186 std::numeric_limits<TIdx>::max(),
187 // m_blockThreadExtentMax
188 max_threads_dim_vec,
189 // m_blockThreadCountMax
190 alpaka::core::clipCast<TIdx>(device.template get_info<sycl::info::device::max_work_group_size>()),
191 // m_threadElemExtentMax
192 Vec<TDim, TIdx>::all(std::numeric_limits<TIdx>::max()),
193 // m_threadElemCountMax
194 std::numeric_limits<TIdx>::max(),
195 // m_sharedMemSizeBytes
196 device.template get_info<sycl::info::device::local_mem_size>(),
197 // m_globalMemSizeBytes
198 getMemBytes(dev),
199 // m_cooperativeLaunch
200 alpaka::detail::syclCooperativeLaunch<TTag>(device)};
201 }
202 };
203
204 //! The SYCL accelerator name trait specialization.
205 template<concepts::Tag TTag, typename TDim, typename TIdx>
206 struct GetAccName<AccGenericSycl<TTag, TDim, TIdx>>
207 {
208 static auto getAccName() -> std::string
209 {
210# if ALPAKA_COMP_CLANG
211# pragma clang diagnostic push
212# pragma clang diagnostic ignored "-Wexit-time-destructors"
213# endif
214 using namespace std::literals;
215 static std::string const accName =
216# ifdef __cpp_lib_format
217 std::format(
218 "Acc{}<{},{}>",
219 core::demangled<TTag>.substr(std::string_view("alpaka::Tag").size()),
220 TDim::value,
222# else
223 "Acc"s + std::string(core::demangled<TTag>.substr(std::string_view("alpaka::Tag").size())) + "<"s
224 + std::to_string(TDim::value) + ","s + std::string(core::demangled<TIdx>) + ">"s;
225# endif
226 return accName;
227# if ALPAKA_COMP_CLANG
228# pragma clang diagnostic pop
229# endif
230 }
231 };
232
233 //! The SYCL accelerator device type trait specialization.
234 template<concepts::Tag TTag, typename TDim, typename TIdx>
235 struct DevType<AccGenericSycl<TTag, TDim, TIdx>>
236 {
237 using type = DevGenericSycl<TTag>;
238 };
239
240 //! The SYCL accelerator dimension getter trait specialization.
241 template<concepts::Tag TTag, typename TDim, typename TIdx>
242 struct DimType<AccGenericSycl<TTag, TDim, TIdx>>
243 {
244 using type = TDim;
245 };
246
247 //! The SYCL accelerator execution task type trait specialization.
248 template<
249 concepts::Tag TTag,
250 typename TDim,
251 typename TIdx,
252 typename TWorkDiv,
253 typename TKernelFnObj,
254 typename... TArgs>
255 struct CreateTaskKernel<AccGenericSycl<TTag, TDim, TIdx>, TWorkDiv, TKernelFnObj, TArgs...>
256 {
257 static auto createTaskKernel(TWorkDiv const& workDiv, TKernelFnObj const& kernelFnObj, TArgs&&... args)
258 {
259 return TaskKernelGenericSycl<
260 TTag,
261 AccGenericSycl<TTag, TDim, TIdx>,
262 TDim,
263 TIdx,
264 TKernelFnObj,
265 false,
266 TArgs...>{workDiv, kernelFnObj, std::forward<TArgs>(args)...};
267 }
268 };
269
270 //! The SYCL accelerator execution task type trait specialization.
271 template<typename TTag, typename TDim, typename TIdx, typename TWorkDiv, typename TKernelFnObj, typename... TArgs>
272 struct CreateTaskCooperativeKernel<AccGenericSycl<TTag, TDim, TIdx>, TWorkDiv, TKernelFnObj, TArgs...>
273 {
274 static auto createTaskCooperativeKernel(
275 TWorkDiv const& workDiv,
276 TKernelFnObj const& kernelFnObj,
277 TArgs&&... args)
278 {
279 return TaskKernelGenericSycl<
280 TTag,
281 AccGenericSycl<TTag, TDim, TIdx>,
282 TDim,
283 TIdx,
284 TKernelFnObj,
285 true,
286 TArgs...>{workDiv, kernelFnObj, std::forward<TArgs>(args)...};
287 }
288 };
289
290 //! The SYCL execution task platform type trait specialization.
291 template<concepts::Tag TTag, typename TDim, typename TIdx>
292 struct PlatformType<AccGenericSycl<TTag, TDim, TIdx>>
293 {
294 using type = PlatformGenericSycl<TTag>;
295 };
296
297 //! The SYCL accelerator idx type trait specialization.
298 template<concepts::Tag TTag, typename TDim, typename TIdx>
299 struct IdxType<AccGenericSycl<TTag, TDim, TIdx>>
300 {
301 using type = TIdx;
302 };
303} // namespace alpaka::trait
304
305#endif
ALPAKA_NO_HOST_ACC_WARNING static ALPAKA_FN_HOST_ACC constexpr auto all(TVal const &val) -> Vec< TDim, TVal >
Single value constructor.
Definition Vec.hpp:89
constexpr std::string_view demangled
auto clipCast(V const &val) -> T
Definition ClipCast.hpp:16
The accelerator traits.
The alpaka accelerator library.
ALPAKA_FN_HOST auto getAccDevProps(TDev const &dev) -> AccDevProps< Dim< TAcc >, Idx< TAcc > >
Definition Traits.hpp:95
Vec(TFirstIndex &&, TRestIndices &&...) -> Vec< DimInt< 1+sizeof...(TRestIndices)>, std::decay_t< TFirstIndex > >
ALPAKA_FN_HOST auto createTaskKernel(TWorkDiv const &workDiv, TKernelFnObj const &kernelFnObj, TArgs &&... args)
Creates a kernel execution task.
Definition Traits.hpp:423
ALPAKA_FN_HOST auto getMemBytes(TDev const &dev) -> std::size_t
Definition Traits.hpp:102
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 createTaskCooperativeKernel(TWorkDiv const &workDiv, TKernelFnObj const &kernelFnObj, TArgs &&... args)
Creates a cooperative kernel execution task. Allows to use grid sync, but disables dynamic parallelis...
Definition Traits.hpp:467
std::integral_constant< std::size_t, N > DimInt
alpaka::meta::InheritFromList< alpaka::meta::Unique< std::tuple< TGridAtomic, TBlockAtomic, TThreadAtomic, interface::Implements< ConceptAtomicGrids, TGridAtomic >, interface::Implements< ConceptAtomicBlocks, TBlockAtomic >, interface::Implements< ConceptAtomicThreads, TThreadAtomic > > > > AtomicHierarchy
build a single class to inherit from different atomic implementations
static ALPAKA_FN_HOST auto getAccName() -> std::string
Definition Traits.hpp:74