DPC++ Runtime
Runtime libraries for oneAPI DPC++
functional.hpp
Go to the documentation of this file.
1 //==----------- functional.hpp --- SYCL functional -------------------------==//
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 #include <sycl/functional.hpp>
11 
12 #include <functional>
13 
14 namespace sycl {
16 namespace ext::oneapi {
17 
18 template <typename T = void> using plus = std::plus<T>;
19 template <typename T = void> using multiplies = std::multiplies<T>;
20 template <typename T = void> using bit_or = std::bit_or<T>;
21 template <typename T = void> using bit_xor = std::bit_xor<T>;
22 template <typename T = void> using bit_and = std::bit_and<T>;
23 template <typename T = void> using maximum = sycl::maximum<T>;
24 template <typename T = void> using minimum = sycl::minimum<T>;
25 
26 } // namespace ext::oneapi
27 
28 #ifdef __SYCL_DEVICE_ONLY__
29 namespace detail {
30 
31 struct GroupOpISigned {};
32 struct GroupOpIUnsigned {};
33 struct GroupOpFP {};
34 
35 template <typename T, typename = void> struct GroupOpTag;
36 
37 template <typename T>
38 struct GroupOpTag<T, detail::enable_if_t<detail::is_sigeninteger<T>::value>> {
39  using type = GroupOpISigned;
40 };
41 
42 template <typename T>
43 struct GroupOpTag<T, detail::enable_if_t<detail::is_sugeninteger<T>::value>> {
44  using type = GroupOpIUnsigned;
45 };
46 
47 template <typename T>
48 struct GroupOpTag<T, detail::enable_if_t<detail::is_sgenfloat<T>::value>> {
49  using type = GroupOpFP;
50 };
51 
52 #define __SYCL_CALC_OVERLOAD(GroupTag, SPIRVOperation, BinaryOperation) \
53  template <typename T, __spv::GroupOperation O, __spv::Scope::Flag S> \
54  static T calc(GroupTag, T x, BinaryOperation) { \
55  using ConvertedT = detail::ConvertToOpenCLType_t<T>; \
56  \
57  using OCLT = \
58  conditional_t<std::is_same<ConvertedT, cl_char>() || \
59  std::is_same<ConvertedT, cl_short>(), \
60  cl_int, \
61  conditional_t<std::is_same<ConvertedT, cl_uchar>() || \
62  std::is_same<ConvertedT, cl_ushort>(), \
63  cl_uint, ConvertedT>>; \
64  OCLT Arg = x; \
65  OCLT Ret = \
66  __spirv_Group##SPIRVOperation(S, static_cast<unsigned int>(O), Arg); \
67  return Ret; \
68  }
69 
70 // calc for sycl function objects
71 __SYCL_CALC_OVERLOAD(GroupOpISigned, SMin, sycl::minimum<T>)
72 __SYCL_CALC_OVERLOAD(GroupOpIUnsigned, UMin, sycl::minimum<T>)
73 __SYCL_CALC_OVERLOAD(GroupOpFP, FMin, sycl::minimum<T>)
74 
75 __SYCL_CALC_OVERLOAD(GroupOpISigned, SMax, sycl::maximum<T>)
76 __SYCL_CALC_OVERLOAD(GroupOpIUnsigned, UMax, sycl::maximum<T>)
77 __SYCL_CALC_OVERLOAD(GroupOpFP, FMax, sycl::maximum<T>)
78 
79 __SYCL_CALC_OVERLOAD(GroupOpISigned, IAdd, sycl::plus<T>)
80 __SYCL_CALC_OVERLOAD(GroupOpIUnsigned, IAdd, sycl::plus<T>)
81 __SYCL_CALC_OVERLOAD(GroupOpFP, FAdd, sycl::plus<T>)
82 
83 __SYCL_CALC_OVERLOAD(GroupOpISigned, IMulKHR, sycl::multiplies<T>)
84 __SYCL_CALC_OVERLOAD(GroupOpIUnsigned, IMulKHR, sycl::multiplies<T>)
85 __SYCL_CALC_OVERLOAD(GroupOpFP, FMulKHR, sycl::multiplies<T>)
86 
87 __SYCL_CALC_OVERLOAD(GroupOpISigned, BitwiseOrKHR, sycl::bit_or<T>)
88 __SYCL_CALC_OVERLOAD(GroupOpIUnsigned, BitwiseOrKHR, sycl::bit_or<T>)
89 __SYCL_CALC_OVERLOAD(GroupOpISigned, BitwiseXorKHR, sycl::bit_xor<T>)
90 __SYCL_CALC_OVERLOAD(GroupOpIUnsigned, BitwiseXorKHR, sycl::bit_xor<T>)
91 __SYCL_CALC_OVERLOAD(GroupOpISigned, BitwiseAndKHR, sycl::bit_and<T>)
92 __SYCL_CALC_OVERLOAD(GroupOpIUnsigned, BitwiseAndKHR, sycl::bit_and<T>)
93 
94 #undef __SYCL_CALC_OVERLOAD
95 
96 template <typename T, __spv::GroupOperation O, __spv::Scope::Flag S,
97  template <typename> class BinaryOperation>
98 static T calc(typename GroupOpTag<T>::type, T x, BinaryOperation<void>) {
99  return calc<T, O, S>(typename GroupOpTag<T>::type(), x, BinaryOperation<T>());
100 }
101 
102 } // namespace detail
103 #endif // __SYCL_DEVICE_ONLY__
104 
105 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
106 } // namespace sycl
#define __SYCL_INLINE_VER_NAMESPACE(X)
typename std::enable_if< B, T >::type enable_if_t
std::plus< T > plus
Definition: functional.hpp:18
std::multiplies< T > multiplies
Definition: functional.hpp:19
std::bit_or< T > bit_or
Definition: functional.hpp:20
sycl::minimum< T > minimum
Definition: functional.hpp:24
sycl::maximum< T > maximum
Definition: functional.hpp:23
std::bit_xor< T > bit_xor
Definition: functional.hpp:21
std::bit_and< T > bit_and
Definition: functional.hpp:22
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14