DPC++ Runtime
Runtime libraries for oneAPI DPC++
sub_group.hpp
Go to the documentation of this file.
1 //==----------- sub_group.hpp --- SYCL sub-group ---------------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
11 #include <sycl/access/access.hpp> // for address_space, decorated
12 #include <sycl/detail/defines_elementary.hpp> // for __SYCL_DEPRECATED
13 #include <sycl/detail/generic_type_traits.hpp> // for select_cl_scalar_inte...
14 #include <sycl/detail/type_traits.hpp> // for is_scalar_arithmetic
15 #include <sycl/exception.hpp> // for exception, make_error...
16 #include <sycl/id.hpp> // for id
17 #include <sycl/memory_enums.hpp> // for memory_scope
18 #include <sycl/multi_ptr.hpp> // for multi_ptr
19 #include <sycl/range.hpp> // for range
20 
21 #include <stdint.h> // for uint32_t
22 #include <tuple> // for _Swallow_assign, ignore
23 #include <type_traits> // for enable_if_t, remove_cv_t
24 
25 namespace sycl {
26 inline namespace _V1 {
27 template <typename T, access::address_space Space,
28  access::decorated DecorateAddress>
29 class multi_ptr;
30 template <typename Type, int NumElements> class __SYCL_EBO vec;
31 namespace detail {
32 
33 namespace sub_group {
34 
35 // Selects 8, 16, 32, or 64-bit type depending on size of scalar type T.
36 template <typename T>
38 
39 template <typename MultiPtrTy> auto convertToBlockPtr(MultiPtrTy MultiPtr) {
40  static_assert(is_multi_ptr_v<MultiPtrTy>);
41  auto DecoratedPtr = convertToOpenCLType(MultiPtr);
42  using DecoratedPtrTy = decltype(DecoratedPtr);
44 
45  using TargetElemTy = SelectBlockT<ElemTy>;
46  // TODO: Handle cv qualifiers.
47 #ifdef __SYCL_DEVICE_ONLY__
48  using ResultTy =
49  typename DecoratedType<TargetElemTy,
50  deduce_AS<DecoratedPtrTy>::value>::type *;
51 #else
52  using ResultTy = TargetElemTy *;
53 #endif
54  return reinterpret_cast<ResultTy>(DecoratedPtr);
55 }
56 
57 template <typename T, access::address_space Space>
59  std::bool_constant<!std::is_same_v<void, SelectBlockT<T>> &&
61 
62 template <typename T, access::address_space Space>
64  std::bool_constant<!std::is_same_v<void, SelectBlockT<T>> &&
66 
67 #ifdef __SYCL_DEVICE_ONLY__
68 template <typename T, access::address_space Space,
69  access::decorated DecorateAddress>
70 T load(const multi_ptr<T, Space, DecorateAddress> src) {
71  using BlockT = SelectBlockT<T>;
72  BlockT Ret = __spirv_SubgroupBlockReadINTEL<BlockT>(convertToBlockPtr(src));
73 
74  return sycl::bit_cast<T>(Ret);
75 }
76 
77 template <int N, typename T, access::address_space Space,
78  access::decorated DecorateAddress>
80  using BlockT = SelectBlockT<T>;
81  using VecT = sycl::detail::ConvertToOpenCLType_t<vec<BlockT, N>>;
82  VecT Ret = __spirv_SubgroupBlockReadINTEL<VecT>(convertToBlockPtr(src));
83 
84  return sycl::bit_cast<typename vec<T, N>::vector_t>(Ret);
85 }
86 
87 template <typename T, access::address_space Space,
88  access::decorated DecorateAddress>
89 void store(multi_ptr<T, Space, DecorateAddress> dst, const T &x) {
90  using BlockT = SelectBlockT<T>;
91 
92  __spirv_SubgroupBlockWriteINTEL(convertToBlockPtr(dst),
93  sycl::bit_cast<BlockT>(x));
94 }
95 
96 template <int N, typename T, access::address_space Space,
97  access::decorated DecorateAddress>
98 void store(multi_ptr<T, Space, DecorateAddress> dst, const vec<T, N> &x) {
99  using BlockT = SelectBlockT<T>;
100  using VecT = sycl::detail::ConvertToOpenCLType_t<vec<BlockT, N>>;
101 
102  __spirv_SubgroupBlockWriteINTEL(convertToBlockPtr(dst),
103  sycl::bit_cast<VecT>(x));
104 }
105 #endif // __SYCL_DEVICE_ONLY__
106 
107 } // namespace sub_group
108 
109 // Helper for removing const and volatile qualifiers from the element type of
110 // a multi_ptr.
111 template <typename CVT, access::address_space Space,
112  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
113 inline multi_ptr<T, Space, IsDecorated>
115  if constexpr (IsDecorated == access::decorated::legacy) {
117  const_cast<typename multi_ptr<T, Space, IsDecorated>::pointer_t>(
118  Mptr.get())};
119  } else {
121  const_cast<typename multi_ptr<T, Space, IsDecorated>::pointer>(
122  Mptr.get_decorated())};
123  }
124 }
125 
126 } // namespace detail
127 
128 struct sub_group;
129 namespace ext::oneapi::this_work_item {
131 } // namespace ext::oneapi::this_work_item
132 
133 struct sub_group {
134 
135  using id_type = id<1>;
137  using linear_id_type = uint32_t;
138  static constexpr int dimensions = 1;
139  static constexpr sycl::memory_scope fence_scope =
141 
142  /* --- common interface members --- */
143 
145 #ifdef __SYCL_DEVICE_ONLY__
146  return __spirv_SubgroupLocalInvocationId();
147 #else
149  "Sub-groups are not supported on host.");
150 #endif
151  }
152 
154 #ifdef __SYCL_DEVICE_ONLY__
155  return static_cast<linear_id_type>(get_local_id()[0]);
156 #else
158  "Sub-groups are not supported on host.");
159 #endif
160  }
161 
163 #ifdef __SYCL_DEVICE_ONLY__
164  return __spirv_SubgroupSize();
165 #else
167  "Sub-groups are not supported on host.");
168 #endif
169  }
170 
172 #ifdef __SYCL_DEVICE_ONLY__
173  return __spirv_SubgroupMaxSize();
174 #else
176  "Sub-groups are not supported on host.");
177 #endif
178  }
179 
181 #ifdef __SYCL_DEVICE_ONLY__
182  return __spirv_SubgroupId();
183 #else
185  "Sub-groups are not supported on host.");
186 #endif
187  }
188 
190 #ifdef __SYCL_DEVICE_ONLY__
191  return static_cast<linear_id_type>(get_group_id()[0]);
192 #else
194  "Sub-groups are not supported on host.");
195 #endif
196  }
197 
199 #ifdef __SYCL_DEVICE_ONLY__
200  return __spirv_NumSubgroups();
201 #else
203  "Sub-groups are not supported on host.");
204 #endif
205  }
206 
207  /* --- sub_group load/stores --- */
208  /* these can map to SIMD or block read/write hardware where available */
209 #ifdef __SYCL_DEVICE_ONLY__
210  // Method for decorated pointer
211  template <typename CVT, typename T = std::remove_cv_t<CVT>>
212  std::enable_if_t<!std::is_same<remove_decoration_t<T>, T>::value, T>
213  load(CVT *cv_src) const {
214  T *src = const_cast<T *>(cv_src);
216  sycl::detail::deduce_AS<T>::value,
217  sycl::access::decorated::yes>(src));
218  }
219 
220  // Method for raw pointer
221  template <typename CVT, typename T = std::remove_cv_t<CVT>>
222  std::enable_if_t<std::is_same<remove_decoration_t<T>, T>::value, T>
223  load(CVT *cv_src) const {
224  T *src = const_cast<T *>(cv_src);
225 
226 #if defined(__NVPTX__) || defined(__AMDGCN__)
227  return src[get_local_id()[0]];
228 #else // __NVPTX__ || __AMDGCN__
229  auto l = __SYCL_GenericCastToPtrExplicit_ToLocal<T>(src);
230  if (l)
231  return load(l);
232 
233  auto g = __SYCL_GenericCastToPtrExplicit_ToGlobal<T>(src);
234  if (g)
235  return load(g);
236 
237  // Sub-group load() is supported for local or global pointers only.
238  return {};
239 #endif // __NVPTX__ || __AMDGCN__
240  }
241 #else //__SYCL_DEVICE_ONLY__
242  template <typename CVT, typename T = std::remove_cv_t<CVT>>
243  T load(CVT *src) const {
244  (void)src;
246  "Sub-groups are not supported on host.");
247  }
248 #endif //__SYCL_DEVICE_ONLY__
249 
250  template <typename CVT, access::address_space Space,
251  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
252  std::enable_if_t<
257 #ifdef __SYCL_DEVICE_ONLY__
258 #if defined(__NVPTX__) || defined(__AMDGCN__)
259  return src.get()[get_local_id()[0]];
260 #else
261  return sycl::detail::sub_group::load(src);
262 #endif // __NVPTX__ || __AMDGCN__
263 #else
264  (void)src;
266  "Sub-groups are not supported on host.");
267 #endif // __SYCL_DEVICE_ONLY__
268  }
269 
270  template <typename CVT, access::address_space Space,
271  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
272  std::enable_if_t<
277 #ifdef __SYCL_DEVICE_ONLY__
278  return src.get()[get_local_id()[0]];
279 #else
280  (void)src;
282  "Sub-groups are not supported on host.");
283 #endif
284  }
285 #ifdef __SYCL_DEVICE_ONLY__
286 #if defined(__NVPTX__) || defined(__AMDGCN__)
287  template <int N, typename CVT, access::address_space Space,
288  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
289  std::enable_if_t<
291  vec<T, N>>
292  load(const multi_ptr<CVT, Space, IsDecorated> cv_src) const {
295  vec<T, N> res;
296  for (int i = 0; i < N; ++i) {
297  res[i] = *(src.get() + i * get_max_local_range()[0] + get_local_id()[0]);
298  }
299  return res;
300  }
301 #else // __NVPTX__ || __AMDGCN__
302  template <int N, typename CVT, access::address_space Space,
303  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
304  std::enable_if_t<
306  N != 1 && N != 3 && N != 16,
307  vec<T, N>>
308  load(const multi_ptr<CVT, Space, IsDecorated> cv_src) const {
309  multi_ptr<T, Space, IsDecorated> src =
311  return sycl::detail::sub_group::load<N, T>(src);
312  }
313 
314  template <int N, typename CVT, access::address_space Space,
315  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
316  std::enable_if_t<
318  N == 16,
319  vec<T, 16>>
320  load(const multi_ptr<CVT, Space, IsDecorated> cv_src) const {
321  multi_ptr<T, Space, IsDecorated> src =
323  return {sycl::detail::sub_group::load<8, T>(src),
324  sycl::detail::sub_group::load<8, T>(src +
325  8 * get_max_local_range()[0])};
326  }
327 
328  template <int N, typename CVT, access::address_space Space,
329  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
330  std::enable_if_t<
332  N == 3,
333  vec<T, 3>>
334  load(const multi_ptr<CVT, Space, IsDecorated> cv_src) const {
335  multi_ptr<T, Space, IsDecorated> src =
337  return {
338  sycl::detail::sub_group::load<1, T>(src),
339  sycl::detail::sub_group::load<2, T>(src + get_max_local_range()[0])};
340  }
341 
342  template <int N, typename CVT, access::address_space Space,
343  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
344  std::enable_if_t<
346  N == 1,
347  vec<T, 1>>
348  load(const multi_ptr<CVT, Space, IsDecorated> cv_src) const {
349  multi_ptr<T, Space, IsDecorated> src =
351  return sycl::detail::sub_group::load(src);
352  }
353 #endif // ___NVPTX___
354 #else // __SYCL_DEVICE_ONLY__
355  template <int N, typename CVT, access::address_space Space,
356  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
357  std::enable_if_t<
359  vec<T, N>>
361  (void)src;
363  "Sub-groups are not supported on host.");
364  }
365 #endif // __SYCL_DEVICE_ONLY__
366 
367  template <int N, typename CVT, access::address_space Space,
368  access::decorated IsDecorated, typename T = std::remove_cv_t<CVT>>
369  std::enable_if_t<
371  vec<T, N>>
375 #ifdef __SYCL_DEVICE_ONLY__
376  vec<T, N> res;
377  for (int i = 0; i < N; ++i) {
378  res[i] = *(src.get() + i * get_max_local_range()[0] + get_local_id()[0]);
379  }
380  return res;
381 #else
382  (void)src;
384  "Sub-groups are not supported on host.");
385 #endif
386  }
387 
388 #ifdef __SYCL_DEVICE_ONLY__
389  // Method for decorated pointer
390  template <typename T>
391  std::enable_if_t<!std::is_same<remove_decoration_t<T>, T>::value>
392  store(T *dst, const remove_decoration_t<T> &x) const {
394  sycl::detail::deduce_AS<T>::value,
395  sycl::access::decorated::yes>(dst),
396  x);
397  }
398 
399  // Method for raw pointer
400  template <typename T>
401  std::enable_if_t<std::is_same<remove_decoration_t<T>, T>::value>
402  store(T *dst, const remove_decoration_t<T> &x) const {
403 
404 #if defined(__NVPTX__) || defined(__AMDGCN__)
405  dst[get_local_id()[0]] = x;
406 #else // __NVPTX__ || __AMDGCN__
407  auto l = __SYCL_GenericCastToPtrExplicit_ToLocal<T>(dst);
408  if (l) {
409  store(l, x);
410  return;
411  }
412 
413  auto g = __SYCL_GenericCastToPtrExplicit_ToGlobal<T>(dst);
414  if (g) {
415  store(g, x);
416  return;
417  }
418 
419  // Sub-group store() is supported for local or global pointers only.
420  return;
421 #endif // __NVPTX__ || __AMDGCN__
422  }
423 #else //__SYCL_DEVICE_ONLY__
424  template <typename T> void store(T *dst, const T &x) const {
425  (void)dst;
426  (void)x;
428  "Sub-groups are not supported on host.");
429  }
430 #endif //__SYCL_DEVICE_ONLY__
431 
432  template <typename T, access::address_space Space,
433  access::decorated DecorateAddress>
434  std::enable_if_t<
437 #ifdef __SYCL_DEVICE_ONLY__
438 #if defined(__NVPTX__) || defined(__AMDGCN__)
439  dst.get()[get_local_id()[0]] = x;
440 #else
441  sycl::detail::sub_group::store(dst, x);
442 #endif // __NVPTX__ || __AMDGCN__
443 #else
444  (void)dst;
445  (void)x;
447  "Sub-groups are not supported on host.");
448 #endif
449  }
450 
451  template <typename T, access::address_space Space,
452  access::decorated DecorateAddress>
453  std::enable_if_t<
456 #ifdef __SYCL_DEVICE_ONLY__
457  dst.get()[get_local_id()[0]] = x;
458 #else
459  (void)dst;
460  (void)x;
462  "Sub-groups are not supported on host.");
463 #endif
464  }
465 
466 #ifdef __SYCL_DEVICE_ONLY__
467 #if defined(__NVPTX__) || defined(__AMDGCN__)
468  template <int N, typename T, access::address_space Space,
469  access::decorated DecorateAddress>
470  std::enable_if_t<
473  for (int i = 0; i < N; ++i) {
474  *(dst.get() + i * get_max_local_range()[0] + get_local_id()[0]) = x[i];
475  }
476  }
477 #else // __NVPTX__ || __AMDGCN__
478  template <int N, typename T, access::address_space Space,
479  access::decorated DecorateAddress>
480  std::enable_if_t<
482  N != 1 && N != 3 && N != 16>
483  store(multi_ptr<T, Space, DecorateAddress> dst, const vec<T, N> &x) const {
484  sycl::detail::sub_group::store(dst, x);
485  }
486 
487  template <int N, typename T, access::address_space Space,
488  access::decorated DecorateAddress>
489  std::enable_if_t<
491  N == 1>
492  store(multi_ptr<T, Space, DecorateAddress> dst, const vec<T, 1> &x) const {
493  sycl::detail::sub_group::store(dst, x);
494  }
495 
496  template <int N, typename T, access::address_space Space,
497  access::decorated DecorateAddress>
498  std::enable_if_t<
500  N == 3>
501  store(multi_ptr<T, Space, DecorateAddress> dst, const vec<T, 3> &x) const {
502  store<1, T, Space, DecorateAddress>(dst, x.s0());
503  store<2, T, Space, DecorateAddress>(dst + get_max_local_range()[0],
504  {x.s1(), x.s2()});
505  }
506 
507  template <int N, typename T, access::address_space Space,
508  access::decorated DecorateAddress>
509  std::enable_if_t<
511  N == 16>
512  store(multi_ptr<T, Space, DecorateAddress> dst, const vec<T, 16> &x) const {
513  store<8, T, Space, DecorateAddress>(dst, x.lo());
514  store<8, T, Space, DecorateAddress>(dst + 8 * get_max_local_range()[0],
515  x.hi());
516  }
517 
518 #endif // __NVPTX__ || __AMDGCN__
519 #else // __SYCL_DEVICE_ONLY__
520  template <int N, typename T, access::address_space Space,
521  access::decorated DecorateAddress>
522  std::enable_if_t<
525  (void)dst;
526  (void)x;
528  "Sub-groups are not supported on host.");
529  }
530 #endif // __SYCL_DEVICE_ONLY__
531 
532  template <int N, typename T, access::address_space Space,
533  access::decorated DecorateAddress>
534  std::enable_if_t<
537 #ifdef __SYCL_DEVICE_ONLY__
538  for (int i = 0; i < N; ++i) {
539  *(dst.get() + i * get_max_local_range()[0] + get_local_id()[0]) = x[i];
540  }
541 #else
542  (void)dst;
543  (void)x;
545  "Sub-groups are not supported on host.");
546 #endif
547  }
548 
549  /* --- synchronization functions --- */
551  "Sub-group barrier with no arguments is deprecated."
552  "Use sycl::group_barrier with the sub-group as the argument instead.")
553  void barrier() const {
554 #ifdef __SYCL_DEVICE_ONLY__
561 #else
563  "Sub-groups are not supported on host.");
564 #endif
565  }
566 
568  "Sub-group barrier accepting fence_space is deprecated."
569  "Use sycl::group_barrier with the sub-group as the argument instead.")
570  void barrier(access::fence_space accessSpace) const {
571 #ifdef __SYCL_DEVICE_ONLY__
572  int32_t flags = sycl::detail::getSPIRVMemorySemanticsMask(accessSpace);
574  flags);
575 #else
576  (void)accessSpace;
578  "Sub-groups are not supported on host.");
579 #endif
580  }
581 
582  linear_id_type get_group_linear_range() const {
583 #ifdef __SYCL_DEVICE_ONLY__
584  return static_cast<linear_id_type>(get_group_range()[0]);
585 #else
587  "Sub-groups are not supported on host.");
588 #endif
589  }
590 
592 #ifdef __SYCL_DEVICE_ONLY__
593  return static_cast<linear_id_type>(get_local_range()[0]);
594 #else
596  "Sub-groups are not supported on host.");
597 #endif
598  }
599 
600  bool leader() const {
601 #ifdef __SYCL_DEVICE_ONLY__
602  return get_local_linear_id() == 0;
603 #else
605  "Sub-groups are not supported on host.");
606 #endif
607  }
608 
609  // Common member functions for by-value semantics
610  friend bool operator==(const sub_group &lhs, const sub_group &rhs) {
611 #ifdef __SYCL_DEVICE_ONLY__
612  return lhs.get_group_id() == rhs.get_group_id();
613 #else
614  std::ignore = lhs;
615  std::ignore = rhs;
617  "Sub-groups are not supported on host.");
618 #endif
619  }
620 
621  friend bool operator!=(const sub_group &lhs, const sub_group &rhs) {
622 #ifdef __SYCL_DEVICE_ONLY__
623  return !(lhs == rhs);
624 #else
625  std::ignore = lhs;
626  std::ignore = rhs;
628  "Sub-groups are not supported on host.");
629 #endif
630  }
631 
632 protected:
633  template <int dimensions> friend class sycl::nd_item;
635  sub_group() = default;
636 };
637 } // namespace _V1
638 } // namespace sycl
Identifies an instance of the function object executing at each point in an nd_range.
Definition: nd_item.hpp:48
#define __SYCL_EBO
__ESIMD_API void barrier()
Generic work-group barrier.
Definition: memory.hpp:12106
std::bool_constant<!std::is_same_v< void, SelectBlockT< T > > &&Space==access::address_space::local_space > AcceptableForLocalLoadStore
Definition: sub_group.hpp:65
select_cl_scalar_integral_unsigned_t< T > SelectBlockT
Definition: sub_group.hpp:37
auto convertToBlockPtr(MultiPtrTy MultiPtr)
Definition: sub_group.hpp:39
std::bool_constant<!std::is_same_v< void, SelectBlockT< T > > &&Space==access::address_space::global_space > AcceptableForGlobalLoadStore
Definition: sub_group.hpp:60
auto get_local_linear_range(Group g)
select_apply_cl_scalar_t< T, sycl::opencl::cl_uchar, sycl::opencl::cl_ushort, sycl::opencl::cl_uint, sycl::opencl::cl_ulong > select_cl_scalar_integral_unsigned_t
constexpr __spv::MemorySemanticsMask::Flag getSPIRVMemorySemanticsMask(memory_order)
Definition: helpers.hpp:195
multi_ptr< T, Space, IsDecorated > GetUnqualMultiPtr(const multi_ptr< CVT, Space, IsDecorated > &Mptr)
Definition: sub_group.hpp:114
bool operator==(const cache_config &lhs, const cache_config &rhs)
class __SYCL_EBO vec
Definition: aliases.hpp:18
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()
Definition: exception.cpp:65
autodecltype(x) x
typename remove_decoration< T >::type remove_decoration_t
Definition: access.hpp:325
Definition: access.hpp:18
__SYCL_CONVERGENT__ __DPCPP_SYCL_EXTERNAL void __spirv_ControlBarrier(__spv::Scope Execution, __spv::Scope Memory, uint32_t Semantics) noexcept
Definition: spirv_ops.cpp:27
std::enable_if_t< sycl::detail::sub_group::AcceptableForLocalLoadStore< T, Space >::value > store(multi_ptr< T, Space, DecorateAddress > dst, const T &x) const
Definition: sub_group.hpp:455
linear_id_type get_group_linear_id() const
Definition: sub_group.hpp:189
std::enable_if_t< sycl::detail::sub_group::AcceptableForGlobalLoadStore< T, Space >::value > store(multi_ptr< T, Space, DecorateAddress > dst, const vec< T, N > &x) const
Definition: sub_group.hpp:524
T load(CVT *src) const
Definition: sub_group.hpp:243
__SYCL_DEPRECATED("Sub-group barrier with no arguments is deprecated." "Use sycl::group_barrier with the sub-group as the argument instead.") void barrier() const
Definition: sub_group.hpp:550
range_type get_max_local_range() const
Definition: sub_group.hpp:171
std::enable_if_t< sycl::detail::sub_group::AcceptableForGlobalLoadStore< T, Space >::value, vec< T, N > > load(const multi_ptr< CVT, Space, IsDecorated > src) const
Definition: sub_group.hpp:360
id_type get_group_id() const
Definition: sub_group.hpp:180
range_type get_local_range() const
Definition: sub_group.hpp:162
static constexpr int dimensions
Definition: sub_group.hpp:138
static constexpr sycl::memory_scope fence_scope
Definition: sub_group.hpp:139
__SYCL_DEPRECATED("Sub-group barrier accepting fence_space is deprecated." "Use sycl::group_barrier with the sub-group as the argument instead.") void barrier(access
Definition: sub_group.hpp:567
std::enable_if_t< sycl::detail::sub_group::AcceptableForGlobalLoadStore< T, Space >::value, T > load(const multi_ptr< CVT, Space, IsDecorated > cv_src) const
Definition: sub_group.hpp:254
std::enable_if_t< sycl::detail::sub_group::AcceptableForLocalLoadStore< T, Space >::value > store(multi_ptr< T, Space, DecorateAddress > dst, const vec< T, N > &x) const
Definition: sub_group.hpp:536
std::enable_if_t< sycl::detail::sub_group::AcceptableForLocalLoadStore< T, Space >::value, T > load(const multi_ptr< CVT, Space, IsDecorated > cv_src) const
Definition: sub_group.hpp:274
id_type get_local_id() const
Definition: sub_group.hpp:144
void store(T *dst, const T &x) const
Definition: sub_group.hpp:424
friend bool operator!=(const sub_group &lhs, const sub_group &rhs)
Definition: sub_group.hpp:621
linear_id_type get_local_linear_id() const
Definition: sub_group.hpp:153
std::enable_if_t< sycl::detail::sub_group::AcceptableForLocalLoadStore< T, Space >::value, vec< T, N > > load(const multi_ptr< CVT, Space, IsDecorated > cv_src) const
Definition: sub_group.hpp:372
range_type get_group_range() const
Definition: sub_group.hpp:198
std::enable_if_t< sycl::detail::sub_group::AcceptableForGlobalLoadStore< T, Space >::value > store(multi_ptr< T, Space, DecorateAddress > dst, const T &x) const
Definition: sub_group.hpp:436