-
Notifications
You must be signed in to change notification settings - Fork 115
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
[oneDPL][ranges] + zip_view implementation for C++20 #1877
base: main
Are you sure you want to change the base?
Conversation
9342293
to
91cf6b0
Compare
603daed
to
80ef9c5
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.
Let me leave just a couple of minor comments. I am going to look at the whole PR during this week.
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.
What do you think about testing the following properties of zip_view/zip?
- begin/end (they should also probably be checked if they are iterators)
- cbegin/cend
- front/back
- size
- empty
- operator bool
- construction:
- ranges::zip(...)/ranges::zip_view(...)
- empty view (views::zip())
- another view (*move construction is not checked)
- another zip_view
- ranges::zip(...) is a customization point object
I assume that the functionality must match what is required from c++ standard looking at the description. That's why I suggest testing all these properties. Let me know if the implementation is expected to be more relaxed (and how if it is).
The description says:
According to SYCL 2020, |
The advantage here of using oneDPL's tuple is that it is trivially copyable (for trivially copyable types) which means that any class or structure which uses oneDPL's tuple can be implicitly device copyable rather than requiring a specialization of sycl::is_device_copyable (because of the tuple). The advantage is not just to avoid extra code here but also to not impose requirements on users to provide these specializations for types which are composed of a zip_view as well. There can be downsides to using oneDPLs tuple in that it may not be as fully featured as |
Actually, before C++23 standard library there is a problem with |
f1c08a6
to
74d52be
Compare
regarding > * cbegin + cend
|
78abd7f
to
fdf3e9b
Compare
if (x.current_ < y.current_) | ||
return -1; | ||
else if (x.current_ == y.current_) | ||
return 0; | ||
return 1; //x.current > y.current_ |
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 cannot we use x.current <=> y.current
? Spaceship operator is undefined for some of our internal iterator types or it is undefined for internal tuple?
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, spaceship operator is undefined for x.current_
...
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.
When adding comparison between internal tuples, we looked at adding spaceship and it was deemed not worth the effort at the time. We could use this as motivation for adding it, but it would require a bit of work. We would need to trigger it off of __cpp_lib_three_way_comparison >= 201907L
, and in that case replace the existing comparison operators with the spaceship, to time it properly with std::tuple <=> operator
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 thought was that it wasn't worth the maintenance because we would need to implement both to support our full support matrix, and it would be only helpful for those explicitly calling <=>
on the internal tuple (which is what we might want to do here as I understand it).
|
||
std::sort(zip_view_sort.begin(), zip_view_sort.begin() + max_n, [](const auto& val1, const auto& val2) { return std::get<0>(val1) > std::get<0>(val2); }); | ||
for(int i = 0; i < max_n; ++i) | ||
assert(std::get<0>(zip_view_sort[i]) == max_n - 1 - i); |
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.
Our testing framework is not adapted for assert
: it defines NDEBUG during release test builds. We should either avoid that definition, or do not rely on assert
in the 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.
- In spite of that we are using
assert
in our tests more then 10 files... It seems an issue should be created. - I know that a better way to use our own macro like
EXPECT_TRUE
f.e.
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 will create it.
- That sounds good. Could you do it? I see that there is still one
assert
in the test.
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 will create it.
Done: #1945.
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.
- done.
And I suggest offline discussion aboutassert
/EXPECT_TRUE
/NDEBUG
int data[max_n] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; | ||
|
||
auto zip_view = dpl_ranges::zip(data, std::views::iota(0, max_n)) | std::views::take(5); | ||
std::ranges::for_each(zip_view, test_std_ranges::f_mutuable, [](const auto& val) { return std::get<1>(val); }); |
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 result is also should be checked. Would not it be better to use existing test_range_algo
utility?
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 is a serial std::ranges::for_each
. We believe that std::ranges::for_each
works fine. So, we are checking just compilation with zip_view
here.
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.
Even if the algorithm is proven to work well, something can theoretically be wrong with the zip_view implementation, which would result in incorrect run-time behavior, e.g. wrong begin() or end() implementation. I am still inclined it would be viable to check the result.
Perhaps, it is also makes sense to check if the operation applies only to the projected value.
std::sort(zip_view_sort.begin(), zip_view_sort.begin() + max_n, [](const auto& val1, const auto& val2) { return std::get<0>(val1) > std::get<0>(val2); }); | ||
for(int i = 0; i < max_n; ++i) | ||
EXPECT_TRUE(std::get<0>(zip_view_sort[i]) == max_n - 1 - i, "Wrong effect for std::sort with zip_view."); |
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 would also expect checking the second sequence, e.g. to test if the zipped elements are moved together.
std::vector<int> vec1(max_n); | ||
std::vector<int> vec2(max_n/2); | ||
|
||
auto zip_view = dpl_ranges::zip(vec1, vec2); |
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.
Should zip also be checked for availability in oneapi::dpl::views
namespace?
zip_view is based on view_iterface, and the later does not have cbegin/cend in c++20. That means our c++20 zip_view will not have cbegin/cend, and we are not going to provide them. Is that correct understanding? |
#ifndef _ONEDPL_ZIP_VIEW_IMPL_H | ||
#define _ONEDPL_ZIP_VIEW_IMPL_H | ||
|
||
#if _ONEDPL_CPP20_RANGES_PRESENT |
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.
Did not we think about having oneapi::dpl::zip_view
as part of namespace std::ranges
prior to C++23?
It will allow the user to have portable code for each version of the standard. Otherwise, we will need to think about aligning oneapi::dpl::zip_view
with the C++23 and later as well.
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 a kind of name injection into std::ranges
prior to C++23? Good question.
On one hand - it is useful when a user is going to modify his code forward to C++23.
On the other hand, having std::ranges::zip_view
(in result of name oneapi::dpl::zip_view
injection), enforces us to be fully compliance with standard zip_view
C++23. At least, the proposed zip_view implementation works only with random access views, for example. And we don't need more for oneDPL needs.
I would suggest rather to have an alias oneapi::dpl::zip_view
, which is our own implementation class prior to C++23 and which is std::ranges::zip_view
for C++23 and higher.
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 like the idea of having the alias to std::ranges::zip_view
in oneDPL for C++23 and higher. It perfectly fits the idea of having everything that should work in the offloaded code in oneapi::dpl
namespace.
…en zip_view::iterators
Co-authored-by: Konstantin Boyarinov <konstantin.boyarinov@intel.com>
Co-authored-by: Konstantin Boyarinov <konstantin.boyarinov@intel.com>
Co-authored-by: Konstantin Boyarinov <konstantin.boyarinov@intel.com>
Co-authored-by: Konstantin Boyarinov <konstantin.boyarinov@intel.com>
Co-authored-by: Konstantin Boyarinov <konstantin.boyarinov@intel.com>
Co-authored-by: Konstantin Boyarinov <konstantin.boyarinov@intel.com>
Co-authored-by: Konstantin Boyarinov <konstantin.boyarinov@intel.com>
Co-authored-by: Konstantin Boyarinov <konstantin.boyarinov@intel.com>
Co-authored-by: Konstantin Boyarinov <konstantin.boyarinov@intel.com>
…because they are supported only with C++23
0e35be1
to
5f43b52
Compare
[oneDPL][ranges] + zip_view implementation for C++20. The implementation and test.