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 
12 #include <CL/sycl/functional.hpp>
13 #include <functional>
14 #include <limits>
15 #include <type_traits>
16 
18 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 // Identity = 0
67 template <typename T, class BinaryOperation>
68 using IsZeroIdentityOp =
74 
75 // Identity = 1
76 template <typename T, class BinaryOperation>
77 using IsOneIdentityOp =
80 
81 // Identity = ~0
82 template <typename T, class BinaryOperation>
85 
86 // Identity = <max possible value>
87 template <typename T, class BinaryOperation>
88 using IsMinimumIdentityOp =
91 
92 // Identity = <min possible value>
93 template <typename T, class BinaryOperation>
94 using IsMaximumIdentityOp =
97 
98 // Identity = false
99 template <typename T, class BinaryOperation>
101 
102 // Identity = true
103 template <typename T, class BinaryOperation>
105 
106 template <typename T, class BinaryOperation>
107 using IsKnownIdentityOp =
115 
116 template <typename BinaryOperation, typename AccumulatorT>
118  : std::integral_constant<
119  bool, IsKnownIdentityOp<AccumulatorT, BinaryOperation>::value> {};
120 
121 template <typename BinaryOperation, typename AccumulatorT, typename = void>
123 
125 template <typename BinaryOperation, typename AccumulatorT>
127  BinaryOperation, AccumulatorT,
128  std::enable_if_t<IsZeroIdentityOp<AccumulatorT, BinaryOperation>::value>> {
129  static constexpr AccumulatorT value = static_cast<AccumulatorT>(0);
130 };
131 
132 #if __cplusplus >= 201703L && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
133 template <typename BinaryOperation, int NumElements>
134 struct known_identity_impl<
135  BinaryOperation, vec<std::byte, NumElements>,
136  std::enable_if_t<IsZeroIdentityOp<vec<std::byte, NumElements>,
137  BinaryOperation>::value>> {
138  static constexpr vec<std::byte, NumElements> value =
140 };
141 
142 template <typename BinaryOperation, int NumElements>
143 struct known_identity_impl<
144  BinaryOperation, marray<std::byte, NumElements>,
145  std::enable_if_t<IsZeroIdentityOp<marray<std::byte, NumElements>,
146  BinaryOperation>::value>> {
147  static constexpr marray<std::byte, NumElements> value =
149 };
150 #endif
151 
152 template <typename BinaryOperation, int NumElements>
154  BinaryOperation, vec<sycl::half, NumElements>,
155  std::enable_if_t<IsZeroIdentityOp<vec<sycl::half, NumElements>,
156  BinaryOperation>::value>> {
157  static constexpr vec<sycl::half, NumElements> value =
159 };
160 
161 template <typename BinaryOperation>
163  BinaryOperation, half,
164  std::enable_if_t<IsZeroIdentityOp<half, BinaryOperation>::value>> {
165  static constexpr half value =
166 #ifdef __SYCL_DEVICE_ONLY__
167  0;
168 #else
169  cl::sycl::detail::host_half_impl::half_v2(static_cast<uint16_t>(0));
170 #endif
171 };
172 
174 template <typename BinaryOperation, typename AccumulatorT>
176  BinaryOperation, AccumulatorT,
177  std::enable_if_t<IsOneIdentityOp<AccumulatorT, BinaryOperation>::value>> {
178  static constexpr AccumulatorT value = static_cast<AccumulatorT>(1);
179 };
180 
181 #if __cplusplus >= 201703L && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
182 template <typename BinaryOperation, int NumElements>
183 struct known_identity_impl<
184  BinaryOperation, vec<std::byte, NumElements>,
186  IsOneIdentityOp<vec<std::byte, NumElements>, BinaryOperation>::value>> {
187  static constexpr vec<std::byte, NumElements> value =
189 };
190 
191 template <typename BinaryOperation, int NumElements>
192 struct known_identity_impl<
193  BinaryOperation, marray<std::byte, NumElements>,
194  std::enable_if_t<IsOneIdentityOp<marray<std::byte, NumElements>,
195  BinaryOperation>::value>> {
196  static constexpr marray<std::byte, NumElements> value =
198 };
199 #endif
200 
201 template <typename BinaryOperation>
203  BinaryOperation, half,
204  std::enable_if_t<IsOneIdentityOp<half, BinaryOperation>::value>> {
205  static constexpr half value =
206 #ifdef __SYCL_DEVICE_ONLY__
207  1;
208 #else
209  cl::sycl::detail::host_half_impl::half_v2(static_cast<uint16_t>(0x3C00));
210 #endif
211 };
212 
214 template <typename BinaryOperation, typename AccumulatorT>
216  BinaryOperation, AccumulatorT,
217  std::enable_if_t<IsOnesIdentityOp<AccumulatorT, BinaryOperation>::value>> {
218  static constexpr AccumulatorT value = static_cast<AccumulatorT>(-1LL);
219 };
220 
221 #if __cplusplus >= 201703L && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
222 template <typename BinaryOperation, int NumElements>
223 struct known_identity_impl<
224  BinaryOperation, vec<std::byte, NumElements>,
225  std::enable_if_t<IsOnesIdentityOp<vec<std::byte, NumElements>,
226  BinaryOperation>::value>> {
227  static constexpr vec<std::byte, NumElements> value =
229 };
230 
231 template <typename BinaryOperation, int NumElements>
232 struct known_identity_impl<
233  BinaryOperation, marray<std::byte, NumElements>,
234  std::enable_if_t<IsOnesIdentityOp<marray<std::byte, NumElements>,
235  BinaryOperation>::value>> {
236  static constexpr marray<std::byte, NumElements> value =
238 };
239 #endif
240 
242 template <typename BinaryOperation, typename AccumulatorT>
243 struct known_identity_impl<BinaryOperation, AccumulatorT,
244  std::enable_if_t<IsMinimumIdentityOp<
245  AccumulatorT, BinaryOperation>::value>> {
246  static constexpr AccumulatorT value = static_cast<AccumulatorT>(
247  std::numeric_limits<AccumulatorT>::has_infinity
248  ? std::numeric_limits<AccumulatorT>::infinity()
249  : (std::numeric_limits<AccumulatorT>::max)());
250 };
251 
252 #if __cplusplus >= 201703L && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
253 template <typename BinaryOperation, int NumElements>
254 struct known_identity_impl<
255  BinaryOperation, vec<std::byte, NumElements>,
256  std::enable_if_t<IsMinimumIdentityOp<vec<std::byte, NumElements>,
257  BinaryOperation>::value>> {
258  static constexpr vec<std::byte, NumElements> value =
259  static_cast<vec<std::byte, NumElements>>(
260  std::numeric_limits<vec<std::byte, NumElements>>::has_infinity
261  ? std::numeric_limits<vec<std::byte, NumElements>>::infinity()
262  : (std::numeric_limits<vec<std::byte, NumElements>>::max)());
263 };
264 
265 template <typename BinaryOperation, int NumElements>
266 struct known_identity_impl<
267  BinaryOperation, marray<std::byte, NumElements>,
268  std::enable_if_t<IsMinimumIdentityOp<marray<std::byte, NumElements>,
269  BinaryOperation>::value>> {
270  static constexpr marray<std::byte, NumElements> value =
271  static_cast<marray<std::byte, NumElements>>(
272  std::numeric_limits<marray<std::byte, NumElements>>::has_infinity
273  ? std::numeric_limits<marray<std::byte, NumElements>>::infinity()
274  : (std::numeric_limits<marray<std::byte, NumElements>>::max)());
275 };
276 #endif
277 
279 template <typename BinaryOperation, typename AccumulatorT>
280 struct known_identity_impl<BinaryOperation, AccumulatorT,
281  std::enable_if_t<IsMaximumIdentityOp<
282  AccumulatorT, BinaryOperation>::value>> {
283  static constexpr AccumulatorT value = static_cast<AccumulatorT>(
284  std::numeric_limits<AccumulatorT>::has_infinity
285  ? static_cast<AccumulatorT>(
286  -std::numeric_limits<AccumulatorT>::infinity())
287  : std::numeric_limits<AccumulatorT>::lowest());
288 };
289 
290 #if __cplusplus >= 201703L && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
291 template <typename BinaryOperation, int NumElements>
292 struct known_identity_impl<
293  BinaryOperation, vec<std::byte, NumElements>,
294  std::enable_if_t<IsMaximumIdentityOp<vec<std::byte, NumElements>,
295  BinaryOperation>::value>> {
296  static constexpr vec<std::byte, NumElements> value = static_cast<
298  std::numeric_limits<vec<std::byte, NumElements>>::has_infinity
299  ? static_cast<vec<std::byte, NumElements>>(
300  -std::numeric_limits<vec<std::byte, NumElements>>::infinity())
301  : std::numeric_limits<vec<std::byte, NumElements>>::lowest());
302 };
303 
304 template <typename BinaryOperation, int NumElements>
305 struct known_identity_impl<
306  BinaryOperation, marray<std::byte, NumElements>,
307  std::enable_if_t<IsMaximumIdentityOp<marray<std::byte, NumElements>,
308  BinaryOperation>::value>> {
309  static constexpr marray<std::byte, NumElements> value =
310  static_cast<marray<std::byte, NumElements>>(
311  std::numeric_limits<marray<std::byte, NumElements>>::has_infinity
312  ? static_cast<marray<std::byte, NumElements>>(
313  -std::numeric_limits<
314  marray<std::byte, NumElements>>::infinity())
315  : std::numeric_limits<marray<std::byte, NumElements>>::lowest());
316 };
317 #endif
318 
320 template <typename BinaryOperation, typename AccumulatorT>
322  BinaryOperation, AccumulatorT,
323  std::enable_if_t<IsFalseIdentityOp<AccumulatorT, BinaryOperation>::value>> {
324  static constexpr AccumulatorT value = static_cast<AccumulatorT>(false);
325 };
326 
327 #if __cplusplus >= 201703L && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
328 template <typename BinaryOperation, int NumElements>
329 struct known_identity_impl<
330  BinaryOperation, vec<std::byte, NumElements>,
331  std::enable_if_t<IsFalseIdentityOp<vec<std::byte, NumElements>,
332  BinaryOperation>::value>> {
333  static constexpr vec<std::byte, NumElements> value =
335 };
336 
337 template <typename BinaryOperation, size_t NumElements>
338 struct known_identity_impl<
339  BinaryOperation, marray<std::byte, NumElements>,
340  std::enable_if_t<IsFalseIdentityOp<marray<std::byte, NumElements>,
341  BinaryOperation>::value>> {
342  static constexpr marray<std::byte, NumElements> value =
344 };
345 #endif
346 
348 template <typename BinaryOperation, typename AccumulatorT>
350  BinaryOperation, AccumulatorT,
351  std::enable_if_t<IsTrueIdentityOp<AccumulatorT, BinaryOperation>::value>> {
352  static constexpr AccumulatorT value = static_cast<AccumulatorT>(true);
353 };
354 
355 #if __cplusplus >= 201703L && (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
356 template <typename BinaryOperation, int NumElements>
357 struct known_identity_impl<
358  BinaryOperation, vec<std::byte, NumElements>,
359  std::enable_if_t<IsTrueIdentityOp<vec<std::byte, NumElements>,
360  BinaryOperation>::value>> {
361  static constexpr vec<std::byte, NumElements> value =
363 };
364 
365 template <typename BinaryOperation, int NumElements>
366 struct known_identity_impl<
367  BinaryOperation, marray<std::byte, NumElements>,
368  std::enable_if_t<IsTrueIdentityOp<marray<std::byte, NumElements>,
369  BinaryOperation>::value>> {
370  static constexpr marray<std::byte, NumElements> value =
372 };
373 #endif
374 
375 } // namespace detail
376 
377 // ---- has_known_identity
378 template <typename BinaryOperation, typename AccumulatorT>
380  : detail::has_known_identity_impl<std::decay_t<BinaryOperation>,
381  std::decay_t<AccumulatorT>> {};
382 
383 template <typename BinaryOperation, typename AccumulatorT>
386 
387 // ---- known_identity
388 template <typename BinaryOperation, typename AccumulatorT>
390  : detail::known_identity_impl<std::decay_t<BinaryOperation>,
391  std::decay_t<AccumulatorT>> {};
392 
393 template <typename BinaryOperation, typename AccumulatorT>
396 
397 } // namespace sycl
398 } // __SYCL_INLINE_NAMESPACE(cl)
cl::sycl::detail::known_identity_impl
Definition: known_identity.hpp:122
cl::sycl::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
cl::sycl::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
cl::sycl::detail::IsFalseIdentityOp
bool_constant< IsLogicalOR< T, BinaryOperation >::value > IsFalseIdentityOp
Definition: known_identity.hpp:100
cl::sycl::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
cl::sycl::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:114
cl::sycl::detail::IsOneIdentityOp
bool_constant<(is_geninteger< T >::value||is_genfloat< T >::value) &&IsMultiplies< T, BinaryOperation >::value > IsOneIdentityOp
Definition: known_identity.hpp:79
cl::sycl::detail::is_contained
Definition: type_list.hpp:54
cl::sycl::detail::IsOnesIdentityOp
bool_constant< is_geninteger< T >::value &&IsBitAND< T, BinaryOperation >::value > IsOnesIdentityOp
Definition: known_identity.hpp:84
cl::sycl::detail::has_known_identity_impl
Definition: known_identity.hpp:117
sycl
Definition: invoke_simd.hpp:68
bool_constant
max
simd< _Tp, _Abi > max(const simd< _Tp, _Abi > &, const simd< _Tp, _Abi > &) noexcept
cl::sycl::has_known_identity
Definition: known_identity.hpp:379
cl::sycl::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
cl::sycl::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
cl::sycl::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
cl::sycl::detail::half_impl::half
Definition: half_type.hpp:329
cl::sycl::known_identity_v
__SYCL_INLINE_CONSTEXPR AccumulatorT known_identity_v
Definition: known_identity.hpp:394
generic_type_traits.hpp
cl::sycl::detail::IsZeroIdentityOp
bool_constant<(is_geninteger< T >::value &&(IsPlus< T, BinaryOperation >::value||IsBitOR< T, BinaryOperation >::value||IsBitXOR< T, BinaryOperation >::value))||(is_genfloat< T >::value &&IsPlus< T, BinaryOperation >::value)> IsZeroIdentityOp
Definition: known_identity.hpp:73
cl::sycl::byte
unsigned char byte
Definition: image.hpp:59
cl
We provide new interfaces for matrix muliply in this patch:
Definition: access.hpp:13
cl::sycl::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
cl::sycl::detail::host_half_impl::half_v2
Definition: half_type.hpp:198
cl::sycl::detail::IsTrueIdentityOp
bool_constant< IsLogicalAND< T, BinaryOperation >::value > IsTrueIdentityOp
Definition: known_identity.hpp:104
cl::sycl::vec
Provides a cross-patform vector class template that works efficiently on SYCL devices as well as in h...
Definition: aliases.hpp:19
cl::sycl::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
std
Definition: accessor.hpp:2617
__SYCL_INLINE_CONSTEXPR
#define __SYCL_INLINE_CONSTEXPR
Definition: defines_elementary.hpp:65
cl::sycl::marray
Provides a cross-patform math array class template that works on SYCL devices as well as in host C++ ...
Definition: generic_type_lists.hpp:24
cl::sycl::known_identity
Definition: known_identity.hpp:389
cl::sycl::detail::IsMaximumIdentityOp
bool_constant<(is_geninteger< T >::value||is_genfloat< T >::value) &&IsMaximum< T, BinaryOperation >::value > IsMaximumIdentityOp
Definition: known_identity.hpp:96
cl::sycl::detail::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: stl_type_traits.hpp:24
cl::sycl::detail::IsMinimumIdentityOp
bool_constant<(is_geninteger< T >::value||is_genfloat< T >::value) &&IsMinimum< T, BinaryOperation >::value > IsMinimumIdentityOp
Definition: known_identity.hpp:90
cl::sycl::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
cl::sycl::has_known_identity_v
__SYCL_INLINE_CONSTEXPR bool has_known_identity_v
Definition: known_identity.hpp:384
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:12