DPC++ Runtime
Runtime libraries for oneAPI DPC++
cache_control_properties.hpp
Go to the documentation of this file.
1 //==--------- SYCL annotated_ptr properties for caching control ------------==//
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 
17 #include <type_traits>
18 
19 namespace sycl {
20 inline namespace _V1 {
21 namespace ext {
22 namespace intel {
23 namespace experimental {
24 
25 // SYCL encodings of read/write control. Definition of cache_mode should match
26 // definition in file CompileTimePropertiesPass.cpp.
27 enum class cache_mode {
28  uncached,
29  cached,
30  streaming,
31  invalidate,
32  constant,
35 };
37 
38 namespace detail {
39 
40 template <int count> static constexpr void checkLevel1() {
41  static_assert(count < 2, "Duplicate cache_level L1 specification");
42 }
43 template <int count> static constexpr void checkLevel2() {
44  static_assert(count < 2, "Duplicate cache_level L2 specification");
45 }
46 template <int count> static constexpr void checkLevel3() {
47  static_assert(count < 2, "Duplicate cache_level L3 specification");
48 }
49 template <int count> static constexpr void checkLevel4() {
50  static_assert(count < 2, "Duplicate cache_level L4 specification");
51 }
52 
53 } // namespace detail
54 
55 template <cache_mode M, cache_level... Ls> struct cache_control {
56  static constexpr const auto mode = M;
57  static constexpr const int countL1 = ((Ls == cache_level::L1 ? 1 : 0) + ...);
58  static constexpr const int countL2 = ((Ls == cache_level::L2 ? 1 : 0) + ...);
59  static constexpr const int countL3 = ((Ls == cache_level::L3 ? 1 : 0) + ...);
60  static constexpr const int countL4 = ((Ls == cache_level::L4 ? 1 : 0) + ...);
61  static constexpr const uint32_t levels = ((1 << static_cast<int>(Ls)) | ...);
62  // Starting bit position for cache levels of a cache mode are uncached=0,
63  // cached=4, streaming=8, invalidate=12, constant=16, write_through=20 and
64  // write_back=24. The shift value is computed as cache_mode * 4.
65  static constexpr const uint32_t encoding =
66  (countL1, countL2, countL3, countL4, detail::checkLevel1<countL1>(),
67  detail::checkLevel2<countL2>(), detail::checkLevel3<countL3>(),
68  detail::checkLevel4<countL4>(), levels << static_cast<int>(M) * 4);
69 };
70 
71 template <typename PropertyT, typename... Ts>
74 
77  oneapi::experimental::detail::PropKind::CacheControlReadHint> {
78  template <typename... Cs>
80 };
81 
84  oneapi::experimental::detail::PropKind::CacheControlReadAssertion> {
85  template <typename... Cs>
87 };
88 
91  oneapi::experimental::detail::PropKind::CacheControlWrite> {
92  template <typename... Cs>
94 };
95 
96 template <typename... Cs>
97 inline constexpr read_hint_key::value_t<Cs...> read_hint;
98 
99 template <typename... Cs>
101 
102 template <typename... Cs>
103 inline constexpr write_hint_key::value_t<Cs...> write_hint;
104 
105 } // namespace experimental
106 } // namespace intel
107 
108 namespace oneapi {
109 namespace experimental {
110 
111 template <typename T, typename PropertyListT> class annotated_ptr;
112 
113 template <typename T, typename PropertyListT>
114 struct is_property_key_of<intel::experimental::read_hint_key,
115  annotated_ptr<T, PropertyListT>> : std::true_type {};
116 
117 template <typename T, typename PropertyListT>
118 struct is_property_key_of<intel::experimental::read_assertion_key,
119  annotated_ptr<T, PropertyListT>> : std::true_type {};
120 
121 template <typename T, typename PropertyListT>
122 struct is_property_key_of<intel::experimental::write_hint_key,
123  annotated_ptr<T, PropertyListT>> : std::true_type {};
124 
125 template <>
126 struct propagateToPtrAnnotation<intel::experimental::read_hint_key>
127  : std::true_type {};
128 template <>
129 struct propagateToPtrAnnotation<intel::experimental::read_assertion_key>
130  : std::true_type {};
131 template <>
132 struct propagateToPtrAnnotation<intel::experimental::write_hint_key>
133  : std::true_type {};
134 
135 namespace detail {
136 
137 // Values assigned to cache levels in a nibble.
138 static constexpr int L1BIT = 1;
139 static constexpr int L2BIT = 2;
140 static constexpr int L3BIT = 4;
141 static constexpr int L4BIT = 8;
142 
143 static constexpr int countL(int levels, int mask) {
144  return levels & mask ? 1 : 0;
145 }
146 
147 template <int countL1, int countL2, int countL3, int countL4>
148 static constexpr void checkUnique() {
149  static_assert(countL1 < 2, "Conflicting cache_mode at L1");
150  static_assert(countL2 < 2, "Conflicting cache_mode at L2");
151  static_assert(countL3 < 2, "Conflicting cache_mode at L3");
152  static_assert(countL4 < 2, "Conflicting cache_mode at L4");
153 }
154 
156 
157 template <cache_mode M> static constexpr int checkReadHint() {
158  static_assert(
159  M == cache_mode::uncached || M == cache_mode::cached ||
160  M == cache_mode::streaming,
161  "read_hint must specify cache_mode uncached, cached or streaming");
162  return 0;
163 }
164 
165 template <cache_mode M> static constexpr int checkReadAssertion() {
166  static_assert(
167  M == cache_mode::invalidate || M == cache_mode::constant,
168  "read_assertion must specify cache_mode invalidate or constant");
169  return 0;
170 }
171 
172 template <cache_mode M> static constexpr int checkWriteHint() {
173  static_assert(M == cache_mode::uncached || M == cache_mode::write_through ||
174  M == cache_mode::write_back || M == cache_mode::streaming,
175  "write_hint must specify cache_mode uncached, write_through, "
176  "write_back or streaming");
177  return 0;
178 }
179 
180 template <typename... Cs>
181 struct PropertyMetaInfo<intel::experimental::read_hint_key::value_t<Cs...>> {
182  static constexpr const char *name = "sycl-cache-read-hint";
183  static constexpr const int value =
184  ((checkReadHint<Cs::mode>() + ...),
185  checkUnique<(countL(Cs::levels, L1BIT) + ...),
186  (countL(Cs::levels, L2BIT) + ...),
187  (countL(Cs::levels, L3BIT) + ...),
188  (countL(Cs::levels, L4BIT) + ...)>(),
189  ((Cs::encoding) | ...));
190 };
191 
192 template <typename... Cs>
194  intel::experimental::read_assertion_key::value_t<Cs...>> {
195  static constexpr const char *name = "sycl-cache-read-assertion";
196  static constexpr const int value =
197  ((checkReadAssertion<Cs::mode>() + ...),
198  checkUnique<(countL(Cs::levels, L1BIT) + ...),
199  (countL(Cs::levels, L2BIT) + ...),
200  (countL(Cs::levels, L3BIT) + ...),
201  (countL(Cs::levels, L4BIT) + ...)>(),
202  ((Cs::encoding) | ...));
203 };
204 
205 template <typename... Cs>
206 struct PropertyMetaInfo<intel::experimental::write_hint_key::value_t<Cs...>> {
207  static constexpr const char *name = "sycl-cache-write-hint";
208  static constexpr const int value =
209  ((checkWriteHint<Cs::mode>() + ...),
210  checkUnique<(countL(Cs::levels, L1BIT) + ...),
211  (countL(Cs::levels, L2BIT) + ...),
212  (countL(Cs::levels, L3BIT) + ...),
213  (countL(Cs::levels, L4BIT) + ...)>(),
214  ((Cs::encoding) | ...));
215 };
216 
217 } // namespace detail
218 
219 template <typename T, typename... Cs>
220 struct is_valid_property<T, intel::experimental::read_hint_key::value_t<Cs...>>
221  : std::bool_constant<std::is_pointer<T>::value> {};
222 
223 template <typename T, typename... Cs>
225  T, intel::experimental::read_assertion_key::value_t<Cs...>>
226  : std::bool_constant<std::is_pointer<T>::value> {};
227 
228 template <typename T, typename... Cs>
229 struct is_valid_property<T, intel::experimental::write_hint_key::value_t<Cs...>>
230  : std::bool_constant<std::is_pointer<T>::value> {};
231 
232 } // namespace experimental
233 } // namespace oneapi
234 } // namespace ext
235 } // namespace _V1
236 } // namespace sycl
sycl::ext::oneapi::experimental::cache_level cache_level
constexpr read_hint_key::value_t< Cs... > read_hint
constexpr write_hint_key::value_t< Cs... > write_hint
constexpr read_assertion_key::value_t< Cs... > read_assertion
sycl::ext::intel::experimental::cache_mode cache_mode
static constexpr int countL(int levels, int mask)
Definition: access.hpp:18