DPC++ Runtime
Runtime libraries for oneAPI DPC++
known_identity.hpp
Go to the documentation of this file.
1 //==----------- known_identity.hpp -----------------------------------------==//
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 <functional>
12 #include <limits>
14 #include <sycl/functional.hpp>
15 #include <type_traits>
16 
17 namespace sycl {
19 namespace detail {
20 
21 template <typename T, class BinaryOperation>
22 using IsPlus =
23  bool_constant<std::is_same<BinaryOperation, sycl::plus<T>>::value ||
24  std::is_same<BinaryOperation, sycl::plus<void>>::value>;
25 
26 template <typename T, class BinaryOperation>
27 using IsMultiplies =
29  std::is_same<BinaryOperation, sycl::multiplies<void>>::value>;
30 
31 template <typename T, class BinaryOperation>
32 using IsMinimum =
34  std::is_same<BinaryOperation, sycl::minimum<void>>::value>;
35 
36 template <typename T, class BinaryOperation>
37 using IsMaximum =
39  std::is_same<BinaryOperation, sycl::maximum<void>>::value>;
40 
41 template <typename T, class BinaryOperation>
42 using IsBitAND =
44  std::is_same<BinaryOperation, sycl::bit_and<void>>::value>;
45 
46 template <typename T, class BinaryOperation>
47 using IsBitOR =
49  std::is_same<BinaryOperation, sycl::bit_or<void>>::value>;
50 
51 template <typename T, class BinaryOperation>
52 using IsBitXOR =
54  std::is_same<BinaryOperation, sycl::bit_xor<void>>::value>;
55 
56 template <typename T, class BinaryOperation>
58  std::is_same<BinaryOperation, sycl::logical_and<T>>::value ||
59  std::is_same<BinaryOperation, sycl::logical_and<void>>::value>;
60 
61 template <typename T, class BinaryOperation>
62 using IsLogicalOR =
64  std::is_same<BinaryOperation, sycl::logical_or<void>>::value>;
65 
66 template <typename T>
68  std::is_same<T, std::complex<double>>::value>;
69 
70 // Identity = 0
71 template <typename T, class BinaryOperation>
78 
79 // Identity = 1
80 template <typename T, class BinaryOperation>
81 using IsOneIdentityOp =
85 
86 // Identity = ~0
87 template <typename T, class BinaryOperation>
88 using IsOnesIdentityOp =
91 
92 // Identity = <max possible value>
93 template <typename T, class BinaryOperation>
94 using IsMinimumIdentityOp =
98 
99 // Identity = <min possible value>
100 template <typename T, class BinaryOperation>
101 using IsMaximumIdentityOp =
105 
106 // Identity = false
107 template <typename T, class BinaryOperation>
109 
110 // Identity = true
111 template <typename T, class BinaryOperation>
113 
114 template <typename T, class BinaryOperation>
115 using IsKnownIdentityOp =
123 
124 template <typename BinaryOperation, typename AccumulatorT>
126  : std::integral_constant<
127  bool, IsKnownIdentityOp<AccumulatorT, BinaryOperation>::value> {};
128 
129 template <typename BinaryOperation, typename AccumulatorT, typename = void>
131 
133 template <typename BinaryOperation, typename AccumulatorT>
135  BinaryOperation, AccumulatorT,
136  std::enable_if_t<IsZeroIdentityOp<AccumulatorT, BinaryOperation>::value>> {
137  static constexpr AccumulatorT value = static_cast<AccumulatorT>(0);
138 };
139 
140 #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
141 template <typename BinaryOperation, int NumElements>
143  BinaryOperation, vec<std::byte, NumElements>,
144  std::enable_if_t<IsZeroIdentityOp<vec<std::byte, NumElements>,
145  BinaryOperation>::value>> {
146  static constexpr vec<std::byte, NumElements> value =
148 };
149 
150 template <typename BinaryOperation, int NumElements>
152  BinaryOperation, marray<std::byte, NumElements>,
153  std::enable_if_t<IsZeroIdentityOp<marray<std::byte, NumElements>,
154  BinaryOperation>::value>> {
155  static constexpr marray<std::byte, NumElements> value =
157 };
158 #endif
159 
160 template <typename BinaryOperation, int NumElements>
162  BinaryOperation, vec<sycl::half, NumElements>,
163  std::enable_if_t<IsZeroIdentityOp<vec<sycl::half, NumElements>,
164  BinaryOperation>::value>> {
165  static constexpr vec<sycl::half, NumElements> value =
167 };
168 
169 template <typename BinaryOperation>
171  BinaryOperation, half,
172  std::enable_if_t<IsZeroIdentityOp<half, BinaryOperation>::value>> {
173  static constexpr half value =
174 #ifdef __SYCL_DEVICE_ONLY__
175  0;
176 #else
177  sycl::detail::host_half_impl::half(static_cast<uint16_t>(0));
178 #endif
179 };
180 
182 template <typename BinaryOperation, typename AccumulatorT>
184  BinaryOperation, AccumulatorT,
185  std::enable_if_t<IsOneIdentityOp<AccumulatorT, BinaryOperation>::value>> {
186  static constexpr AccumulatorT value = static_cast<AccumulatorT>(1);
187 };
188 
189 #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
190 template <typename BinaryOperation, int NumElements>
192  BinaryOperation, vec<std::byte, NumElements>,
194  IsOneIdentityOp<vec<std::byte, NumElements>, BinaryOperation>::value>> {
195  static constexpr vec<std::byte, NumElements> value =
197 };
198 
199 template <typename BinaryOperation, int NumElements>
201  BinaryOperation, marray<std::byte, NumElements>,
202  std::enable_if_t<IsOneIdentityOp<marray<std::byte, NumElements>,
203  BinaryOperation>::value>> {
204  static constexpr marray<std::byte, NumElements> value =
206 };
207 #endif
208 
209 template <typename BinaryOperation>
211  BinaryOperation, half,
212  std::enable_if_t<IsOneIdentityOp<half, BinaryOperation>::value>> {
213  static constexpr half value =
214 #ifdef __SYCL_DEVICE_ONLY__
215  1;
216 #else
217  sycl::detail::host_half_impl::half(static_cast<uint16_t>(0x3C00));
218 #endif
219 };
220 
222 template <typename BinaryOperation, typename AccumulatorT>
224  BinaryOperation, AccumulatorT,
225  std::enable_if_t<IsOnesIdentityOp<AccumulatorT, BinaryOperation>::value>> {
226  static constexpr AccumulatorT value = static_cast<AccumulatorT>(-1LL);
227 };
228 
229 #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
230 template <typename BinaryOperation, int NumElements>
232  BinaryOperation, vec<std::byte, NumElements>,
233  std::enable_if_t<IsOnesIdentityOp<vec<std::byte, NumElements>,
234  BinaryOperation>::value>> {
235  static constexpr vec<std::byte, NumElements> value =
237 };
238 
239 template <typename BinaryOperation, int NumElements>
241  BinaryOperation, marray<std::byte, NumElements>,
242  std::enable_if_t<IsOnesIdentityOp<marray<std::byte, NumElements>,
243  BinaryOperation>::value>> {
244  static constexpr marray<std::byte, NumElements> value =
246 };
247 #endif
248 
250 template <typename BinaryOperation, typename AccumulatorT>
251 struct known_identity_impl<BinaryOperation, AccumulatorT,
252  std::enable_if_t<IsMinimumIdentityOp<
253  AccumulatorT, BinaryOperation>::value>> {
254  static constexpr AccumulatorT value = static_cast<AccumulatorT>(
255  std::numeric_limits<AccumulatorT>::has_infinity
256  ? std::numeric_limits<AccumulatorT>::infinity()
257  : (std::numeric_limits<AccumulatorT>::max)());
258 };
259 
260 #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
261 template <typename BinaryOperation, int NumElements>
263  BinaryOperation, vec<std::byte, NumElements>,
264  std::enable_if_t<IsMinimumIdentityOp<vec<std::byte, NumElements>,
265  BinaryOperation>::value>> {
266  static constexpr vec<std::byte, NumElements> value =
267  static_cast<vec<std::byte, NumElements>>(
268  std::numeric_limits<vec<std::byte, NumElements>>::has_infinity
269  ? std::numeric_limits<vec<std::byte, NumElements>>::infinity()
270  : (std::numeric_limits<vec<std::byte, NumElements>>::max)());
271 };
272 
273 template <typename BinaryOperation, int NumElements>
275  BinaryOperation, marray<std::byte, NumElements>,
276  std::enable_if_t<IsMinimumIdentityOp<marray<std::byte, NumElements>,
277  BinaryOperation>::value>> {
278  static constexpr marray<std::byte, NumElements> value =
279  static_cast<marray<std::byte, NumElements>>(
280  std::numeric_limits<marray<std::byte, NumElements>>::has_infinity
281  ? std::numeric_limits<marray<std::byte, NumElements>>::infinity()
282  : (std::numeric_limits<marray<std::byte, NumElements>>::max)());
283 };
284 #endif
285 
287 template <typename BinaryOperation, typename AccumulatorT>
288 struct known_identity_impl<BinaryOperation, AccumulatorT,
289  std::enable_if_t<IsMaximumIdentityOp<
290  AccumulatorT, BinaryOperation>::value>> {
291  static constexpr AccumulatorT value = static_cast<AccumulatorT>(
292  std::numeric_limits<AccumulatorT>::has_infinity
293  ? static_cast<AccumulatorT>(
294  -std::numeric_limits<AccumulatorT>::infinity())
295  : std::numeric_limits<AccumulatorT>::lowest());
296 };
297 
298 #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
299 template <typename BinaryOperation, int NumElements>
301  BinaryOperation, vec<std::byte, NumElements>,
302  std::enable_if_t<IsMaximumIdentityOp<vec<std::byte, NumElements>,
303  BinaryOperation>::value>> {
304  static constexpr vec<std::byte, NumElements> value = static_cast<
306  std::numeric_limits<vec<std::byte, NumElements>>::has_infinity
307  ? static_cast<vec<std::byte, NumElements>>(
308  -std::numeric_limits<vec<std::byte, NumElements>>::infinity())
309  : std::numeric_limits<vec<std::byte, NumElements>>::lowest());
310 };
311 
312 template <typename BinaryOperation, int NumElements>
314  BinaryOperation, marray<std::byte, NumElements>,
315  std::enable_if_t<IsMaximumIdentityOp<marray<std::byte, NumElements>,
316  BinaryOperation>::value>> {
317  static constexpr marray<std::byte, NumElements> value =
318  static_cast<marray<std::byte, NumElements>>(
319  std::numeric_limits<marray<std::byte, NumElements>>::has_infinity
320  ? static_cast<marray<std::byte, NumElements>>(
321  -std::numeric_limits<
322  marray<std::byte, NumElements>>::infinity())
323  : std::numeric_limits<marray<std::byte, NumElements>>::lowest());
324 };
325 #endif
326 
328 template <typename BinaryOperation, typename AccumulatorT>
330  BinaryOperation, AccumulatorT,
331  std::enable_if_t<IsFalseIdentityOp<AccumulatorT, BinaryOperation>::value>> {
332  static constexpr AccumulatorT value = static_cast<AccumulatorT>(false);
333 };
334 
335 #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
336 template <typename BinaryOperation, int NumElements>
338  BinaryOperation, vec<std::byte, NumElements>,
339  std::enable_if_t<IsFalseIdentityOp<vec<std::byte, NumElements>,
340  BinaryOperation>::value>> {
341  static constexpr vec<std::byte, NumElements> value =
343 };
344 
345 template <typename BinaryOperation, size_t NumElements>
347  BinaryOperation, marray<std::byte, NumElements>,
348  std::enable_if_t<IsFalseIdentityOp<marray<std::byte, NumElements>,
349  BinaryOperation>::value>> {
350  static constexpr marray<std::byte, NumElements> value =
352 };
353 #endif
354 
356 template <typename BinaryOperation, typename AccumulatorT>
358  BinaryOperation, AccumulatorT,
359  std::enable_if_t<IsTrueIdentityOp<AccumulatorT, BinaryOperation>::value>> {
360  static constexpr AccumulatorT value = static_cast<AccumulatorT>(true);
361 };
362 
363 #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
364 template <typename BinaryOperation, int NumElements>
366  BinaryOperation, vec<std::byte, NumElements>,
367  std::enable_if_t<IsTrueIdentityOp<vec<std::byte, NumElements>,
368  BinaryOperation>::value>> {
369  static constexpr vec<std::byte, NumElements> value =
371 };
372 
373 template <typename BinaryOperation, int NumElements>
375  BinaryOperation, marray<std::byte, NumElements>,
376  std::enable_if_t<IsTrueIdentityOp<marray<std::byte, NumElements>,
377  BinaryOperation>::value>> {
378  static constexpr marray<std::byte, NumElements> value =
380 };
381 #endif
382 
383 } // namespace detail
384 
385 // ---- has_known_identity
386 template <typename BinaryOperation, typename AccumulatorT>
388  : detail::has_known_identity_impl<std::decay_t<BinaryOperation>,
389  std::decay_t<AccumulatorT>> {};
390 
391 template <typename BinaryOperation, typename AccumulatorT>
392 inline constexpr bool has_known_identity_v =
393  sycl::has_known_identity<BinaryOperation, AccumulatorT>::value;
394 
395 // ---- known_identity
396 template <typename BinaryOperation, typename AccumulatorT>
398  : detail::known_identity_impl<std::decay_t<BinaryOperation>,
399  std::decay_t<AccumulatorT>> {};
400 
401 template <typename BinaryOperation, typename AccumulatorT>
402 inline constexpr AccumulatorT known_identity_v =
403  sycl::known_identity<BinaryOperation, AccumulatorT>::value;
404 
405 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
406 } // namespace sycl
sycl::_V1::detail::IsLogicalOR
bool_constant< std::is_same< BinaryOperation, sycl::logical_or< T > >::value||std::is_same< BinaryOperation, sycl::logical_or< void > >::value > IsLogicalOR
Definition: known_identity.hpp:64
sycl::_V1::has_known_identity
Definition: known_identity.hpp:387
sycl::_V1::detail::IsBitOR
bool_constant< std::is_same< BinaryOperation, sycl::bit_or< T > >::value||std::is_same< BinaryOperation, sycl::bit_or< void > >::value > IsBitOR
Definition: known_identity.hpp:49
sycl::_V1::detail::IsMaximum
bool_constant< std::is_same< BinaryOperation, sycl::maximum< T > >::value||std::is_same< BinaryOperation, sycl::maximum< void > >::value > IsMaximum
Definition: known_identity.hpp:39
sycl::_V1::detail::isComplex
bool_constant< std::is_same< T, std::complex< float > >::value||std::is_same< T, std::complex< double > >::value > isComplex
Definition: known_identity.hpp:68
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
sycl::_V1::detail::IsBitXOR
bool_constant< std::is_same< BinaryOperation, sycl::bit_xor< T > >::value||std::is_same< BinaryOperation, sycl::bit_xor< void > >::value > IsBitXOR
Definition: known_identity.hpp:54
sycl::_V1::byte
unsigned char byte
Definition: image.hpp:63
sycl::_V1::detail::known_identity_impl
Definition: known_identity.hpp:130
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
sycl::_V1::detail::IsOneIdentityOp
bool_constant<(is_genbool< T >::value||is_geninteger< T >::value||is_genfloat< T >::value) &&IsMultiplies< T, BinaryOperation >::value > IsOneIdentityOp
Definition: known_identity.hpp:84
bool_constant
max
simd< _Tp, _Abi > max(const simd< _Tp, _Abi > &, const simd< _Tp, _Abi > &) noexcept
sycl::_V1::detail::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: stl_type_traits.hpp:24
generic_type_traits.hpp
sycl::_V1::marray
Provides a cross-platform math array class template that works on SYCL devices as well as in host C++...
Definition: generic_type_lists.hpp:25
sycl::_V1::detail::IsLogicalAND
bool_constant< std::is_same< BinaryOperation, sycl::logical_and< T > >::value||std::is_same< BinaryOperation, sycl::logical_and< void > >::value > IsLogicalAND
Definition: known_identity.hpp:59
functional.hpp
sycl::_V1::detail::IsPlus
bool_constant< std::is_same< BinaryOperation, sycl::plus< T > >::value||std::is_same< BinaryOperation, sycl::plus< void > >::value > IsPlus
Definition: known_identity.hpp:24
sycl::_V1::detail::has_known_identity_impl
Definition: known_identity.hpp:125
sycl::_V1::detail::IsKnownIdentityOp
bool_constant< IsZeroIdentityOp< T, BinaryOperation >::value||IsOneIdentityOp< T, BinaryOperation >::value||IsOnesIdentityOp< T, BinaryOperation >::value||IsMinimumIdentityOp< T, BinaryOperation >::value||IsMaximumIdentityOp< T, BinaryOperation >::value||IsFalseIdentityOp< T, BinaryOperation >::value||IsTrueIdentityOp< T, BinaryOperation >::value > IsKnownIdentityOp
Definition: known_identity.hpp:122
sycl::_V1::detail::IsZeroIdentityOp
bool_constant<((is_genbool< T >::value||is_geninteger< T >::value) &&(IsPlus< T, BinaryOperation >::value||IsBitOR< T, BinaryOperation >::value||IsBitXOR< T, BinaryOperation >::value))||(is_genfloat< T >::value &&IsPlus< T, BinaryOperation >::value)||(isComplex< T >::value &&IsPlus< T, BinaryOperation >::value)> IsZeroIdentityOp
Definition: known_identity.hpp:77
sycl::_V1::half
sycl::detail::half_impl::half half
Definition: aliases.hpp:103
sycl::_V1::detail::IsTrueIdentityOp
bool_constant< IsLogicalAND< T, BinaryOperation >::value > IsTrueIdentityOp
Definition: known_identity.hpp:112
sycl::_V1::detail::IsBitAND
bool_constant< std::is_same< BinaryOperation, sycl::bit_and< T > >::value||std::is_same< BinaryOperation, sycl::bit_and< void > >::value > IsBitAND
Definition: known_identity.hpp:44
sycl::_V1::detail::IsMinimum
bool_constant< std::is_same< BinaryOperation, sycl::minimum< T > >::value||std::is_same< BinaryOperation, sycl::minimum< void > >::value > IsMinimum
Definition: known_identity.hpp:34
sycl::_V1::detail::IsMinimumIdentityOp
bool_constant<(is_genbool< T >::value||is_geninteger< T >::value||is_genfloat< T >::value) &&IsMinimum< T, BinaryOperation >::value > IsMinimumIdentityOp
Definition: known_identity.hpp:97
sycl::_V1::detail::IsFalseIdentityOp
bool_constant< IsLogicalOR< T, BinaryOperation >::value > IsFalseIdentityOp
Definition: known_identity.hpp:108
sycl::_V1::vec
Provides a cross-patform vector class template that works efficiently on SYCL devices as well as in h...
Definition: aliases.hpp:20
std
Definition: accessor.hpp:3230
sycl::_V1::detail::is_contained
Definition: type_list.hpp:54
sycl::_V1::known_identity
Definition: known_identity.hpp:397
sycl::_V1::detail::IsOnesIdentityOp
bool_constant<(is_genbool< T >::value||is_geninteger< T >::value) &&IsBitAND< T, BinaryOperation >::value > IsOnesIdentityOp
Definition: known_identity.hpp:90
sycl::_V1::detail::IsMaximumIdentityOp
bool_constant<(is_genbool< T >::value||is_geninteger< T >::value||is_genfloat< T >::value) &&IsMaximum< T, BinaryOperation >::value > IsMaximumIdentityOp
Definition: known_identity.hpp:104
sycl::_V1::ext::intel::experimental::byte
unsigned char byte
Definition: online_compiler.hpp:22
sycl::_V1::known_identity_v
constexpr AccumulatorT known_identity_v
Definition: known_identity.hpp:402
sycl::_V1::detail::IsMultiplies
bool_constant< std::is_same< BinaryOperation, sycl::multiplies< T > >::value||std::is_same< BinaryOperation, sycl::multiplies< void > >::value > IsMultiplies
Definition: known_identity.hpp:29
sycl::_V1::has_known_identity_v
constexpr bool has_known_identity_v
Definition: known_identity.hpp:392