-
Notifications
You must be signed in to change notification settings - Fork 787
[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
Conversation
These traits have been requested by developers who would like to determine at compile-time whether the reduction() interface supports their use-case, or whether they need to fall back to some other implementation. Signed-off-by: John Pennycook <john.pennycook@intel.com>
Exposes existing functionality of reduction implementation as part of the public API for reductions. Signed-off-by: John Pennycook <john.pennycook@intel.com>
Signed-off-by: John Pennycook <john.pennycook@intel.com>
@Fznamznon, @AlexeySachkov: Could you please take a look at the build failures here and help identify a path forwards? It looks to me like static constexpr AccumulatorT value =
std::numeric_limits<AccumulatorT>::has_infinity
? static_cast<AccumulatorT>(
-std::numeric_limits<AccumulatorT>::infinity())
: std::numeric_limits<AccumulatorT>::lowest(); I think unary |
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.
Looks good to me, I found only 1 typo.
typename std::enable_if<IsMinimumIdentityOp< | ||
AccumulatorT, BinaryOperation>::value>::type> { |
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.
Minor comment, definitely not a request to change.
This could be a little bit shorter (but same number of lines though):
typename std::enable_if<IsMinimumIdentityOp< | |
AccumulatorT, BinaryOperation>::value>::type> { | |
enable_if_t<IsMinimumIdentityOp< | |
AccumulatorT, BinaryOperation>::value>> { |
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 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 enable_if_t
differs from std::enable_if
. Can you compile locally if you make this change? Maybe I'm doing something wrong.
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 checked our enable_if_t
implementation. It is the same as in C++ standard. So, there should not be any problem. If you need help we may have a call or IM
Signed-off-by: John Pennycook <john.pennycook@intel.com>
Signed-off-by: John Pennycook <john.pennycook@intel.com>
If an implementation can identify the identity value for a given combination of accumulator type `AccumulatorT` and function object type `BinaryOperation`, the value is defined as a member of the `known_identity` trait class: | ||
```c++ | ||
template <typename BinaryOperation, typename AccumulatorT> | ||
struct known_identity { |
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 am not sure we should telling that known_identity
is a struct
on the spec level. It may be implemented as the using
to something. I would also try to align the API with integral_constant
. I understand that this is not possible for 100% but traits with values usually have some run-time API as well. The comment is applicable to other traits
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.
All of the traits in C++ are defined as a struct
, aren't they? Is there a good reason that known_identity
should be different?
I'm not sure what you're imagining when aligning with integral_constant
. In the general case, I don't think we can guarantee that the identity value is something that can be passed as a template parameter (e.g. it may be a floating-point type).
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 comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like AccumulatorT
is the the fundamental C++ type only (because it's used in std::numeric_limits
).
Two questions basing on that:
- What about custom types?
- If only fundamental types should be supported, can we introduce the
integral_constant
semantics forknown_identity
API as I suggested forhas_known_identity
?
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.
This is a short-term fix. Our reduction implementation currently only detects identity values automatically for fundamental C++ types (and half
), so that's all we've decided to cover with the traits for now.
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. std::plus<>
) the traits will continue to work as implemented here, but for anything else they'll check the function object for something like an identity
member.
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 T1
and T1
is convertible to T2
, is it safe to assume that the identity for T1
can be used?). These are important questions, but I don't think the first implementation of the traits should be blocked by them.
typename std::enable_if<IsMinimumIdentityOp< | ||
AccumulatorT, BinaryOperation>::value>::type> { |
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 checked our enable_if_t
implementation. It is the same as in C++ standard. So, there should not be any problem. If you need help we may have a call or IM
Signed-off-by: John Pennycook <john.pennycook@intel.com>
sycl/include/CL/sycl/half_type.hpp
Outdated
uint16_t Buf; | ||
friend std::numeric_limits<class cl::sycl::detail::half_impl::half>; |
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 didn't realize all is fwd-declared and therefore
friend std::numeric_limits<class cl::sycl::detail::half_impl::half>; | |
friend std::numeric_limits<half_impl::half>; |
or
friend std::numeric_limits<class cl::sycl::detail::half_impl::half>; | |
friend std::numeric_limits<sycl::half>; |
works too. Do we prefer one of these shorter options?
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 have no preference.
@rolandschulz: Are you still working on fixing the broken cases here? |
We also need resolve conflicts with #2624. |
@@ -26,6 +26,11 @@ | |||
#else | |||
#define __SYCL_CONSTEXPR_ON_DEVICE | |||
#endif | |||
#if __cplusplus >= 201402L |
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.
Why is there the sycl-include-gnu11.cpp test which checks it compiles with C++11? I thought we only support compiling as >=C++14.
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 think the RT library is C++14, but the headers are C++11.
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.
@bader , @romanovvlad - Can't we assume C++14 or newer in SYCL header files?
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 don't have a simple "yes/no" answer, but I'm aware of a couple of factors restricting usage of C++ features:
- SYCL specification: SYCL-1.2.1 relies on C++11 and SYCL-2020 relies on C++17 features. It seems to me that DPC++ is not going to support "strict SYCL-1.2.1" mode where C++14 (or later) features are not supported.
- Runtime library ABI compatibility (see the note in our contribution guide). It's hard to say if using C++14 features in SYCL headers breaks runtime ABI, but it possible and should be prevented by regression tests.
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.
We have C++ version documented at:
https://github.com/intel/llvm/blob/sycl/sycl/doc/GetStartedGuide.md#c-standard
but it doesn't answer whether C++11 mode will be functional or broken.
I think it would be good to know and catch the case when we really want to break C++11 compatibility and have some discussion on that. Maybe that's what sycl-include-gnu11.cpp test is doing?
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 test only checks that the header can be included. But not that any template in the header can be instantiated in C++11 mode. The current version of this PR passes all tests . But trying to instantiate known_identity for half in C++11 will give a compiler error (not tested).
It shouldn't have any ABI issues to use any C++14 features in the header. The problematic release for ABI issues is C++11 (e.g. string). There weren't any such things in C++14.
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.
C++14 is required now. The doc changes have been merged 10 days ago: #3053
Thanks for the fixes, @rolandschulz. Opening up to review now. |
* Add note that SYCL 2020 implementation is in progress (see issue intel#2971) * Add note that DPC++ runtime and headers require C++14 (see PR intel#2528) Signed-off-by: Pavel V Chupin <pavel.v.chupin@intel.com>
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.
Looks good to me. I suggest merging this patch as is now.
A bit later I'll fix the c++11 LIT test (the fix in that LIT test is included into #3123) and also will remove the macro _CPP14_CONSTEXPR .
@Pennycook please approve the fix if you agree with the changes and the idea to merge the fix in the current state.
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.
half_type.hpp
changes look good to me, one minor code style comment
Apparently GitHub doesn't let people approve their own PRs, but I agree with your proposal. Thanks for picking up the required LIT test and macro changes. |
These traits have been requested by developers who would like to
determine at compile-time whether the reduction() interface supports
their use-case, or whether they need to fall back to some other
implementation.
Exposes existing functionality of reduction implementation as part of
the public API for reductions.
Signed-off-by: John Pennycook john.pennycook@intel.com