DPC++ Runtime
Runtime libraries for oneAPI DPC++
memory_properties.hpp
Go to the documentation of this file.
1 //==-- memory_properties.hpp - ESIMD memory properties ---------------------==//
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 
16 #include <utility>
17 
18 #define SYCL_EXT_INTEL_ESIMD_MEMORY_PROPERTIES 1
19 
20 namespace sycl {
21 inline namespace _V1 {
22 namespace ext::intel::esimd {
23 
25 enum class cache_level : uint8_t { L1 = 1, L2 = 2, L3 = 3 };
26 
28 enum class cache_hint : uint8_t {
29  none = 0,
31  uncached = 1,
32 
33  // load: cache data to cache;
34  cached = 2,
35 
39  write_back = 3,
40 
43  write_through = 4,
44 
50  streaming = 5,
51 
56  read_invalidate = 6,
57 
58  // TODO: Implement the verification of this enum in check_cache_hint().
64  const_cached = 7
65 };
66 
67 template <typename PropertiesT>
69  : public sycl::ext::oneapi::experimental::properties<PropertiesT> {
70 public:
71  template <typename... PropertyValueTs>
72  constexpr properties(PropertyValueTs... props)
73  : sycl::ext::oneapi::experimental::properties<PropertiesT>(props...) {}
74 };
75 
76 #ifdef __cpp_deduction_guides
77 // Deduction guides
78 template <typename... PropertyValueTs>
79 properties(PropertyValueTs... props)
81  PropertyValueTs...>::type>;
82 #endif
83 
86 //
90 //
95 
97 
98 template <int K> inline constexpr alignment_key::value_t<K> alignment;
99 
109  oneapi::experimental::detail::PropKind::ESIMDL1CacheHint> {
110  template <cache_hint Hint>
112  cache_hint_L1_key, std::integral_constant<cache_hint, Hint>>;
113 };
116  oneapi::experimental::detail::PropKind::ESIMDL2CacheHint> {
117  template <cache_hint Hint>
119  cache_hint_L2_key, std::integral_constant<cache_hint, Hint>>;
120 };
123  oneapi::experimental::detail::PropKind::ESIMDL3CacheHint> {
124  template <cache_hint Hint>
126  cache_hint_L3_key, std::integral_constant<cache_hint, Hint>>;
127 };
128 
129 template <cache_hint Hint>
131 template <cache_hint Hint>
133 template <cache_hint Hint>
135 
136 #if 0
137 // TODO: Introduce the 2-parameter cache_hint property after looking
138 // for a better name for it. It cannot be 'esimd::cache_hint' because that
139 // may conflict with the enum name 'experimental::esimd::cache_hint' when
140 // both namespaces (esimd and experimental::esimd) are imported with 'using'
141 // statement.
142 // Naming alternatives: 'esimd::esimd_cache_hint, esimd::cache_hint_L,
143 // esimd::cache_hint_property'.
144 template <cache_level Level, cache_hint Hint>
145 inline constexpr std::conditional_t<
147  std::conditional_t<Level == cache_level::L2,
150  cache_hint; // Get a non-conflicting name
151 #endif
152 
156 
157 namespace detail {
158 
159 template <typename PropsT>
161 
162 template <typename PropsT>
164 
168 template <typename PropertiesT, typename KeyT, typename KeyValueT,
169  typename = std::enable_if_t<is_property_list_v<PropertiesT>>>
170 constexpr auto getPropertyValue(KeyValueT DefaultValue) {
171  if constexpr (!PropertiesT::template has_property<KeyT>()) {
172  return DefaultValue;
173  } else if constexpr (std::is_same_v<KeyT, cache_hint_L1_key> ||
174  std::is_same_v<KeyT, cache_hint_L2_key> ||
175  std::is_same_v<KeyT, cache_hint_L3_key>) {
176  constexpr auto ValueT = PropertiesT::template get_property<KeyT>();
177  return ValueT.hint;
178  } else {
179  constexpr auto ValueT = PropertiesT::template get_property<KeyT>();
180  return ValueT.value;
181  }
182 }
183 
186 template <typename PropertiesT> struct get_ext_oneapi_properties;
187 template <typename PropertiesT>
189  ext::oneapi::experimental::properties<PropertiesT>> {
191 };
192 template <typename PropertiesT>
193 struct get_ext_oneapi_properties<properties<PropertiesT>> {
195 };
196 
198 template <typename PropertyListT, size_t Alignment, bool HasAlignment = true>
200  using type = PropertyListT;
201 };
204 template <typename PropertyListT, size_t Alignment>
205 struct add_alignment_property_helper<PropertyListT, Alignment, false> {
211 
212  using type =
215 };
216 
217 // Creates and adds a compile-time property 'alignment<Alignment>' if
218 // the given property list 'PropertyListT' does not yet have the 'alignment'
219 // property in it.
220 template <typename PropertyListT, size_t Alignment>
222  using ExpPropertyListT =
224 
225 public:
227  ExpPropertyListT, Alignment,
228  ExpPropertyListT::template has_property<alignment_key>()>::type;
229 };
230 template <typename PropertyListT, size_t Alignment>
233 
234 // Removes the 'alignment' property from 'PropertyListT' if it is there.
235 // Otherwise, keeps the 'PropertyListT' without changes.
236 template <typename PropertyListT> struct remove_alignment_property {
237  using type = PropertyListT;
238 };
239 template <size_t Alignment, typename... LastTs>
241  properties<std::tuple<alignment_key::value_t<Alignment>, LastTs...>>> {
242  using type = properties<std::tuple<LastTs...>>;
243 };
244 template <typename FirstT, size_t Alignment, typename... LastTs>
246  std::tuple<FirstT, alignment_key::value_t<Alignment>, LastTs...>>> {
247  using type = properties<std::tuple<FirstT, LastTs...>>;
248 };
249 template <typename PropertyListT>
252 
253 // Creates and adds a compile-time property 'alignment<Alignment>' to the given
254 // property list 'PropertyListT'. If 'alignment' property was already in
255 // 'PropertyListT', then it is replaced with a new one - `alignment<Alignment>`.
256 template <typename PropertyListT, size_t Alignment>
258  using type =
260  Alignment>;
261 };
262 template <typename PropertyListT, size_t Alignment>
265 
266 // Creates the type for the list of L1, L2, and alignment properties.
267 template <cache_hint L1H, cache_hint L2H, size_t Alignment>
272 };
273 template <cache_hint L1H, cache_hint L2H, size_t Alignment>
276 
277 // Creates the type for the list of L1 and L2 properties.
278 template <cache_hint L1H, cache_hint L2H> struct make_L1_L2_properties {
281 };
282 template <cache_hint L1H, cache_hint L2H>
284 
285 } // namespace detail
286 } // namespace ext::intel::esimd
287 
288 namespace ext::oneapi::experimental {
289 
290 template <__ESIMD_NS::cache_hint Hint>
291 struct property_value<__ESIMD_NS::cache_hint_L1_key,
292  std::integral_constant<__ESIMD_NS::cache_hint, Hint>> {
293  using key_t = __ESIMD_NS::cache_hint_L1_key;
294  static constexpr __ESIMD_NS::cache_level level = __ESIMD_NS::cache_level::L1;
295  static constexpr __ESIMD_NS::cache_hint hint = Hint;
296 };
297 template <__ESIMD_NS::cache_hint Hint>
298 struct property_value<__ESIMD_NS::cache_hint_L2_key,
299  std::integral_constant<__ESIMD_NS::cache_hint, Hint>> {
300  using key_t = __ESIMD_NS::cache_hint_L2_key;
301  static constexpr __ESIMD_NS::cache_level level = __ESIMD_NS::cache_level::L2;
302  static constexpr __ESIMD_NS::cache_hint hint = Hint;
303 };
304 template <__ESIMD_NS::cache_hint Hint>
305 struct property_value<__ESIMD_NS::cache_hint_L3_key,
306  std::integral_constant<__ESIMD_NS::cache_hint, Hint>> {
307  using key_t = __ESIMD_NS::cache_hint_L3_key;
308  static constexpr __ESIMD_NS::cache_level level = __ESIMD_NS::cache_level::L3;
309  static constexpr __ESIMD_NS::cache_hint hint = Hint;
310 };
311 
312 // Declare that esimd::properties is a property_list.
313 template <typename... PropertyValueTs>
314 struct is_property_list<__ESIMD_NS::properties<std::tuple<PropertyValueTs...>>>
315  : is_property_list<properties<std::tuple<PropertyValueTs...>>> {};
316 
317 namespace detail {
318 // We do not override the class ConflictingProperties for cache_hint properties
319 // because that mechanism would only allow to verify few obvious restrictions
320 // without the knowledge of the context in which the cache_hint properties are
321 // used (load, store, prefetch, atomic). Thus the function
322 // __ESIMD_DNS::check_cache_hint() is used to verify correctness of properties.
323 } // namespace detail
324 } // namespace ext::oneapi::experimental
325 } // namespace _V1
326 } // namespace sycl
typename add_alignment_property_helper< ExpPropertyListT, Alignment, ExpPropertyListT::template has_property< alignment_key >()>::type type
constexpr properties(PropertyValueTs... props)
typename make_L1_L2_alignment_properties< L1H, L2H, Alignment >::type make_L1_L2_alignment_properties_t
typename add_or_replace_alignment_property< PropertyListT, Alignment >::type add_or_replace_alignment_property_t
typename make_L1_L2_properties< L1H, L2H >::type make_L1_L2_properties_t
constexpr auto getPropertyValue(KeyValueT DefaultValue)
Helper-function that returns the value of the compile time property KeyT if PropertiesT includes it.
typename add_alignment_property< PropertyListT, Alignment >::type add_alignment_property_t
typename remove_alignment_property< PropertyListT >::type remove_alignment_property_t
constexpr alignment_key::value_t< K > alignment
cache_level
L1, L2 or L3 cache hint levels. L3 is reserved for future use.
cache_hint
L1, L2 or L3 cache hints.
@ read_invalidate
load: asserts that the cache line containing the data will not be read again until it’s overwritten,...
@ const_cached
load, L2 cache only, next gen GPU after Xe required: asserts that the L2 cache line containing the da...
@ write_through
store: immediately write data to the subsequent furthest cache, marking the cache line in the current...
@ write_back
store: write data into cache level and mark the cache line as "dirty".
@ streaming
load: cache data to cache using the evict-first policy to minimize cache pollution caused by temporar...
@ uncached
load/store/atomic: do not cache data to cache;
constexpr cache_hint_L3_key::value_t< Hint > cache_hint_L3
constexpr cache_hint_L2_key::value_t< Hint > cache_hint_L2
constexpr cache_hint_L1_key::value_t< Hint > cache_hint_L1
sycl::ext::oneapi::experimental::alignment_key alignment_key
The 'alignment' property is used to specify the alignment of memory accessed in ESIMD memory operatio...
typename merged_properties< LHSPropertiesT, RHSPropertiesT >::type merged_properties_t
Definition: properties.hpp:225
Definition: access.hpp:18
The 'cache_hint_L1', 'cache_hint_L2' and 'cache_hint_L3' properties are used to specify L1,...
typename ext::oneapi::experimental::detail::properties_t< alignment_key::value_t< Alignment > > AlignmentPropList
ext::oneapi::experimental::detail::merged_properties_t< ExpPropertyListT, AlignmentPropList > type
Simply returns 'PropertyListT' as it already has the alignment property.
add_alignment_property_t< remove_alignment_property_t< PropertyListT >, Alignment > type
This helper returns the ext::oneapi::experimental::properties class for ext::oneapi::experimental::pr...