6363
6464#pragma once
6565
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
6771
6872namespace sycl {
6973inline namespace _V1 {
7074namespace 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+
71133template <typename ... Ts>
72134inline constexpr bool builtin_same_shape_v =
73135 ((... && is_scalar_arithmetic_v<Ts>) || (... && is_marray_v<Ts>) ||
@@ -80,6 +142,23 @@ inline constexpr bool builtin_same_or_swizzle_v =
80142 // Use builtin_same_shape_v to filter out types unrelated to builtins.
81143 builtin_same_shape_v<Ts...> && all_same_v<simplify_if_swizzle_t <Ts>...>;
82144
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+
83162namespace builtins {
84163#ifdef __SYCL_DEVICE_ONLY__
85164template <typename T> auto convert_arg (T &&x) {
0 commit comments