-
Notifications
You must be signed in to change notification settings - Fork 114
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
Inconsecutive implementation of __select_backend
#1455
Inconsecutive implementation of __select_backend
#1455
Conversation
FYI: looks like our upstream implementation has the same inconsecutive implementation here: template <typename _IteratorTag, typename... _IteratorTypes>
using __are_iterators_of = std::conjunction<
std::is_base_of<_IteratorTag, typename std::iterator_traits<std::decay_t<_IteratorTypes>>::iterator_category>...>;
template <typename... _IteratorTypes>
using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>; |
@@ -31,23 +31,18 @@ namespace __internal | |||
// SFINAE with a non-iterator type by providing a default value. | |||
template <typename _IteratorTag, typename... _IteratorTypes> | |||
auto | |||
__is_iterator_of(int) -> decltype( |
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.
Here the returning type is ::std::conjunction
- looks like an error!
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.
Additionally, this implementation is incompletable with the code below:
template <typename... _IteratorTypes>
auto
__is_iterator_of(...) -> ::std::false_type;
__is_iterator_of(int) -> decltype( | ||
::std::conjunction<::std::is_base_of< | ||
_IteratorTag, typename ::std::iterator_traits<::std::decay_t<_IteratorTypes>>::iterator_category>...>{}); | ||
__is_iterator_of(int) -> typename ::std::conjunction<::std::is_base_of< |
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.
Here the returning type is the resulting type of std::conjunction
which is std::true_type
or std::false_type
(according to https://en.cppreference.com/w/cpp/types/conjunction).
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.
If I'm understanding the problem correctly, std::conjunction
falls into the same issue as doing struct __is_random_access_iterator
. There may be a simpler way of doing this, but to end up with exactly std::true_type
or std::false_type
, I think this may need to be:
std::integral_constant<bool, std::conjunction_v<...>>
where ...
is the list of std::true_type
, std::false_type
for the individual iterators provided.
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.
Never mind. I missed the ::type
at the end of your formulation which is, in fact, the more direct / simpler way I thought might exist. :)
You can ignore my previous message.
|
||
template <typename... _IteratorTypes> | ||
auto | ||
__is_iterator_of(...) -> ::std::false_type; | ||
|
||
template <typename... _IteratorTypes> | ||
struct __is_random_access_iterator : decltype(__is_iterator_of<::std::random_access_iterator_tag, _IteratorTypes...>(0)) |
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.
Here __is_random_access_iterator
is the separate type (structure) which derived from result type of decltype(__is_iterator_of<::std::random_access_iterator_tag, _IteratorTypes...>(0))
struct __is_random_access_iterator : decltype(__is_iterator_of<::std::random_access_iterator_tag, _IteratorTypes...>(0)) | ||
{ | ||
}; | ||
using __is_random_access_iterator = decltype(__is_iterator_of<::std::random_access_iterator_tag, _IteratorTypes...>(0)); |
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.
Here __is_random_access_iterator
is template alias which is exactly the same type as decltype(__is_iterator_of<::std::random_access_iterator_tag, _IteratorTypes...>(0))
|
||
template <typename... _IteratorTypes> | ||
struct __is_forward_iterator : decltype(__is_iterator_of<::std::forward_iterator_tag, _IteratorTypes...>(0)) |
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.
Here __is_forward_iterator
is the separate type (structure) which derived from result type of decltype(__is_iterator_of<::std::forward_iterator_tag, _IteratorTypes...>(0))
struct __is_forward_iterator : decltype(__is_iterator_of<::std::forward_iterator_tag, _IteratorTypes...>(0)) | ||
{ | ||
}; | ||
using __is_forward_iterator = decltype(__is_iterator_of<::std::forward_iterator_tag, _IteratorTypes...>(0)); |
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.
Here __is_forward_iterator
is template alias which is exactly the same type as decltype(__is_iterator_of<::std::forward_iterator_tag, _IteratorTypes...>(0))
@MikeDvorskiy I believe this change should fix your errors. Please try to apply these changes into your code. |
__select_backend
implementation__select_backend
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.
Based on the explanation and some experimentation in godbolt, this looks like a good fix to me.
Of course, it should wait for confirmation of fixing the error from @MikeDvorskiy
__select_backend
__select_backend
The base branch was changed.
322fb09
to
6799326
Compare
Discussed offline: |
The yet another implementation of this task is in #1456
Looks like we have incontinent implementation of
__select_backend
.Sometimes we parametrize our dispatch tags with
std::true_type
orstd::false_type
types.But in some cases we parametrize our dispatch tags with some another types like
_internal::__is_random_access_iterator<_IteratorTypes...>
In this case it's not the same as
std::true_type
orstd::false_type
types.For example let's analyze the next example of code:
With our previous implementation
overload (1)
wouldn't work foroneapi::dpl::execution::unsequenced_policy
due error in the code :because
__serial_tag
has been specialized here with some another type like__is_random_access_iterator
.This issue has been found by @MikeDvorskiy during works with tag dispatching.
Another example - some code like
__pattern_for_loop_n
Let's take a loot at our code :
The straightforward path too rewrite this function on tags is :
But here we have some problem in this param type
__serial_tag<::std::false_type>
: not always the real type of_IsVector
inside__serial_tag
isstd::true_type
orstd::false_type
.So we have the question - what is correct way to write overload of this concrete function on tags?
In this PR I am trying to resolve this point.