-
Notifications
You must be signed in to change notification settings - Fork 110
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
Changes from 5 commits
0e97668
7ebc87a
67d9653
b942833
5ba920d
ffc1d4c
e899696
d8a9081
6aa5662
17d24e6
45206ac
2f45d02
1e928d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| /*! | ||
| ****************************************************************************** | ||
| * | ||
| * \file | ||
| * | ||
| * \brief RAJA header file defining the SubView class | ||
| * | ||
| ****************************************************************************** | ||
| */ | ||
|
|
||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
| // Copyright (c) 2016-25, Lawrence Livermore National Security, LLC | ||
| // and RAJA project contributors. See the RAJA/LICENSE file for details. | ||
| // | ||
| // SPDX-License-Identifier: (BSD-3-Clause) | ||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
|
|
||
| #ifndef RAJA_SUBVIEW_HPP | ||
| #define RAJA_SUBVIEW_HPP | ||
|
|
||
| #include "RAJA/util/types.hpp" | ||
| #include "camp/number.hpp" | ||
| #include "camp/tuple.hpp" | ||
| #include "camp/array.hpp" | ||
|
|
||
| namespace RAJA | ||
| { | ||
|
|
||
| // Slice descriptors | ||
|
|
||
| template<typename IndexType = Index_type> | ||
| struct RangeSlice { | ||
| IndexType start, end; | ||
|
|
||
| static constexpr bool reduces_dimension = false; | ||
|
|
||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexType map_index(IndexType& idx) const { | ||
| return start + idx; | ||
| } | ||
| }; | ||
|
|
||
| template<typename IndexType = Index_type> | ||
| struct FixedSlice { | ||
| IndexType idx; | ||
|
|
||
| static constexpr bool reduces_dimension = true; | ||
|
|
||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexType map_index(IndexType&) const { | ||
| return idx; | ||
| } | ||
| }; | ||
|
|
||
| struct NoSlice { | ||
| static constexpr bool reduces_dimension = false; | ||
|
|
||
| template<typename IndexType = Index_type> | ||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexType map_index(IndexType& idx) const { | ||
| return idx; | ||
| } | ||
| }; | ||
|
|
||
| // Helper to count non-fixed dimensions at compile time | ||
| template <typename... Slices> | ||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr size_t count_nonfixed_dims() { | ||
| return (!Slices::reduces_dimension + ...); | ||
MrBurmark marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| template <typename T, size_t N, RAJA::Index_type... Is> | ||
| 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>{}); | ||
| } | ||
|
||
|
|
||
| template <typename ViewType, typename IndexType = Index_type, typename... Slices> | ||
MrBurmark marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| class SubView { | ||
| ViewType view_; | ||
| camp::tuple<Slices...> slices_; | ||
|
||
| std::array<IndexType, sizeof...(Slices)> map_; | ||
|
||
|
|
||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr void make_subview_index_map() { | ||
| size_t sub_idx = 0; | ||
| size_t i = 0; | ||
| ((map_[i++] = (Slices::reduces_dimension ? -1 : sub_idx++)), ...); | ||
| } | ||
MrBurmark marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| template<IndexType I> | ||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr auto map_subview_idx_to_parent(IndexType* idxs) const { | ||
| return camp::get<I>(slices_).map_index(idxs[map_[I]]); | ||
MrBurmark marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| template <IndexType... Is> | ||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr auto map_indices(IndexType* idxs, camp::idx_seq<Is...>) const { | ||
| // For each slice, map subview index to parent index | ||
| return camp::array{(map_subview_idx_to_parent<Is>(idxs))...}; | ||
| } | ||
|
|
||
| public: | ||
|
|
||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr SubView(ViewType view, Slices... slices) | ||
| : view_(view), slices_(slices...) { make_subview_index_map(); } | ||
|
|
||
| template <typename... Idxs> | ||
| RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexType operator()(Idxs... idxs) const { | ||
| constexpr size_t nidx = count_nonfixed_dims<Slices...>(); | ||
MrBurmark marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| static_assert(sizeof...(idxs) == nidx, "Wrong number of indices for subview"); | ||
|
|
||
| camp::array<RAJA::Index_type, nidx> arr{idxs...}; | ||
| auto parent_indices = map_indices(arr.data(), camp::make_idx_seq_t<sizeof...(Slices)>()); | ||
|
|
||
| return camp::apply(view_, array_to_tuple(parent_indices)); | ||
|
||
| } | ||
| }; | ||
|
|
||
| } // namespace RAJA | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
| // Copyright (c) 2016-25, Lawrence Livermore National Security, LLC | ||
| // and RAJA project contributors. See the RAJA/LICENSE file for details. | ||
| // | ||
| // SPDX-License-Identifier: (BSD-3-Clause) | ||
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
|
|
||
| #include <gtest/gtest.h> | ||
| #include "RAJA/policy/PolicyBase.hpp" | ||
| #include "RAJA/util/SubView.hpp" | ||
| #include "RAJA/util/types.hpp" | ||
| #include "RAJA_test-base.hpp" | ||
| #include "RAJA_unit-test-forone.hpp" | ||
|
|
||
| using namespace RAJA; | ||
|
|
||
| TEST(SubView, RangeSubView1D) | ||
| { | ||
|
|
||
| Index_type a[] = {1,2,3,4,5}; | ||
|
|
||
| View<Index_type, Layout<1>> view(&a[0], Layout<1>(5)); | ||
|
|
||
| // sv = View[1:3] | ||
| auto sv = SubView(view, RangeSlice<>{1,3}); | ||
|
|
||
| EXPECT_EQ(sv(0), 2); | ||
| EXPECT_EQ(sv(1), 3); | ||
| EXPECT_EQ(sv(2), 4); | ||
|
|
||
| } | ||
|
|
||
| TEST(SubView, RangeSubView2D) | ||
| { | ||
|
|
||
| Index_type a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; | ||
|
|
||
| View<Index_type, Layout<2>> view(&a[0][0], Layout<2>(3,3)); | ||
|
|
||
| // sv = View[1:2,1:2] | ||
| auto sv = SubView(view, RangeSlice<>{1,2}, RangeSlice<>{1,2}); | ||
|
|
||
| EXPECT_EQ(sv(0,0), 5); | ||
| EXPECT_EQ(sv(0,1), 6); | ||
| EXPECT_EQ(sv(1,0), 8); | ||
| EXPECT_EQ(sv(1,1), 9); | ||
|
|
||
| } | ||
|
|
||
| TEST(SubView, RangeFixedSubView2D) | ||
| { | ||
|
|
||
| Index_type a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; | ||
|
|
||
| View<Index_type, Layout<2>> view(&a[0][0], Layout<2>(3,3)); | ||
|
|
||
| // sv = View[1:2,1] | ||
| auto sv = SubView(view, RangeSlice<>{1,2}, FixedSlice<>{1}); | ||
|
|
||
| EXPECT_EQ(sv(0), 5); | ||
| EXPECT_EQ(sv(1), 8); | ||
|
|
||
| } | ||
|
|
||
| TEST(SubView, FixedFirstDimSubView2D) | ||
| { | ||
|
|
||
| Index_type a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; | ||
|
|
||
| View<Index_type, Layout<2>> view(&a[0][0], Layout<2>(3,3)); | ||
|
|
||
| // sv = View[1,:] | ||
| auto sv = SubView(view, FixedSlice<>{1}, NoSlice{}); | ||
|
|
||
| EXPECT_EQ(sv(0), 4); | ||
| EXPECT_EQ(sv(1), 5); | ||
| EXPECT_EQ(sv(2), 6); | ||
|
|
||
| } | ||
|
|
||
| TEST(SubView, RangeFirstDimSubView2D) | ||
| { | ||
|
|
||
| Index_type a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; | ||
|
|
||
| View<Index_type, Layout<2>> view(&a[0][0], Layout<2>(3,3)); | ||
|
|
||
| // sv = View[1:2,:] | ||
| auto sv = SubView(view, RangeSlice<>{1,2}, NoSlice{}); | ||
|
|
||
| EXPECT_EQ(sv(0,0), 4); | ||
| EXPECT_EQ(sv(0,1), 5); | ||
| EXPECT_EQ(sv(0,2), 6); | ||
|
|
||
| EXPECT_EQ(sv(1,0), 7); | ||
| EXPECT_EQ(sv(1,1), 8); | ||
| EXPECT_EQ(sv(1,2), 9); | ||
|
|
||
| } | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added |
||
| // void test_subviewGPU() { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To Do: Fix GPU tests. |
||
| // #if defined(RAJA_ENABLE_HIP) | ||
| // forone<test_hip>([=] __host__ __device__ () { | ||
| // Index_type a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; | ||
|
|
||
| // View<Index_type, Layout<2>> view(&a[0][0], Layout<2>(3,3)); | ||
|
|
||
| // // sv = View[1:2,:] | ||
| // auto sv = SubView(view, RangeSlice<>{1,2}, NoSlice{}); | ||
|
|
||
| // //printf("sv(0,0): %ld\n", sv(0,0)); | ||
|
|
||
| // }); | ||
| // #endif | ||
| // } | ||
|
|
||
| // TEST(SubView, RangeFirstDimSubView2DGPU) | ||
| // { | ||
| // test_subviewGPU(); | ||
| // } | ||
Uh oh!
There was an error while loading. Please reload this page.