alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
WarpGenericSycl.hpp
Go to the documentation of this file.
1/* Copyright 2026 Jan Stephan, Luca Ferragina, Andrea Bocci, Aurora Perego, Simone Balducci
2 * SPDX-License-Identifier: MPL-2.0
3 *
4 * The implementations of Shfl::shfl(), ShflUp::shfl_up(), ShflDown::shfl_down() and ShflXor::shfl_xor() are derived
5 * from Intel DPCT.
6 * Copyright (C) Intel Corporation.
7 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 * See https://llvm.org/LICENSE.txt for license information.
9 */
10
11#pragma once
12
16
17#include <cstdint>
18
19#ifdef ALPAKA_ACC_SYCL_ENABLED
20
21# include <sycl/sycl.hpp>
22
23namespace alpaka::warp
24{
25 //! The SYCL warp.
26 template<typename TDim>
27 class WarpGenericSycl : public interface::Implements<alpaka::warp::ConceptWarp, WarpGenericSycl<TDim>>
28 {
29 public:
30 using mask_type = std::uint32_t;
31
32 WarpGenericSycl(sycl::nd_item<TDim::value> my_item) : m_item_warp{my_item}
33 {
34 }
35
36 sycl::nd_item<TDim::value> m_item_warp;
37 };
38} // namespace alpaka::warp
39
40namespace alpaka::warp::trait
41{
42 // oneAPI up to 2025.3 uses sycl::ext::oneapi::experimental::this_kernel::get_opportunistic_group(),
43 // while oneAPI 2026.0 uses sycl::ext::oneapi::experimental::this_work_item::get_opportunistic_group()
44# if ALPAKA_COMP_ICPX >= ALPAKA_VERSION_NUMBER(2026, 0, 0)
45 using sycl::ext::oneapi::experimental::this_work_item::get_opportunistic_group;
46# else
47 using sycl::ext::oneapi::experimental::this_kernel::get_opportunistic_group;
48# endif
49
50 template<typename TDim>
51 struct GetSize<warp::WarpGenericSycl<TDim>>
52 {
53 static auto getSize(warp::WarpGenericSycl<TDim> const& warp) -> std::int32_t
54 {
55 auto const sub_group = warp.m_item_warp.get_sub_group();
56 // SYCL sub-groups are always 1D
57 return static_cast<std::int32_t>(sub_group.get_max_local_range()[0]);
58 }
59 };
60
61 template<typename TDim>
62 struct GetSizeCompileTime<warp::WarpGenericSycl<TDim>>
63 {
64 static constexpr auto getSizeCompileTime() -> std::int32_t
65 {
66 // SYCL sub-groups size is usually not known at compile time
67 return 0;
68 }
69 };
70
71 template<typename TDim>
72 struct GetSizeUpperLimit<warp::WarpGenericSycl<TDim>>
73 {
74 static constexpr auto getSizeUpperLimit() -> std::int32_t
75 {
76 // See include/alpaka/kernel/SyclSubgroupSize.hpp for possible sub-group sizes.
77 return 64;
78 }
79 };
80
81 template<typename TDim>
82 struct Activemask<warp::WarpGenericSycl<TDim>>
83 {
84 // FIXME This should be std::uint64_t on AMD GCN architectures and on CPU,
85 // but the former is not targeted in alpaka and CPU case is not supported in SYCL yet.
86 // Restrict to warpSize <= 32 for now.
87 static auto activemask(warp::WarpGenericSycl<TDim> const& /*warp*/) -> warp::WarpGenericSycl<TDim>::mask_type
88 {
89 sycl::sub_group sg = sycl::ext::oneapi::this_work_item::get_sub_group();
90 auto const mask = sycl::ext::oneapi::group_ballot(sg, true);
91 std::uint32_t bits = 0;
92 mask.extract_bits(bits);
93 return bits;
94 }
95 };
96
97 template<typename TDim>
98 struct All<warp::WarpGenericSycl<TDim>>
99 {
100 static auto all(warp::WarpGenericSycl<TDim> const& /*warp*/, std::int32_t predicate) -> std::int32_t
101 {
102 auto activegroup = get_opportunistic_group();
103 return static_cast<std::int32_t>(sycl::all_of_group(activegroup, static_cast<bool>(predicate)));
104 }
105 };
106
107 template<typename TDim>
108 struct Any<warp::WarpGenericSycl<TDim>>
109 {
110 static auto any(warp::WarpGenericSycl<TDim> const& /*warp*/, std::int32_t predicate) -> std::int32_t
111 {
112 auto activegroup = get_opportunistic_group();
113 return static_cast<std::int32_t>(sycl::any_of_group(activegroup, static_cast<bool>(predicate)));
114 }
115 };
116
117 template<typename TDim>
118 struct Ballot<warp::WarpGenericSycl<TDim>>
119 {
120 // FIXME This should be std::uint64_t on AMD GCN architectures and on CPU,
121 // but the former is not targeted in alpaka and CPU case is not supported in SYCL yet.
122 // Restrict to warpSize <= 32 for now.
123 static auto ballot(warp::WarpGenericSycl<TDim> const& /*warp*/, std::int32_t predicate)
124 -> warp::WarpGenericSycl<TDim>::mask_type
125 {
126 auto sub_group = sycl::ext::oneapi::this_work_item::get_sub_group();
127 auto const mask = sycl::ext::oneapi::group_ballot(sub_group, static_cast<bool>(predicate));
128 // FIXME This should be std::uint64_t on AMD GCN architectures and on CPU,
129 // but the former is not targeted in alpaka and CPU case is not supported in SYCL yet.
130 // Restrict to warpSize <= 32 for now.
131 std::uint32_t bits = 0;
132 mask.extract_bits(bits);
133 return bits;
134 }
135 };
136
137 template<typename TDim>
138 struct Shfl<warp::WarpGenericSycl<TDim>>
139 {
140 template<typename T>
141 static auto shfl(
142 warp::WarpGenericSycl<TDim> const& /*warp*/,
143 T value,
144 std::int32_t srcLane,
145 std::int32_t width)
146 {
147 ALPAKA_ASSERT_ACC(width > 0);
148 ALPAKA_ASSERT_ACC(srcLane >= 0);
149
150 /* If width < srcLane the sub-group needs to be split into assumed subdivisions. The first item of each
151 subdivision has the assumed index 0. The srcLane index is relative to the subdivisions.
152
153 Example: If we assume a sub-group size of 32 and a width of 16 we will receive two subdivisions:
154 The first starts at sub-group index 0 and the second at sub-group index 16. For srcLane = 4 the
155 first subdivision will access the value at sub-group index 4 and the second at sub-group index 20. */
156 auto actual_group = get_opportunistic_group();
157 std::uint32_t const w = static_cast<std::uint32_t>(width);
158 std::uint32_t const start_index = actual_group.get_local_linear_id() / w * w;
159 return sycl::select_from_group(actual_group, value, start_index + static_cast<std::uint32_t>(srcLane) % w);
160 }
161 };
162
163 template<typename TDim>
164 struct ShflUp<warp::WarpGenericSycl<TDim>>
165 {
166 template<typename T>
167 static auto shfl_up(
168 warp::WarpGenericSycl<TDim> const& /*warp*/,
169 T value,
170 std::uint32_t offset, /* must be the same for all work-items in the group */
171 std::int32_t width)
172 {
173 auto actual_group = get_opportunistic_group();
174 std::uint32_t const w = static_cast<std::uint32_t>(width);
175 std::uint32_t const id = actual_group.get_local_linear_id();
176 std::uint32_t const start_index = id / w * w;
177 T result = sycl::shift_group_right(actual_group, value, offset);
178 if((id - start_index) < offset)
179 {
180 result = value;
181 }
182 return result;
183 }
184 };
185
186 template<typename TDim>
187 struct ShflDown<warp::WarpGenericSycl<TDim>>
188 {
189 template<typename T>
190 static auto shfl_down(
191 warp::WarpGenericSycl<TDim> const& /*warp*/,
192 T value,
193 std::uint32_t offset,
194 std::int32_t width)
195 {
196 auto actual_group = get_opportunistic_group();
197 std::uint32_t const w = static_cast<std::uint32_t>(width);
198 std::uint32_t const id = actual_group.get_local_linear_id();
199 std::uint32_t const end_index = (id / w + 1) * w;
200 T result = sycl::shift_group_left(actual_group, value, offset);
201 if((id + offset) >= end_index)
202 {
203 result = value;
204 }
205 return result;
206 }
207 };
208
209 template<typename TDim>
210 struct ShflXor<warp::WarpGenericSycl<TDim>>
211 {
212 template<typename T>
213 static auto shfl_xor(
214 warp::WarpGenericSycl<TDim> const& /*warp*/,
215 T value,
216 std::int32_t mask,
217 std::int32_t width)
218 {
219 auto actual_group = get_opportunistic_group();
220 std::uint32_t const w = static_cast<std::uint32_t>(width);
221 std::uint32_t const id = actual_group.get_local_linear_id();
222 std::uint32_t const start_index = id / w * w;
223 std::uint32_t const target_offset = (id % w) ^ static_cast<std::uint32_t>(mask);
224 return sycl::select_from_group(actual_group, value, target_offset < w ? start_index + target_offset : id);
225 }
226 };
227} // namespace alpaka::warp::trait
228
229#endif
#define ALPAKA_ASSERT_ACC(...)
ALPAKA_ASSERT_ACC is an assert-like macro.
Definition Assert.hpp:52
The warp traits.
Definition Traits.hpp:21
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto ballot(TWarp const &warp, std::int32_t predicate) -> typename TWarp::mask_type
Evaluates predicate for all non-exited threads in a warp and returns a 32- or 64-bit unsigned integer...
Definition Traits.hpp:194
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto all(TWarp const &warp, std::int32_t predicate) -> std::int32_t
Evaluates predicate for all active threads of the warp and returns non-zero if and only if predicate ...
Definition Traits.hpp:144
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto shfl_up(TWarp const &warp, T value, std::uint32_t offset, std::int32_t width=0)
Exchange data between threads within a warp. It copies from a lane with lower ID relative to caller....
Definition Traits.hpp:266
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC constexpr auto getSizeUpperLimit() -> std::int32_t
If the warp size is available as a compile-time constant returns its value; otherwise returns an uppe...
Definition Traits.hpp:96
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto any(TWarp const &warp, std::int32_t predicate) -> std::int32_t
Evaluates predicate for all active threads of the warp and returns non-zero if and only if predicate ...
Definition Traits.hpp:167
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto shfl_down(TWarp const &warp, T value, std::uint32_t offset, std::int32_t width=0)
Exchange data between threads within a warp. It copies from a lane with higher ID relative to caller....
Definition Traits.hpp:304
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto getSize(TWarp const &warp) -> std::int32_t
Returns warp size.
Definition Traits.hpp:73
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto shfl_xor(TWarp const &warp, T value, std::int32_t mask, std::int32_t width=0)
Exchange data between threads within a warp. It copies from a lane based on bitwise XOR of own lane I...
Definition Traits.hpp:342
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto activemask(TWarp const &warp) -> typename TWarp::mask_type
Returns a 32- or 64-bit unsigned integer (depending on the accelerator) whose Nth bit is set if and o...
Definition Traits.hpp:121
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC constexpr auto getSizeCompileTime() -> std::int32_t
If the warp size is available as a compile-time constant returns its value; otherwise returns 0.
Definition Traits.hpp:84
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto shfl(TWarp const &warp, T value, std::int32_t srcLane, std::int32_t width=0)
Exchange data between threads within a warp.
Definition Traits.hpp:228