DPC++ Runtime
Runtime libraries for oneAPI DPC++
|
|
Go to the documentation of this file.
28 namespace ext::intel::esimd::detail {
111 #define __ESIMD_DEF_SIMD_OBJ_IMPL_BIN_OP(BINOP, BINOP_ID, COND) \
114 template <class T1, class T2, int N, template <class, int> class SimdT, \
115 class SimdTx = SimdT<T1, N>, class = std::enable_if_t<COND>> \
116 inline auto operator BINOP( \
117 const __ESIMD_DNS::simd_obj_impl<__raw_t<T1>, N, SimdT<T1, N>> &LHS, \
118 const __ESIMD_DNS::simd_obj_impl<__raw_t<T2>, N, SimdT<T2, N>> &RHS) { \
119 if constexpr (__ESIMD_DNS::is_simd_type_v<SimdT<T1, N>>) { \
123 using PromotedT = __ESIMD_DNS::computation_type_t<T1, T2>; \
125 SimdT<PromotedT, N> Res = vector_binary_op<BINOP_ID, PromotedT, N>( \
126 __ESIMD_DNS::convert_vector<PromotedT, T1, N>(LHS.data()), \
127 __ESIMD_DNS::convert_vector<PromotedT, T2, N>(RHS.data())); \
132 return SimdT<T1, N>(LHS.data() BINOP RHS.data()); \
137 template <class T1, int N1, template <class, int> class SimdT1, class T2, \
138 class SimdTx = SimdT1<T1, N1>, class = std::enable_if_t<COND>> \
139 inline auto operator BINOP( \
140 const __ESIMD_DNS::simd_obj_impl<__raw_t<T1>, N1, SimdT1<T1, N1>> &LHS, \
142 if constexpr (__ESIMD_DNS::is_simd_type_v<SimdT1<T1, N1>>) { \
145 return LHS BINOP SimdT1<T2, N1>(RHS); \
149 return LHS BINOP SimdT1<T1, N1>(RHS); \
154 template <class T1, class T2, int N2, template <class, int> class SimdT2, \
155 class SimdTx = SimdT2<T2, N2>, class = std::enable_if_t<COND>> \
156 inline auto operator BINOP( \
158 const __ESIMD_DNS::simd_obj_impl<__raw_t<T2>, N2, SimdT2<T2, N2>> \
160 if constexpr (__ESIMD_DNS::is_simd_type_v<SimdT2<T2, N2>>) { \
163 return SimdT2<T1, N2>(LHS) BINOP RHS; \
166 return SimdT2<T2, N2>(LHS) BINOP RHS; \
171 #define __ESIMD_BITWISE_OP_FILTER \
172 std::is_integral_v<T1> &&std::is_integral_v<T2>
176 #undef __ESIMD_BITWISE_OP_FILTER
178 #define __ESIMD_SHIFT_OP_FILTER \
179 std::is_integral_v<T1> &&std::is_integral_v<T2> \
180 &&__ESIMD_DNS::is_simd_type_v<SimdTx>
184 #undef __ESIMD_SHIFT_OP_FILTER
186 #define __ESIMD_ARITH_OP_FILTER \
187 __ESIMD_DNS::is_valid_simd_elem_type_v<T1> \
188 &&__ESIMD_DNS::is_valid_simd_elem_type_v<T2> \
189 &&__ESIMD_DNS::is_simd_type_v<SimdTx>
195 #undef __ESIMD_ARITH_OP_FILTER
197 #undef __ESIMD_DEF_SIMD_OBJ_IMPL_BIN_OP
203 #define __ESIMD_DEF_SIMD_OBJ_IMPL_CMP_OP(CMPOP, CMPOP_ID, COND) \
206 template <class T1, class T2, int N, template <class, int> class SimdT, \
207 class SimdTx = SimdT<T1, N>, class = std::enable_if_t<COND>> \
208 inline __ESIMD_NS::simd_mask<N> operator CMPOP( \
209 const __ESIMD_DNS::simd_obj_impl<__raw_t<T1>, N, SimdT<T1, N>> &LHS, \
210 const __ESIMD_DNS::simd_obj_impl<__raw_t<T2>, N, SimdT<T2, N>> &RHS) { \
211 using MaskVecT = typename __ESIMD_NS::simd_mask<N>::raw_vector_type; \
213 if constexpr (is_simd_type_v<SimdT<T1, N>>) { \
214 using PromotedT = computation_type_t<T1, T2>; \
218 auto Res = vector_comparison_op<CMPOP_ID, PromotedT, N>( \
219 __ESIMD_DNS::convert_vector<PromotedT, T1, N>(LHS.data()), \
220 __ESIMD_DNS::convert_vector<PromotedT, T2, N>(RHS.data())); \
221 using ResElemT = element_type_t<decltype(Res)>; \
222 return __ESIMD_NS::simd_mask<N>( \
223 __ESIMD_DNS::convert_vector<simd_mask_elem_type, ResElemT, N>(Res) & \
227 auto ResVec = LHS.data() CMPOP RHS.data(); \
228 return __ESIMD_NS::simd_mask<N>(__ESIMD_DNS::convert<MaskVecT>(ResVec) & \
234 template <class T1, int N1, template <class, int> class SimdT1, class T2, \
235 class SimdTx = SimdT1<T1, N1>, \
236 class = std::enable_if_t< \
237 __ESIMD_DNS::is_valid_simd_elem_type_v<T2> && COND>> \
238 inline __ESIMD_NS::simd_mask<N1> operator CMPOP( \
239 const __ESIMD_DNS::simd_obj_impl<__raw_t<T1>, N1, SimdT1<T1, N1>> &LHS, \
241 if constexpr (__ESIMD_DNS::is_simd_type_v<SimdT1<T1, N1>>) \
243 return LHS CMPOP SimdT1<T2, N1>(RHS); \
246 return LHS CMPOP SimdT1<T1, N1>(convert_scalar<T1>(RHS)); \
250 template <class T1, class T2, int N2, template <class, int> class SimdT2, \
251 class SimdTx = SimdT2<T2, N2>, \
252 class = std::enable_if_t< \
253 __ESIMD_DNS::is_valid_simd_elem_type_v<T1> && COND>> \
254 inline __ESIMD_NS::simd_mask<N2> operator CMPOP( \
256 const __ESIMD_DNS::simd_obj_impl<__raw_t<T2>, N2, SimdT2<T2, N2>> \
258 if constexpr (__ESIMD_DNS::is_simd_type_v<SimdT2<T2, N2>>) \
260 return SimdT2<T1, N2>(LHS) CMPOP RHS; \
263 return SimdT2<T2, N2>(convert_scalar<T2>(LHS)) CMPOP RHS; \
272 __ESIMD_DNS::is_simd_type_v<SimdTx>)
274 __ESIMD_DNS::is_simd_type_v<SimdTx>)
276 __ESIMD_DNS::is_simd_type_v<SimdTx>)
278 __ESIMD_DNS::is_simd_type_v<SimdTx>)
282 __ESIMD_DNS::is_simd_mask_type_v<SimdTx>)
284 __ESIMD_DNS::is_simd_mask_type_v<SimdTx>)
286 #undef __ESIMD_DEF_SIMD_OBJ_IMPL_CMP_OP
294 #define __ESIMD_DEF_SIMD_VIEW_BIN_OP(BINOP, COND) \
298 class SimdT1, class RegionT1, class SimdT2, class RegionT2, \
299 class T1 = typename __ESIMD_NS::shape_type<RegionT1>::element_type, \
300 class T2 = typename __ESIMD_NS::shape_type<RegionT2>::element_type, \
301 auto N1 = __ESIMD_NS::shape_type<RegionT1>::length, \
302 auto N2 = __ESIMD_NS::shape_type<RegionT2>::length, \
303 class = std::enable_if_t<__ESIMD_DNS::is_simd_type_v<SimdT1> == \
304 __ESIMD_DNS::is_simd_type_v<SimdT2> && \
305 (N1 == N2 || N1 == 1 || N2 == 1) && COND>> \
306 inline auto operator BINOP( \
307 const __ESIMD_NS::simd_view<SimdT1, RegionT1> &LHS, \
308 const __ESIMD_NS::simd_view<SimdT2, RegionT2> &RHS) { \
309 if constexpr (N1 == 1) \
310 return (T1)LHS.read()[0] BINOP RHS.read(); \
311 else if constexpr (N2 == 1) \
312 return LHS.read() BINOP(T2) RHS.read()[0]; \
314 return LHS.read() BINOP RHS.read(); \
318 template <class SimdT1, class SimdT2, class RegionT2, \
319 class T1 = typename SimdT1::element_type, \
321 typename __ESIMD_NS::shape_type<RegionT2>::element_type, \
322 class = std::enable_if_t< \
323 __ESIMD_DNS::is_simd_obj_impl_derivative_v<SimdT1> && \
324 (__ESIMD_DNS::is_simd_type_v<SimdT1> == \
325 __ESIMD_DNS::is_simd_type_v< \
326 SimdT2>)&&(SimdT1::length == \
327 __ESIMD_NS::shape_type<RegionT2>::length) && \
329 inline auto operator BINOP( \
330 const SimdT1 &LHS, const __ESIMD_NS::simd_view<SimdT2, RegionT2> &RHS) { \
331 return LHS BINOP RHS.read(); \
336 class SimdT1, class RegionT1, class SimdT2, \
337 class T1 = typename __ESIMD_NS::shape_type<RegionT1>::element_type, \
338 class T2 = typename SimdT2::element_type, \
339 class = std::enable_if_t< \
340 __ESIMD_DNS::is_simd_obj_impl_derivative_v<SimdT2> && \
341 __ESIMD_DNS::is_simd_type_v<SimdT1> == \
342 __ESIMD_DNS::is_simd_type_v<SimdT2> && \
343 (SimdT2::length == __ESIMD_NS::shape_type<RegionT1>::length) && \
345 inline auto operator BINOP( \
346 const __ESIMD_NS::simd_view<SimdT1, RegionT1> &LHS, const SimdT2 &RHS) { \
347 return LHS.read() BINOP RHS; \
351 template <class T1, class SimdViewT2, \
352 class T2 = typename SimdViewT2::element_type, \
353 class SimdT1 = typename SimdViewT2::value_type, \
354 class = std::enable_if_t< \
355 __ESIMD_DNS::is_any_simd_view_type_v<SimdViewT2> && COND>> \
356 inline auto operator BINOP(T1 LHS, const SimdViewT2 &RHS) { \
357 return LHS BINOP RHS.read(); \
361 template <class SimdViewT1, class T2, \
362 class T1 = typename SimdViewT1::element_type, \
363 class SimdT1 = typename SimdViewT1::value_type, \
364 class = std::enable_if_t< \
365 __ESIMD_DNS::is_any_simd_view_type_v<SimdViewT1> && COND>> \
366 inline auto operator BINOP(const SimdViewT1 &LHS, T2 RHS) { \
367 return LHS.read() BINOP RHS; \
370 #define __ESIMD_BITWISE_OP_FILTER \
371 std::is_integral_v<T1> &&std::is_integral_v<T2>
375 #undef __ESIMD_BITWISE_OP_FILITER
377 #define __ESIMD_SHIFT_OP_FILTER \
378 std::is_integral_v<T1> &&std::is_integral_v<T2> \
379 &&__ESIMD_DNS::is_simd_type_v<SimdT1>
384 #undef __ESIMD_SHIFT_OP_FILTER
386 #define __ESIMD_ARITH_OP_FILTER \
387 __ESIMD_DNS::is_simd_type_v<SimdT1> \
388 &&__ESIMD_DNS::is_valid_simd_elem_type_v<T1> \
389 &&__ESIMD_DNS::is_valid_simd_elem_type_v<T2>
395 #undef __ESIMD_ARITH_OP_FILTER
400 #undef __ESIMD_DEF_SIMD_VIEW_BIN_OP
404 #define __ESIMD_DEF_SIMD_VIEW_CMP_OP(CMPOP, COND) \
407 template <class SimdT1, class RegionT1, class SimdT2, class RegionT2, \
408 auto N1 = __ESIMD_NS::shape_type<RegionT1>::length, \
409 auto N2 = __ESIMD_NS::shape_type<RegionT2>::length, \
410 class = std::enable_if_t<
412 (__ESIMD_DNS::is_simd_type_v<SimdT1> == \
413 __ESIMD_DNS::is_simd_type_v< \
416 (N1 == N2 || N1 == 1 || N2 == 1) && \
418 inline auto operator CMPOP( \
419 const __ESIMD_NS::simd_view<SimdT1, RegionT1> &LHS, \
420 const __ESIMD_NS::simd_view<SimdT2, RegionT2> &RHS) { \
421 using T1 = typename __ESIMD_NS::shape_type<RegionT1>::element_type; \
422 using T2 = typename __ESIMD_NS::shape_type<RegionT2>::element_type; \
423 if constexpr (N1 == 1) \
424 return (T1)LHS.read()[0] CMPOP RHS.read(); \
425 else if constexpr (N2 == 1) \
426 return LHS.read() CMPOP(T2) RHS.read()[0]; \
428 return LHS.read() CMPOP RHS.read(); \
432 template <class SimdT1, class RegionT1, class RawT2, int N2, class SimdT2, \
433 class = std::enable_if_t< \
434 (__ESIMD_NS::shape_type<RegionT1>::length == N2) && \
435 (__ESIMD_DNS::is_simd_type_v<SimdT1> == \
436 __ESIMD_DNS::is_simd_type_v<SimdT2>)&&COND>> \
437 inline __ESIMD_NS::simd_mask<N2> operator CMPOP( \
438 const __ESIMD_NS::simd_view<SimdT1, RegionT1> &LHS, \
439 const __ESIMD_DNS::simd_obj_impl<RawT2, N2, SimdT2> &RHS) { \
440 return LHS.read() CMPOP SimdT2(RHS.data()); \
444 template <class RawT1, int N1, class SimdT1, class SimdT2, class RegionT2, \
445 class = std::enable_if_t< \
446 (__ESIMD_NS::shape_type<RegionT2>::length == N1) && \
447 (__ESIMD_DNS::is_simd_type_v<SimdT1> == \
448 __ESIMD_DNS::is_simd_type_v<SimdT2>)&&COND>> \
449 inline __ESIMD_NS::simd_mask<N1> operator CMPOP( \
450 const __ESIMD_DNS::simd_obj_impl<RawT1, N1, SimdT1> &LHS, \
451 const __ESIMD_NS::simd_view<SimdT2, RegionT2> &RHS) { \
452 return SimdT1(LHS.data()) CMPOP RHS.read(); \
456 template <class SimdT1, class RegionT1, class T2, \
457 class = std::enable_if_t< \
458 __ESIMD_DNS::is_valid_simd_elem_type_v<T2> && COND>> \
459 inline auto operator CMPOP( \
460 const __ESIMD_NS::simd_view<SimdT1, RegionT1> &LHS, T2 RHS) { \
461 return LHS.read() CMPOP RHS; \
465 template <class T1, class SimdT2, class RegionT2, class SimdT1 = SimdT2, \
466 class = std::enable_if_t< \
467 __ESIMD_DNS::is_valid_simd_elem_type_v<T1> && COND>> \
468 inline auto operator CMPOP( \
469 T1 LHS, const __ESIMD_NS::simd_view<SimdT2, RegionT2> &RHS) { \
470 return LHS CMPOP RHS.read(); \
483 #undef __ESIMD_DEF_SIMD_VIEW_CMP_OP
#define __ESIMD_DEF_SIMD_VIEW_CMP_OP(CMPOP, COND)
__ESIMD_API std::enable_if_t< std::is_integral< T0 >::value &&std::is_integral< T1 >::value &&std::is_integral< U >::value, sycl::ext::intel::esimd::simd< T0, SZ > > shr(sycl::ext::intel::esimd::simd< T1, SZ > src0, U src1, Sat sat={})
Shift right operation (vector version)
#define __SYCL_INLINE_VER_NAMESPACE(X)
#define __ESIMD_DEF_SIMD_VIEW_BIN_OP(BINOP, COND)
std::bit_xor< T > bit_xor
---— Error handling, matching OpenCL plugin semantics.
__ESIMD_API std::enable_if_t< std::is_integral< T0 >::value &&std::is_integral< T1 >::value &&std::is_integral< U >::value, sycl::ext::intel::esimd::simd< T0, SZ > > shl(sycl::ext::intel::esimd::simd< T1, SZ > src0, U src1, Sat sat={})
Shift left operation (vector version)
#define __ESIMD_DEF_SIMD_OBJ_IMPL_CMP_OP(CMPOP, CMPOP_ID, COND)
__ESIMD_API std::enable_if_t< std::is_integral< T >::value &&std::is_integral< U >::value, sycl::ext::intel::esimd::simd< T, SZ > > div(sycl::ext::intel::esimd::simd< T, SZ > &remainder, sycl::ext::intel::esimd::simd< T, SZ > src0, U src1)
Integral division with a vector dividend and a scalar divisor.
#define __ESIMD_SHIFT_OP_FILTER
#define __ESIMD_BITWISE_OP_FILTER
#define __ESIMD_DEF_SIMD_OBJ_IMPL_BIN_OP(BINOP, BINOP_ID, COND)
#define __ESIMD_ARITH_OP_FILTER
void add(const void *DeviceGlobalPtr, const char *UniqueId)