DPC++ Runtime
Runtime libraries for oneAPI DPC++
prefetch.hpp
Go to the documentation of this file.
1 //==--------------- prefetch.hpp --- SYCL prefetch extension ---------------==//
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 <CL/__spirv/spirv_ops.hpp>
13 
14 namespace sycl {
15 inline namespace _V1 {
16 namespace ext::oneapi::experimental {
17 
18 enum class cache_level { L1 = 0, L2 = 1, L3 = 2, L4 = 3 };
19 
20 struct nontemporal;
21 
23  template <cache_level Level, typename Hint>
24  using value_t =
26  std::integral_constant<cache_level, Level>, Hint>;
27 };
28 
29 template <cache_level Level, typename Hint>
31 
40 
49 
50 namespace detail {
51 template <> struct IsCompileTimeProperty<prefetch_hint_key> : std::true_type {};
52 
53 template <cache_level Level, typename Hint>
54 struct PropertyMetaInfo<prefetch_hint_key::value_t<Level, Hint>> {
55  static constexpr const char *name = std::is_same_v<Hint, nontemporal>
56  ? "sycl-prefetch-hint-nt"
57  : "sycl-prefetch-hint";
58  static constexpr int value = static_cast<int>(Level);
59 };
60 
61 template <access::address_space AS>
62 inline constexpr bool check_prefetch_AS =
65 
66 template <access_mode mode>
67 inline constexpr bool check_prefetch_acc_mode =
69 
70 template <typename T, typename Properties>
71 void prefetch_impl(T *ptr, size_t bytes, Properties properties) {
72 #ifdef __SYCL_DEVICE_ONLY__
73  auto *ptrGlobalAS = __SYCL_GenericCastToPtrExplicit_ToGlobal<const char>(ptr);
74  const __attribute__((opencl_global)) char *ptrAnnotated = nullptr;
75  if constexpr (!properties.template has_property<prefetch_hint_key>()) {
76  ptrAnnotated = __builtin_intel_sycl_ptr_annotation(
77  ptrGlobalAS, "sycl-prefetch-hint", static_cast<int>(cache_level::L1));
78  } else {
79  auto prop = properties.template get_property<prefetch_hint_key>();
80  ptrAnnotated = __builtin_intel_sycl_ptr_annotation(
81  ptrGlobalAS, PropertyMetaInfo<decltype(prop)>::name,
82  PropertyMetaInfo<decltype(prop)>::value);
83  }
84  __spirv_ocl_prefetch(ptrAnnotated, bytes);
85 #else
86  std::ignore = ptr;
87  std::ignore = bytes;
88  std::ignore = properties;
89 #endif
90 }
91 
92 template <typename Group, typename T, typename Properties>
93 void joint_prefetch_impl(Group g, T *ptr, size_t bytes, Properties properties) {
94  // Although calling joint_prefetch is functionally equivalent to calling
95  // prefetch from every work-item in a group, native suppurt may be added to to
96  // issue cooperative prefetches more efficiently on some hardware.
97  std::ignore = g;
98  prefetch_impl(ptr, bytes, properties);
99 }
100 } // namespace detail
101 
102 template <typename Properties = empty_properties_t>
103 std::enable_if_t<is_property_list_v<std::decay_t<Properties>>>
104 prefetch(void *ptr, Properties properties = {}) {
105  detail::prefetch_impl(ptr, 1, properties);
106 }
107 
108 template <typename Properties = empty_properties_t>
109 std::enable_if_t<is_property_list_v<std::decay_t<Properties>>>
110 prefetch(void *ptr, size_t bytes, Properties properties = {}) {
111  detail::prefetch_impl(ptr, bytes, properties);
112 }
113 
114 template <typename T, typename Properties = empty_properties_t>
115 std::enable_if_t<is_property_list_v<std::decay_t<Properties>>>
116 prefetch(T *ptr, Properties properties = {}) {
117  detail::prefetch_impl(ptr, sizeof(T), properties);
118 }
119 
120 template <typename T, typename Properties = empty_properties_t>
121 std::enable_if_t<is_property_list_v<std::decay_t<Properties>>>
122 prefetch(T *ptr, size_t count, Properties properties = {}) {
123  detail::prefetch_impl(ptr, count * sizeof(T), properties);
124 }
125 
126 template <access::address_space AddressSpace, access::decorated IsDecorated,
127  typename Properties = empty_properties_t>
128 std::enable_if_t<detail::check_prefetch_AS<AddressSpace> &&
129  is_property_list_v<std::decay_t<Properties>>>
131  Properties properties = {}) {
132  detail::prefetch_impl(ptr.get(), 1, properties);
133 }
134 
135 template <access::address_space AddressSpace, access::decorated IsDecorated,
136  typename Properties = empty_properties_t>
137 std::enable_if_t<detail::check_prefetch_AS<AddressSpace> &&
138  is_property_list_v<std::decay_t<Properties>>>
140  Properties properties = {}) {
141  detail::prefetch_impl(ptr.get(), bytes, properties);
142 }
143 
144 template <typename T, access::address_space AddressSpace,
145  access::decorated IsDecorated,
146  typename Properties = empty_properties_t>
147 std::enable_if_t<detail::check_prefetch_AS<AddressSpace> &&
148  is_property_list_v<std::decay_t<Properties>>>
150  Properties properties = {}) {
151  detail::prefetch_impl(ptr.get(), sizeof(T), properties);
152 }
153 
154 template <typename T, access::address_space AddressSpace,
155  access::decorated IsDecorated,
156  typename Properties = empty_properties_t>
157 std::enable_if_t<detail::check_prefetch_AS<AddressSpace> &&
158  is_property_list_v<std::decay_t<Properties>>>
160  Properties properties = {}) {
161  detail::prefetch_impl(ptr.get(), count * sizeof(T), properties);
162 }
163 
164 template <typename DataT, int Dimensions, access_mode AccessMode,
166  typename Properties = empty_properties_t,
167  typename AccessorProperties = empty_properties_t>
168 std::enable_if_t<detail::check_prefetch_acc_mode<AccessMode> &&
169  (Dimensions > 0) &&
170  is_property_list_v<std::decay_t<Properties>>>
172  AccessorProperties>
173  acc,
174  id<Dimensions> offset, Properties properties = {}) {
175  detail::prefetch_impl(&acc[offset], sizeof(DataT), properties);
176 }
177 
178 template <typename DataT, int Dimensions, access_mode AccessMode,
180  typename Properties = empty_properties_t,
181  typename AccessorProperties = empty_properties_t>
182 std::enable_if_t<detail::check_prefetch_acc_mode<AccessMode> &&
183  (Dimensions > 0) &&
184  is_property_list_v<std::decay_t<Properties>>>
186  AccessorProperties>
187  acc,
188  size_t offset, size_t count, Properties properties = {}) {
189  detail::prefetch_impl(&acc[offset], count * sizeof(DataT), properties);
190 }
191 
192 template <typename Group, typename Properties = empty_properties_t>
193 std::enable_if_t<sycl::is_group_v<std::decay_t<Group>> &&
194  is_property_list_v<std::decay_t<Properties>>>
195 joint_prefetch(Group g, void *ptr, Properties properties = {}) {
196  detail::joint_prefetch_impl(g, ptr, 1, properties);
197 }
198 
199 template <typename Group, typename Properties = empty_properties_t>
200 std::enable_if_t<sycl::is_group_v<std::decay_t<Group>> &&
201  is_property_list_v<std::decay_t<Properties>>>
202 joint_prefetch(Group g, void *ptr, size_t bytes, Properties properties = {}) {
203  detail::joint_prefetch_impl(g, ptr, bytes, properties);
204 }
205 
206 template <typename Group, typename T, typename Properties = empty_properties_t>
207 std::enable_if_t<sycl::is_group_v<std::decay_t<Group>> &&
208  is_property_list_v<std::decay_t<Properties>>>
209 joint_prefetch(Group g, T *ptr, Properties properties = {}) {
210  detail::joint_prefetch_impl(g, ptr, sizeof(T), properties);
211 }
212 
213 template <typename Group, typename T, typename Properties = empty_properties_t>
214 std::enable_if_t<sycl::is_group_v<std::decay_t<Group>> &&
215  is_property_list_v<std::decay_t<Properties>>>
216 joint_prefetch(Group g, T *ptr, size_t count, Properties properties = {}) {
217  detail::joint_prefetch_impl(g, ptr, count * sizeof(T), properties);
218 }
219 
220 template <typename Group, access::address_space AddressSpace,
221  access::decorated IsDecorated,
222  typename Properties = empty_properties_t>
223 std::enable_if_t<detail::check_prefetch_AS<AddressSpace> &&
224  sycl::is_group_v<std::decay_t<Group>> &&
225  is_property_list_v<std::decay_t<Properties>>>
227  Properties properties = {}) {
228  detail::joint_prefetch_impl(g, ptr.get(), 1, properties);
229 }
230 
231 template <typename Group, access::address_space AddressSpace,
232  access::decorated IsDecorated,
233  typename Properties = empty_properties_t>
234 std::enable_if_t<detail::check_prefetch_AS<AddressSpace> &&
235  sycl::is_group_v<std::decay_t<Group>> &&
236  is_property_list_v<std::decay_t<Properties>>>
238  size_t bytes, Properties properties = {}) {
239  detail::joint_prefetch_impl(g, ptr.get(), bytes, properties);
240 }
241 
242 template <typename Group, typename T, access::address_space AddressSpace,
243  access::decorated IsDecorated,
244  typename Properties = empty_properties_t>
245 std::enable_if_t<detail::check_prefetch_AS<AddressSpace> &&
246  sycl::is_group_v<std::decay_t<Group>> &&
247  is_property_list_v<std::decay_t<Properties>>>
249  Properties properties = {}) {
250  detail::joint_prefetch_impl(g, ptr.get(), sizeof(T), properties);
251 }
252 
253 template <typename Group, typename T, access::address_space AddressSpace,
254  access::decorated IsDecorated,
255  typename Properties = empty_properties_t>
256 std::enable_if_t<detail::check_prefetch_AS<AddressSpace> &&
257  sycl::is_group_v<std::decay_t<Group>> &&
258  is_property_list_v<std::decay_t<Properties>>>
260  size_t count, Properties properties = {}) {
261  detail::joint_prefetch_impl(g, ptr.get(), count * sizeof(T), properties);
262 }
263 
264 template <typename Group, typename DataT, int Dimensions,
266  typename Properties = empty_properties_t,
267  typename AccessorProperties = empty_properties_t>
268 std::enable_if_t<detail::check_prefetch_acc_mode<AccessMode> &&
269  (Dimensions > 0) && sycl::is_group_v<std::decay_t<Group>> &&
270  is_property_list_v<std::decay_t<Properties>>>
272  accessor<DataT, Dimensions, AccessMode, target::device,
273  IsPlaceholder, AccessorProperties>
274  acc,
275  size_t offset, Properties properties = {}) {
276  detail::joint_prefetch_impl(g, &acc[offset], sizeof(DataT), properties);
277 }
278 
279 template <typename Group, typename DataT, int Dimensions,
281  typename Properties = empty_properties_t,
282  typename AccessorProperties = empty_properties_t>
283 std::enable_if_t<detail::check_prefetch_acc_mode<AccessMode> &&
284  (Dimensions > 0) && sycl::is_group_v<std::decay_t<Group>> &&
285  is_property_list_v<std::decay_t<Properties>>>
287  accessor<DataT, Dimensions, AccessMode, target::device,
288  IsPlaceholder, AccessorProperties>
289  acc,
290  size_t offset, size_t count, Properties properties = {}) {
291  detail::joint_prefetch_impl(g, &acc[offset], count * sizeof(DataT),
292  properties);
293 }
294 
295 } // namespace ext::oneapi::experimental
296 } // namespace _V1
297 } // namespace sycl
A unique identifier of an item in an index space.
Definition: id.hpp:36
void prefetch_impl(T *ptr, size_t bytes, Properties properties)
Definition: prefetch.hpp:71
void joint_prefetch_impl(Group g, T *ptr, size_t bytes, Properties properties)
Definition: prefetch.hpp:93
constexpr prefetch_hint_key::value_t< cache_level::L2, void > prefetch_hint_L2
Definition: prefetch.hpp:35
void prefetch(handler &CGH, void *Ptr, size_t NumBytes)
constexpr prefetch_hint_key::value_t< cache_level::L1, void > prefetch_hint_L1
Definition: prefetch.hpp:33
constexpr prefetch_hint_key::value_t< cache_level::L3, nontemporal > prefetch_hint_L3_nt
Definition: prefetch.hpp:46
constexpr prefetch_hint_key::value_t< cache_level::L2, nontemporal > prefetch_hint_L2_nt
Definition: prefetch.hpp:44
constexpr prefetch_hint_key::value_t< Level, Hint > prefetch_hint
Definition: prefetch.hpp:30
constexpr prefetch_hint_key::value_t< cache_level::L1, nontemporal > prefetch_hint_L1_nt
Definition: prefetch.hpp:42
constexpr prefetch_hint_key::value_t< cache_level::L4, nontemporal > prefetch_hint_L4_nt
Definition: prefetch.hpp:48
constexpr prefetch_hint_key::value_t< cache_level::L3, void > prefetch_hint_L3
Definition: prefetch.hpp:37
constexpr prefetch_hint_key::value_t< cache_level::L4, void > prefetch_hint_L4
Definition: prefetch.hpp:39
decltype(properties{}) empty_properties_t
Definition: properties.hpp:190
std::enable_if_t< sycl::is_group_v< std::decay_t< Group > > &&is_property_list_v< std::decay_t< Properties > > > joint_prefetch(Group g, void *ptr, Properties properties={})
Definition: prefetch.hpp:195
__attribute__((always_inline)) auto invoke_simd(sycl
The invoke_simd free function invokes a SIMD function using all work-items in a sub_group.
class __SYCL_EBO __SYCL_SPECIAL_CLASS Dimensions
constexpr mode_tag_t< access_mode::read_write > read_write
Definition: access.hpp:85
class __SYCL_EBO __SYCL_SPECIAL_CLASS IsPlaceholder
class __SYCL_EBO __SYCL_SPECIAL_CLASS AccessMode
constexpr bool is_group_v
Definition: access.hpp:18
void __spirv_ocl_prefetch(const char *Ptr, size_t NumBytes) noexcept
Definition: spirv_ops.cpp:47