Skip to content
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

Adding legacy is_hetero trait and supporting it more fully #1380

Closed
wants to merge 5 commits into from

Conversation

danhoeflinger
Copy link
Contributor

@danhoeflinger danhoeflinger commented Jan 24, 2024

Re-add legacy trait is_hetero, but supporting it more fully by adding an additional requirement for the is_hetero type to provide get_idx() which returns the buffer offset this iterator has to its base buffer.

Adding this function to sycl_iterator, incorporating it into __get_sycl_range implementation.
This allows us to support hetero types other than sycl_iterator if they support get_buffer() and get_idx().

@danhoeflinger danhoeflinger added this to the 2022.5.0 milestone Jan 24, 2024
@danhoeflinger danhoeflinger marked this pull request as draft January 24, 2024 21:29
@danhoeflinger danhoeflinger marked this pull request as ready for review January 24, 2024 21:40
Signed-off-by: Dan Hoeflinger <[email protected]>
@@ -118,6 +118,12 @@ struct sycl_iterator
{
return buffer;
}

Size
get_idx() const
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand correctly that "soclomatic" uses such API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SYCLomatic does not use sycl_iterator at all, but rather creates a type similar to sycl_iterator (device_pointer / device_iterator) which are similar. They already provide get_idx() within those types.

The idea is to require these is_hetero types to provide get_idx() and then use it within __get_sycl_range processing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't quite understand. __get_sycl_range works fine without get_idx().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... Actually, the answer the next comment explain that. I see..

@@ -505,8 +515,10 @@ struct __get_sycl_range
auto __n = __last - __first;
assert(__n > 0);

auto res_src =
__process_input_iter<_LocalAccMode>(__first.base(), oneapi::dpl::end(__first.base().get_buffer()));
auto __base_iter = __first.base();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that new 4 lines are equivalent to the couple of line that we had before... No?

__process_input_iter<_LocalAccMode>(__first.base(), oneapi::dpl::end(__first.base().get_buffer()));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is, but only if first.base() is a sycl_iterator. If first.base() is instead a dpct::device_pointer this fails because no overload exists with such combination of types for __process_input_iter (dpct::device_pointer,sycl_iterator).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see..

@@ -581,7 +593,7 @@ struct __get_sycl_range
assert(__first < __last);
using value_type = val_t<_Iter>;

const auto __offset = __first - oneapi::dpl::begin(__first.get_buffer());
const auto __offset = __first.get_idx();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is equivalent to code that we had before.

const auto __offset = __first - oneapi::dpl::begin(__first.get_buffer());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar response to above, it is the same as long as __first is a sycl_iterator. If it is instead a dpct::device_pointer then this subtraction is undefined.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see.
It looks we need to extend the contract for sycl_iterator type

Copy link
Contributor

@MikeDvorskiy MikeDvorskiy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the necessity of these changes is not so obviously, it makes sense to add comments why we need some changes, otherwise, some new developer may re-write (revert )that code as redundant.

__process_input_iter<_LocalAccMode>(__first.base(), oneapi::dpl::end(__first.base().get_buffer()));
auto __base_iter = __first.base();
auto __base_buffer = __base_iter.get_buffer();
auto res_src = __process_input_iter<_LocalAccMode>(oneapi::dpl::begin(__base_buffer) + __base_iter.get_idx(),
Copy link
Contributor

@adamfidel adamfidel Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I understand, the issue is that we cannot easily get the index of the iterator because we are assuming that the base iterator type is a sycl_iterator. I believe we can solve this by instead of using oneapl::dpl::begin, explicitly constructing a begin iterator of the base iterator type directly from the buffer.

Suggested change
auto res_src = __process_input_iter<_LocalAccMode>(oneapi::dpl::begin(__base_buffer) + __base_iter.get_idx(),
using _BaseIterator = ::std::decay_t<decltype(__base_iter)>;
auto __base_begin = _BaseIterator(__base_buffer);
auto __idx = __first.base() - __base_begin;
auto res_src = __process_input_iter<_LocalAccMode>(__base_begin + __idx,

In this way, we do not have to introduce a get_idx method to the sycl_iterator class.

One drawback to using the above proposed approach is that we rely on the base iterator to define a constructor that takes just a sycl::buffer. From what I can tell, this is true for both sycl_iterator and dpct::device_ptr.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand your suggestion correctly, I think the problem here is that we would lose the information of the buffer offset if we use oneapi::dpl::begin.

@danhoeflinger
Copy link
Contributor Author

Closing this in favor of #1383, I will add the requested comments there.

@danhoeflinger danhoeflinger reopened this Jan 25, 2024
@danhoeflinger danhoeflinger deleted the dev/dhoeflin/is_hetero_legacy branch January 30, 2024 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants