DPC++ Runtime
Runtime libraries for oneAPI DPC++
util.hpp
Go to the documentation of this file.
1 //==----------------- util.hpp - DPC++ Explicit SIMD API ------------------==//
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 // Utility functions used for implementing Explicit SIMD APIs.
9 //===----------------------------------------------------------------------===//
10 
11 #pragma once
12 
14 
17 
18 #include <type_traits>
19 
20 #ifdef __SYCL_DEVICE_ONLY__
21 #define __ESIMD_INTRIN __DPCPP_SYCL_EXTERNAL SYCL_ESIMD_FUNCTION
22 #elif !defined(__ESIMD_BUILD_HOST_CODE)
23 #define __ESIMD_INTRIN ESIMD_NOINLINE __attribute__((internal_linkage))
24 #else
25 #define __ESIMD_INTRIN inline
26 #endif // __SYCL_DEVICE_ONLY__
27 
28 #ifdef __SYCL_DEVICE_ONLY__
29 #define __ESIMD_INTRIN_END ;
30 #else
31 #define __ESIMD_INTRIN_END \
32  { __ESIMD_UNSUPPORTED_ON_HOST; }
33 #endif // __SYCL_DEVICE_ONLY__
34 
35 namespace sycl {
36 inline namespace _V1 {
37 namespace ext::intel::esimd::detail {
38 
40 struct OperandSize {
41  enum { BYTE = 1, WORD = 2, DWORD = 4, QWORD = 8, OWORD = 16, GRF = 32 };
42 };
43 
46 template <unsigned int N, unsigned int K, bool K_gt_eq_N> struct NextPowerOf2;
47 
48 template <unsigned int N, unsigned int K> struct NextPowerOf2<N, K, true> {
49  static constexpr unsigned int get() { return K; }
50 };
51 
52 template <unsigned int N, unsigned int K> struct NextPowerOf2<N, K, false> {
53  static constexpr unsigned int get() {
54  return NextPowerOf2<N, K * 2, K * 2 >= N>::get();
55  }
56 };
57 
58 template <unsigned int N> constexpr unsigned int getNextPowerOf2() {
59  return NextPowerOf2<N, 1, (1 >= N)>::get();
60 }
61 
62 template <> constexpr unsigned int getNextPowerOf2<0>() { return 0; }
63 
64 template <unsigned int N, unsigned int M>
65 constexpr unsigned int roundUpNextMultiple() {
66  return ((N + M - 1) / M) * M;
67 }
68 
71 template <unsigned int N, bool N_gt_1> struct Log2;
72 
73 template <unsigned int N> struct Log2<N, false> {
74  static constexpr unsigned int get() { return 0; }
75 };
76 
77 template <unsigned int N> struct Log2<N, true> {
78  static constexpr unsigned int get() {
79  return 1 + Log2<(N >> 1), ((N >> 1) > 1)>::get();
80  }
81 };
82 
83 template <unsigned int N> constexpr unsigned int log2() {
84  return Log2<N, (N > 1)>::get();
85 }
86 
88 template <typename T> struct is_esimd_vector : public std::false_type {};
89 
90 template <typename T, int N>
91 struct is_esimd_vector<simd<T, N>> : public std::true_type {};
92 
93 template <typename T, int N>
94 using is_hw_int_type =
95  typename std::bool_constant<std::is_integral_v<T> && (sizeof(T) == N)>;
96 
97 template <typename T> using is_qword_type = is_hw_int_type<T, 8>;
98 template <typename T> using is_dword_type = is_hw_int_type<T, 4>;
99 template <typename T> using is_word_type = is_hw_int_type<T, 2>;
100 template <typename T> using is_byte_type = is_hw_int_type<T, 1>;
101 
102 template <typename T, int N>
103 using is_hw_fp_type = typename std::bool_constant<std::is_floating_point_v<T> &&
104  (sizeof(T) == N)>;
105 
106 template <typename T> using is_fp_type = is_hw_fp_type<T, 4>;
107 template <typename T> using is_df_type = is_hw_fp_type<T, 8>;
108 
109 template <typename T>
110 using is_fp_or_dword_type =
111  typename std::bool_constant<is_fp_type<T>::value ||
112  is_dword_type<T>::value>;
113 
115 template <typename T> struct simd_type {
116  using type = simd<T, 1>;
117 };
118 template <typename T, int N> struct simd_type<raw_vector_type<T, N>> {
119  using type = simd<T, N>;
120 };
121 
122 template <typename T> struct simd_type<T &> {
123  using type = typename simd_type<T>::type;
124 };
125 template <typename T> struct simd_type<T &&> {
126  using type = typename simd_type<T>::type;
127 };
128 template <typename T> struct simd_type<const T> {
129  using type = typename simd_type<T>::type;
130 };
131 
132 template <typename T> struct dword_type {
133  using type = T;
134 };
135 template <> struct dword_type<char> {
136  using type = int;
137 };
138 template <> struct dword_type<short> {
139  using type = int;
140 };
141 template <> struct dword_type<uchar> {
142  using type = uint;
143 };
144 template <> struct dword_type<ushort> {
145  using type = uint;
146 };
147 
148 template <typename T> struct byte_type {
149  using type = T;
150 };
151 template <> struct byte_type<short> {
152  using type = char;
153 };
154 template <> struct byte_type<int> {
155  using type = char;
156 };
157 template <> struct byte_type<ushort> {
158  using type = uchar;
159 };
160 template <> struct byte_type<uint> {
161  using type = uchar;
162 };
163 
164 template <typename T> struct word_type {
165  using type = T;
166 };
167 template <> struct word_type<char> {
168  using type = short;
169 };
170 template <> struct word_type<int> {
171  using type = short;
172 };
173 template <> struct word_type<uchar> {
174  using type = ushort;
175 };
176 template <> struct word_type<uint> {
177  using type = ushort;
178 };
179 
180 // Utility for compile time loop unrolling.
181 template <unsigned N> class ForHelper {
182  template <unsigned I, typename Action> static void repeat(Action A) {
183  if constexpr (I < N)
184  A(I);
185  if constexpr (I + 1 < N)
186  repeat<I + 1, Action>(A);
187  }
188 
189 public:
190  template <typename Action> static void unroll(Action A) {
191  ForHelper::template repeat<0, Action>(A);
192  }
193 };
194 
195 #ifdef __ESIMD_FORCE_STATELESS_MEM
198 template <typename T, typename AccessorTy, typename OffsetTy = uint32_t>
199 auto accessorToPointer(AccessorTy Acc, OffsetTy Offset = 0) {
200  using QualCharPtrType =
201  std::conditional_t<std::is_const_v<typename AccessorTy::value_type>,
202  const char *, char *>;
203  using QualTPtrType =
204  std::conditional_t<std::is_const_v<typename AccessorTy::value_type>,
205  const T *, T *>;
206  auto BytePtr =
207  reinterpret_cast<QualCharPtrType>(Acc.get_pointer().get()) + Offset;
208  return reinterpret_cast<QualTPtrType>(BytePtr);
209 }
210 #endif // __ESIMD_FORCE_STATELESS_MEM
211 
212 } // namespace ext::intel::esimd::detail
213 } // namespace _V1
214 } // namespace sycl
215 
Definition: simd.hpp:1387
unsigned short ushort
Definition: common.hpp:42
__ESIMD_API simd< T, N > log2(simd< T, N > src, Sat sat={})
Logarithm base 2.
Definition: math.hpp:380
pointer get() const
Definition: multi_ptr.hpp:544
Definition: access.hpp:18