Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a new tutorial example to ease the onboarding of RAJA::kernel.
- Loading branch information
1 parent
ef49fae
commit b53d72a
Showing
9 changed files
with
308 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
// Copyright (c) 2016-19, Lawrence Livermore National Security, LLC | ||
// and RAJA project contributors. See the RAJA/COPYRIGHT file for details. | ||
// | ||
// SPDX-License-Identifier: (BSD-3-Clause) | ||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
|
||
#include <cstdlib> | ||
#include <iostream> | ||
|
||
#include "RAJA/RAJA.hpp" | ||
|
||
/* | ||
* EXERCISE #6: Nested Loop Reordering | ||
* | ||
* In this exercise, you will use RAJA::kernel execution policies | ||
* to permute the order of loops in a triple loop nest. In particular, | ||
* you will reorder loop statements in execution policies. The exercise | ||
* does no actual computation and just prints out the loop indices to show | ||
* the different orderings. | ||
* | ||
* To avoid the complexity of interpreting parallel output, the execution | ||
* policies you will write will use sequential execution. | ||
* | ||
* RAJA features shown: | ||
* - Index range segment | ||
* - 'RAJA::kernel' loop abstractions and execution policies | ||
* - Nested loop reordering | ||
* - Strongly-typed loop indices | ||
*/ | ||
|
||
// | ||
// Define three named loop index types used in the triply-nested loops. | ||
// These will trigger compilation errors if lambda index argument ordering | ||
// and types do not match the typed range index ordering. See final | ||
// example in this file. | ||
// | ||
RAJA_INDEX_VALUE(KIDX, "KIDX"); | ||
RAJA_INDEX_VALUE(JIDX, "JIDX"); | ||
RAJA_INDEX_VALUE(IIDX, "IIDX"); | ||
|
||
|
||
int main(int RAJA_UNUSED_ARG(argc), char **RAJA_UNUSED_ARG(argv[])) | ||
{ | ||
|
||
std::cout << "\n\nExercise #7: RAJA nested loop reorder example...\n"; | ||
|
||
// | ||
// Typed index ranges | ||
// | ||
RAJA::TypedRangeSegment<KIDX> KRange(2, 4); | ||
RAJA::TypedRangeSegment<JIDX> JRange(1, 3); | ||
RAJA::TypedRangeSegment<IIDX> IRange(0, 2); | ||
|
||
//----------------------------------------------------------------------------// | ||
|
||
std::cout << "\n Running loop reorder example (K-outer, J-middle, I-inner)" | ||
<< "...\n\n" << " (I, J, K)\n" << " ---------\n"; | ||
|
||
using KJI_EXECPOL = RAJA::KernelPolicy< | ||
RAJA::statement::For<2, RAJA::seq_exec, // k | ||
RAJA::statement::For<1, RAJA::seq_exec, // j | ||
RAJA::statement::For<0, RAJA::seq_exec,// i | ||
RAJA::statement::Lambda<0> | ||
> | ||
> | ||
> | ||
>; | ||
|
||
RAJA::kernel<KJI_EXECPOL>( RAJA::make_tuple(IRange, JRange, KRange), | ||
[=] (IIDX i, JIDX j, KIDX k) { | ||
printf( " (%d, %d, %d) \n", (int)(*i), (int)(*j), (int)(*k)); | ||
}); | ||
|
||
|
||
//----------------------------------------------------------------------------// | ||
|
||
std::cout << "\n Running loop reorder example (J-outer, I-middle, K-inner)" | ||
<< "...\n\n" << " (I, J, K)\n" << " ---------\n"; | ||
|
||
/// | ||
/// TODO... | ||
/// | ||
/// EXERCISE: Define an execution policy (JIK_EXECPOL) that reorders the | ||
/// loop nest so that the outer loop is the j-loop (slowest | ||
/// running index), the inner loop is the k-loop (fastest | ||
/// running index), and the i-loop is the middle loop. | ||
/// | ||
/// NOTE: You will have to enable this code section to compile and run it. | ||
/// | ||
|
||
#if 0 | ||
using JIK_EXECPOL = | ||
|
||
RAJA::kernel<JIK_EXECPOL>( RAJA::make_tuple(IRange, JRange, KRange), | ||
[=] (IIDX i, JIDX j, KIDX k) { | ||
printf( " (%d, %d, %d) \n", (int)(*i), (int)(*j), (int)(*k)); | ||
}); | ||
#endif | ||
|
||
|
||
//----------------------------------------------------------------------------// | ||
|
||
std::cout << "\n Running loop reorder example (I-outer, K-middle, J-inner)" | ||
<< "...\n\n" << " (I, J, K)\n" << " ---------\n"; | ||
|
||
/// | ||
/// TODO... | ||
/// | ||
/// EXERCISE: Define an execution policy (IKJ_EXECPOL) that reorders the | ||
/// loop nest so that the outer loop is the i-loop (slowest | ||
/// running index), the inner loop is the j-loop (fastest | ||
/// running index), and the k-loop is the middle loop. | ||
/// | ||
/// NOTE: You will have to enable this code section to compile and run it. | ||
/// | ||
|
||
#if 0 | ||
using IKJ_EXECPOL = | ||
|
||
RAJA::kernel<IKJ_EXECPOL>( RAJA::make_tuple(IRange, JRange, KRange), | ||
[=] (IIDX i, JIDX j, KIDX k) { | ||
printf( " (%d, %d, %d) \n", (int)(*i), (int)(*j), (int)(*k)); | ||
}); | ||
#endif | ||
|
||
|
||
#if 0 | ||
//----------------------------------------------------------------------------// | ||
// The following demonstrates that code will not compile if lambda argument | ||
// types/order do not match the types/order For statements in the execution | ||
// policy. To see this, enable this code section and try to compile this file. | ||
//----------------------------------------------------------------------------// | ||
|
||
RAJA::kernel<IKJ_EXECPOL>( RAJA::make_tuple(IRange, JRange, KRange), | ||
[=] (JIDX i, IIDX j, KIDX k) { | ||
printf( " (%d, %d, %d) \n", (int)(*i), (int)(*j), (int)(*k)); | ||
}); | ||
|
||
#endif | ||
|
||
std::cout << "\n DONE!...\n"; | ||
|
||
return 0; | ||
} | ||
|
136 changes: 136 additions & 0 deletions
136
exercises/tutorial_halfday/ex7_nested-loop-reorder_solution.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
// Copyright (c) 2016-19, Lawrence Livermore National Security, LLC | ||
// and RAJA project contributors. See the RAJA/COPYRIGHT file for details. | ||
// | ||
// SPDX-License-Identifier: (BSD-3-Clause) | ||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// | ||
|
||
#include <cstdlib> | ||
#include <iostream> | ||
|
||
#include "RAJA/RAJA.hpp" | ||
|
||
/* | ||
* EXERCISE #6: Nested Loop Reordering | ||
* | ||
* In this exercise, you will use RAJA::kernel execution policies | ||
* to permute the order of loops in a triple loop nest. In particular, | ||
* you will reorder loop statements in execution policies. The exercise | ||
* does no actual computation and just prints out the loop indices to show | ||
* the different orderings. | ||
* | ||
* To avoid the complexity of interpreting parallel output, the execution | ||
* policies you will write will use sequential execution. | ||
* | ||
* RAJA features shown: | ||
* - Index range segment | ||
* - 'RAJA::kernel' loop abstractions and execution policies | ||
* - Nested loop reordering | ||
* - Strongly-typed loop indices | ||
*/ | ||
|
||
// | ||
// Define three named loop index types used in the triply-nested loops. | ||
// These will trigger compilation errors if lambda index argument ordering | ||
// and types do not match the typed range index ordering. See final | ||
// example in this file. | ||
// | ||
RAJA_INDEX_VALUE(KIDX, "KIDX"); | ||
RAJA_INDEX_VALUE(JIDX, "JIDX"); | ||
RAJA_INDEX_VALUE(IIDX, "IIDX"); | ||
|
||
|
||
int main(int RAJA_UNUSED_ARG(argc), char **RAJA_UNUSED_ARG(argv[])) | ||
{ | ||
|
||
std::cout << "\n\nExercise #7: RAJA nested loop reorder example...\n"; | ||
|
||
// | ||
// Typed index ranges | ||
// | ||
RAJA::TypedRangeSegment<KIDX> KRange(2, 4); | ||
RAJA::TypedRangeSegment<JIDX> JRange(1, 3); | ||
RAJA::TypedRangeSegment<IIDX> IRange(0, 2); | ||
|
||
//----------------------------------------------------------------------------// | ||
|
||
std::cout << "\n Running loop reorder example (K-outer, J-middle, I-inner)" | ||
<< "...\n\n" << " (I, J, K)\n" << " ---------\n"; | ||
|
||
using KJI_EXECPOL = RAJA::KernelPolicy< | ||
RAJA::statement::For<2, RAJA::seq_exec, // k | ||
RAJA::statement::For<1, RAJA::seq_exec, // j | ||
RAJA::statement::For<0, RAJA::seq_exec,// i | ||
RAJA::statement::Lambda<0> | ||
> | ||
> | ||
> | ||
>; | ||
|
||
RAJA::kernel<KJI_EXECPOL>( RAJA::make_tuple(IRange, JRange, KRange), | ||
[=] (IIDX i, JIDX j, KIDX k) { | ||
printf( " (%d, %d, %d) \n", (int)(*i), (int)(*j), (int)(*k)); | ||
}); | ||
|
||
|
||
//----------------------------------------------------------------------------// | ||
|
||
std::cout << "\n Running loop reorder example (J-outer, I-middle, K-inner)" | ||
<< "...\n\n" << " (I, J, K)\n" << " ---------\n"; | ||
|
||
using JIK_EXECPOL = RAJA::KernelPolicy< | ||
RAJA::statement::For<1, RAJA::seq_exec, // j | ||
RAJA::statement::For<0, RAJA::seq_exec, // i | ||
RAJA::statement::For<2, RAJA::seq_exec,// k | ||
RAJA::statement::Lambda<0> | ||
> | ||
> | ||
> | ||
>; | ||
|
||
RAJA::kernel<JIK_EXECPOL>( RAJA::make_tuple(IRange, JRange, KRange), | ||
[=] (IIDX i, JIDX j, KIDX k) { | ||
printf( " (%d, %d, %d) \n", (int)(*i), (int)(*j), (int)(*k)); | ||
}); | ||
|
||
|
||
//----------------------------------------------------------------------------// | ||
|
||
std::cout << "\n Running loop reorder example (I-outer, K-middle, J-inner)" | ||
<< "...\n\n" << " (I, J, K)\n" << " ---------\n"; | ||
|
||
using IKJ_EXECPOL = RAJA::KernelPolicy< | ||
RAJA::statement::For<0, RAJA::seq_exec, // i | ||
RAJA::statement::For<2, RAJA::seq_exec, // k | ||
RAJA::statement::For<1, RAJA::seq_exec,// j | ||
RAJA::statement::Lambda<0> | ||
> | ||
> | ||
> | ||
>; | ||
|
||
RAJA::kernel<IKJ_EXECPOL>( RAJA::make_tuple(IRange, JRange, KRange), | ||
[=] (IIDX i, JIDX j, KIDX k) { | ||
printf( " (%d, %d, %d) \n", (int)(*i), (int)(*j), (int)(*k)); | ||
}); | ||
|
||
|
||
#if 0 | ||
//----------------------------------------------------------------------------// | ||
// The following demonstrates that code will not compile if lambda argument | ||
// types/order do not match the types/order For statements in the execution | ||
// policy. To see this, enable this code section and try to compile this file. | ||
//----------------------------------------------------------------------------// | ||
|
||
RAJA::kernel<IKJ_EXECPOL>( RAJA::make_tuple(IRange, JRange, KRange), | ||
[=] (JIDX i, IIDX j, KIDX k) { | ||
printf( " (%d, %d, %d) \n", (int)(*i), (int)(*j), (int)(*k)); | ||
}); | ||
|
||
#endif | ||
|
||
std::cout << "\n DONE!...\n"; | ||
|
||
return 0; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.