-
Notifications
You must be signed in to change notification settings - Fork 108
Add SubView class #1915
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: develop
Are you sure you want to change the base?
Add SubView class #1915
Conversation
|
This PR is still a WIP! |
include/RAJA/util/SubView.hpp
Outdated
| struct RangeSlice { long start, end; }; | ||
| struct FixedSlice { long idx; }; | ||
| struct NoSlice { }; |
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.
We will probably want to generalize the integer types used in the slices. We will probably want to add strongly typed slices like the strongly typed indices.
| RAJA_INLINE RAJA_HOST_DEVICE constexpr auto array_to_tuple_impl(const camp::array<T, N>& arr, camp::idx_seq<Is...>) { | ||
| return camp::make_tuple(arr[Is]...); | ||
| } | ||
|
|
||
| template <typename T, size_t N> | ||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr auto array_to_tuple(const camp::array<T, N>& arr) { | ||
| return array_to_tuple_impl(arr, camp::make_idx_seq_t<N>{}); | ||
| } |
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 we not have this somewhere?
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 not it would be good to add it in a more general header.
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.
Agreed. I'll look into moving this to camp.
804abcd to
5ba920d
Compare
|
|
||
| } | ||
|
|
||
| // void test_subviewGPU() { |
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 Do: Fix GPU tests.
| ViewType view_; | ||
| camp::tuple<Slices...> slices_; |
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 there be a static assert that the dimensionality of the view and number of slices match?
| EXPECT_EQ(sv(1,2), 9); | ||
|
|
||
| } | ||
|
|
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.
@gberg617 how would you do something like we have in the original impl of SubViews: https://github.com/LLNL/SNLS/blob/develop/test/SNLS_forall_subviews.cxx#L69-L75 where we allow for a sliding window with the SubView. Additionally, how can we get the underlying data pointer at the SubView's (0..) index like here: https://github.com/LLNL/SNLS/blob/develop/test/SNLS_forall_subviews.cxx#L150 ?
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.
Added set_slice to allow things like "sliding windows"
|
I'm considering separating the SubView holding the view from the slices that are used to access the view, somewhat analogous to the approach of having layouts and Views be separate classes. Any thoughts on this? |
| class SubView<ViewType, camp::list<Slices...>, IndexType> { | ||
| ViewType view_; | ||
| camp::tuple<Slices...> slices_; | ||
| std::array<IndexType, sizeof...(Slices)> map_; |
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 need to make this static inline constexpr
| size_t sub_idx = 0; | ||
| std::array<IndexType, sizeof...(Slices)> map; | ||
|
|
||
| for_each_tuple_index( slices_, |
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 looks great. Unfortunately it uses a non-static member to do something static.
|
|
||
| template <typename... Idxs> | ||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexType operator()(Idxs... idxs) const { | ||
| constexpr size_t nidx = ((Slices::reduces_dimension == false ? 1 : 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.
This should be a static member variable of the class.
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 would be nice to have something like num_slices 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.
It would also be nice to have a bit more descriptive names.
|
|
||
| for_each_tuple_index( slices_, | ||
| [&](auto slice, auto index) { | ||
| parent_indices[index] = slice.map_index(arr[map_[index]]); |
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 causes out of bounds accesses for slices that reduce dimensions.
| parent_indices[index] = slice.map_index(arr[map_[index]]); | ||
| }); | ||
|
|
||
| return camp::apply(view_, array_to_tuple(parent_indices)); |
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 not just use a tuple to start with?
| { | ||
| using camp::get; | ||
| // braced init lists are evaluated in order | ||
| int seq_unused_array[] = {0, (func(get<Is>(std::forward<Tuple>(t)), Is), 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.
| int seq_unused_array[] = {0, (func(get<Is>(std::forward<Tuple>(t)), Is), 0)...}; | |
| int seq_unused_array[] = {0, (func(get<Is>(std::forward<Tuple>(t)), std::integral_constant<std::size_t, Is>{}), 0)...}; |
| template<typename UnaryFunc, typename IndexType, IndexType... Is> | ||
| RAJA_HOST_DEVICE RAJA_INLINE UnaryFunc for_each_index(camp::idx_seq<Is...>, |
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.
| template<typename UnaryFunc, typename IndexType, IndexType... Is> | |
| RAJA_HOST_DEVICE RAJA_INLINE UnaryFunc for_each_index(camp::idx_seq<Is...>, | |
| template<typename UnaryFunc, camp::idx_t... Is> | |
| RAJA_HOST_DEVICE RAJA_INLINE UnaryFunc for_each_index(camp::idx_seq<Is...>, |
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 should all be size_t or camp::idx_t.
You mean something more like making a SubLayout that you can use anywhere a layout can be used? |
Yes, but the intent is that these "sub-layouts" are only used with SubViews. I will try to prototype something here soon. |
We'd have to think about it. It seems simpler to me if you can use a sublayout like a layout, that way a subview would just be a view using a sublayout. |
Summary
A few simple examples are provided below:
Here,
sv1andsv2are subviews of dimensions(2,3)and(2)respectively.