-
Notifications
You must be signed in to change notification settings - Fork 795
[SYCL] Add is_native_function_object trait #2412
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 all commits
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 | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -190,6 +190,28 @@ using EnableIfIsNonNativeOp = cl::sycl::detail::enable_if_t< | |||||||||||||||
!cl::sycl::detail::is_native_op<T, BinaryOperation>::value, | ||||||||||||||||
T>; | ||||||||||||||||
|
||||||||||||||||
template <typename T> | ||||||||||||||||
struct is_native_function_object_impl : std::false_type {}; | ||||||||||||||||
|
||||||||||||||||
template <template <typename> class BinaryOperation, typename T> | ||||||||||||||||
struct is_native_function_object_impl<BinaryOperation<T>> | ||||||||||||||||
: std::integral_constant< | ||||||||||||||||
bool, (sycl::detail::is_scalar_arithmetic<T>::value || | ||||||||||||||||
sycl::detail::is_vector_arithmetic<T>::value || | ||||||||||||||||
std::is_same<T, void>::value) && | ||||||||||||||||
sycl::detail::is_native_op<T, BinaryOperation<T>>::value> { | ||||||||||||||||
}; | ||||||||||||||||
Comment on lines
+198
to
+203
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 mentioned it as a minor in the other thread. I don't think there is any value in checking anything about
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. This is much harder than I anticipated. You're right that the specification doesn't say anything about checking You'd almost convinced me (and I started implementing your suggestion), but then I realized that if SYCL itself doesn't provide a trait that checks the combination of Consider the below: is_native_function_object_v<BinaryOperation> && /* T is a SYCL fundamental type */ With your proposed patch, this will return true if |
||||||||||||||||
|
||||||||||||||||
template <typename T> | ||||||||||||||||
struct is_native_function_object | ||||||||||||||||
: is_native_function_object_impl<typename std::decay<T>::type> {}; | ||||||||||||||||
|
||||||||||||||||
#if __cplusplus >= 201703L | ||||||||||||||||
rolandschulz marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
template <typename T> | ||||||||||||||||
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 think we may emulate To be clear, I am ok to leave it as is. Just wanted to point out that if it's important to have that API prior c++17 there is the way 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'm leaning towards leaving it as it is. The My opinion would be different if there was a precedent for emulating standard SYCL 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. Variable templates were added in C++14. It is true that they weren't added to the STL until C++17. But I see no reason why that should impact us. Therefore I think this should be enabled for C++14 (but not C++11). |
||||||||||||||||
inline constexpr bool is_native_function_object_v = | ||||||||||||||||
is_native_function_object<T>::value; | ||||||||||||||||
#endif | ||||||||||||||||
|
||||||||||||||||
template <typename Group> bool all_of(Group, bool pred) { | ||||||||||||||||
static_assert(sycl::detail::is_generic_group<Group>::value, | ||||||||||||||||
"Group algorithms only support the sycl::group and " | ||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// RUN: %clangxx -std=c++17 -fsyntax-only -Xclang -verify %s -I %sycl_include -Xclang -verify-ignore-unexpected=note,warning | ||
// expected-no-diagnostics | ||
#include <CL/sycl.hpp> | ||
|
||
using namespace sycl::ONEAPI; | ||
|
||
struct CustomType {}; | ||
|
||
template <typename T> struct CustomFunctor {}; | ||
|
||
int main() { | ||
static_assert(is_native_function_object_v<plus<>>); | ||
rolandschulz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
static_assert(is_native_function_object_v<multiplies<>>); | ||
static_assert(is_native_function_object_v<bit_or<>>); | ||
static_assert(is_native_function_object_v<bit_xor<>>); | ||
static_assert(is_native_function_object_v<bit_and<>>); | ||
static_assert(is_native_function_object_v<const plus<>>); | ||
static_assert(is_native_function_object_v<plus<float>>); | ||
static_assert(is_native_function_object_v<plus<sycl::vec<float, 4>>>); | ||
static_assert(!is_native_function_object_v<plus<CustomType>>); | ||
static_assert(!is_native_function_object_v<CustomFunctor<float>>); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case of T is void (when real type will be auto-deduced on binary_op call) - how an identity will be auto-detected?
In general - it is not possible...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that's the interesting question
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Above John wrote:
Are you referring to the same or something different? If something different what identity do you mean? This is the reason I think we shouldn't test
T
at all and only testBinaryOperation
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An identity value isn't always required by the group algorithms. For example,
reduce
andexclusive_scan
all take aninit
parameter for the cases where the identity value is unknown.We should introduce a separate type trait for whether a functor has a known identity, and it shouldn't be tied to whether the functor is declared in the standard. @v-klochkov's already has something like this in the
reduction
implementation; we need to make it official, and provide a mechanism for users to declare the identity values for custom functors.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
John, it seems that we may incorrect result in case of considering an init parameter instead of identity... Or you want to
say the group algorithms don't combine the partial "sums"? ('m not properly aware about the group algorithms. Please, correct me if I mistake.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The kernel-wide
reduction
needs an identity value for optimization purposes, because it's possible for a work-item executing a kernel to contribute nothing to the reduction. In such cases, the fact that the work-item didn't contribute anything needs to be tracked somehow (e.g. by storing astd::optional
or an extrabool
), or the work-item's contribution can be initialized to a value that doesn't impact the result (i.e. the identity value).With the most common forms of
reduce
andexclusive_scan
, all work-items contribute a value to the operation, and so that initialization issue goes away. I think the only form that strictly requires a known identity issycl::exclusive_scan(Group, T, BinaryOperation)
, because it's not obvious what value to return on the first work-item otherwise.