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 
15 #include <sycl/types.hpp>
16 
17 #include <tuple>
18 #include <type_traits>
19 
20 namespace sycl {
22 namespace ext {
23 namespace oneapi {
24 namespace experimental {
25 
26 namespace detail {
27 
28 // Checks if a tuple of properties contains a property.
29 template <typename PropT, typename PropertiesT>
30 struct ContainsProperty : std::false_type {};
31 template <typename PropT, typename T, typename... Ts>
32 struct ContainsProperty<PropT, std::tuple<T, Ts...>>
33  : ContainsProperty<PropT, std::tuple<Ts...>> {};
34 template <typename PropT, typename... Rest>
35 struct ContainsProperty<PropT, std::tuple<PropT, Rest...>> : std::true_type {};
36 template <typename PropT, typename... PropValuesTs, typename... Rest>
38  PropT, std::tuple<property_value<PropT, PropValuesTs...>, Rest...>>
39  : std::true_type {};
40 
41 // Finds the full property_value type of a property in a tuple of properties.
42 // type is void if the type was not found in the tuple of properties.
43 template <typename CTPropertyT, typename PropertiesT = void>
45  using type = void;
46 };
47 template <typename CTPropertyT, typename OtherProperty, typename... Rest>
49  std::tuple<OtherProperty, Rest...>> {
50  using type =
51  typename FindCompileTimePropertyValueType<CTPropertyT,
52  std::tuple<Rest...>>::type;
53 };
54 template <typename CTPropertyT, typename... CTPropertyValueTs, typename... Rest>
56  CTPropertyT,
57  std::tuple<property_value<CTPropertyT, CTPropertyValueTs...>, Rest...>> {
58  using type = property_value<CTPropertyT, CTPropertyValueTs...>;
59 };
60 
61 template <typename CTPropertyT, bool HasProperty, typename PropertiesT = void>
62 static constexpr std::enable_if_t<
63  HasProperty,
66  return {};
67 }
68 
69 template <typename CTPropertyT, bool HasProperty, typename PropertiesT = void>
70 static constexpr std::enable_if_t<!HasProperty, void> get_property() {
71  return;
72 }
73 
74 // Filters for all runtime properties with data in a tuple of properties.
75 // NOTE: We only need storage for runtime properties with data.
76 template <typename T> struct RuntimePropertyStorage {};
77 template <typename... Ts> struct RuntimePropertyStorage<std::tuple<Ts...>> {
78  using type = std::tuple<>;
79 };
80 template <typename T, typename... Ts>
81 struct RuntimePropertyStorage<std::tuple<T, Ts...>>
83  IsRuntimeProperty<T>::value,
84  PrependTuple<
85  T, typename RuntimePropertyStorage<std::tuple<Ts...>>::type>,
86  RuntimePropertyStorage<std::tuple<Ts...>>> {};
87 
88 // Helper class to extract a subset of elements from a tuple.
89 // NOTES: This assumes no duplicate properties and that all properties in the
90 // struct template argument appear in the tuple passed to Extract.
91 template <typename PropertiesT> struct ExtractProperties {};
92 template <typename... PropertiesTs>
93 struct ExtractProperties<std::tuple<PropertiesTs...>> {
94  template <typename... PropertyValueTs>
95  using ExtractedPropertiesT = std::tuple<>;
96 
97  template <typename... PropertyValueTs>
98  static constexpr ExtractedPropertiesT<PropertyValueTs...>
99  Extract(std::tuple<PropertyValueTs...>) {
100  return {};
101  }
102 };
103 template <typename PropertyT, typename... PropertiesTs>
104 struct ExtractProperties<std::tuple<PropertyT, PropertiesTs...>> {
105  template <typename... PropertyValueTs>
107  typename ExtractProperties<std::tuple<PropertiesTs...>>::
108  template ExtractedPropertiesT<PropertyValueTs...>;
109  template <typename... PropertyValueTs>
111  typename PrependTuple<PropertyT,
112  NextExtractedPropertiesT<PropertyValueTs...>>::type;
113 
114  template <typename... PropertyValueTs>
115  static constexpr ExtractedPropertiesT<PropertyValueTs...>
116  Extract(std::tuple<PropertyValueTs...> PropertyValues) {
117  PropertyT ThisExtractedProperty = std::get<PropertyT>(PropertyValues);
118  NextExtractedPropertiesT<PropertyValueTs...> NextExtractedProperties =
119  ExtractProperties<std::tuple<PropertiesTs...>>::template Extract<
120  PropertyValueTs...>(PropertyValues);
121  return std::tuple_cat(std::tuple<PropertyT>{ThisExtractedProperty},
122  NextExtractedProperties);
123  }
124 };
125 
126 } // namespace detail
127 
128 template <typename PropertiesT> class properties {
130  "Properties must be in a tuple.");
132  "Unrecognized property in property list.");
134  "Properties in property list are not sorted.");
135  static_assert(detail::SortedAllUnique<PropertiesT>::value,
136  "Duplicate properties in property list.");
137 
138 public:
139  template <typename... PropertyValueTs>
140  constexpr properties(PropertyValueTs... props)
141  : Storage(detail::ExtractProperties<StorageT>::Extract(
142  std::tuple<PropertyValueTs...>{props...})) {}
143 
144  template <typename PropertyT>
145  static constexpr std::enable_if_t<detail::IsProperty<PropertyT>::value, bool>
148  }
149 
150  template <typename PropertyT>
151  typename std::enable_if_t<detail::IsRuntimeProperty<PropertyT>::value &&
152  has_property<PropertyT>(),
153  PropertyT>
154  get_property() const {
155  return std::get<PropertyT>(Storage);
156  }
157 
158  template <typename PropertyT>
159  typename std::enable_if_t<detail::IsRuntimeProperty<PropertyT>::value &&
160  !has_property<PropertyT>(),
161  void>
162  get_property() const {
163  static_assert(has_property<PropertyT>(),
164  "Property list does not contain the requested property.");
165  return;
166  }
167 
168  template <typename PropertyT>
169  static constexpr auto get_property(
171  * = 0) {
172  static_assert(has_property<PropertyT>(),
173  "Property list does not contain the requested property.");
174  return detail::get_property<PropertyT, has_property<PropertyT>(),
175  PropertiesT>();
176  }
177 
178 private:
180 
181  StorageT Storage;
182 };
183 
184 #ifdef __cpp_deduction_guides
185 // Deduction guides
186 template <typename... PropertyValueTs>
187 properties(PropertyValueTs... props)
188  -> properties<typename detail::Sorted<PropertyValueTs...>::type>;
189 #endif
190 
191 // Property list traits
192 template <typename propertiesT> struct is_property_list : std::false_type {};
193 template <typename... PropertyValueTs>
194 struct is_property_list<properties<std::tuple<PropertyValueTs...>>>
195  : std::is_same<
196  properties<std::tuple<PropertyValueTs...>>,
197  properties<typename detail::Sorted<PropertyValueTs...>::type>> {};
198 
199 #if __cplusplus > 201402L
200 template <typename propertiesT>
201 inline constexpr bool is_property_list_v = is_property_list<propertiesT>::value;
202 #endif
203 
204 namespace detail {
205 // Helper for default properties when deduction guides are not enabled.
207 
208 // Helper for reconstructing a properties type. This assumes that
209 // PropertyValueTs is sorted and contains only valid properties.
210 template <typename... PropertyValueTs>
211 using properties_t = properties<std::tuple<PropertyValueTs...>>;
212 
213 // Helper for merging two property lists;
214 template <typename LHSPropertiesT, typename RHSPropertiesT>
216 template <typename... LHSPropertiesTs, typename... RHSPropertiesTs>
217 struct merged_properties<properties_t<LHSPropertiesTs...>,
218  properties_t<RHSPropertiesTs...>> {
219  using type = properties<typename MergeProperties<
220  std::tuple<LHSPropertiesTs...>, std::tuple<RHSPropertiesTs...>>::type>;
221 };
222 template <typename LHSPropertiesT, typename RHSPropertiesT>
225 
226 } // namespace detail
227 } // namespace experimental
228 } // namespace oneapi
229 } // namespace ext
230 
231 // If property_list is not trivially copyable, allow properties to propagate
232 // is_device_copyable
233 template <typename PropertiesT>
235  ext::oneapi::experimental::properties<PropertiesT>,
236  std::enable_if_t<!std::is_trivially_copyable<
237  ext::oneapi::experimental::properties<PropertiesT>>::value>>
238  : is_device_copyable<PropertiesT> {};
239 template <typename PropertiesT>
241  const ext::oneapi::experimental::properties<PropertiesT>,
242  std::enable_if_t<!std::is_trivially_copyable<
243  const ext::oneapi::experimental::properties<PropertiesT>>::value>>
244  : is_device_copyable<PropertiesT> {};
245 
246 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
247 } // namespace sycl
std::enable_if_t< detail::IsRuntimeProperty< PropertyT >::value &&has_property< PropertyT >), PropertyT > get_property() const
Definition: properties.hpp:154
std::enable_if_t< detail::IsRuntimeProperty< PropertyT >::value &&!has_property< PropertyT >), void > get_property() const
Definition: properties.hpp:162
constexpr properties(PropertyValueTs... props)
Definition: properties.hpp:140
static constexpr auto get_property(typename std::enable_if_t< detail::IsCompileTimeProperty< PropertyT >::value > *=0)
Definition: properties.hpp:169
static constexpr std::enable_if_t< detail::IsProperty< PropertyT >::value, bool > has_property()
Definition: properties.hpp:146
#define __SYCL_INLINE_VER_NAMESPACE(X)
detail::host_half_impl::half StorageT
Definition: half_type.hpp:247
typename std::enable_if< B, T >::type enable_if_t
typename merged_properties< LHSPropertiesT, RHSPropertiesT >::type merged_properties_t
Definition: properties.hpp:224
static constexpr std::enable_if_t<!HasProperty, void > get_property()
Definition: properties.hpp:70
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
static constexpr ExtractedPropertiesT< PropertyValueTs... > Extract(std::tuple< PropertyValueTs... >)
Definition: properties.hpp:99
typename ExtractProperties< std::tuple< PropertiesTs... > >::template ExtractedPropertiesT< PropertyValueTs... > NextExtractedPropertiesT
Definition: properties.hpp:108
static constexpr ExtractedPropertiesT< PropertyValueTs... > Extract(std::tuple< PropertyValueTs... > PropertyValues)
Definition: properties.hpp:116
typename PrependTuple< PropertyT, NextExtractedPropertiesT< PropertyValueTs... > >::type ExtractedPropertiesT
Definition: properties.hpp:112
is_device_copyable is a user specializable class template to indicate that a type T is device copyabl...
Definition: types.hpp:2394