Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 61 additions & 31 deletions Intro_Tutorial/lessons/09_raja_view/09_raja_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,80 @@

int main()
{
#if defined(COMPILE)

constexpr int N{1000};
#if defined(COMPILE)
constexpr int M{3};
constexpr int N{5};
double* a{nullptr};
double* b{nullptr};
double* c{nullptr};
double* result_right{nullptr};
double* result_left{nullptr};

auto& rm = umpire::ResourceManager::getInstance();

auto allocator = rm.getAllocator("HOST");
auto pool = rm.makeAllocator<umpire::strategy::QuickPool>("POOL", allocator);

a = static_cast<double *>(pool.allocate(N*N*sizeof(double)));
b = static_cast<double *>(pool.allocate(N*N*sizeof(double)));
c = static_cast<double *>(pool.allocate(N*N*sizeof(double)));

RAJA::TypedRangeSegment<int> row_range(0, N);
RAJA::TypedRangeSegment<int> col_range(0, N);
a = static_cast<double *>(pool.allocate(M*N*sizeof(double)));
result_right = static_cast<double *>(pool.allocate(M*N*sizeof(double)));
result_left = static_cast<double *>(pool.allocate(M*N*sizeof(double)));

// TODO: Create a view for A, B, and C
// TODO: Create a standard MxN RAJA::View called, "A", initialized with the "a" array.
// TODO: Create a permuted MxN view with a right-oriented layout called, "R", initialized with the "result_right" array.
constexpr int DIM = 2;
auto L = RAJA::make_permuted_view<RAJA::layout_left>(result_left, M, N);

// TODO: Fill in loop bounds that are appropriate for right-oriented layouts of Views A and R.
for ( ??? )
{
for ( ??? )
{
// TODO: Initialize A and R views to their index values, e.g. index 0 should contain 0,
// index 1 should contain 1, . . ., index 14 should contain 14. Note that both
// A and R should print out the same sequence of values, due to the default
// View for A being constructed with a right-oriented layout.
A(row, col) = ???;
R(row, col) = ???;
}
}

// The L view will receive the same values as A and R. Note to achieve this,
// the loop indexing is reversed from the previous initialization loops because L
// is a left-oriented layout. The values assigned to L also reflect left-oriented
// indexing arithmetic.
for ( int col = 0; col < N; ++col )
{
for ( int row = 0; row < M; ++row )
{
L(row, col) = col * M + row;
}
}

RAJA::forall<RAJA::seq_exec>( row_range, [=](int row) {
RAJA::forall<RAJA::seq_exec>( col_range, [=](int col) {
A(row, col) = row;
B(row, col) = col;
});
});

RAJA::forall<RAJA::seq_exec>( row_range, [=](int row) {
RAJA::forall<RAJA::seq_exec>( col_range, [=](int col) {
double dot = 0.0;
for (int k = 0; k < N; ++k) {
dot += A(row, k) * B(k, col);
auto printArrayAsMatrix = [&](double * array)
{
for ( int ii = 0; ii < M*N; ++ii )
{
printf("%f ", array[ii]);
if ( ((ii+1) % N == 0) )
{
printf("\n");
}
C(row, col) = dot;
});
});
}
};

pool.deallocate(a);
pool.deallocate(b);
pool.deallocate(c);
// TODO: Look at the output and make sure each array prints the same ordering of values.
// "a" and "result_right" should match "result_left".
printf("\na array under View A:\n");
printArrayAsMatrix( a );

printf("\nresult_right array under View R:\n");
printArrayAsMatrix( result_right );

#endif
printf("\nresult_left array under View L:\n");
printArrayAsMatrix( result_left );

pool.deallocate(a);
pool.deallocate(result_right);
pool.deallocate(result_left);
#endif // COMPILE

return 0;
}
13 changes: 8 additions & 5 deletions Intro_Tutorial/lessons/09_raja_view/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ RAJA::View<double, RAJA::Layout<2, int>> view(data, N, N);
where `data` is a `double*`, and `N` is the size of each dimension. The size of
`data` should be at least `N*N`.

In the file `09_raja_view.cpp`, there is a `TODO` comment where you should create three
views, A, B, and C. You will notice that we are doing the same dot product
calculation, but this time for matrices. Thus, we are now doing a matrix
multiplication. When you are ready, uncomment the COMPILE define on line 7;
then you can compile and run the code:
In the file `09_raja_view.cpp`, there is a `TODO` comment where you should create two
views, A, and R. R will be created via a permuted view with the same right-oriented layout
as A. Knowledge of `RAJA::make_permuted_view` is not required to complete this task, but
more information can be found here:
https://raja.readthedocs.io/en/develop/sphinx/user_guide/feature/view.html#make-permuted-view.
There are two `TODO` comments where you should complete the loop indexing and bounds, and fill
in A and R with their respective index values.
When you are ready, uncomment the COMPILE define on line 7; then you can compile and run the code:

```
$ make 09_raja_view
Expand Down
93 changes: 62 additions & 31 deletions Intro_Tutorial/lessons/09_raja_view/solution/09_raja_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,80 @@

int main()
{
constexpr int N{10000};
constexpr int M{3};
constexpr int N{5};
double* a{nullptr};
double* b{nullptr};
double* c{nullptr};
double* result_right{nullptr};
double* result_left{nullptr};

auto& rm = umpire::ResourceManager::getInstance();

auto allocator = rm.getAllocator("HOST");
auto pool = rm.makeAllocator<umpire::strategy::QuickPool>("POOL", allocator);

a = static_cast<double *>(pool.allocate(N*N*sizeof(double)));
b = static_cast<double *>(pool.allocate(N*N*sizeof(double)));
c = static_cast<double *>(pool.allocate(N*N*sizeof(double)));
a = static_cast<double *>(pool.allocate(M*N*sizeof(double)));
result_right = static_cast<double *>(pool.allocate(M*N*sizeof(double)));
result_left = static_cast<double *>(pool.allocate(M*N*sizeof(double)));

RAJA::TypedRangeSegment<int> row_range(0, N);
RAJA::TypedRangeSegment<int> col_range(0, N);

// TODO: Create a view for A, B, and C
// TODO: Create a standard MxN RAJA::View called, "A", initialized with the "a" array.
// TODO: Create a permuted MxN view with a right-oriented layout called, "R", initialized with the "result_right" array.
constexpr int DIM = 2;
RAJA::View<double, RAJA::Layout<DIM>> A(a, N, N);
RAJA::View<double, RAJA::Layout<DIM>> B(b, N, N);
RAJA::View<double, RAJA::Layout<DIM>> C(c, N, N);

RAJA::forall<RAJA::seq_exec>( row_range, [=](int row) {
RAJA::forall<RAJA::seq_exec>( col_range, [=](int col) {
A(row, col) = row;
B(row, col) = col;
});
});

RAJA::forall<RAJA::seq_exec>( row_range, [=](int row) {
RAJA::forall<RAJA::seq_exec>( col_range, [=](int col) {
double dot = 0.0;
for (int k = 0; k < N; ++k) {
dot += A(row, k) * B(k, col);
RAJA::View<double, RAJA::Layout<DIM>> A(a, M, N);
auto R = RAJA::make_permuted_view<RAJA::layout_right>(result_right, M, N);
auto L = RAJA::make_permuted_view<RAJA::layout_left>(result_left, M, N);

// TODO: Fill in loop bounds that are appropriate for right-oriented layouts of Views A and R.
for ( int row = 0; row < M; ++row )
{
for ( int col = 0; col < N; ++col )
{
// TODO: Initialize A and R views to their index values, e.g. index 0 should contain 0,
// index 1 should contain 1, . . ., index 14 should contain 14. Note that both
// A and R should print out the same sequence of values, due to the default
// View for A being constructed with a right-oriented layout.
A(row, col) = row * N + col;
R(row, col) = row * N + col;
}
}

// The L view will receive the same values as A and R. Note to achieve this,
// the loop indexing is reversed from the previous initialization loops because L
// is a left-oriented layout. The values assigned to L also reflect left-oriented
// indexing arithmetic.
for ( int col = 0; col < N; ++col )
{
for ( int row = 0; row < M; ++row )
{
L(row, col) = col * M + row;
}
}

auto printArrayAsMatrix = [&](double * array)
{
for ( int ii = 0; ii < M*N; ++ii )
{
printf("%f ", array[ii]);
if ( ((ii+1) % N == 0) )
{
printf("\n");
}
C(row, col) = dot;
});
});
}
};

// TODO: Look at the output and make sure each array prints the same ordering of values.
// "a" and "result_right" should match "result_left".
printf("\na array under View A:\n");
printArrayAsMatrix( a );

printf("\nresult_right array under View R:\n");
printArrayAsMatrix( result_right );

printf("\nresult_left array under View L:\n");
printArrayAsMatrix( result_left );

pool.deallocate(a);
pool.deallocate(b);
pool.deallocate(c);
pool.deallocate(result_right);
pool.deallocate(result_left);

return 0;
}