From 01da58c6e74fc4febeac706554f1883d304379c1 Mon Sep 17 00:00:00 2001 From: Arturo Vargas Date: Thu, 31 Oct 2024 16:32:48 -0700 Subject: [PATCH 1/5] add reduction support to dynamic_forall --- examples/dynamic-forall.cpp | 33 +++++++++++++-------------- include/RAJA/pattern/forall.hpp | 40 ++++++++++++++++----------------- 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/examples/dynamic-forall.cpp b/examples/dynamic-forall.cpp index 5131010bd6..3c120cb0ea 100644 --- a/examples/dynamic-forall.cpp +++ b/examples/dynamic-forall.cpp @@ -77,28 +77,25 @@ int main(int argc, char *argv[]) //----------------------------------------------------------------------------// - std::cout << "\n Running C-style vector addition...\n"; - - // _cstyle_vector_add_start - for (int i = 0; i < N; ++i) { - c[i] = a[i] + b[i]; - } - // _cstyle_vector_add_end - - checkResult(c, N); -//printResult(c, N); - - -//----------------------------------------------------------------------------// -// Example of dynamic policy selection for forall -//----------------------------------------------------------------------------// + std::cout << "\n Running dynamic forall vector addition and reductions...\n"; + int sum = 0; + using VAL_INT_SUM = RAJA::expt::ValOp; + + RAJA::RangeSegment range(0, N); + //policy is chosen from the list - RAJA::expt::dynamic_forall(pol, RAJA::RangeSegment(0, N), [=] RAJA_HOST_DEVICE (int i) { + RAJA::expt::dynamic_forall(pol, range, + RAJA::expt::Reduce(&sum), + RAJA::expt::KernelName("RAJA dynamic forall"), + [=] RAJA_HOST_DEVICE (int i, VAL_INT_SUM &_sum) { + c[i] = a[i] + b[i]; + _sum += 1; }); // _rajaseq_vector_add_end + std::cout<<"Sum = "< struct dynamic_helper { - template - static void invoke_forall(const int pol, SEGMENT const &seg, BODY const &body) + template + static void invoke_forall(const int pol, SEGMENT const &seg, PARAMS&&... params) { if(IDX==pol){ using t_pol = typename camp::at>::type; - RAJA::forall(seg, body); + RAJA::forall(seg, params...); return; } - dynamic_helper::invoke_forall(pol, seg, body); + dynamic_helper::invoke_forall(pol, seg, params...); } - template + template static resources::EventProxy - invoke_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, BODY const &body) + invoke_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, PARAMS&&... params) { using t_pol = typename camp::at>::type; using resource_type = typename resources::get_resource::type; if(IDX==pol){ - RAJA::forall(r.get(), seg, body); + RAJA::forall(r.get(), seg, params...); //Return a generic event proxy from r, //because forall returns a typed event proxy return {r}; } - return dynamic_helper::invoke_forall(r, pol, seg, body); + return dynamic_helper::invoke_forall(r, pol, seg, params...); } }; @@ -688,28 +688,28 @@ namespace expt template struct dynamic_helper<0, POLICY_LIST> { - template + template static void - invoke_forall(const int pol, SEGMENT const &seg, BODY const &body) + invoke_forall(const int pol, SEGMENT const &seg, PARAMS&&... params) { if(0==pol){ using t_pol = typename camp::at>::type; - RAJA::forall(seg, body); + RAJA::forall(seg, params...); return; } RAJA_ABORT_OR_THROW("Policy enum not supported "); } - template + template static resources::EventProxy - invoke_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, BODY const &body) + invoke_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, PARAMS&&... params) { if(pol != 0) RAJA_ABORT_OR_THROW("Policy value out of range "); using t_pol = typename camp::at>::type; using resource_type = typename resources::get_resource::type; - RAJA::forall(r.get(), seg, body); + RAJA::forall(r.get(), seg, params...); //Return a generic event proxy from r, //because forall returns a typed event proxy @@ -718,8 +718,8 @@ namespace expt }; - template - void dynamic_forall(const int pol, SEGMENT const &seg, BODY const &body) + template + void dynamic_forall(const int pol, SEGMENT const &seg, PARAMS&&... params) { constexpr int N = camp::size::value; static_assert(N > 0, "RAJA policy list must not be empty"); @@ -727,12 +727,12 @@ namespace expt if(pol > N-1) { RAJA_ABORT_OR_THROW("Policy enum not supported"); } - dynamic_helper::invoke_forall(pol, seg, body); + dynamic_helper::invoke_forall(pol, seg, params...); } - template + template resources::EventProxy - dynamic_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, BODY const &body) + dynamic_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, PARAMS&&... params) { constexpr int N = camp::size::value; static_assert(N > 0, "RAJA policy list must not be empty"); @@ -741,7 +741,7 @@ namespace expt RAJA_ABORT_OR_THROW("Policy value out of range"); } - return dynamic_helper::invoke_forall(r, pol, seg, body); + return dynamic_helper::invoke_forall(r, pol, seg, params...); } } // namespace expt From 41a3765d80b079c2ce0f200ee105da8396806775 Mon Sep 17 00:00:00 2001 From: Arturo Vargas Date: Thu, 31 Oct 2024 16:40:48 -0700 Subject: [PATCH 2/5] remove dynamic forall from expt --- examples/dynamic-forall.cpp | 2 +- include/RAJA/pattern/forall.hpp | 141 +++++++++++++++----------------- 2 files changed, 69 insertions(+), 74 deletions(-) diff --git a/examples/dynamic-forall.cpp b/examples/dynamic-forall.cpp index 3c120cb0ea..7c037571e9 100644 --- a/examples/dynamic-forall.cpp +++ b/examples/dynamic-forall.cpp @@ -85,7 +85,7 @@ int main(int argc, char *argv[]) RAJA::RangeSegment range(0, N); //policy is chosen from the list - RAJA::expt::dynamic_forall(pol, range, + RAJA::dynamic_forall(pol, range, RAJA::expt::Reduce(&sum), RAJA::expt::KernelName("RAJA dynamic forall"), [=] RAJA_HOST_DEVICE (int i, VAL_INT_SUM &_sum) { diff --git a/include/RAJA/pattern/forall.hpp b/include/RAJA/pattern/forall.hpp index 28e8897397..e75cc43af7 100644 --- a/include/RAJA/pattern/forall.hpp +++ b/include/RAJA/pattern/forall.hpp @@ -647,68 +647,29 @@ RAJA_INLINE camp::resources::EventProxy CallForallIcount::operator()(T cons // - Returns a generic event proxy only if a resource is provided // avoids overhead of constructing a typed erased resource // -namespace expt +template +struct dynamic_helper { - - template - struct dynamic_helper + template + static void invoke_forall(const int pol, SEGMENT const &seg, PARAMS&&... params) { - template - static void invoke_forall(const int pol, SEGMENT const &seg, PARAMS&&... params) - { - if(IDX==pol){ - using t_pol = typename camp::at>::type; - RAJA::forall(seg, params...); - return; - } - dynamic_helper::invoke_forall(pol, seg, params...); - } - - template - static resources::EventProxy - invoke_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, PARAMS&&... params) - { - + if(IDX==pol){ using t_pol = typename camp::at>::type; - using resource_type = typename resources::get_resource::type; - - if(IDX==pol){ - RAJA::forall(r.get(), seg, params...); - - //Return a generic event proxy from r, - //because forall returns a typed event proxy - return {r}; - } - - return dynamic_helper::invoke_forall(r, pol, seg, params...); + RAJA::forall(seg, params...); + return; } + dynamic_helper::invoke_forall(pol, seg, params...); + } - }; - - template - struct dynamic_helper<0, POLICY_LIST> + template + static resources::EventProxy + invoke_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, PARAMS&&... params) { - template - static void - invoke_forall(const int pol, SEGMENT const &seg, PARAMS&&... params) - { - if(0==pol){ - using t_pol = typename camp::at>::type; - RAJA::forall(seg, params...); - return; - } - RAJA_ABORT_OR_THROW("Policy enum not supported "); - } - template - static resources::EventProxy - invoke_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, PARAMS&&... params) - { - if(pol != 0) RAJA_ABORT_OR_THROW("Policy value out of range "); - - using t_pol = typename camp::at>::type; - using resource_type = typename resources::get_resource::type; + using t_pol = typename camp::at>::type; + using resource_type = typename resources::get_resource::type; + if(IDX==pol){ RAJA::forall(r.get(), seg, params...); //Return a generic event proxy from r, @@ -716,35 +677,69 @@ namespace expt return {r}; } - }; + return dynamic_helper::invoke_forall(r, pol, seg, params...); + } - template - void dynamic_forall(const int pol, SEGMENT const &seg, PARAMS&&... params) - { - constexpr int N = camp::size::value; - static_assert(N > 0, "RAJA policy list must not be empty"); +}; - if(pol > N-1) { - RAJA_ABORT_OR_THROW("Policy enum not supported"); +template +struct dynamic_helper<0, POLICY_LIST> +{ + template + static void + invoke_forall(const int pol, SEGMENT const &seg, PARAMS&&... params) + { + if(0==pol){ + using t_pol = typename camp::at>::type; + RAJA::forall(seg, params...); + return; } - dynamic_helper::invoke_forall(pol, seg, params...); + RAJA_ABORT_OR_THROW("Policy enum not supported "); } - template - resources::EventProxy - dynamic_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, PARAMS&&... params) + template + static resources::EventProxy + invoke_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, PARAMS&&... params) { - constexpr int N = camp::size::value; - static_assert(N > 0, "RAJA policy list must not be empty"); + if(pol != 0) RAJA_ABORT_OR_THROW("Policy value out of range "); - if(pol > N-1) { - RAJA_ABORT_OR_THROW("Policy value out of range"); - } + using t_pol = typename camp::at>::type; + using resource_type = typename resources::get_resource::type; + + RAJA::forall(r.get(), seg, params...); + + //Return a generic event proxy from r, + //because forall returns a typed event proxy + return {r}; + } + +}; - return dynamic_helper::invoke_forall(r, pol, seg, params...); +template +void dynamic_forall(const int pol, SEGMENT const &seg, PARAMS&&... params) +{ + constexpr int N = camp::size::value; + static_assert(N > 0, "RAJA policy list must not be empty"); + + if(pol > N-1) { + RAJA_ABORT_OR_THROW("Policy enum not supported"); + } + dynamic_helper::invoke_forall(pol, seg, params...); +} + +template +resources::EventProxy +dynamic_forall(RAJA::resources::Resource r, const int pol, SEGMENT const &seg, PARAMS&&... params) +{ + constexpr int N = camp::size::value; + static_assert(N > 0, "RAJA policy list must not be empty"); + + if(pol > N-1) { + RAJA_ABORT_OR_THROW("Policy value out of range"); } -} // namespace expt + return dynamic_helper::invoke_forall(r, pol, seg, params...); +} } // namespace RAJA From 36e06139c5f9175c36f860c533b8c024ffa1d8e6 Mon Sep 17 00:00:00 2001 From: Arturo Vargas Date: Thu, 31 Oct 2024 16:54:59 -0700 Subject: [PATCH 3/5] bring resource dynamic forall out of expt --- examples/resource-dynamic-forall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/resource-dynamic-forall.cpp b/examples/resource-dynamic-forall.cpp index 0b35017fac..ac6fd62398 100644 --- a/examples/resource-dynamic-forall.cpp +++ b/examples/resource-dynamic-forall.cpp @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) RAJA::resources::Resource res = RAJA::Get_Host_Resource(host_res, select_cpu_or_gpu); #endif - RAJA::expt::dynamic_forall + RAJA::dynamic_forall (res, pol, RAJA::RangeSegment(0, N), [=] RAJA_HOST_DEVICE (int i) { c[i] = a[i] + b[i]; From ff4bbf8b7917546f1a0b8d178bdf19d99f23773d Mon Sep 17 00:00:00 2001 From: Arturo Vargas Date: Thu, 31 Oct 2024 17:03:07 -0700 Subject: [PATCH 4/5] fix tests --- .../tests/test-dynamic-forall-resource-RangeSegment.hpp | 2 +- .../segment/tests/test-dynamic-forall-RangeSegment.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/functional/dynamic_forall/resource-segment/tests/test-dynamic-forall-resource-RangeSegment.hpp b/test/functional/dynamic_forall/resource-segment/tests/test-dynamic-forall-resource-RangeSegment.hpp index 8c8d051d8f..dde4273abe 100644 --- a/test/functional/dynamic_forall/resource-segment/tests/test-dynamic-forall-resource-RangeSegment.hpp +++ b/test/functional/dynamic_forall/resource-segment/tests/test-dynamic-forall-resource-RangeSegment.hpp @@ -34,7 +34,7 @@ void DynamicForallResourceRangeSegmentTestImpl(INDEX_TYPE first, INDEX_TYPE last std::iota(test_array, test_array + RAJA::stripIndexType(N), rbegin); - RAJA::expt::dynamic_forall(working_res, pol, r1, [=] RAJA_HOST_DEVICE(INDEX_TYPE idx) { + RAJA::dynamic_forall(working_res, pol, r1, [=] RAJA_HOST_DEVICE(INDEX_TYPE idx) { working_array[RAJA::stripIndexType(idx - rbegin)] = idx; }); diff --git a/test/functional/dynamic_forall/segment/tests/test-dynamic-forall-RangeSegment.hpp b/test/functional/dynamic_forall/segment/tests/test-dynamic-forall-RangeSegment.hpp index 11168b0e30..6f13f07cf5 100644 --- a/test/functional/dynamic_forall/segment/tests/test-dynamic-forall-RangeSegment.hpp +++ b/test/functional/dynamic_forall/segment/tests/test-dynamic-forall-RangeSegment.hpp @@ -40,7 +40,7 @@ void DynamicForallRangeSegmentTestImpl(INDEX_TYPE first, INDEX_TYPE last, const std::iota(test_array, test_array + RAJA::stripIndexType(N), rbegin); - RAJA::expt::dynamic_forall(pol, r1, [=] RAJA_HOST_DEVICE(INDEX_TYPE idx) { + RAJA::dynamic_forall(pol, r1, [=] RAJA_HOST_DEVICE(INDEX_TYPE idx) { working_array[RAJA::stripIndexType(idx - rbegin)] = idx; }); @@ -50,7 +50,7 @@ void DynamicForallRangeSegmentTestImpl(INDEX_TYPE first, INDEX_TYPE last, const working_res.memcpy(working_array, test_array, sizeof(INDEX_TYPE) * data_len); - RAJA::expt::dynamic_forall(pol, r1, [=] RAJA_HOST_DEVICE(INDEX_TYPE idx) { + RAJA::dynamic_forall(pol, r1, [=] RAJA_HOST_DEVICE(INDEX_TYPE idx) { (void) idx; working_array[0]++; }); From 775e869a0a755edac89f71f2ee75952a74df9bc4 Mon Sep 17 00:00:00 2001 From: Arturo Vargas Date: Tue, 26 Nov 2024 11:03:02 -0800 Subject: [PATCH 5/5] Update examples/dynamic-forall.cpp Co-authored-by: Robert Chen --- examples/dynamic-forall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dynamic-forall.cpp b/examples/dynamic-forall.cpp index 7c037571e9..d405408e7f 100644 --- a/examples/dynamic-forall.cpp +++ b/examples/dynamic-forall.cpp @@ -95,7 +95,7 @@ int main(int argc, char *argv[]) }); // _rajaseq_vector_add_end - std::cout<<"Sum = "<