DPC++ Runtime
Runtime libraries for oneAPI DPC++
type_traits.hpp
Go to the documentation of this file.
1 //==----------------- type_traits.hpp - SYCL type traits -------------------==//
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/access/access.hpp> // for decorated, address_space
12 #include <sycl/detail/generic_type_lists.hpp> // for vec, marray, integer_list
13 #include <sycl/detail/type_list.hpp> // for is_contained, find_twi...
14 #include <sycl/half_type.hpp> // for half
15 
16 #include <array> // for array
17 #include <cstddef> // for size_t
18 #include <tuple> // for tuple
19 #include <type_traits> // for true_type, false_type
20 
21 namespace sycl {
22 inline namespace _V1 {
23 namespace detail {
24 template <class T> struct is_fixed_size_group : std::false_type {};
25 
26 template <class T>
28 
29 template <typename VecT, typename OperationLeftT, typename OperationRightT,
30  template <typename> class OperationCurrentT, int... Indexes>
31 class SwizzleOp;
32 } // namespace detail
33 
34 template <int Dimensions> class group;
35 struct sub_group;
36 namespace ext::oneapi {
37 struct sub_group;
38 
39 namespace experimental {
40 template <typename Group, std::size_t Extent> class group_with_scratchpad;
41 
42 template <class T> struct is_fixed_topology_group : std::false_type {};
43 
44 template <class T>
45 inline constexpr bool is_fixed_topology_group_v =
47 
48 template <int Dimensions> class root_group;
49 template <int Dimensions>
50 struct is_fixed_topology_group<root_group<Dimensions>> : std::true_type {};
51 
52 template <int Dimensions>
53 struct is_fixed_topology_group<sycl::group<Dimensions>> : std::true_type {};
54 
55 template <>
56 struct is_fixed_topology_group<sycl::ext::oneapi::sub_group> : std::true_type {
57 };
58 template <> struct is_fixed_topology_group<sycl::sub_group> : std::true_type {};
59 
60 template <class T> struct is_user_constructed_group : std::false_type {};
61 
62 template <class T>
63 inline constexpr bool is_user_constructed_group_v =
65 
66 namespace detail {
67 template <typename T> struct is_group_helper : std::false_type {};
68 
69 template <typename Group, std::size_t Extent>
70 struct is_group_helper<group_with_scratchpad<Group, Extent>> : std::true_type {
71 };
72 } // namespace detail
73 } // namespace experimental
74 } // namespace ext::oneapi
75 
76 namespace detail {
77 
78 template <typename T> struct is_group : std::false_type {};
79 
80 template <int Dimensions>
81 struct is_group<group<Dimensions>> : std::true_type {};
82 
83 template <typename T> struct is_sub_group : std::false_type {};
84 
85 template <> struct is_sub_group<ext::oneapi::sub_group> : std::true_type {};
86 template <> struct is_sub_group<sycl::sub_group> : std::true_type {};
87 
88 template <typename T>
90  : std::integral_constant<bool,
91  is_group<T>::value || is_sub_group<T>::value> {};
92 template <typename T>
94 
95 namespace half_impl {
96 class half;
97 }
98 } // namespace detail
100 
101 // Forward declaration
102 template <typename ElementType, access::address_space Space,
103  access::decorated DecorateAddress>
104 class multi_ptr;
105 
106 template <class T>
107 struct is_group : std::bool_constant<detail::is_group<T>::value ||
108  detail::is_sub_group<T>::value> {};
109 
110 template <class T> inline constexpr bool is_group_v = is_group<T>::value;
111 
112 namespace ext::oneapi::experimental {
113 template <class T>
114 inline constexpr bool is_group_helper_v =
116 } // namespace ext::oneapi::experimental
117 
118 namespace detail {
119 // Type for Intel device UUID extension.
120 // For details about this extension, see
121 // sycl/doc/extensions/supported/sycl_ext_intel_device_info.md
122 using uuid_type = std::array<unsigned char, 16>;
123 
124 template <typename T, typename R> struct copy_cv_qualifiers;
125 
126 template <typename T, typename R>
128 
129 template <int V> using int_constant = std::integral_constant<int, V>;
130 // vector_size
131 // scalars are interpreted as a vector of 1 length.
132 template <typename T> struct vector_size_impl : int_constant<1> {};
133 template <typename T, int N>
134 struct vector_size_impl<vec<T, N>> : int_constant<N> {};
135 template <typename T>
137  : vector_size_impl<std::remove_cv_t<std::remove_reference_t<T>>> {};
138 
139 // vector_element
140 template <typename T> struct vector_element_impl;
141 template <typename T>
143 template <typename T> struct vector_element_impl {
144  using type = T;
145 };
146 template <typename T, int N> struct vector_element_impl<vec<T, N>> {
147  using type = T;
148 };
149 template <typename T> struct vector_element {
150  using type =
152 };
153 template <class T> using vector_element_t = typename vector_element<T>::type;
154 
155 template <class T> using marray_element_t = typename T::value_type;
156 
157 // get_elem_type
158 // Get the element type of T. If T is a scalar, the element type is considered
159 // the type of the scalar.
160 template <typename T, typename = void> struct get_elem_type {
161  using type = T;
162 };
163 template <typename T, size_t N> struct get_elem_type<marray<T, N>> {
164  using type = T;
165 };
166 template <typename T, int N> struct get_elem_type<vec<T, N>> {
167  using type = T;
168 };
169 template <typename VecT, typename OperationLeftT, typename OperationRightT,
170  template <typename> class OperationCurrentT, int... Indexes>
171 struct get_elem_type<SwizzleOp<VecT, OperationLeftT, OperationRightT,
172  OperationCurrentT, Indexes...>> {
174 };
175 
176 template <typename ElementType, access::address_space Space,
177  access::decorated DecorateAddress>
178 struct get_elem_type<multi_ptr<ElementType, Space, DecorateAddress>> {
179  using type = ElementType;
180 };
181 
182 template <typename T, typename = void>
183 struct is_ext_vector : std::false_type {};
184 
185 template <typename T>
187  T, std::void_t<decltype(__builtin_reduce_max(std::declval<T>()))>>
188  : std::true_type {};
189 
190 template <typename T>
191 inline constexpr bool is_ext_vector_v = is_ext_vector<T>::value;
192 
193 template <typename T>
194 struct get_elem_type<T, std::enable_if_t<is_ext_vector_v<T>>> {
195  using type = decltype(__builtin_reduce_max(std::declval<T>()));
196 };
197 
198 template <typename T> using get_elem_type_t = typename get_elem_type<T>::type;
199 
200 // change_base_type_t
201 template <typename T, typename B> struct change_base_type {
202  using type = B;
203 };
204 
205 template <typename T, int N, typename B> struct change_base_type<vec<T, N>, B> {
206  using type = vec<B, N>;
207 };
208 
209 template <typename T, typename B>
211 
212 // Applies the same the cv-qualifiers from T type to R type
213 template <typename T, typename R> struct copy_cv_qualifiers_impl {
214  using type = R;
215 };
216 
217 template <typename T, typename R> struct copy_cv_qualifiers_impl<const T, R> {
218  using type = const R;
219 };
220 
221 template <typename T, typename R>
222 struct copy_cv_qualifiers_impl<volatile T, R> {
223  using type = volatile R;
224 };
225 
226 template <typename T, typename R>
227 struct copy_cv_qualifiers_impl<const volatile T, R> {
228  using type = const volatile R;
229 };
230 
231 template <typename T, typename R> struct copy_cv_qualifiers {
233 };
234 
235 // make_signed with support SYCL vec class
236 template <typename T> struct make_signed {
237  using type = std::make_signed_t<T>;
238 };
239 template <typename T> using make_signed_t = typename make_signed<T>::type;
240 template <class T> struct make_signed<const T> {
241  using type = const make_signed_t<T>;
242 };
243 template <class T, int N> struct make_signed<vec<T, N>> {
245 };
246 template <typename VecT, typename OperationLeftT, typename OperationRightT,
247  template <typename> class OperationCurrentT, int... Indexes>
248 struct make_signed<SwizzleOp<VecT, OperationLeftT, OperationRightT,
249  OperationCurrentT, Indexes...>> {
251 };
252 template <class T, std::size_t N> struct make_signed<marray<T, N>> {
254 };
255 
256 // make_unsigned with support SYCL vec class
257 template <typename T> struct make_unsigned {
258  using type = std::make_unsigned_t<T>;
259 };
260 template <typename T> using make_unsigned_t = typename make_unsigned<T>::type;
261 template <class T> struct make_unsigned<const T> {
262  using type = const make_unsigned_t<T>;
263 };
264 template <class T, int N> struct make_unsigned<vec<T, N>> {
266 };
267 template <typename VecT, typename OperationLeftT, typename OperationRightT,
268  template <typename> class OperationCurrentT, int... Indexes>
269 struct make_unsigned<SwizzleOp<VecT, OperationLeftT, OperationRightT,
270  OperationCurrentT, Indexes...>> {
272 };
273 template <class T, std::size_t N> struct make_unsigned<marray<T, N>> {
275 };
276 
277 // Checks that sizeof base type of T equal N and T satisfies S<T>::value
278 template <typename T, int N, template <typename> class S>
279 inline constexpr bool is_gen_based_on_type_sizeof_v =
280  S<T>::value && (sizeof(vector_element_t<T>) == N);
281 
282 template <typename> struct is_vec : std::false_type {};
283 template <typename T, int N> struct is_vec<sycl::vec<T, N>> : std::true_type {};
284 
285 template <typename T> constexpr bool is_vec_v = is_vec<T>::value;
286 
287 template <typename> struct get_vec_size {
288  static constexpr int size = 1;
289 };
290 
291 template <typename T, int N> struct get_vec_size<sycl::vec<T, N>> {
292  static constexpr int size = N;
293 };
294 
295 // is_marray
296 template <typename> struct is_marray : std::false_type {};
297 template <typename T, size_t N>
298 struct is_marray<sycl::marray<T, N>> : std::true_type {};
299 
300 template <typename T> constexpr bool is_marray_v = is_marray<T>::value;
301 
302 // is_integral
303 template <typename T>
304 struct is_integral : std::is_integral<vector_element_t<T>> {};
305 
306 // is_floating_point
307 template <typename T>
308 struct is_floating_point_impl : std::is_floating_point<T> {};
309 
310 template <> struct is_floating_point_impl<half> : std::true_type {};
311 
312 template <typename T>
314  : is_floating_point_impl<std::remove_cv_t<vector_element_t<T>>> {};
315 
316 // is_arithmetic
317 template <typename T>
319  : std::bool_constant<is_integral<T>::value || is_floating_point<T>::value> {
320 };
321 
322 template <typename T>
324  : std::bool_constant<!is_vec<T>::value && is_arithmetic<T>::value> {};
325 
326 template <typename T>
328 
329 template <typename T>
331  : std::bool_constant<is_vec<T>::value && is_arithmetic<T>::value> {};
332 
333 // is_bool
334 template <typename T>
336  : std::bool_constant<std::is_same_v<std::remove_cv_t<T>, bool>> {};
337 
338 template <typename T>
340  : std::bool_constant<is_vec<T>::value &&
341  is_scalar_bool<vector_element_t<T>>::value> {};
342 
343 template <typename T>
344 struct is_bool
345  : std::bool_constant<is_scalar_bool<vector_element_t<T>>::value> {};
346 
347 // is_boolean
348 template <int N> struct Boolean;
349 template <typename T> struct is_boolean : std::false_type {};
350 template <int N> struct is_boolean<Boolean<N>> : std::true_type {};
351 template <typename T> inline constexpr bool is_boolean_v = is_boolean<T>::value;
352 
353 // is_pointer
354 template <typename T> struct is_pointer_impl : std::false_type {};
355 
356 template <typename T> struct is_pointer_impl<T *> : std::true_type {};
357 
358 template <typename T, access::address_space Space,
359  access::decorated DecorateAddress>
360 struct is_pointer_impl<multi_ptr<T, Space, DecorateAddress>> : std::true_type {
361 };
362 
363 template <typename T>
364 struct is_pointer : is_pointer_impl<std::remove_cv_t<T>> {};
365 
366 template <typename T> inline constexpr bool is_pointer_v = is_pointer<T>::value;
367 
368 // is_multi_ptr
369 template <typename T> struct is_multi_ptr : std::false_type {};
370 
371 template <typename ElementType, access::address_space Space,
372  access::decorated IsDecorated>
373 struct is_multi_ptr<multi_ptr<ElementType, Space, IsDecorated>>
374  : std::true_type {};
375 
376 template <class T>
377 inline constexpr bool is_multi_ptr_v = is_multi_ptr<T>::value;
378 
379 // is_non_legacy_multi_ptr
380 template <typename T> struct is_non_legacy_multi_ptr : std::false_type {};
381 
382 template <typename ElementType, access::address_space Space>
384  multi_ptr<ElementType, Space, access::decorated::yes>> : std::true_type {};
385 
386 template <typename ElementType, access::address_space Space>
388  multi_ptr<ElementType, Space, access::decorated::no>> : std::true_type {};
389 
390 template <class T>
391 inline constexpr bool is_non_legacy_multi_ptr_v =
393 
394 // is_legacy_multi_ptr
395 template <typename T> struct is_legacy_multi_ptr : std::false_type {};
396 
397 template <typename ElementType, access::address_space Space>
399  multi_ptr<ElementType, Space, access::decorated::legacy>> : std::true_type {
400 };
401 
402 template <class T>
404 
405 // remove_pointer_t
406 template <typename T> struct remove_pointer_impl {
407  using type = T;
408 };
409 
410 template <typename T> struct remove_pointer_impl<T *> {
411  using type = T;
412 };
413 
414 template <typename T, access::address_space Space,
415  access::decorated DecorateAddress>
416 struct remove_pointer_impl<multi_ptr<T, Space, DecorateAddress>> {
417  using type = T;
418 };
419 
420 template <typename T>
421 struct remove_pointer : remove_pointer_impl<std::remove_cv_t<T>> {};
422 
423 template <typename T> using remove_pointer_t = typename remove_pointer<T>::type;
424 
425 // is_address_space_compliant
426 template <typename T, typename SpaceList>
427 struct is_address_space_compliant_impl : std::false_type {};
428 
429 template <typename T, typename SpaceList>
430 struct is_address_space_compliant_impl<T *, SpaceList> : std::true_type {};
431 
432 template <typename T, typename SpaceList, access::address_space Space,
433  access::decorated DecorateAddress>
434 struct is_address_space_compliant_impl<multi_ptr<T, Space, DecorateAddress>,
435  SpaceList>
436  : std::bool_constant<is_one_of_spaces<Space, SpaceList>::value> {};
437 
438 template <typename T, typename SpaceList>
440  : is_address_space_compliant_impl<std::remove_cv_t<T>, SpaceList> {};
441 
442 template <typename T, typename SpaceList>
443 inline constexpr bool is_address_space_compliant_v =
445 
446 // make_type_t
447 template <typename T, typename TL> struct make_type_impl {
449 };
450 
451 template <typename T, int N, typename TL> struct make_type_impl<vec<T, N>, TL> {
454 };
455 
456 template <typename T, typename TL>
458 
459 // make_larger_t
460 template <typename T, typename Enable = void> struct make_larger_impl;
461 template <typename T>
463  T, std::enable_if_t<is_contained<T, gtl::scalar_floating_list>::value, T>> {
465 };
466 
467 template <typename T>
469  T, std::enable_if_t<is_contained<T, gtl::scalar_signed_integer_list>::value,
470  T>> {
472 };
473 
474 template <typename T>
476  T, std::enable_if_t<
477  is_contained<T, gtl::scalar_unsigned_integer_list>::value, T>> {
479 };
480 
481 template <typename T, int N> struct make_larger_impl<vec<T, N>, vec<T, N>> {
485  static constexpr bool found = !std::is_same_v<upper_type, void>;
486  using type = std::conditional_t<found, new_type, void>;
487 };
488 
489 template <typename T, size_t N>
490 struct make_larger_impl<marray<T, N>, marray<T, N>> {
494  static constexpr bool found = !std::is_same_v<upper_type, void>;
495  using type = std::conditional_t<found, new_type, void>;
496 };
497 
498 template <typename T> struct make_larger {
500 };
501 
502 template <typename T> using make_larger_t = typename make_larger<T>::type;
503 
504 #if defined(RESTRICT_WRITE_ACCESS_TO_CONSTANT_PTR)
505 template <access::address_space AS, class DataT>
506 using const_if_const_AS =
507  typename std::conditional<AS == access::address_space::constant_space,
508  const DataT, DataT>::type;
509 #else
510 template <access::address_space AS, class DataT>
511 using const_if_const_AS = DataT;
512 #endif
513 
514 template <typename T> struct function_traits {};
515 
516 template <typename Ret, typename... Args> struct function_traits<Ret(Args...)> {
517  using ret_type = Ret;
518  using args_type = std::tuple<Args...>;
519 };
520 
521 // No first_type_t due to
522 // https://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430.
523 template <typename T, typename... Ts> struct first_type {
524  using type = T;
525 };
526 
527 template <typename T0, typename... Ts>
528 inline constexpr bool all_same_v = (... && std::is_same_v<T0, Ts>);
529 
530 // Example usage:
531 // using mapped = map_type<type_to_map, from0, /*->*/ to0,
532 // from1, /*->*/ to1,
533 // ...>
534 template <typename...> struct map_type {
535  using type = void;
536 };
537 
538 template <typename T, typename From, typename To, typename... Rest>
539 struct map_type<T, From, To, Rest...> {
540  using type = std::conditional_t<std::is_same_v<From, T>, To,
541  typename map_type<T, Rest...>::type>;
542 };
543 template <typename T, typename... Ts> constexpr bool CheckTypeIn() {
544  constexpr bool SameType[] = {
545  std::is_same_v<std::remove_cv_t<T>, std::remove_cv_t<Ts>>...};
546  // Replace with std::any_of with C++20.
547  for (size_t I = 0; I < sizeof...(Ts); ++I)
548  if (SameType[I])
549  return true;
550  return false;
551 }
552 
553 // NOTE: We need a constexpr variable definition for the constexpr functions
554 // as MSVC thinks function definitions are the same otherwise.
555 template <typename... Ts> constexpr bool check_type_in_v = CheckTypeIn<Ts...>();
556 
557 } // namespace detail
558 } // namespace _V1
559 } // namespace sycl
Provides a cross-platform math array class template that works on SYCL devices as well as in host C++...
Definition: marray.hpp:48
Provides a cross-patform vector class template that works efficiently on SYCL devices as well as in h...
Definition: types.hpp:284
constexpr bool check_type_in_v
typename change_base_type< T, B >::type change_base_type_t
constexpr bool is_scalar_arithmetic_v
constexpr bool is_pointer_v
constexpr bool is_boolean_v
typename T::value_type marray_element_t
constexpr bool is_marray_v
constexpr bool is_vec_v
constexpr bool is_gen_based_on_type_sizeof_v
constexpr bool is_non_legacy_multi_ptr_v
typename remove_pointer< T >::type remove_pointer_t
typename make_larger< T >::type make_larger_t
typename make_unsigned< T >::type make_unsigned_t
typename vector_element_impl< T >::type vector_element_impl_t
constexpr bool is_address_space_compliant_v
constexpr bool is_ext_vector_v
typename get_elem_type< T >::type get_elem_type_t
constexpr bool all_same_v
constexpr bool is_legacy_multi_ptr_v
constexpr bool CheckTypeIn()
typename vector_element< T >::type vector_element_t
typename copy_cv_qualifiers< T, R >::type copy_cv_qualifiers_t
typename make_signed< T >::type make_signed_t
constexpr bool is_multi_ptr_v
std::array< unsigned char, 16 > uuid_type
find_type_t< TypeList, is_type_size_equal, T > find_same_size_type_t
Definition: type_list.hpp:91
constexpr bool is_fixed_size_group_v
Definition: type_traits.hpp:27
find_type_t< TypeList, is_type_size_double_of, T > find_twice_as_large_type_t
Definition: type_list.hpp:95
std::integral_constant< int, V > int_constant
typename make_type_impl< T, TL >::type make_type_t
constexpr bool is_generic_group_v
Definition: type_traits.hpp:93
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS Dimensions
Definition: accessor.hpp:3233
constexpr bool is_group_v
sycl::detail::half_impl::half half
Definition: aliases.hpp:101
const void value_type
Definition: multi_ptr.hpp:457
Definition: access.hpp:18
typename copy_cv_qualifiers_impl< T, std::remove_cv_t< R > >::type type
typename make_larger_impl< base_type, base_type >::type upper_type
typename make_larger_impl< base_type, base_type >::type upper_type
std::conditional_t< found, new_type, void > type
typename make_larger_impl< T, T >::type type
std::make_signed_t< T > type
typename make_type_impl< T, TL >::type scalar_type
find_same_size_type_t< TL, T > type
std::make_unsigned_t< T > type
std::conditional_t< std::is_same_v< From, T >, To, typename map_type< T, Rest... >::type > type
copy_cv_qualifiers_t< T, vector_element_impl_t< std::remove_cv_t< T > >> type