DPC++ Runtime
Runtime libraries for oneAPI DPC++
properties.hpp
Go to the documentation of this file.
1 //==---------- properties.hpp --- SYCL extended property list --------------==//
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/ext/oneapi/properties/property.hpp> // for IsRuntimePr...
12 #include <sycl/ext/oneapi/properties/property_utils.hpp> // for Sorted, Mer...
13 #include <sycl/ext/oneapi/properties/property_value.hpp> // for property_value
14 #include <sycl/types.hpp> // for is_device_c...
15 
16 #include <tuple> // for tuple, tupl...
17 #include <type_traits> // for enable_if_t
18 #include <variant> // for tuple
19 
20 namespace sycl {
21 inline namespace _V1 {
22 namespace ext::oneapi::experimental {
23 
24 namespace detail {
25 
26 // Checks if a tuple of properties contains a property.
27 template <typename PropT, typename PropertiesT>
28 struct ContainsProperty : std::false_type {};
29 template <typename PropT, typename T, typename... Ts>
30 struct ContainsProperty<PropT, std::tuple<T, Ts...>>
31  : ContainsProperty<PropT, std::tuple<Ts...>> {};
32 template <typename PropT, typename... Rest>
33 struct ContainsProperty<PropT, std::tuple<PropT, Rest...>> : std::true_type {};
34 template <typename PropT, typename... PropValuesTs, typename... Rest>
36  PropT, std::tuple<property_value<PropT, PropValuesTs...>, Rest...>>
37  : std::true_type {};
38 
39 // Finds the full property_value type of a property in a tuple of properties.
40 // type is void if the type was not found in the tuple of properties.
41 template <typename CTPropertyT, typename PropertiesT = void>
43  using type = void;
44 };
45 template <typename CTPropertyT, typename OtherProperty, typename... Rest>
47  std::tuple<OtherProperty, Rest...>> {
48  using type =
49  typename FindCompileTimePropertyValueType<CTPropertyT,
50  std::tuple<Rest...>>::type;
51 };
52 template <typename CTPropertyT, typename... CTPropertyValueTs, typename... Rest>
54  CTPropertyT,
55  std::tuple<property_value<CTPropertyT, CTPropertyValueTs...>, Rest...>> {
56  using type = property_value<CTPropertyT, CTPropertyValueTs...>;
57 };
58 
59 template <typename CTPropertyT, bool HasProperty, typename PropertiesT = void>
60 static constexpr std::enable_if_t<
64  return {};
65 }
66 
67 template <typename CTPropertyT, bool HasProperty, typename PropertiesT = void>
68 static constexpr std::enable_if_t<!HasProperty, void> get_property() {
69  return;
70 }
71 
72 // Filters for all runtime properties with data in a tuple of properties.
73 // NOTE: We only need storage for runtime properties with data.
74 template <typename T> struct RuntimePropertyStorage {};
75 template <typename... Ts> struct RuntimePropertyStorage<std::tuple<Ts...>> {
76  using type = std::tuple<>;
77 };
78 template <typename T, typename... Ts>
79 struct RuntimePropertyStorage<std::tuple<T, Ts...>>
80  : std::conditional_t<IsRuntimeProperty<T>::value,
81  PrependTuple<T, typename RuntimePropertyStorage<
82  std::tuple<Ts...>>::type>,
83  RuntimePropertyStorage<std::tuple<Ts...>>> {};
84 
85 // Helper class to extract a subset of elements from a tuple.
86 // NOTES: This assumes no duplicate properties and that all properties in the
87 // struct template argument appear in the tuple passed to Extract.
88 template <typename PropertiesT> struct ExtractProperties {};
89 template <typename... PropertiesTs>
90 struct ExtractProperties<std::tuple<PropertiesTs...>> {
91  template <typename... PropertyValueTs>
92  using ExtractedPropertiesT = std::tuple<>;
93 
94  template <typename... PropertyValueTs>
95  static constexpr ExtractedPropertiesT<PropertyValueTs...>
96  Extract(std::tuple<PropertyValueTs...>) {
97  return {};
98  }
99 };
100 template <typename PropertyT, typename... PropertiesTs>
101 struct ExtractProperties<std::tuple<PropertyT, PropertiesTs...>> {
102  template <typename... PropertyValueTs>
104  typename ExtractProperties<std::tuple<PropertiesTs...>>::
105  template ExtractedPropertiesT<PropertyValueTs...>;
106  template <typename... PropertyValueTs>
108  typename PrependTuple<PropertyT,
109  NextExtractedPropertiesT<PropertyValueTs...>>::type;
110 
111  template <typename... PropertyValueTs>
112  static constexpr ExtractedPropertiesT<PropertyValueTs...>
113  Extract(std::tuple<PropertyValueTs...> PropertyValues) {
114  PropertyT ThisExtractedProperty = std::get<PropertyT>(PropertyValues);
115  NextExtractedPropertiesT<PropertyValueTs...> NextExtractedProperties =
116  ExtractProperties<std::tuple<PropertiesTs...>>::template Extract<
117  PropertyValueTs...>(PropertyValues);
118  return std::tuple_cat(std::tuple<PropertyT>{ThisExtractedProperty},
119  NextExtractedProperties);
120  }
121 };
122 
123 } // namespace detail
124 
125 template <typename PropertiesT> class properties {
127  "Properties must be in a tuple.");
129  "Unrecognized property in property list.");
131  "Properties in property list are not sorted.");
132  static_assert(detail::SortedAllUnique<PropertiesT>::value,
133  "Duplicate properties in property list.");
134  static_assert(detail::NoConflictingProperties<PropertiesT>::value,
135  "Conflicting properties in property list.");
136 
137 public:
138  template <typename... PropertyValueTs>
139  constexpr properties(PropertyValueTs... props)
140  : Storage(detail::ExtractProperties<StorageT>::Extract(
141  std::tuple<PropertyValueTs...>{props...})) {}
142 
143  template <typename PropertyT>
144  static constexpr std::enable_if_t<detail::IsProperty<PropertyT>::value, bool>
147  }
148 
149  template <typename PropertyT>
150  typename std::enable_if_t<detail::IsRuntimeProperty<PropertyT>::value &&
151  has_property<PropertyT>(),
152  PropertyT>
153  get_property() const {
154  return std::get<PropertyT>(Storage);
155  }
156 
157  template <typename PropertyT>
158  typename std::enable_if_t<detail::IsRuntimeProperty<PropertyT>::value &&
159  !has_property<PropertyT>(),
160  void>
161  get_property() const {
162  static_assert(has_property<PropertyT>(),
163  "Property list does not contain the requested property.");
164  return;
165  }
166 
167  template <typename PropertyT>
168  static constexpr auto get_property(
169  typename std::enable_if_t<detail::IsCompileTimeProperty<PropertyT>::value>
170  * = 0) {
171  static_assert(has_property<PropertyT>(),
172  "Property list does not contain the requested property.");
173  return detail::get_property<PropertyT, has_property<PropertyT>(),
174  PropertiesT>();
175  }
176 
177 private:
178  using StorageT = typename detail::RuntimePropertyStorage<PropertiesT>::type;
179 
180  StorageT Storage;
181 };
182 
183 #ifdef __cpp_deduction_guides
184 // Deduction guides
185 template <typename... PropertyValueTs>
186 properties(PropertyValueTs... props)
187  -> properties<typename detail::Sorted<PropertyValueTs...>::type>;
188 #endif
189 
190 using empty_properties_t = decltype(properties{});
191 
192 // Property list traits
193 template <typename propertiesT> struct is_property_list : std::false_type {};
194 template <typename... PropertyValueTs>
195 struct is_property_list<properties<std::tuple<PropertyValueTs...>>>
196  : std::is_same<
197  properties<std::tuple<PropertyValueTs...>>,
198  properties<typename detail::Sorted<PropertyValueTs...>::type>> {};
199 
200 #if __cplusplus > 201402L
201 template <typename propertiesT>
202 inline constexpr bool is_property_list_v = is_property_list<propertiesT>::value;
203 #endif
204 
205 namespace detail {
206 // Helper for default properties when deduction guides are not enabled.
208 
209 // Helper for reconstructing a properties type. This assumes that
210 // PropertyValueTs is sorted and contains only valid properties.
211 template <typename... PropertyValueTs>
212 using properties_t = properties<std::tuple<PropertyValueTs...>>;
213 
214 // Helper for merging two property lists;
215 template <typename LHSPropertiesT, typename RHSPropertiesT>
217 template <typename... LHSPropertiesTs, typename... RHSPropertiesTs>
218 struct merged_properties<properties_t<LHSPropertiesTs...>,
219  properties_t<RHSPropertiesTs...>> {
220  using type = properties<typename MergeProperties<
221  std::tuple<LHSPropertiesTs...>, std::tuple<RHSPropertiesTs...>>::type>;
222 };
223 template <typename LHSPropertiesT, typename RHSPropertiesT>
226 
227 template <typename Properties, typename PropertyKey, typename Cond = void>
229  template <typename ValT> static constexpr ValT get(ValT Default) {
230  return Default;
231  }
232 };
233 
234 template <typename Properties, typename PropertyKey>
236  Properties, PropertyKey,
237  std::enable_if_t<is_property_list_v<Properties> &&
238  Properties::template has_property<PropertyKey>()>> {
239  template <typename ValT> static constexpr ValT get(ValT) {
240  return Properties::template get_property<PropertyKey>().value;
241  }
242 };
243 
244 template <typename SyclT, typename PropertiesT> struct all_props_are_keys_of;
245 
246 template <typename SyclT, typename PropertiesT>
247 struct all_props_are_keys_of : std::true_type {};
248 
249 template <typename SyclT>
252  : std::true_type {};
253 
254 template <typename SyclT, typename PropT>
256  SyclT, ext::oneapi::experimental::properties<std::tuple<PropT>>>
257  : std::bool_constant<
258  ext::oneapi::experimental::is_property_key_of<PropT, SyclT>::value> {
259 };
260 
261 template <typename SyclT, typename PropT, typename... PropTs>
263  SyclT, ext::oneapi::experimental::properties<std::tuple<PropT, PropTs...>>>
264  : std::bool_constant<
265  ext::oneapi::experimental::is_property_key_of<PropT, SyclT>::value &&
266  all_props_are_keys_of<SyclT, PropTs...>()> {};
267 
268 } // namespace detail
269 } // namespace ext::oneapi::experimental
270 
271 template <typename PropertiesT>
272 struct is_device_copyable<ext::oneapi::experimental::properties<PropertiesT>>
273  : is_device_copyable<PropertiesT> {};
274 } // namespace _V1
275 } // namespace sycl
std::enable_if_t< detail::IsRuntimeProperty< PropertyT >::value &&has_property< PropertyT >), PropertyT > get_property() const
Definition: properties.hpp:153
std::enable_if_t< detail::IsRuntimeProperty< PropertyT >::value &&!has_property< PropertyT >), void > get_property() const
Definition: properties.hpp:161
constexpr properties(PropertyValueTs... props)
Definition: properties.hpp:139
static constexpr auto get_property(typename std::enable_if_t< detail::IsCompileTimeProperty< PropertyT >::value > *=0)
Definition: properties.hpp:168
static constexpr std::enable_if_t< detail::IsProperty< PropertyT >::value, bool > has_property()
Definition: properties.hpp:145
static constexpr std::enable_if_t< HasProperty, typename FindCompileTimePropertyValueType< CTPropertyT, PropertiesT >::type > get_property()
Definition: properties.hpp:63
typename merged_properties< LHSPropertiesT, RHSPropertiesT >::type merged_properties_t
Definition: properties.hpp:225
decltype(properties{}) empty_properties_t
Definition: properties.hpp:190
Definition: access.hpp:18
static constexpr ExtractedPropertiesT< PropertyValueTs... > Extract(std::tuple< PropertyValueTs... >)
Definition: properties.hpp:96
typename ExtractProperties< std::tuple< PropertiesTs... > >::template ExtractedPropertiesT< PropertyValueTs... > NextExtractedPropertiesT
Definition: properties.hpp:105
static constexpr ExtractedPropertiesT< PropertyValueTs... > Extract(std::tuple< PropertyValueTs... > PropertyValues)
Definition: properties.hpp:113
typename PrependTuple< PropertyT, NextExtractedPropertiesT< PropertyValueTs... > >::type ExtractedPropertiesT
Definition: properties.hpp:109
is_device_copyable is a user specializable class template to indicate that a type T is device copyabl...
Definition: types.hpp:2778