DPC++ Runtime
Runtime libraries for oneAPI DPC++
property.hpp
Go to the documentation of this file.
1 //==---------- properties.hpp --- SYCL extension property tooling ----------==//
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 // HOW-TO: Add new compile-time property
10 // 1. Add a new enumerator to
11 // `sycl::ext::oneapi::experimental::detail::PropKind` representing the new
12 // property. Increment
13 // `sycl::ext::oneapi::experimental::detail::PropKind::PropKindSize`
14 // 2. Define property key class with `value_t` that must be `property_value`
15 // with the first template argument being the property class itself. The
16 // name of the key class must be the property name suffixed by `_key`, i.e.
17 // for a property `foo` the class should be named `foo_key`.
18 // 3. Add an `inline constexpr` variable in the same namespace as the property
19 // key. The variable should have the same type as `value_t` of the property
20 // class, e.g. for a property `foo`, there should be a definition
21 // `inline constexpr foo_key::value_t foo`.
22 // 4. Specialize `sycl::ext::oneapi::experimental::is_property_key` and
23 // `sycl::ext::oneapi::experimental::is_property_key_of` for the property
24 // key class.
25 // 5. Specialize `sycl::ext::oneapi::experimental::detail::PropertyToKind` for
26 // the new property key class. The specialization should have a `Kind`
27 // member with the value equal to the enumerator added in 1.
28 // 6. Specialize
29 // `sycl::ext::oneapi::experimental::detail::IsCompileTimeProperty` for the
30 // new property key class. This specialization should derive from
31 // `std::true_type`.
32 // 7. If the property needs an LLVM IR attribute, specialize
33 // `sycl::ext::oneapi::experimental::detail::PropertyMetaInfo` for the new
34 // `value_t` of the property key class. The specialization must have a
35 // `static constexpr const char *name` member with a value equal to the
36 // expected LLVM IR attribute name. The common naming scheme for these is
37 // the name of the property with "_" replaced with "-" and "sycl-" appended,
38 // for example a property `foo_bar` would have an LLVM IR attribute name
39 // "sycl-foo-bar". Likewise, the specialization must have a `static
40 // constexpr T value` member where `T` is either an integer, a floating
41 // point, a boolean, an enum, a char, or a `const char *`, or a
42 // `std::nullptr_t`. This will be the value of the generated LLVM IR
43 // attribute. If `std::nullptr_t` is used the attribute will not have a
44 // value.
45 /******************************** EXAMPLE **************************************
46 ------------- sycl/include/sycl/ext/oneapi/properties/property.hpp -------------
47 // (1.)
48 enum PropKind : uint32_t {
49  ...
50  Bar,
51  PropKindSize = N + 1, // N was the previous value
52 };
53 ---------------------- path/to/new/property/file.hpp ---------------------------
54 namespace sycl::ext::oneapi::experimental {
55 
56 // (2.)
57 struct bar_key : detail::compile_time_property_key<PropKind::Bar> {
58  using value_t = property_value<bar_key>;
59 };
60 
61 // (3.)
62 inline constexpr bar_key::value_t bar;
63 
64 // (4.)
65 // Replace SYCL_OBJ with the SYCL object to support the property.
66 template <> struct is_property_key_of<bar_key, SYCL_OBJ> : std::true_type {};
67 
68 namespace detail {
69 // (5.)
70 template <> struct PropertyMetaInfo<bar_key::value_t> {
71  static constexpr const char *name = "sycl-bar";
72  static constexpr int value = 5;
73 };
74 
75 } // namespace detail
76 } // namespace sycl::ext::oneapi::experimental
77 *******************************************************************************/
78 
79 // HOW-TO: Add new runtime property
80 // 1. Add a new enumerator to `sycl::ext::oneapi::detail::PropKind`
81 // representing the new property. Increment
82 // `sycl::ext::oneapi::experimental::detail::PropKind::PropKindSize`
83 // 2. Define property class, inheriting from `detail::run_time_property_key`.
84 // 3. Declare the property key as an alias to the property class. The name of
85 // the key class must be the property name suffixed by `_key`, i.e. for a
86 // property `foo` the class should be named `foo_key`.
87 // 4. Overload the `==` and `!=` operators for the new property class. The
88 // comparison should compare all data members of the property class.
89 // 5. Specialize `sycl::ext::oneapi::experimental::is_property_key_of` for the
90 // property class.
91 /******************************* EXAMPLE ***************************************
92 ------------- sycl/include/sycl/ext/oneapi/properties/property.hpp -------------
93 // (1.)
94 enum PropKind : uint32_t {
95  ...
96  Foo,
97  PropKindSize = N + 1, // N was the previous value
98 };
99 ---------------------- path/to/new/property/file.hpp ---------------------------
100 namespace sycl::ext::oneapi::experimental {
101 
102 // (2.)
103 struct foo : detail::run_time_property_key<PropKind::Foo> {
104  foo(int v) : value(v) {}
105  int value;
106 };
107 
108 // 3.
109 using foo_key = foo;
110 
111 // (4.)
112 inline bool operator==(const foo &lhs, const foo &rhs) {
113  return lhs.value == rhs.value;
114 }
115 inline bool operator!=(const foo &lhs, const foo &rhs) {
116  return !(lhs == rhs);
117 }
118 
119 // (5.)
120 // Replace SYCL_OBJ with the SYCL object to support the property.
121 template <> struct is_property_key_of<foo, SYCL_OBJ> : std::true_type {};
122 
123 } // namespace sycl::ext::oneapi::experimental
124 *******************************************************************************/
125 
126 #pragma once
127 
128 #include <iosfwd> // for nullptr_t
129 #include <stdint.h> // for uint32_t
130 #include <type_traits> // for false_type
131 
132 namespace sycl {
133 inline namespace _V1 {
134 namespace ext {
135 namespace oneapi {
136 namespace experimental {
137 namespace detail {
138 
139 // List of all properties.
140 enum PropKind : uint32_t {
143  InitMode = 2,
151  StreamingInterface = 10, // kernel attribute
153  Pipelined = 12,
154  RegisterMap = 13, // kernel argument attribute
155  Conduit = 14,
156  Stable = 15,
158  AddrWidth = 17,
159  DataWidth = 18,
160  Latency = 19,
161  RWMode = 20,
162  MaxBurst = 21,
164  Alignment = 23,
170  UsesValid = 29,
173  GRFSize = 32,
175  Resource = 34,
176  NumBanks = 35,
178  WordSize = 37,
180  Clock2x = 39,
184  Datapath = 43,
188  UsmKind = 47,
193  BuildLog = 52,
196  Balanced = 55,
199  // PropKindSize must always be the last value.
201 };
202 
205 
206 template <PropKind Kind_> struct run_time_property_key : property_key_base_tag {
207 protected:
208  static constexpr PropKind Kind = Kind_;
209 
210  template <typename T>
211  friend struct PropertyToKind;
212 };
213 
214 template <PropKind Kind_>
216 protected:
217  static constexpr PropKind Kind = Kind_;
218 
219  template <typename T>
220  friend struct PropertyToKind;
221 };
222 
223 // This trait must be specialized for all properties and must have a unique
224 // constexpr PropKind member named Kind.
225 template <typename PropertyT> struct PropertyToKind {
226  static constexpr PropKind Kind = PropertyT::Kind;
227 };
228 
229 // Get unique ID for property.
230 template <typename PropertyT> struct PropertyID {
231  static constexpr int value =
232  static_cast<int>(PropertyToKind<PropertyT>::Kind);
233 };
234 
235 // Trait for identifying runtime properties.
236 template <typename PropertyT>
238  : std::bool_constant<
239  std::is_base_of_v<property_key_base_tag, PropertyT> &&
240  !std::is_base_of_v<compile_time_property_key_base_tag, PropertyT>> {};
241 
242 // Trait for identifying compile-time properties.
243 template <typename PropertyT>
245  : std::bool_constant<
246  std::is_base_of_v<property_key_base_tag, PropertyT> &&
247  std::is_base_of_v<compile_time_property_key_base_tag, PropertyT>> {};
248 
249 // Trait for property compile-time meta names and values.
250 template <typename PropertyT> struct PropertyMetaInfo {
251  // Some properties don't have meaningful compile-time values.
252  // Default to empty, as those will be ignored anyway.
253  static constexpr const char *name = "";
254  static constexpr std::nullptr_t value = nullptr;
255 };
256 
257 } // namespace detail
258 
259 template <typename T>
261  : std::bool_constant<std::is_base_of_v<detail::property_key_base_tag, T>> {
262 };
263 template <typename, typename> struct is_property_key_of : std::false_type {};
264 
265 } // namespace experimental
266 } // namespace oneapi
267 } // namespace ext
268 } // namespace _V1
269 } // namespace sycl
Definition: access.hpp:18