-
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
Enable zip_iterator to satisfy C++20 std::input_iterator constraint #1408
Conversation
typedef typename oneapi::dpl::__internal::tuple<_Types...> __it_types; | ||
|
||
public: | ||
typedef ::std::make_signed_t<::std::size_t> difference_type; | ||
typedef ::std::tuple<typename ::std::iterator_traits<_Types>::value_type...> value_type; | ||
typedef ::std::tuple<typename ::std::iterator_traits<_Types>::reference...> reference; | ||
typedef ::std::tuple<typename ::std::iterator_traits<_Types>::pointer...> pointer; | ||
typedef oneapi::dpl::__internal::tuple<typename ::std::iterator_traits<_Types>::value_type...> value_type; | ||
typedef oneapi::dpl::__internal::tuple<typename ::std::iterator_traits<_Types>::reference...> reference; | ||
typedef oneapi::dpl::__internal::tuple<typename ::std::iterator_traits<_Types>::pointer...> pointer; |
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 isn't an argument against these changes, but to provide some context / history:
In #1432 (still unmerged), we removed a similar change because zip_forward_iterator
was only used on the host side, not in hetero / dpcpp backend, and therefore did not need the tuple to be trivially copyable.
For further context about the change to use I have tested with Attempting to define |
template <typename... TTypes, typename... UTypes, template <typename> typename TQual, | ||
template <typename> typename UQual> | ||
struct basic_common_reference<oneapi::dpl::__internal::tuple<TTypes...>, oneapi::dpl::__internal::tuple<UTypes...>, | ||
TQual, UQual> |
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'm having trouble understanding TQual
and UQual
.
Are they just something which is required for this function for it to be of use to the Standard library implementation?
Perhaps it uses these to add type qualifiers like const
to the types?
Its not very clear to me as it is written in the standard.
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.
They are required for this function to be used by the standard library implementation. My understanding is that they add cvref-qualifiers to the types.
It is mentioned briefly in the explanation of std::common_reference's required behavior:
"Otherwise, if std::basic_common_reference<std::remove_cvref_t<T1>, std::remove_cvref_t<T2>, T1Q, T2Q>::type
exists, where TiQ is a unary alias template such that TiQ is U with the addition of Ti's cv- and reference qualifiers, then the member type type names that type;"
…::__internal::tuple Signed-off-by: Matthew Michel <matthew.michel@intel.com>
Signed-off-by: Matthew Michel <matthew.michel@intel.com>
Signed-off-by: Matthew Michel <matthew.michel@intel.com>
This switch allows us to use the basic_common_reference specialization for this utility we provide for C++20 and greater. Signed-off-by: Matthew Michel <matthew.michel@intel.com>
We are only allowed to extend the std namespace for program-defined types for C++ spec compliance. Signed-off-by: Matthew Michel <matthew.michel@intel.com>
Signed-off-by: Matthew Michel <matthew.michel@intel.com>
Signed-off-by: Matthew Michel <matthew.michel@intel.com>
Signed-off-by: Matthew Michel <matthew.michel@intel.com>
Signed-off-by: Matthew Michel <matthew.michel@intel.com>
5e54070
to
df72987
Compare
One thing to note is that oneDPL's internal tuple may not support everything that I don't expect problems with this necessarily... however its worth acknowledging the potential risk of such a change. I don't think I like the following option, but I'll mention it anyway for discussion: |
I have looked a bit deeper to see if we can find a way to continue to use
I have looked into this error some more and it seems to be unavoidable with The following godbolt example demonstrates the issue in C++20 and its resolution in C++23: https://godbolt.org/z/YzTje39K6. With our internal tuple implementation, this is not an issue. My take is that we add some functionality to use |
I think this is a reasonable way to limit exposure of potential issues that could arise from switching to the internal tuple, and is probably the best path. It could be possible to further limit exposure by limiting it only to the backends for which this concept is used (TBB). edit: However, without some known issue with our internal tuple to avoid, I don't think its necessary to limit only to the TBB backend, just raising it as an option. |
C++20 std::tuple is only problematic in our proxy iterator in C++20. With C++17, concepts do not exist and in C++23, adjustments to std::tuple are provided along with a basic_common_reference specialization that resolves our issues. Signed-off-by: Matthew Michel <matthew.michel@intel.com>
I have added these changes and used the exact library features macros to dictate whether to use I have chosen not to limit to just the TBB backend in this commit. My reasoning is that |
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 close to me, minor comments to address.
Signed-off-by: Matthew Michel <matthew.michel@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.
LGTM, but I'd recommend circling back with @rarutyun as well.
Signed-off-by: Matthew Michel <matthew.michel@intel.com>
Signed-off-by: Matthew Michel <matthew.michel@intel.com>
…and clang-format Signed-off-by: Matthew Michel <matthew.michel@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.
I think the remaining concern is about changing the layout of zip_forward_iterator
based upon the standard library version specified.
zip_forward_iterator
is in the __internal
namespace, but we had discussed possibly adding a comment to its definition which points out that this should stay "internal", because of the layout ABI breaking changes which occur with different standard library implementations.
It may not be clear to someone refactoring down the line that this would be problematic if they were wanting to expose it as a part of the public API.
I think such a comment is a good idea. Otherwise, I think this is the best we can do for this issue.
Signed-off-by: Matthew Michel <matthew.michel@intel.com>
Thanks, I have added a comment to address this in the zip_forward_iterator class definition. |
Signed-off-by: Matthew Michel <matthew.michel@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.
LGTM
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 the discussion with @mmichel11 and going through the files it looks good to me except one thing
Currently with C++20,
oneapi::dpl::zip_iterator
cannot satisfy the C++20 std::input_iterator constraint due to it's failure to satisfy std::indirectly_readable which requires certain common references between a iterator's value and reference types.To resolve this issue, we specialize
std::basic_common_reference
foroneapi::dpl::__internal::tuple
to recursively fetch the common reference types of each corresponding tuple element in the input tuples.Furthermore, we currently use
std::tuple
in the internalzip_forward_iterator
. In our internal use case, this becomes problematic whenoneapi::dpl::__internal::tuple
is nested insidestd::tuple
and we attempt to find common reference types. This can be produced withtransform_unary.pass
andtransform_binary.pass
with the TBB backend, where we meet compile errors such as the following:Tuple-like common reference types are not standardized until C++23 which seems to be the root of this error: https://en.cppreference.com/w/cpp/utility/tuple/basic_common_reference
To resolve such errors, I have switched
zip_forward_iterator
to use the internal tuple implementation in a manner consistent withzip_iterator
. This will invoke thebasic_common_reference
specialization provided in this PR foroneapi::dpl::__internal::tuple
and resolve the encountered compilation errors with oneTBB. Bothzip_iterator
andzip_forward_iterator
will now satisfy thestd::input_iterator
concept.