-
Notifications
You must be signed in to change notification settings - Fork 113
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
Enable binary comparison operations for internal tuple #1472
Conversation
3b00d48
to
a2efde9
Compare
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.
LGTM
include/oneapi/dpl/pstl/tuple_impl.h
Outdated
template <typename _U1, typename... _U, typename = ::std::enable_if_t<(sizeof...(_U) == sizeof...(T))>> \ | ||
friend bool operator __OPERATOR(const tuple& __lhs, const oneapi::dpl::__internal::tuple<_U1, _U...>& __rhs) \ | ||
{ \ | ||
return static_cast<std::tuple<T1, T...>>(__lhs) __OPERATOR static_cast<std::tuple<_U1, _U...>>(__rhs); \ |
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.
Slightly pedantic, but std::
should be ::std::
to match the rest of the methods in this class.
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.
So, I think our mindset has changed on ::std
vs std
. Tagging @MikeDvorskiy. We had talked about adding this to some sort of a style document or at least making an announcement, but that hasn't happened yet.
I was told that it is unnecessary to use ::std
vs std
and that new code should be the later. Similar to formatting though, we don't want to ruin the "blame" by changing it aggressively everywhere.
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.
Ah, okay. I wasn't aware of this discussion. Better to stick with std::
here in that case.
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.
Yes, we need to propagate that decision out and also codify it somewhere here in the repo in some sort of a style guide, I think. We could even simply add a section to CONTRIBUTING.md
with some general rules and best practices.
I'm working on adding some unit testing for tuple to the test suite. Once I add that, I will probably revert the changes to |
I was curious if the three provided functions in the macro were enough to cover all of the cases to compare. But I enumerated them and it does seem like it is sufficient. There are three tuple types we would like to compare:
Based on this, it seems like the three functions that are defined are sufficient. |
Yes, thanks for doing this enumeration of the possibilities. Working on a test which should prove that out as well. |
b84f8b0
to
bd94d9b
Compare
OK, now all those options @adamfidel mentioned should be covered by the unit test. I've reverted the I've also rebased to have 2 commits so that we can separate the unit test addition in the main git log from the tuple changes. |
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 better if we will support all restrictions for these operators like in https://en.cppreference.com/w/cpp/utility/tuple : all these operators will be removed in C++20.
main() | ||
{ | ||
|
||
test_tuple(std::tuple<int, int, int>{1, 2, 3}, std::tuple<int, int, int>{1, 2, 3}); |
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.
Does it make sense to add tests for Kernels too?
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.
Do you mean calling sycl kernels or oneDPL algos with oneDPL internal tuples? Checking is_trivially_copyable
should check that this is possible. Also, we have other tests which utilize zip_iterator
with the algorithms which should provide system level testing.
My goal when adding this new test is to unit test tuple for some specific attributes we want it to have.
@SergeyKopienko Also, these operators are removed in C++20, but only in favor of the |
For me it's looks like we should implement all these operators only for C++17 version and implement |
That's fine. I can do that. |
I'm wondering if it is a good idea after some exploration... The way it is currently, it works for both C++17 and C++20 and offers the support and comparison with If we change it to be I think the only thing we miss out on in c++20 with the current implementation is if someone explicitly uses the |
Understood, ok. |
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.
Let me ask: what's a motivation for that internal::tuple functionality extending?
Other words, where in OneDPL impl do we need such functionality?
Example: Then, if we are covering this case, why should it work with one such operator and not others? Similarly, since we return this tuple type from I'd say the most important use case is to (1) allow binary comparison between two same element-typed internal tuples as that is what we may encounter within oneDPL algorithm calls. This allows a much simpler implementation. Second most interesting would be (2) comparisons between onedpl tuples with different element types as users could contrive examples which this is necessary inside of a oneDPL call. Least interesting is (3) interoperability with I'd be willing to drop (3) from this PR, it causes the most complication in implementation and has the least utility. |
I've re-organized the code to make clear which code is to support which functionality. The first set of operators covers 1+2, the second and third sets of operators are required to enable (3). (If we wanted to only support (1), we could reduce the complexity of the first set of operators to just use |
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
42d7935
to
2a167c2
Compare
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@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.
After some help from @akukanov, I was able to consolidate 3 the different implementations of the comparators using some trait definitions.
Its a little tricky because we have to avoid ambiguous definitions of the same comparator from two separate instantiations of the internal tuple. The logic in the current set of enable_if
is able to work by only defining comparisons between two different internal tuples in the instantiation matching the lhs
type.
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@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.
The implementation looks good to me. The only question is whether oneapi::dpl::__internal
namespace "prefix" is justified when used within the same namespace; but I do not mind it either way.
I have not reviewed the test.
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
Signed-off-by: Dan Hoeflinger <dan.hoeflinger@intel.com>
…ple" This reverts commit 0690030.
Summary
This PR enables comparison
<
,>
,<=
,>=
of our internal tupleoneapi::dpl::__internal::tuple<T...>
with anotheroneapi::dpl::__internal::tuple<U...>
orstd::tuple<U...>
with equal number of elements where corresponding elements from rhs and lhs are comparable.We use the std::tuple implementation for these operations by static casting and repeating the operation.
We extend the same to
==
and!=
, where we previously implemented the operation directly.Details
We already provide an implicit conversion operator to a
std::tuple
, and also are able to construct from astd::tuple
. However, when a template function is considered for overload resolution it does type deduction and will only use exact matches. It will not use any implicit conversion to build the candidate list. Therefore, this implicit conversion is not used when searching for resolution foroperator<
, and we cannot take advantage ofstd::tuple
's implementation of these operators (at least without extra effort).We use a macro to unify implementation of all binary operators in the same fashion and reduce code to a minimum.