-
Notifications
You must be signed in to change notification settings - Fork 104
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
Reshape method #1760
base: develop
Are you sure you want to change the base?
Reshape method #1760
Changes from 9 commits
726da15
119cc95
e105bae
78d32b3
9807f31
28e714d
fc1f6a8
4d05ea5
b0a836a
a1a254d
a691f40
cf3ff8c
7ddbdb1
c33e1d1
d09d6e0
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,162 @@ | ||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
// Copyright (c) 2016-24, Lawrence Livermore National Security, LLC | ||
// and RAJA project contributors. See the RAJA/LICENSE file for details. | ||
// | ||
// SPDX-License-Identifier: (BSD-3-Clause) | ||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
|
||
#include <cmath> | ||
#include <cstdlib> | ||
#include <cstring> | ||
#include <iostream> | ||
|
||
#include "RAJA/RAJA.hpp" | ||
#include "RAJA/util/Timer.hpp" | ||
|
||
|
||
#include "memoryManager.hpp" | ||
|
||
/* | ||
* RAJA Reshape method | ||
* | ||
* This example will intialize array using | ||
* the RAJA Reshape method. The Reshape | ||
* method offers right and left most unit | ||
* stride. | ||
* | ||
*/ | ||
|
||
/* | ||
* Define number of threads in a GPU thread block | ||
*/ | ||
#if defined(RAJA_ENABLE_CUDA) | ||
constexpr int CUDA_BLOCK_SIZE = 256; | ||
#endif | ||
|
||
#if defined(RAJA_ENABLE_HIP) | ||
constexpr int HIP_BLOCK_SIZE = 256; | ||
#endif | ||
|
||
// | ||
//Function for checking results | ||
// | ||
void checkResult(int *ptr, int K, int N, int M); | ||
|
||
int main(int RAJA_UNUSED_ARG(argc), char **RAJA_UNUSED_ARG(argv[])) | ||
{ | ||
|
||
std::cout << "\n\nRAJA reshape method example....\n"<< std::endl; | ||
|
||
const int K = 3; | ||
const int N = 1; | ||
const int M = 2; | ||
|
||
// Allocate memory for pointer | ||
int *Rptr = memoryManager::allocate<int>(K * N * M); | ||
int *Lptr = memoryManager::allocate<int>(K * N * M); | ||
int *Cptr = memoryManager::allocate<int>(K * N * M); | ||
|
||
//----------------------------------------------------------------------------// | ||
// | ||
// Initialize memory using right most unit stride | ||
// | ||
//----------------------------------------------------------------------------// | ||
std::cout << "\n\nInitialize array with right most indexing...\n"; | ||
auto Rview = RAJA::Reshape<RAJA::layout_right>::get(Rptr, K, N, M); | ||
|
||
for(int k = 0; k < K; ++k) { | ||
for(int n = 0; n < N; ++n) { | ||
for(int m = 0; m < M; ++m) { | ||
const int idx = m + M * (n + N * k); | ||
Rview(k,n,m) = idx; | ||
} | ||
} | ||
} | ||
|
||
checkResult(Rptr, K, N, M); | ||
|
||
|
||
//----------------------------------------------------------------------------// | ||
// | ||
// Initialize memory using left most unit stride | ||
// | ||
//----------------------------------------------------------------------------// | ||
std::cout << "\n\nInitialize array with left most indexing...\n"; | ||
|
||
auto Lview = RAJA::Reshape<RAJA::layout_left>::get(Lptr, K, N, M); | ||
|
||
//Note the loop ordering has change from above | ||
for(int m = 0; m < M; ++m) { | ||
for(int n = 0; n < N; ++n) { | ||
for(int k = 0; k < K; ++k) { | ||
|
||
const int idx = k + K * (n + N * m); | ||
Lview(k,n,m) = idx; | ||
} | ||
} | ||
} | ||
|
||
checkResult(Lptr, K, N, M); | ||
|
||
|
||
//----------------------------------------------------------------------------// | ||
// | ||
// Initialize memory using custom ordering, left most value of the index sequence | ||
// is assumed to have unit stride, while the right most has the longest stride | ||
// | ||
//----------------------------------------------------------------------------// | ||
std::cout << "\n\nInitialize array with custom indexing...\n"; | ||
|
||
using custom_seq = std::index_sequence<1U,0U,2U>; | ||
|
||
auto Cview = RAJA::Reshape<custom_seq>::get(Cptr, K, N, M); | ||
|
||
//Note the loop ordering has change from above | ||
for(int k = 0; k < K; ++k) { | ||
for(int m = 0; m < M; ++m) { | ||
for(int n = 0; n < N; ++n) { | ||
|
||
const int idx = n + N * (m + M * k); | ||
Cview(k,n,m) = idx; | ||
} | ||
} | ||
} | ||
|
||
checkResult(Cptr, K, N, M); | ||
|
||
|
||
// | ||
// Clean up. | ||
// | ||
memoryManager::deallocate(Rptr); | ||
memoryManager::deallocate(Lptr); | ||
|
||
std::cout << "\n DONE!...\n"; | ||
return 0; | ||
} | ||
|
||
// | ||
// check result | ||
// | ||
void checkResult(int *ptr, int K, int N, int M) | ||
{ | ||
|
||
bool status = true; | ||
|
||
for(int k = 0; k < K; ++k) { | ||
for(int n = 0; n < N; ++n) { | ||
for(int m = 0; m < M; ++m) { | ||
const int idx = m + M * (n + N * k); | ||
if (std::abs(ptr[idx] - idx) > 0) { | ||
artv3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
status = false; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if ( status ) { | ||
std::cout << "\tresult -- PASS\n"; | ||
} else { | ||
std::cout << "\tresult -- FAIL\n"; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
#define RAJA_VIEW_HPP | ||
|
||
#include <type_traits> | ||
#include <array> | ||
|
||
#include "RAJA/config.hpp" | ||
|
||
|
@@ -81,14 +82,14 @@ RAJA_INLINE View<ValueType, IndexLayout<n_dims, IndexType, IndexTypes...> > make | |
// select certain indices from a tuple, given a curated index sequence | ||
// returns linear index of layout(ar...) | ||
template <typename Lay, typename Tup, camp::idx_t... Idxs> | ||
RAJA_HOST_DEVICE RAJA_INLINE | ||
RAJA_HOST_DEVICE RAJA_INLINE | ||
auto selecttuple( Lay lyout, Tup&& tup, camp::idx_seq<Idxs...> ) -> | ||
decltype( | ||
lyout( | ||
camp::get<Idxs>(std::forward<Tup>(tup))... | ||
) | ||
) | ||
{ | ||
{ | ||
return lyout( | ||
camp::get<Idxs>(std::forward<Tup>(tup))... | ||
); | ||
|
@@ -234,7 +235,7 @@ struct MultiView { | |
{ | ||
RAJA_ABORT_OR_THROW( "Negative index while accessing array of pointers.\n" ); | ||
} | ||
|
||
auto idx = stripIndexType( removenth<LayoutType, P2Pidx>( layout, camp::forward_as_tuple( ar... ) ) ); | ||
return data[pidx][idx]; | ||
} | ||
|
@@ -296,6 +297,76 @@ RAJA_INLINE AtomicViewWrapper<ViewType, AtomicPolicy> make_atomic_view( | |
return RAJA::AtomicViewWrapper<ViewType, AtomicPolicy>(view); | ||
} | ||
|
||
struct layout_left{}; | ||
struct layout_right{}; | ||
|
||
template<typename LAYOUT> | ||
MrBurmark marked this conversation as resolved.
Show resolved
Hide resolved
|
||
struct Reshape; | ||
|
||
template<typename LAYOUT> | ||
struct Reshape; | ||
MrBurmark marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
template<std::size_t Id, std::size_t...Ids> | ||
constexpr auto get_first_index() | ||
{ | ||
return Id; | ||
} | ||
|
||
template<std::size_t...Is> | ||
struct Reshape<std::index_sequence<Is...>> | ||
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. @MrBurmark , this is the specialization that takes an index_sequence and identifies the correct unit stride 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. Makes sense, I see an example is documentation coming? 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. Yes, thanks for reminding me. I'll make something in the read the docs page within the next few days. |
||
{ | ||
template<typename T, typename...Ts> | ||
static auto get(T *ptr, Ts... s) | ||
{ | ||
constexpr int N = sizeof...(Ts); | ||
std::array<RAJA::idx_t, N> extent{s...}; | ||
|
||
auto custom_layout = | ||
RAJA::make_permuted_layout(extent, std::array<RAJA::idx_t, N>{Is...}); | ||
|
||
constexpr auto unit_stride = get_first_index<Is...>(); | ||
|
||
return RAJA::View<T, RAJA::Layout<N, RAJA::Index_type, unit_stride>> | ||
artv3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
(ptr, custom_layout); | ||
} | ||
}; | ||
|
||
template<> | ||
struct Reshape<layout_right> | ||
{ | ||
template<typename T, typename...Ts> | ||
static auto get(T *ptr, Ts... s) | ||
{ | ||
constexpr int N = sizeof...(Ts); | ||
using view_t = RAJA::View<T, RAJA::Layout<N, RAJA::Index_type, N-1>>; | ||
artv3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return view_t(ptr, s...); | ||
} | ||
}; | ||
|
||
template<std::size_t... Is> | ||
constexpr std::array<RAJA::idx_t, sizeof...(Is)> make_reverse_array(std::index_sequence<Is...>) { | ||
artv3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return std::array<RAJA::idx_t, sizeof...(Is)>{sizeof...(Is) - 1U - Is ...}; | ||
} | ||
|
||
template<> | ||
struct Reshape<layout_left> | ||
{ | ||
template<typename T, typename...Ts> | ||
static auto get(T *ptr, Ts... s) | ||
{ | ||
constexpr int N = sizeof...(Ts); | ||
|
||
std::array<RAJA::idx_t, N> extent{s...}; | ||
|
||
constexpr auto reverse_array = make_reverse_array(std::make_index_sequence<N>{}); | ||
|
||
auto reverse_layout = RAJA::make_permuted_layout(extent, reverse_array); | ||
|
||
return RAJA::View<T, RAJA::Layout<N, RAJA::Index_type, 0>>(ptr, reverse_layout); | ||
} | ||
|
||
}; | ||
|
||
} // namespace RAJA | ||
|
||
|
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 these implementations are much easier to understand if your intent is just to show the mechanics of View reshaping. 👍