@@ -27,15 +27,42 @@ namespace RAJA
2727{
2828
2929// Slice descriptors
30- struct RangeSlice { long start, end; };
31- struct FixedSlice { long idx; };
32- struct NoSlice { };
30+
31+ template <typename IndexType = Index_type>
32+ struct RangeSlice {
33+ IndexType start, end;
34+
35+ static constexpr bool reduces_dimension = false ;
36+
37+ RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexType map_index (IndexType& idx) const {
38+ return start + idx;
39+ }
40+ };
41+
42+ template <typename IndexType = Index_type>
43+ struct FixedSlice {
44+ IndexType idx;
45+
46+ static constexpr bool reduces_dimension = true ;
47+
48+ RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexType map_index (IndexType&) const {
49+ return idx;
50+ }
51+ };
52+
53+ struct NoSlice {
54+ static constexpr bool reduces_dimension = false ;
55+
56+ template <typename IndexType = Index_type>
57+ RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexType map_index (IndexType& idx) const {
58+ return idx;
59+ }
60+ };
3361
3462// Helper to count non-fixed dimensions at compile time
3563template <typename ... Slices>
3664RAJA_INLINE RAJA_HOST_DEVICE constexpr size_t count_nonfixed_dims () {
37- return (0 + ... + ((std::is_same_v<Slices, RangeSlice> ||
38- std::is_same_v<Slices, NoSlice>) ? 1 : 0 ));
65+ return (!Slices::reduces_dimension + ...);
3966}
4067
4168template <typename T, size_t N, RAJA ::Index_type... Is>
@@ -48,45 +75,42 @@ RAJA_INLINE RAJA_HOST_DEVICE constexpr auto array_to_tuple(const camp::array<T,
4875 return array_to_tuple_impl (arr, camp::make_idx_seq_t <N>{});
4976}
5077
51- template <typename ViewType, typename ... Slices>
78+ template <typename ViewType, typename IndexType = Index_type, typename ... Slices>
5279class SubView {
5380 ViewType view_;
5481 camp::tuple<Slices...> slices_;
82+ std::array<IndexType, sizeof ...(Slices)> map_;
5583
56- template <typename IndexType, IndexType... Is>
57- RAJA_INLINE RAJA_HOST_DEVICE constexpr auto map_indices (IndexType* idxs, camp::idx_seq<Is...>) const {
58- camp::array<RAJA ::Index_type, sizeof ...(Is)> parent_indices{};
59- RAJA ::Index_type idx = 0 ;
84+ RAJA_INLINE RAJA_HOST_DEVICE constexpr void make_subview_index_map () {
85+ size_t sub_idx = 0 ;
86+ size_t i = 0 ;
87+ ((map_[i++] = (Slices::reduces_dimension ? -1 : sub_idx++)), ...);
88+ }
6089
90+ template <IndexType I>
91+ RAJA_INLINE RAJA_HOST_DEVICE constexpr auto map_subview_idx_to_parent (IndexType* idxs) const {
92+ return camp::get<I>(slices_).map_index (idxs[map_[I]]);
93+ }
94+
95+ template <IndexType... Is>
96+ RAJA_INLINE RAJA_HOST_DEVICE constexpr auto map_indices (IndexType* idxs, camp::idx_seq<Is...>) const {
6197 // For each slice, map subview index to parent index
62- (
63- (
64- parent_indices[Is] = [&] {
65- const auto & s = camp::get<Is>(slices_);
66- if constexpr (std::is_same_v<std::decay_t <decltype (s)>, RangeSlice>) {
67- return s.start + idxs[idx++];
68- } else if constexpr (std::is_same_v<std::decay_t <decltype (s)>, FixedSlice>) {
69- return s.idx ;
70- } else {
71- return idxs[idx++];
72- }
73- }()
74- ), ...
75- );
76-
77- return parent_indices;
98+ return camp::array{(map_subview_idx_to_parent<Is>(idxs))...};
7899 }
79100
80101public:
81- RAJA_INLINE RAJA_HOST_DEVICE SubView (ViewType view, Slices... slices)
82- : view_(view), slices_(slices...) {}
102+
103+ RAJA_INLINE RAJA_HOST_DEVICE constexpr SubView (ViewType view, Slices... slices)
104+ : view_(view), slices_(slices...) { make_subview_index_map (); }
83105
84106 template <typename ... Idxs>
85- RAJA_INLINE RAJA_HOST_DEVICE constexpr auto operator ()(Idxs... idxs) const {
107+ RAJA_INLINE RAJA_HOST_DEVICE constexpr IndexType operator ()(Idxs... idxs) const {
86108 constexpr size_t nidx = count_nonfixed_dims<Slices...>();
87109 static_assert (sizeof ...(idxs) == nidx, " Wrong number of indices for subview" );
110+
88111 camp::array<RAJA ::Index_type, nidx> arr{idxs...};
89112 auto parent_indices = map_indices (arr.data (), camp::make_idx_seq_t <sizeof ...(Slices)>());
113+
90114 return camp::apply (view_, array_to_tuple (parent_indices));
91115 }
92116};
0 commit comments