Skip to content

Commit 6c077a0

Browse files
authored
[SYCL] Add SYCL 2020 operators sycl::logical_and and sycl::logical_or (#4476)
Signed-off-by: Vyacheslav N Klochkov <[email protected]>
1 parent 27c632e commit 6c077a0

File tree

3 files changed

+120
-37
lines changed

3 files changed

+120
-37
lines changed

sycl/include/CL/sycl/functional.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ namespace sycl {
1414

1515
template <typename T = void> using plus = std::plus<T>;
1616
template <typename T = void> using multiplies = std::multiplies<T>;
17+
template <typename T = void> using bit_and = std::bit_and<T>;
1718
template <typename T = void> using bit_or = std::bit_or<T>;
1819
template <typename T = void> using bit_xor = std::bit_xor<T>;
19-
template <typename T = void> using bit_and = std::bit_and<T>;
20+
template <typename T = void> using logical_and = std::logical_and<T>;
21+
template <typename T = void> using logical_or = std::logical_or<T>;
2022

2123
template <typename T = void> struct minimum {
2224
T operator()(const T &lhs, const T &rhs) const {

sycl/include/CL/sycl/known_identity.hpp

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ using IsMaximum =
3737
bool_constant<std::is_same<BinaryOperation, sycl::maximum<T>>::value ||
3838
std::is_same<BinaryOperation, sycl::maximum<void>>::value>;
3939

40+
template <typename T, class BinaryOperation>
41+
using IsBitAND =
42+
bool_constant<std::is_same<BinaryOperation, sycl::bit_and<T>>::value ||
43+
std::is_same<BinaryOperation, sycl::bit_and<void>>::value>;
44+
4045
template <typename T, class BinaryOperation>
4146
using IsBitOR =
4247
bool_constant<std::is_same<BinaryOperation, sycl::bit_or<T>>::value ||
@@ -48,9 +53,14 @@ using IsBitXOR =
4853
std::is_same<BinaryOperation, sycl::bit_xor<void>>::value>;
4954

5055
template <typename T, class BinaryOperation>
51-
using IsBitAND =
52-
bool_constant<std::is_same<BinaryOperation, sycl::bit_and<T>>::value ||
53-
std::is_same<BinaryOperation, sycl::bit_and<void>>::value>;
56+
using IsLogicalAND = bool_constant<
57+
std::is_same<BinaryOperation, sycl::logical_and<T>>::value ||
58+
std::is_same<BinaryOperation, sycl::logical_and<void>>::value>;
59+
60+
template <typename T, class BinaryOperation>
61+
using IsLogicalOR =
62+
bool_constant<std::is_same<BinaryOperation, sycl::logical_or<T>>::value ||
63+
std::is_same<BinaryOperation, sycl::logical_or<void>>::value>;
5464

5565
// Identity = 0
5666
template <typename T, class BinaryOperation>
@@ -83,13 +93,23 @@ using IsMaximumIdentityOp =
8393
bool_constant<(is_sgeninteger<T>::value || is_sgenfloat<T>::value) &&
8494
IsMaximum<T, BinaryOperation>::value>;
8595

96+
// Identity = false
97+
template <typename T, class BinaryOperation>
98+
using IsFalseIdentityOp = bool_constant<IsLogicalOR<T, BinaryOperation>::value>;
99+
100+
// Identity = true
101+
template <typename T, class BinaryOperation>
102+
using IsTrueIdentityOp = bool_constant<IsLogicalAND<T, BinaryOperation>::value>;
103+
86104
template <typename T, class BinaryOperation>
87105
using IsKnownIdentityOp =
88106
bool_constant<IsZeroIdentityOp<T, BinaryOperation>::value ||
89107
IsOneIdentityOp<T, BinaryOperation>::value ||
90108
IsOnesIdentityOp<T, BinaryOperation>::value ||
91109
IsMinimumIdentityOp<T, BinaryOperation>::value ||
92-
IsMaximumIdentityOp<T, BinaryOperation>::value>;
110+
IsMaximumIdentityOp<T, BinaryOperation>::value ||
111+
IsFalseIdentityOp<T, BinaryOperation>::value ||
112+
IsTrueIdentityOp<T, BinaryOperation>::value>;
93113

94114
template <typename BinaryOperation, typename AccumulatorT>
95115
struct has_known_identity_impl
@@ -101,16 +121,16 @@ struct known_identity_impl {};
101121

102122
/// Returns zero as identity for ADD, OR, XOR operations.
103123
template <typename BinaryOperation, typename AccumulatorT>
104-
struct known_identity_impl<BinaryOperation, AccumulatorT,
105-
typename std::enable_if<IsZeroIdentityOp<
106-
AccumulatorT, BinaryOperation>::value>::type> {
124+
struct known_identity_impl<
125+
BinaryOperation, AccumulatorT,
126+
std::enable_if_t<IsZeroIdentityOp<AccumulatorT, BinaryOperation>::value>> {
107127
static constexpr AccumulatorT value = 0;
108128
};
109129

110130
template <typename BinaryOperation>
111-
struct known_identity_impl<BinaryOperation, half,
112-
typename std::enable_if<IsZeroIdentityOp<
113-
half, BinaryOperation>::value>::type> {
131+
struct known_identity_impl<
132+
BinaryOperation, half,
133+
std::enable_if_t<IsZeroIdentityOp<half, BinaryOperation>::value>> {
114134
static constexpr half value =
115135
#ifdef __SYCL_DEVICE_ONLY__
116136
0;
@@ -121,16 +141,16 @@ struct known_identity_impl<BinaryOperation, half,
121141

122142
/// Returns one as identify for MULTIPLY operations.
123143
template <typename BinaryOperation, typename AccumulatorT>
124-
struct known_identity_impl<BinaryOperation, AccumulatorT,
125-
typename std::enable_if<IsOneIdentityOp<
126-
AccumulatorT, BinaryOperation>::value>::type> {
144+
struct known_identity_impl<
145+
BinaryOperation, AccumulatorT,
146+
std::enable_if_t<IsOneIdentityOp<AccumulatorT, BinaryOperation>::value>> {
127147
static constexpr AccumulatorT value = 1;
128148
};
129149

130150
template <typename BinaryOperation>
131-
struct known_identity_impl<BinaryOperation, half,
132-
typename std::enable_if<IsOneIdentityOp<
133-
half, BinaryOperation>::value>::type> {
151+
struct known_identity_impl<
152+
BinaryOperation, half,
153+
std::enable_if_t<IsOneIdentityOp<half, BinaryOperation>::value>> {
134154
static constexpr half value =
135155
#ifdef __SYCL_DEVICE_ONLY__
136156
1;
@@ -141,17 +161,17 @@ struct known_identity_impl<BinaryOperation, half,
141161

142162
/// Returns bit image consisting of all ones as identity for AND operations.
143163
template <typename BinaryOperation, typename AccumulatorT>
144-
struct known_identity_impl<BinaryOperation, AccumulatorT,
145-
typename std::enable_if<IsOnesIdentityOp<
146-
AccumulatorT, BinaryOperation>::value>::type> {
164+
struct known_identity_impl<
165+
BinaryOperation, AccumulatorT,
166+
std::enable_if_t<IsOnesIdentityOp<AccumulatorT, BinaryOperation>::value>> {
147167
static constexpr AccumulatorT value = ~static_cast<AccumulatorT>(0);
148168
};
149169

150170
/// Returns maximal possible value as identity for MIN operations.
151171
template <typename BinaryOperation, typename AccumulatorT>
152172
struct known_identity_impl<BinaryOperation, AccumulatorT,
153-
typename std::enable_if<IsMinimumIdentityOp<
154-
AccumulatorT, BinaryOperation>::value>::type> {
173+
std::enable_if_t<IsMinimumIdentityOp<
174+
AccumulatorT, BinaryOperation>::value>> {
155175
static constexpr AccumulatorT value =
156176
std::numeric_limits<AccumulatorT>::has_infinity
157177
? std::numeric_limits<AccumulatorT>::infinity()
@@ -161,22 +181,38 @@ struct known_identity_impl<BinaryOperation, AccumulatorT,
161181
/// Returns minimal possible value as identity for MAX operations.
162182
template <typename BinaryOperation, typename AccumulatorT>
163183
struct known_identity_impl<BinaryOperation, AccumulatorT,
164-
typename std::enable_if<IsMaximumIdentityOp<
165-
AccumulatorT, BinaryOperation>::value>::type> {
184+
std::enable_if_t<IsMaximumIdentityOp<
185+
AccumulatorT, BinaryOperation>::value>> {
166186
static constexpr AccumulatorT value =
167187
std::numeric_limits<AccumulatorT>::has_infinity
168188
? static_cast<AccumulatorT>(
169189
-std::numeric_limits<AccumulatorT>::infinity())
170190
: std::numeric_limits<AccumulatorT>::lowest();
171191
};
172192

193+
/// Returns false as identity for LOGICAL OR operations.
194+
template <typename BinaryOperation, typename AccumulatorT>
195+
struct known_identity_impl<
196+
BinaryOperation, AccumulatorT,
197+
std::enable_if_t<IsFalseIdentityOp<AccumulatorT, BinaryOperation>::value>> {
198+
static constexpr AccumulatorT value = false;
199+
};
200+
201+
/// Returns true as identity for LOGICAL AND operations.
202+
template <typename BinaryOperation, typename AccumulatorT>
203+
struct known_identity_impl<
204+
BinaryOperation, AccumulatorT,
205+
std::enable_if_t<IsTrueIdentityOp<AccumulatorT, BinaryOperation>::value>> {
206+
static constexpr AccumulatorT value = true;
207+
};
208+
173209
} // namespace detail
174210

175211
// ---- has_known_identity
176212
template <typename BinaryOperation, typename AccumulatorT>
177-
struct has_known_identity : detail::has_known_identity_impl<
178-
typename std::decay<BinaryOperation>::type,
179-
typename std::decay<AccumulatorT>::type> {};
213+
struct has_known_identity
214+
: detail::has_known_identity_impl<std::decay_t<BinaryOperation>,
215+
std::decay_t<AccumulatorT>> {};
180216

181217
template <typename BinaryOperation, typename AccumulatorT>
182218
__SYCL_INLINE_CONSTEXPR bool has_known_identity_v =
@@ -185,8 +221,8 @@ __SYCL_INLINE_CONSTEXPR bool has_known_identity_v =
185221
// ---- known_identity
186222
template <typename BinaryOperation, typename AccumulatorT>
187223
struct known_identity
188-
: detail::known_identity_impl<typename std::decay<BinaryOperation>::type,
189-
typename std::decay<AccumulatorT>::type> {};
224+
: detail::known_identity_impl<std::decay_t<BinaryOperation>,
225+
std::decay_t<AccumulatorT>> {};
190226

191227
template <typename BinaryOperation, typename AccumulatorT>
192228
__SYCL_INLINE_CONSTEXPR AccumulatorT known_identity_v =

sycl/test/basic_tests/reduction_known_identity.cpp renamed to sycl/test/basic_tests/known_identity.cpp

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,31 @@
99

1010
using namespace cl::sycl;
1111

12-
template <typename T> void checkCommonBasicKnownIdentity() {
12+
template <typename T> void checkCommonKnownIdentity() {
1313
static_assert(has_known_identity<sycl::maximum<>, T>::value);
1414
static_assert(has_known_identity<sycl::maximum<T>, T>::value);
1515
static_assert(has_known_identity<sycl::minimum<>, T>::value);
1616
static_assert(has_known_identity<sycl::minimum<T>, T>::value);
17-
}
18-
19-
template <typename T> void checkCommonKnownIdentity() {
20-
checkCommonBasicKnownIdentity<T>();
2117

2218
static_assert(has_known_identity<std::plus<>, T>::value);
2319
static_assert(has_known_identity<std::plus<T>, T>::value);
2420
static_assert(known_identity<std::plus<>, T>::value == 0);
2521
static_assert(known_identity<std::plus<T>, T>::value == 0);
2622

23+
static_assert(has_known_identity<sycl::plus<>, T>::value);
24+
static_assert(has_known_identity<sycl::plus<T>, T>::value);
25+
static_assert(known_identity<sycl::plus<>, T>::value == 0);
26+
static_assert(known_identity<sycl::plus<T>, T>::value == 0);
27+
2728
static_assert(has_known_identity<std::multiplies<>, T>::value);
2829
static_assert(has_known_identity<std::multiplies<T>, T>::value);
2930
static_assert(known_identity<std::multiplies<>, T>::value == 1);
3031
static_assert(known_identity<std::multiplies<T>, T>::value == 1);
32+
33+
static_assert(has_known_identity<sycl::multiplies<>, T>::value);
34+
static_assert(has_known_identity<sycl::multiplies<T>, T>::value);
35+
static_assert(known_identity<sycl::multiplies<>, T>::value == 1);
36+
static_assert(known_identity<sycl::multiplies<T>, T>::value == 1);
3137
}
3238

3339
template <typename T> void checkIntKnownIdentity() {
@@ -39,15 +45,52 @@ template <typename T> void checkIntKnownIdentity() {
3945
static_assert(known_identity<std::bit_and<>, T>::value == Ones);
4046
static_assert(known_identity<std::bit_and<T>, T>::value == Ones);
4147

48+
static_assert(has_known_identity<sycl::bit_and<>, T>::value);
49+
static_assert(has_known_identity<sycl::bit_and<T>, T>::value);
50+
static_assert(known_identity<sycl::bit_and<>, T>::value == Ones);
51+
static_assert(known_identity<sycl::bit_and<T>, T>::value == Ones);
52+
4253
static_assert(has_known_identity<std::bit_or<>, T>::value);
4354
static_assert(has_known_identity<std::bit_or<T>, T>::value);
4455
static_assert(known_identity<std::bit_or<>, T>::value == 0);
4556
static_assert(known_identity<std::bit_or<T>, T>::value == 0);
4657

58+
static_assert(has_known_identity<sycl::bit_or<>, T>::value);
59+
static_assert(has_known_identity<sycl::bit_or<T>, T>::value);
60+
static_assert(known_identity<sycl::bit_or<>, T>::value == 0);
61+
static_assert(known_identity<sycl::bit_or<T>, T>::value == 0);
62+
4763
static_assert(has_known_identity<std::bit_xor<>, T>::value);
4864
static_assert(has_known_identity<std::bit_xor<T>, T>::value);
4965
static_assert(known_identity<std::bit_xor<>, T>::value == 0);
5066
static_assert(known_identity<std::bit_xor<T>, T>::value == 0);
67+
68+
static_assert(has_known_identity<sycl::bit_xor<>, T>::value);
69+
static_assert(has_known_identity<sycl::bit_xor<T>, T>::value);
70+
static_assert(known_identity<sycl::bit_xor<>, T>::value == 0);
71+
static_assert(known_identity<sycl::bit_xor<T>, T>::value == 0);
72+
}
73+
74+
template <typename T> void checkBoolKnownIdentity() {
75+
static_assert(has_known_identity<std::logical_and<>, T>::value);
76+
static_assert(has_known_identity<std::logical_and<T>, T>::value);
77+
static_assert(known_identity<std::logical_and<>, T>::value == true);
78+
static_assert(known_identity<std::logical_and<T>, T>::value == true);
79+
80+
static_assert(has_known_identity<sycl::logical_and<>, T>::value);
81+
static_assert(has_known_identity<sycl::logical_and<T>, T>::value);
82+
static_assert(known_identity<sycl::logical_and<>, T>::value == true);
83+
static_assert(known_identity<sycl::logical_and<T>, T>::value == true);
84+
85+
static_assert(has_known_identity<std::logical_or<>, T>::value);
86+
static_assert(has_known_identity<std::logical_or<T>, T>::value);
87+
static_assert(known_identity<std::logical_or<>, T>::value == false);
88+
static_assert(known_identity<std::logical_or<T>, T>::value == false);
89+
90+
static_assert(has_known_identity<sycl::logical_or<>, T>::value);
91+
static_assert(has_known_identity<sycl::logical_or<T>, T>::value);
92+
static_assert(known_identity<sycl::logical_or<>, T>::value == false);
93+
static_assert(known_identity<sycl::logical_or<T>, T>::value == false);
5194
}
5295

5396
int main() {
@@ -94,9 +137,11 @@ int main() {
94137
checkCommonKnownIdentity<double>();
95138
checkCommonKnownIdentity<cl_double>();
96139

97-
checkCommonBasicKnownIdentity<half>();
98-
checkCommonBasicKnownIdentity<sycl::cl_half>();
99-
checkCommonBasicKnownIdentity<::cl_half>();
140+
checkCommonKnownIdentity<half>();
141+
checkCommonKnownIdentity<sycl::cl_half>();
142+
checkCommonKnownIdentity<::cl_half>();
143+
144+
checkBoolKnownIdentity<bool>();
100145

101146
// Few negative tests just to check that it does not always return true.
102147
static_assert(!has_known_identity<std::minus<>, int>::value);

0 commit comments

Comments
 (0)