Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
104 changes: 75 additions & 29 deletions Intro_Tutorial/lessons/09_raja_view/09_raja_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,94 @@
int main()
{
#if defined(COMPILE)

constexpr int N{1000};
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
constexpr int DIM = 2;

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);
// TODO: Create a standard MxN RAJA::View called "A", initialized with the
// "a" array.
RAJA::View<double, ???>> A(???, ???, ???);

// A left-oriented layout view initialized with "result_left" array
auto L = RAJA::make_permuted_view<RAJA::layout_left>(result_left, M, N);

// TODO: Create a permuted MxN view with a right-oriented layout called "R",
// initialized with the "result_right" array.
auto R = ???;

// Note that Views created by RAJA::make_permuted_view know the unit stride
// index at compile time, which prevents unnecessary index arithmetic

// TODO: Fill in loop bounds that are appropriate for right-oriented layout
// Views A and R.
for ( int row = 0; row < ???; ++row )
{
for ( int col = 0; col < ???; ++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
// in the calls to 'printArrayAsMatrix' below.
A(row, col) = ???;
R(row, col) = ???;
}
}

// The L view will receive the same values as A and R. 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;
}
}

// Method to print arrays associated with the Views constructed above
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: Run the code and review the output from the following method calls
// to 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(result_right);
pool.deallocate(result_left);
#endif

return 0;
Expand Down
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
54 changes: 0 additions & 54 deletions Intro_Tutorial/lessons/09_raja_view/solution/09_raja_view.cpp

This file was deleted.

103 changes: 103 additions & 0 deletions Intro_Tutorial/lessons/09_raja_view/solution/09_raja_view_solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include <iostream>

#include "RAJA/RAJA.hpp"
#include "umpire/Umpire.hpp"
#include "umpire/strategy/QuickPool.hpp"

#define COMPILE

int main()
{
#if defined(COMPILE)
constexpr int M{3};
constexpr int N{5};
double* a{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(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)));

constexpr int DIM = 2;

// TODO: Create a standard MxN RAJA::View called "A", initialized with the
// "a" array.
RAJA::View<double, RAJA::Layout<DIM>> A(a, M, N);

// A left-oriented layout view initialized with "result_left" array
auto L = RAJA::make_permuted_view<RAJA::layout_left>(result_left, M, N);

// TODO: Create a permuted MxN view with a right-oriented layout called "R",
// initialized with the "result_right" array.
auto R = RAJA::make_permuted_view<RAJA::layout_right>(result_right, M, N);

// Note that Views created by RAJA::make_permuted_view know the unit stride
// index at compile time, which prevents unnecessary index arithmetic

// TODO: Fill in loop bounds that are appropriate for right-oriented layout
// 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
// in the calls to 'printArrayAsMatrix' below.
A(row, col) = row * N + col;
R(row, col) = row * N + col;
}
}

// The L view will receive the same values as A and R. 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;
}
}

// Method to print arrays associated with the Views constructed above
auto printArrayAsMatrix = [&](double * array)
{
for ( int ii = 0; ii < M*N; ++ii )
{
printf("%f ", array[ii]);
if ( ((ii+1) % N == 0) )
{
printf("\n");
}
}
};

// TODO: Run the code and review the output from the following method calls
// to 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(result_right);
pool.deallocate(result_left);
#endif

return 0;
}