DPC++ Runtime
Runtime libraries for oneAPI DPC++
property_utils.hpp
Go to the documentation of this file.
1 //==-- property_utils.hpp --- SYCL extended property list common utilities -==//
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 
13 
14 #include <tuple>
15 
17 namespace sycl {
18 namespace ext {
19 namespace oneapi {
20 namespace experimental {
21 
22 // Forward declaration
23 template <typename PropertyT, typename T, typename... Ts> struct property_value;
24 
25 namespace detail {
26 
27 //******************************************************************************
28 // Misc
29 //******************************************************************************
30 
31 // Checks if a type is a tuple.
32 template <typename T> struct IsTuple : std::false_type {};
33 template <typename... Ts> struct IsTuple<std::tuple<Ts...>> : std::true_type {};
34 
35 // Gets the first type in a parameter pack of types.
36 template <typename... Ts>
37 using GetFirstType = typename std::tuple_element<0, std::tuple<Ts...>>::type;
38 
39 // Prepends a value to a tuple.
40 template <typename T, typename Tuple> struct PrependTuple {};
41 template <typename T, typename... Ts>
42 struct PrependTuple<T, std::tuple<Ts...>> {
43  using type = std::tuple<T, Ts...>;
44 };
45 
46 // Checks if a type T has a static value member variable.
47 template <typename T, typename U = int> struct HasValue : std::false_type {};
48 template <typename T>
49 struct HasValue<T, decltype((void)T::value, 0)> : std::true_type {};
50 
51 //******************************************************************************
52 // Property identification
53 //******************************************************************************
54 
55 // Checks if a type is a compile-time property values.
56 // Note: This is specialized for property_value elsewhere.
57 template <typename PropertyT>
58 struct IsCompileTimePropertyValue : std::false_type {};
59 
60 // Checks if a type is either a runtime property or if it is a compile-time
61 // property
62 template <typename T> struct IsProperty {
63  static constexpr bool value =
65 };
66 
67 // Checks if a type is a valid property value, i.e either runtime property or
68 // property_value with a valid compile-time property
69 template <typename T> struct IsPropertyValue {
70  static constexpr bool value =
72 };
73 
74 // Checks that all types in a tuple are valid properties.
75 template <typename T> struct AllPropertyValues {};
76 template <typename... Ts>
77 struct AllPropertyValues<std::tuple<Ts...>> : std::true_type {};
78 template <typename T, typename... Ts>
79 struct AllPropertyValues<std::tuple<T, Ts...>>
80  : sycl::detail::conditional_t<IsPropertyValue<T>::value,
81  AllPropertyValues<std::tuple<Ts...>>,
82  std::false_type> {};
83 
84 //******************************************************************************
85 // Property type sorting
86 //******************************************************************************
87 
88 // Splits a tuple into head and tail if ShouldSplit is true. If ShouldSplit is
89 // false the head will be void and the tail will be the full tuple.
90 template <typename T1, bool ShouldSplit> struct HeadSplit {};
91 template <typename T, typename... Ts>
92 struct HeadSplit<std::tuple<T, Ts...>, true> {
93  using htype = T;
94  using ttype = std::tuple<Ts...>;
95 };
96 template <typename... Ts> struct HeadSplit<std::tuple<Ts...>, false> {
97  using htype = void;
98  using ttype = std::tuple<Ts...>;
99 };
100 
101 // Selects the one of two types that is not void. This assumes that at least one
102 // of the two template arguemnts is void.
103 template <typename LHS, typename RHS> struct SelectNonVoid {};
104 template <typename LHS> struct SelectNonVoid<LHS, void> {
105  using type = LHS;
106 };
107 template <typename RHS> struct SelectNonVoid<void, RHS> {
108  using type = RHS;
109 };
110 
111 // Merges two tuples by recursively extracting the type with the minimum
112 // PropertyID in the two tuples and prepending it to the merging of the
113 // remaining elements.
114 template <typename T1, typename T2> struct Merge {};
115 template <typename... LTs> struct Merge<std::tuple<LTs...>, std::tuple<>> {
116  using type = std::tuple<LTs...>;
117 };
118 template <typename... RTs> struct Merge<std::tuple<>, std::tuple<RTs...>> {
119  using type = std::tuple<RTs...>;
120 };
121 template <typename... LTs, typename... RTs>
122 struct Merge<std::tuple<LTs...>, std::tuple<RTs...>> {
123  using l_head = GetFirstType<LTs...>;
124  using r_head = GetFirstType<RTs...>;
125  static constexpr bool left_has_min =
127  using l_split = HeadSplit<std::tuple<LTs...>, left_has_min>;
128  using r_split = HeadSplit<std::tuple<RTs...>, !left_has_min>;
129  using min = typename SelectNonVoid<typename l_split::htype,
130  typename r_split::htype>::type;
131  using merge_tails =
134 };
135 
136 // Creates pairs of tuples with a single element from a tuple with N elements.
137 // Resulting tuple will have ceil(N/2) elements.
138 template <typename...> struct CreateTuplePairs {
139  using type = typename std::tuple<>;
140 };
141 template <typename T> struct CreateTuplePairs<T> {
142  using type = typename std::tuple<std::pair<std::tuple<T>, std::tuple<>>>;
143 };
144 template <typename L, typename R, typename... Rest>
145 struct CreateTuplePairs<L, R, Rest...> {
146  using type =
147  typename PrependTuple<std::pair<std::tuple<L>, std::tuple<R>>,
148  typename CreateTuplePairs<Rest...>::type>::type;
149 };
150 
151 // Merges pairs of tuples and creates new pairs of the merged pairs. Let N be
152 // the number of pairs in the supplied tuple, then the resulting tuple will
153 // contain ceil(N/2) pairs of tuples.
154 template <typename T> struct MergePairs {
155  using type = std::tuple<>;
156 };
157 template <typename... LTs, typename... RTs, typename... Rest>
158 struct MergePairs<
159  std::tuple<std::pair<std::tuple<LTs...>, std::tuple<RTs...>>, Rest...>> {
160  using merged = typename Merge<std::tuple<LTs...>, std::tuple<RTs...>>::type;
161  using type = std::tuple<std::pair<merged, std::tuple<>>>;
162 };
163 template <typename... LLTs, typename... LRTs, typename... RLTs,
164  typename... RRTs, typename... Rest>
165 struct MergePairs<
166  std::tuple<std::pair<std::tuple<LLTs...>, std::tuple<LRTs...>>,
167  std::pair<std::tuple<RLTs...>, std::tuple<RRTs...>>, Rest...>> {
168  using lmerged =
169  typename Merge<std::tuple<LLTs...>, std::tuple<LRTs...>>::type;
170  using rmerged =
171  typename Merge<std::tuple<RLTs...>, std::tuple<RRTs...>>::type;
172  using type = typename PrependTuple<
173  std::pair<lmerged, rmerged>,
174  typename MergePairs<std::tuple<Rest...>>::type>::type;
175 };
176 
177 // Recursively merges all pairs of tuples until only a single pair of tuples
178 // is left, where the right element of the pair is an empty tuple.
179 template <typename T> struct MergeAll {};
180 template <typename... Ts> struct MergeAll<std::tuple<Ts...>> {
181  using type = std::tuple<Ts...>;
182 };
183 template <typename... Ts>
184 struct MergeAll<std::tuple<std::pair<std::tuple<Ts...>, std::tuple<>>>> {
185  using type = std::tuple<Ts...>;
186 };
187 template <typename T, typename... Ts> struct MergeAll<std::tuple<T, Ts...>> {
188  using reduced = typename MergePairs<std::tuple<T, Ts...>>::type;
189  using type = typename MergeAll<reduced>::type;
190 };
191 
192 // Performs merge-sort on types with PropertyID.
193 template <typename... Ts> struct Sorted {
194  static_assert(detail::AllPropertyValues<std::tuple<Ts...>>::value,
195  "Unrecognized property in property list.");
196  using split = typename CreateTuplePairs<Ts...>::type;
197  using type = typename MergeAll<split>::type;
198 };
199 
200 // Checks if the types in a tuple are sorted w.r.t. their PropertyID.
201 template <typename T> struct IsSorted {};
202 template <typename... Ts>
203 struct IsSorted<std::tuple<Ts...>> : std::true_type {};
204 template <typename T> struct IsSorted<std::tuple<T>> : std::true_type {};
205 template <typename L, typename R, typename... Rest>
206 struct IsSorted<std::tuple<L, R, Rest...>>
207  : sycl::detail::conditional_t<PropertyID<L>::value <= PropertyID<R>::value,
208  IsSorted<std::tuple<R, Rest...>>,
209  std::false_type> {};
210 
211 // Checks that all types in a sorted tuple have unique PropertyID.
212 template <typename T> struct SortedAllUnique {};
213 template <typename... Ts>
214 struct SortedAllUnique<std::tuple<Ts...>> : std::true_type {};
215 template <typename T> struct SortedAllUnique<std::tuple<T>> : std::true_type {};
216 template <typename L, typename R, typename... Rest>
217 struct SortedAllUnique<std::tuple<L, R, Rest...>>
218  : sycl::detail::conditional_t<PropertyID<L>::value != PropertyID<R>::value,
219  SortedAllUnique<std::tuple<R, Rest...>>,
220  std::false_type> {};
221 
222 } // namespace detail
223 } // namespace experimental
224 } // namespace oneapi
225 } // namespace ext
226 } // namespace sycl
227 } // __SYCL_INLINE_NAMESPACE(cl)
cl::sycl::ext::oneapi::experimental::detail::AllPropertyValues
Definition: property_utils.hpp:75
cl::sycl::ext::oneapi::experimental::detail::SelectNonVoid< LHS, void >::type
LHS type
Definition: property_utils.hpp:105
cl::sycl::ext::oneapi::experimental::detail::CreateTuplePairs::type
typename std::tuple<> type
Definition: property_utils.hpp:139
cl::sycl::ext::oneapi::experimental::detail::IsPropertyValue
Definition: property_utils.hpp:69
cl::sycl::ext::oneapi::experimental::detail::MergeAll
Definition: property_utils.hpp:179
cl::sycl::ext::oneapi::experimental::detail::MergeAll< std::tuple< T, Ts... > >::type
typename MergeAll< reduced >::type type
Definition: property_utils.hpp:189
cl::sycl::ext::oneapi::experimental::detail::Merge< std::tuple< LTs... >, std::tuple< RTs... > >::l_head
GetFirstType< LTs... > l_head
Definition: property_utils.hpp:123
cl::sycl::ext::oneapi::experimental::detail::HasValue
Definition: property_utils.hpp:47
conditional_t
cl::sycl::ext::oneapi::experimental::detail::MergeAll< std::tuple< std::pair< std::tuple< Ts... >, std::tuple<> > > >::type
std::tuple< Ts... > type
Definition: property_utils.hpp:185
cl::sycl::ext::oneapi::experimental::detail::IsRuntimeProperty
Definition: property.hpp:186
cl::sycl::ext::oneapi::experimental::detail::IsProperty
Definition: property_utils.hpp:62
cl::sycl::ext::oneapi::experimental::detail::HeadSplit< std::tuple< Ts... >, false >::htype
void htype
Definition: property_utils.hpp:97
cl::sycl::ext::oneapi::experimental::detail::Sorted::split
typename CreateTuplePairs< Ts... >::type split
Definition: property_utils.hpp:196
cl::sycl::ext::oneapi::experimental::detail::PropertyID
Definition: property.hpp:180
cl::sycl::ext::oneapi::experimental::detail::SelectNonVoid
Definition: property_utils.hpp:103
sycl
Definition: invoke_simd.hpp:68
cl::sycl::ext::oneapi::experimental::detail::MergePairs< std::tuple< std::pair< std::tuple< LLTs... >, std::tuple< LRTs... > >, std::pair< std::tuple< RLTs... >, std::tuple< RRTs... > >, Rest... > >::type
typename PrependTuple< std::pair< lmerged, rmerged >, typename MergePairs< std::tuple< Rest... > >::type >::type type
Definition: property_utils.hpp:174
cl::sycl::ext::oneapi::experimental::detail::IsCompileTimeProperty
Definition: property.hpp:189
cl::sycl::ext::oneapi::experimental::detail::MergePairs< std::tuple< std::pair< std::tuple< LLTs... >, std::tuple< LRTs... > >, std::pair< std::tuple< RLTs... >, std::tuple< RRTs... > >, Rest... > >::lmerged
typename Merge< std::tuple< LLTs... >, std::tuple< LRTs... > >::type lmerged
Definition: property_utils.hpp:169
cl::sycl::ext::oneapi::experimental::detail::HeadSplit< std::tuple< Ts... >, false >::ttype
std::tuple< Ts... > ttype
Definition: property_utils.hpp:98
cl::sycl::ext::oneapi::experimental::detail::MergePairs< std::tuple< std::pair< std::tuple< LLTs... >, std::tuple< LRTs... > >, std::pair< std::tuple< RLTs... >, std::tuple< RRTs... > >, Rest... > >::rmerged
typename Merge< std::tuple< RLTs... >, std::tuple< RRTs... > >::type rmerged
Definition: property_utils.hpp:171
cl::sycl::ext::oneapi::experimental::detail::Sorted::type
typename MergeAll< split >::type type
Definition: property_utils.hpp:197
cl::sycl::ext::oneapi::experimental::detail::IsTuple
Definition: property_utils.hpp:32
cl::sycl::ext::oneapi::experimental::detail::GetFirstType
typename std::tuple_element< 0, std::tuple< Ts... > >::type GetFirstType
Definition: property_utils.hpp:37
cl::sycl::ext::oneapi::experimental::detail::CreateTuplePairs< T >
Definition: property_utils.hpp:141
cl::sycl::ext::oneapi::experimental::detail::MergeAll< std::tuple< T, Ts... > >::reduced
typename MergePairs< std::tuple< T, Ts... > >::type reduced
Definition: property_utils.hpp:188
cl::sycl::ext::oneapi::experimental::detail::MergePairs::type
std::tuple<> type
Definition: property_utils.hpp:155
cl::sycl::ext::oneapi::experimental::detail::MergePairs< std::tuple< std::pair< std::tuple< LTs... >, std::tuple< RTs... > >, Rest... > >::merged
typename Merge< std::tuple< LTs... >, std::tuple< RTs... > >::type merged
Definition: property_utils.hpp:160
cl::sycl::ext::oneapi::experimental::detail::SelectNonVoid< void, RHS >::type
RHS type
Definition: property_utils.hpp:108
cl::sycl::ext::oneapi::experimental::detail::HeadSplit< std::tuple< T, Ts... >, true >::ttype
std::tuple< Ts... > ttype
Definition: property_utils.hpp:94
cl
We provide new interfaces for matrix muliply in this patch:
Definition: access.hpp:13
cl::sycl::ext::oneapi::experimental::detail::CreateTuplePairs< L, R, Rest... >::type
typename PrependTuple< std::pair< std::tuple< L >, std::tuple< R > >, typename CreateTuplePairs< Rest... >::type >::type type
Definition: property_utils.hpp:148
cl::sycl::ext::oneapi::experimental::detail::Merge< std::tuple< LTs... >, std::tuple< RTs... > >::merge_tails
typename Merge< typename l_split::ttype, typename r_split::ttype >::type merge_tails
Definition: property_utils.hpp:132
cl::sycl::ext::oneapi::experimental::detail::Merge< std::tuple< LTs... >, std::tuple< RTs... > >::r_head
GetFirstType< RTs... > r_head
Definition: property_utils.hpp:124
cl::sycl::ext::oneapi::experimental::detail::MergePairs
Definition: property_utils.hpp:154
cl::sycl::ext::oneapi::experimental::detail::HeadSplit< std::tuple< T, Ts... >, true >::htype
T htype
Definition: property_utils.hpp:93
cl::sycl::ext::oneapi::experimental::detail::Merge< std::tuple<>, std::tuple< RTs... > >::type
std::tuple< RTs... > type
Definition: property_utils.hpp:119
cl::sycl::ext::oneapi::experimental::detail::CreateTuplePairs
Definition: property_utils.hpp:138
property_helper.hpp
cl::sycl::ext::oneapi::experimental::detail::Sorted
Definition: property_utils.hpp:193
cl::sycl::ext::oneapi::experimental::detail::IsCompileTimePropertyValue
Definition: property_utils.hpp:58
cl::sycl::ext::oneapi::experimental::detail::Merge< std::tuple< LTs... >, std::tuple< RTs... > >::type
typename PrependTuple< min, merge_tails >::type type
Definition: property_utils.hpp:133
cl::sycl::detail::tuple
Definition: tuple.hpp:22
cl::sycl::ext::oneapi::experimental::detail::Merge
Definition: property_utils.hpp:114
cl::sycl::ext::oneapi::experimental::detail::MergeAll< std::tuple< Ts... > >::type
std::tuple< Ts... > type
Definition: property_utils.hpp:181
std
Definition: accessor.hpp:2617
cl::sycl::ext::oneapi::experimental::detail::HeadSplit
Definition: property_utils.hpp:90
cl::sycl::ext::oneapi::experimental::detail::CreateTuplePairs< T >::type
typename std::tuple< std::pair< std::tuple< T >, std::tuple<> >> type
Definition: property_utils.hpp:142
cl::sycl::ext::oneapi::experimental::detail::PrependTuple
Definition: property_utils.hpp:40
cl::sycl::ext::oneapi::experimental::detail::IsSorted
Definition: property_utils.hpp:201
property.hpp
cl::sycl::ext::oneapi::experimental::detail::Merge< std::tuple< LTs... >, std::tuple< RTs... > >::min
typename SelectNonVoid< typename l_split::htype, typename r_split::htype >::type min
Definition: property_utils.hpp:130
cl::sycl::ext::oneapi::experimental::detail::PrependTuple< T, std::tuple< Ts... > >::type
std::tuple< T, Ts... > type
Definition: property_utils.hpp:43
cl::sycl::ext::oneapi::experimental::detail::MergePairs< std::tuple< std::pair< std::tuple< LTs... >, std::tuple< RTs... > >, Rest... > >::type
std::tuple< std::pair< merged, std::tuple<> >> type
Definition: property_utils.hpp:161
cl::sycl::ext::oneapi::experimental::detail::Merge< std::tuple< LTs... >, std::tuple<> >::type
std::tuple< LTs... > type
Definition: property_utils.hpp:116
cl::sycl::ext::oneapi::experimental::property_value
Definition: property_utils.hpp:23
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:11