-
Notifications
You must be signed in to change notification settings - Fork 113
[oneDPL] Indirectly Device Accessible Iterator Customization Point and Public Trait #620
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
source/elements/oneDPL/source/parallel_api/execution_policies.rst
Outdated
Show resolved
Hide resolved
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
source/elements/oneDPL/source/parallel_api/execution_policies.rst
Outdated
Show resolved
Hide resolved
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
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.
Despite a significant amount of suggestions, I think that wording is pretty good, overall. There is one place that is related to the design, where we need to be careful to not prohibit some intendent use-cases.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
A free function ``is_onedpl_device_accessible_content_iterator(IteratorT)`` may be defined, which accepts an argument | ||
of type ``IteratorT`` and returns a type with the characteristics of ``std::true_type`` if ``IteratorT`` refers to |
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 it's not true for a generic case. As I mentioned, I believe std::conjunction
is an important use case. However, std::conjunction
might not have std::true_type
or std::false_type
characteristics at all.
I believe that this sentence about characteristics has a perfect fit to where you describe is_device_accessible_content_iterator
trait itself instead of the current wording, which is "... evaluates to a type...". I would just say "...has characteristics of std::true_type
..."
Here we need something else. Don't have immediate suggestions, though
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.
However, std::conjunction might not have
std::true_type
orstd::false_type
characteristics at all.
If it is used with true_type
/false_type
or derivatives, it will:
The specialization
std::conjunction<B1, ..., BN>
has a public and unambiguous base that is
- if
sizeof...(B) == 0
,std::true_type
;- otherwise the first type Bi in B1, ..., BN for which
bool(Bi::value) == false
, or BN if there is no such type.
And that's exactly our goal I believe.
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 suppose I don't know exactly what we mean by "characteristics of std::true_type
" if a std::conjunction
or similar types will not qualify.
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.
conjunction
, disjunction
and possibly negation
(though, I am not sure) are the only exceptions I am aware of. All other traits have characteristics of either true_type
or false_type
because they inherit from bool_constant
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 suppose I don't know exactly what we mean by "characteristics of std::true_type" if a std::conjunction or similar types will not qualify.
The wording "with a base characteristic of" is used in a few places in the C++ standard, for example in https://eel.is/c++draft/meta.unary:
Subclause [meta.unary] contains templates that may be used to query the properties of a type at compile time.
Each of these templates shall be a Cpp17UnaryTypeTrait with a base characteristic of true_type if the corresponding condition is true, otherwise false_type.
My understanding of this wording is: even though it is not a true_type or false_type, it has all the same characteristics as these types and can be used as such. Practically it means that the trait class inherits either true_type or false_type (maybe indirectly).
In my comment above, I say that std::conjunction
also falls into this category if the chosen template parameter does. Though the standard does not prohibit to use other types with std::conjunction
, typical arguments it is used with will be traits etc. classes that inherit bool_constant
. Therefore requiring that the return type of our ADL customization function should have these characteristics does not preclude the use of std::conjunction
, but limits what types can be passed to it.
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.
My understanding of this wording is: even though it is not a true_type or false_type, it has all the same characteristics as these types and can be used as such.
Actually, it's even more strict - the standard requires public inheritance, see https://eel.is/c++draft/meta.rqmts#:Cpp17UnaryTypeTrait:
It shall be ... publicly and unambiguously derived, directly or indirectly, from its base characteristic ... The member names of the base characteristic shall not be hidden and shall be unambiguously available ....
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.
Is see, thanks for the clarification. I think I agree that our current formulation makes sense then, with a small tweak to the language perhaps to follow the example language you provided.
Unless we have a compelling example to allow conjunction
disjunction
negation
which use something other than types with the base characteristic of a bool_constant
, I think simplicity is better.
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.
To follow up here, I've adjusted the language slightly, but think this simple version is best without making it more broad. I've not been able to come up with any real compelling case for conjunction
or disjunction
of an integral_constant
which is not a bool_constant
worth making this language more complex.
However, I think a valid implementation could easily accommodate arbitrary usage of conjunction
and disjunction
, ensuring that the public trait is always a bool_constant
.
@@ -174,6 +200,10 @@ to index into the index map. The corresponding value in the map is then used | |||
to index into the value set defined by the source iterator. The resulting lvalue is returned | |||
as the result of the operator. | |||
|
|||
``permutation_iterator`` are SYCL device-copyable if both the ``SourceIterator`` and the ``IndexMap`` | |||
are SYCL device-copyable, and are always "device accessible content iterators" if both the ``SourceIterator`` |
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.
are SYCL device-copyable, and are always "device accessible content iterators" if both the ``SourceIterator`` | |
are SYCL device-copyable, and are "device accessible content iterators" if both the ``SourceIterator`` |
"Always" word seems redundant to me. The same comment is applicable for the iterators below.
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.
removed all instances of this.
otherwise. The function must be defined in one of the valid search locations for ADL lookup, which includes the | ||
namespace of the definition of the iterator type ``IteratorT``. |
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 sentence sounds a bit awkward to me. ADL last letter already means lookup. Also, "valid search locations" is a sort of unusual. How about this:
otherwise. The function must be defined in one of the valid search locations for ADL lookup, which includes the | |
namespace of the definition of the iterator type ``IteratorT``. | |
otherwise. The function must be discoverable by ADL, which includes the | |
namespace of the definition of the iterator type ``IteratorT``. |
You may leave this part, if you think it's useful: "... , which includes the
namespace of the definition of the iterator type IteratorT
" but it also might be removed, I think. They choice is yours.
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.
Taken, I removed the second part. It doesn't really make sense after the edit. Its more something for the documentation than the spec.
The public trait ``oneapi::dpl::is_device_accessible_content_iterator[_v]`` can be used to query whether an iterator | ||
is a "device accessible content iterator". The trait is defined in ``<oneapi/dpl/iterator>``. | ||
|
||
``oneapi::dpl::is_device_accessible_content_iterator<T>`` evaluates to a type with the characteristics 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.
Still don't like this style of writing after a template name because it confuses (probably experienced) C++ users. Is the any chance we will define the API properly?
Something like
The following class template and variable template are defined in
namespace oneapi::dpl
:
template <typename T>
struct is_device_accessible_content_iterator;
template <typename T>
inline constexpr bool is_device_accessible_content_iterator = is_device_accessible<T>::value;
and then the descriptive part.
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.
Adjusted to be close to your proposal.
|
||
|
||
|
||
Public Trait: ``oneapi::dpl::is_device_accessible_content_iterator[_v]`` |
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.
naming suggestions to consider
is_passed_directly_to_device
(perhaps obsolete)is_device_accessible_iterator
is_indirectly_device_accessible
For the last one it might be is_device_indirectly_accessible
; not sure what is more accurate from English perspective. But the last proposed option (by me) is my favorite, so far. It also corelates with several C++20 concepts, e.g., indirectly_writable
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 really like is_device_accessible_iterator
because I think there is a difference between the iterator being accessible and its content it refers to being accessible. However, is_indirectly_device_accessible
is more clear and concise than what is currently in the PR.
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 fine with is_indirectly_device_accessible
, but we need to get feedback from the customers (that applies to any name(s) we eventually propose).
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 was also thinking that is_device_accessible_iterator
partially reflects the purpose. On the other hand we pass iterators to eventually get data from it, right? :)
That's how the idea about is_indirectly_device_accessible
comes to my mind. Since three of us like it we should probably reach customers to get feedback (as Alexey suggested). Whether we should change "device accessible content iterators", I am not sure. Perhaps, we should (if we agree on the new name) but I don't have a very strong preference
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 adjusted the name here in the spec.
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
|
||
|
||
|
||
Public Trait: ``oneapi::dpl::is_device_accessible_content_iterator[_v]`` |
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 was also thinking that is_device_accessible_iterator
partially reflects the purpose. On the other hand we pass iterators to eventually get data from it, right? :)
That's how the idea about is_indirectly_device_accessible
comes to my mind. Since three of us like it we should probably reach customers to get feedback (as Alexey suggested). Whether we should change "device accessible content iterators", I am not sure. Perhaps, we should (if we agree on the new name) but I don't have a very strong preference
@@ -64,6 +86,8 @@ counter; dereference operations cannot be used to modify the counter. The arithm | |||
operators of ``counting_iterator`` behave as if applied to the values of Integral type | |||
representing the counters of the iterator instances passed to the operators. | |||
|
|||
``counting_iterator`` are SYCL device-copyable, and are "device accessible content iterators". |
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 was fine with keeping "always for counting_iterator
and discard_iterator
(I think I wrote something like "iterator below". But how it's right now is also good. Please keep it as is.
I have another suggestion somewhere you use "<iterator_name>
are" and somewhere "<iterator_name>
is". I propose to align to "is" everywhere
``counting_iterator`` are SYCL device-copyable, and are "device accessible content iterators". | |
``counting_iterator`` is SYCL device-copyable, and are "device accessible content iterators". |
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.
adjusted all of these "are" -> "is" [a]
@@ -104,6 +128,8 @@ lvalue that may be assigned an arbitrary value. The assignment has no effect on | |||
of ``discard_iterator`` behave as if applied to integer counter values maintained by the | |||
iterator instances to determine their position relative to each other. | |||
|
|||
``discard_iterator`` are SYCL device-copyable, and are "device accessible content iterators". |
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.
``discard_iterator`` are SYCL device-copyable, and are "device accessible content iterators". | |
``discard_iterator`` is SYCL device-copyable, and are "device accessible content iterators". |
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.
adjusted all of these "are" -> "is" [a]
@@ -174,6 +200,10 @@ to index into the index map. The corresponding value in the map is then used | |||
to index into the value set defined by the source iterator. The resulting lvalue is returned | |||
as the result of the operator. | |||
|
|||
``permutation_iterator`` are SYCL device-copyable if both the ``SourceIterator`` and the ``IndexMap`` |
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.
``permutation_iterator`` are SYCL device-copyable if both the ``SourceIterator`` and the ``IndexMap`` | |
``permutation_iterator`` is SYCL device-copyable if both the ``SourceIterator`` and the ``IndexMap`` |
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.
adjusted all of these "are" -> "is" [a]
``template <typename T> oneapi::dpl::is_device_accessible_content_iterator<T>`` evaluates to a type with the | ||
characteristics of ``std::true_type`` if ``T`` refers to "device accessible content", otherwise it evaluates to a type | ||
with the characteristics of ``std::false_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 would still recommend some improvements
``template <typename T> oneapi::dpl::is_device_accessible_content_iterator<T>`` evaluates to a type with the | |
characteristics of ``std::true_type`` if ``T`` refers to "device accessible content", otherwise it evaluates to a type | |
with the characteristics of ``std::false_type``. | |
``is_device_accessible_content_iterator`` has characteristics of ``std::true_type`` if ``T`` refers to "device accessible content", otherwise it has characteristics of ``std::false_type``. |
If you want to keep template <typename T>
at the beginning, that's probably fine (though, looks redundant) but please at least remove <T>
after class name. Also, "evaluates to a type" sounds a little bit clunky to me.
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.
fixed.
{ | ||
struct accessible_it | ||
{ | ||
/* unspecified user definition of a iterator which refers to "device accessible content" */ |
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.
/* unspecified user definition of a iterator which refers to "device accessible content" */ | |
/* unspecified user definition of a iterator which refers to "device accessible content" */ |
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.
fixed.
Signed-off-by: Dan Hoeflinger <[email protected]>
formatting Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
…accessible types (no host allocated random access data) Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Signed-off-by: Dan Hoeflinger <[email protected]>
Specification for "indirectly device accessible iterator" customization point and public trait. Based upon proposed [RFC].(uxlfoundation/oneDPL#1999)