63
63
64
64
#pragma once
65
65
66
- #include < sycl/builtins_utils_vec.hpp>
66
+ #include < sycl/detail/type_traits.hpp>
67
+ #include < sycl/detail/type_traits/vec_marray_traits.hpp>
68
+ #include < sycl/detail/vector_convert.hpp>
69
+ #include < sycl/marray.hpp> // for marray
70
+ #include < sycl/vector.hpp> // for vec
67
71
68
72
namespace sycl {
69
73
inline namespace _V1 {
70
74
namespace detail {
75
+ #ifdef __FAST_MATH__
76
+ template <typename T>
77
+ struct use_fast_math
78
+ : std::is_same<std::remove_cv_t <get_elem_type_t <T>>, float > {};
79
+ #else
80
+ template <typename > struct use_fast_math : std::false_type {};
81
+ #endif
82
+ template <typename T> constexpr bool use_fast_math_v = use_fast_math<T>::value;
83
+
84
+ // Utility trait for getting the decoration of a multi_ptr.
85
+ template <typename T> struct get_multi_ptr_decoration ;
86
+ template <typename ElementType, access::address_space Space,
87
+ access::decorated DecorateAddress>
88
+ struct get_multi_ptr_decoration <
89
+ multi_ptr<ElementType, Space, DecorateAddress>> {
90
+ static constexpr access::decorated value = DecorateAddress;
91
+ };
92
+
93
+ template <typename T>
94
+ constexpr access::decorated get_multi_ptr_decoration_v =
95
+ get_multi_ptr_decoration<T>::value;
96
+
97
+ // Utility trait for checking if a multi_ptr has a "writable" address space,
98
+ // i.e. global, local, private or generic.
99
+ template <typename T> struct has_writeable_addr_space : std::false_type {};
100
+ template <typename ElementType, access::address_space Space,
101
+ access::decorated DecorateAddress>
102
+ struct has_writeable_addr_space <multi_ptr<ElementType, Space, DecorateAddress>>
103
+ : std::bool_constant<Space == access::address_space::global_space ||
104
+ Space == access::address_space::local_space ||
105
+ Space == access::address_space::private_space ||
106
+ Space == access::address_space::generic_space> {};
107
+
108
+ template <typename T>
109
+ constexpr bool has_writeable_addr_space_v = has_writeable_addr_space<T>::value;
110
+
111
+ // Utility trait for changing the element type of a type T. If T is a scalar,
112
+ // the new type replaces T completely.
113
+ template <typename NewElemT, typename T, typename = void >
114
+ struct change_elements {
115
+ using type = NewElemT;
116
+ };
117
+ template <typename NewElemT, typename T>
118
+ struct change_elements <NewElemT, T, std::enable_if_t <is_marray_v<T>>> {
119
+ using type =
120
+ marray<typename change_elements<NewElemT, typename T::value_type>::type,
121
+ T::size ()>;
122
+ };
123
+ template <typename NewElemT, typename T>
124
+ struct change_elements <NewElemT, T, std::enable_if_t <is_vec_or_swizzle_v<T>>> {
125
+ using type =
126
+ vec<typename change_elements<NewElemT, typename T::element_type>::type,
127
+ T::size ()>;
128
+ };
129
+
130
+ template <typename NewElemT, typename T>
131
+ using change_elements_t = typename change_elements<NewElemT, T>::type;
132
+
71
133
template <typename ... Ts>
72
134
inline constexpr bool builtin_same_shape_v =
73
135
((... && is_scalar_arithmetic_v<Ts>) || (... && is_marray_v<Ts>) ||
@@ -80,6 +142,23 @@ inline constexpr bool builtin_same_or_swizzle_v =
80
142
// Use builtin_same_shape_v to filter out types unrelated to builtins.
81
143
builtin_same_shape_v<Ts...> && all_same_v<simplify_if_swizzle_t <Ts>...>;
82
144
145
+ // Utility functions for converting to/from vec/marray.
146
+ template <class T , size_t N> vec<T, 2 > to_vec2 (marray<T, N> X, size_t Start) {
147
+ return {X[Start], X[Start + 1 ]};
148
+ }
149
+ template <class T , size_t N> vec<T, N> to_vec (marray<T, N> X) {
150
+ vec<T, N> Vec;
151
+ for (size_t I = 0 ; I < N; I++)
152
+ Vec[I] = X[I];
153
+ return Vec;
154
+ }
155
+ template <class T , int N> marray<T, N> to_marray (vec<T, N> X) {
156
+ marray<T, N> Marray;
157
+ for (size_t I = 0 ; I < N; I++)
158
+ Marray[I] = X[I];
159
+ return Marray;
160
+ }
161
+
83
162
namespace builtins {
84
163
#ifdef __SYCL_DEVICE_ONLY__
85
164
template <typename T> auto convert_arg (T &&x) {
0 commit comments