-
Notifications
You must be signed in to change notification settings - Fork 797
[SYCL] Add has_known_identity/known_identity #2528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
aef3c5b
be643d0
c2ff9dc
aa2222a
0136df2
6ca8965
b791034
3717a98
d5b3766
bb3c4c2
93d9499
857bfd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -142,6 +142,62 @@ using IsKnownIdentityOp = | |||||||||
IsMinimumIdentityOp<T, BinaryOperation>::value || | ||||||||||
IsMaximumIdentityOp<T, BinaryOperation>::value>; | ||||||||||
|
||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
struct has_known_identity_impl { | ||||||||||
rarutyun marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
static constexpr bool value = | ||||||||||
IsKnownIdentityOp<AccumulatorT, BinaryOperation>::value; | ||||||||||
}; | ||||||||||
|
||||||||||
template <typename BinaryOperation, typename AccumulatorT, typename = void> | ||||||||||
struct known_identity_impl {}; | ||||||||||
|
||||||||||
/// Returns zero as identity for ADD, OR, XOR operations. | ||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
struct known_identity_impl<BinaryOperation, AccumulatorT, | ||||||||||
typename std::enable_if<IsZeroIdentityOp< | ||||||||||
AccumulatorT, BinaryOperation>::value>::type> { | ||||||||||
static constexpr AccumulatorT value = 0; | ||||||||||
}; | ||||||||||
|
||||||||||
/// Returns one as identify for MULTIPLY operations. | ||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
struct known_identity_impl<BinaryOperation, AccumulatorT, | ||||||||||
typename std::enable_if<IsOneIdentityOp< | ||||||||||
AccumulatorT, BinaryOperation>::value>::type> { | ||||||||||
static constexpr AccumulatorT value = 1; | ||||||||||
}; | ||||||||||
|
||||||||||
/// Returns bit image consisting of all ones as identity for AND operations. | ||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
struct known_identity_impl<BinaryOperation, AccumulatorT, | ||||||||||
typename std::enable_if<IsOnesIdentityOp< | ||||||||||
AccumulatorT, BinaryOperation>::value>::type> { | ||||||||||
static constexpr AccumulatorT value = ~static_cast<AccumulatorT>(0); | ||||||||||
}; | ||||||||||
|
||||||||||
/// Returns maximal possible value as identity for MIN operations. | ||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
struct known_identity_impl<BinaryOperation, AccumulatorT, | ||||||||||
typename std::enable_if<IsMinimumIdentityOp< | ||||||||||
AccumulatorT, BinaryOperation>::value>::type> { | ||||||||||
Comment on lines
+206
to
+207
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor comment, definitely not a request to change.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried this during development and couldn't get it to work. I chalked it up to me not understanding enough about how our implementation of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked our |
||||||||||
static constexpr AccumulatorT value = | ||||||||||
std::numeric_limits<AccumulatorT>::has_infinity | ||||||||||
? std::numeric_limits<AccumulatorT>::infinity() | ||||||||||
: (std::numeric_limits<AccumulatorT>::max)(); | ||||||||||
}; | ||||||||||
|
||||||||||
/// Returns minimal possible value as identity for MAX operations. | ||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
struct known_identity_impl<BinaryOperation, AccumulatorT, | ||||||||||
typename std::enable_if<IsMaximumIdentityOp< | ||||||||||
AccumulatorT, BinaryOperation>::value>::type> { | ||||||||||
static constexpr AccumulatorT value = | ||||||||||
std::numeric_limits<AccumulatorT>::has_infinity | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like Two questions basing on that:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a short-term fix. Our reduction implementation currently only detects identity values automatically for fundamental C++ types (and Eventually we want developers to be able to declare the identity value for their own types and function object types. The current thinking is that for combinations of fundamental types and known function object types (e.g. There are still some open questions about exactly what this should look like for transparent functors and what additional checks are needed (e.g. if we can determine an identity for |
||||||||||
? static_cast<AccumulatorT>( | ||||||||||
-std::numeric_limits<AccumulatorT>::infinity()) | ||||||||||
: std::numeric_limits<AccumulatorT>::lowest(); | ||||||||||
}; | ||||||||||
|
||||||||||
/// Class that is used to represent objects that are passed to user's lambda | ||||||||||
/// functions and representing users' reduction variable. | ||||||||||
/// The generic version of the class represents those reductions of those | ||||||||||
|
@@ -191,43 +247,10 @@ class reducer<T, BinaryOperation, | |||||||||
MValue = BOp(MValue, Partial); | ||||||||||
} | ||||||||||
|
||||||||||
/// Returns zero as identity for ADD, OR, XOR operations. | ||||||||||
template <typename _T = T, class _BinaryOperation = BinaryOperation> | ||||||||||
static enable_if_t<IsZeroIdentityOp<_T, _BinaryOperation>::value, _T> | ||||||||||
getIdentity() { | ||||||||||
return 0; | ||||||||||
} | ||||||||||
|
||||||||||
/// Returns one as identify for MULTIPLY operations. | ||||||||||
template <typename _T = T, class _BinaryOperation = BinaryOperation> | ||||||||||
static enable_if_t<IsOneIdentityOp<_T, _BinaryOperation>::value, _T> | ||||||||||
static enable_if_t<has_known_identity_impl<_BinaryOperation, _T>::value, _T> | ||||||||||
getIdentity() { | ||||||||||
return 1; | ||||||||||
} | ||||||||||
|
||||||||||
/// Returns bit image consisting of all ones as identity for AND operations. | ||||||||||
template <typename _T = T, class _BinaryOperation = BinaryOperation> | ||||||||||
static enable_if_t<IsOnesIdentityOp<_T, _BinaryOperation>::value, _T> | ||||||||||
getIdentity() { | ||||||||||
return ~static_cast<_T>(0); | ||||||||||
} | ||||||||||
|
||||||||||
/// Returns maximal possible value as identity for MIN operations. | ||||||||||
template <typename _T = T, class _BinaryOperation = BinaryOperation> | ||||||||||
static enable_if_t<IsMinimumIdentityOp<_T, _BinaryOperation>::value, _T> | ||||||||||
getIdentity() { | ||||||||||
return std::numeric_limits<_T>::has_infinity | ||||||||||
? std::numeric_limits<_T>::infinity() | ||||||||||
: (std::numeric_limits<_T>::max)(); | ||||||||||
} | ||||||||||
|
||||||||||
/// Returns minimal possible value as identity for MAX operations. | ||||||||||
template <typename _T = T, class _BinaryOperation = BinaryOperation> | ||||||||||
static enable_if_t<IsMaximumIdentityOp<_T, _BinaryOperation>::value, _T> | ||||||||||
getIdentity() { | ||||||||||
return std::numeric_limits<_T>::has_infinity | ||||||||||
? static_cast<_T>(-std::numeric_limits<_T>::infinity()) | ||||||||||
: std::numeric_limits<_T>::lowest(); | ||||||||||
return known_identity_impl<_BinaryOperation, _T>::value; | ||||||||||
} | ||||||||||
|
||||||||||
template <typename _T = T> | ||||||||||
|
@@ -1076,6 +1099,26 @@ reduction(T *VarPtr, BinaryOperation) { | |||||||||
access::mode::read_write>(VarPtr); | ||||||||||
} | ||||||||||
|
||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
struct has_known_identity : detail::has_known_identity_impl< | ||||||||||
typename std::decay<BinaryOperation>::type, | ||||||||||
typename std::decay<AccumulatorT>::type> {}; | ||||||||||
#if __cplusplus >= 201703L | ||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
inline constexpr bool has_known_identity_v = | ||||||||||
has_known_identity<BinaryOperation, AccumulatorT>::value; | ||||||||||
#endif | ||||||||||
|
||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
struct known_identity | ||||||||||
: detail::known_identity_impl<typename std::decay<BinaryOperation>::type, | ||||||||||
typename std::decay<AccumulatorT>::type> {}; | ||||||||||
#if __cplusplus >= 201703L | ||||||||||
template <typename BinaryOperation, typename AccumulatorT> | ||||||||||
inline constexpr AccumulatorT known_identity_v = | ||||||||||
known_identity<BinaryOperation, AccumulatorT>::value; | ||||||||||
#endif | ||||||||||
|
||||||||||
} // namespace ONEAPI | ||||||||||
} // namespace sycl | ||||||||||
} // __SYCL_INLINE_NAMESPACE(cl) |
Uh oh!
There was an error while loading. Please reload this page.