From 05ba18efe71710c17555d18c91d61cb0ec4389e4 Mon Sep 17 00:00:00 2001 From: john bowen Date: Tue, 17 Feb 2026 15:52:09 -0800 Subject: [PATCH 1/4] Initial concepts implementation --- include/RAJA/index/IndexSet.hpp | 13 +++- include/RAJA/index/RangeSegment.hpp | 2 +- include/RAJA/pattern/concepts.hpp | 33 +++++++++ include/RAJA/pattern/forall.hpp | 108 ++++++++++++---------------- include/RAJA/policy/MultiPolicy.hpp | 4 +- include/RAJA/util/resource.hpp | 4 ++ 6 files changed, 96 insertions(+), 68 deletions(-) create mode 100644 include/RAJA/pattern/concepts.hpp diff --git a/include/RAJA/index/IndexSet.hpp b/include/RAJA/index/IndexSet.hpp index 42bcd358c4..8830aac32e 100644 --- a/include/RAJA/index/IndexSet.hpp +++ b/include/RAJA/index/IndexSet.hpp @@ -22,9 +22,6 @@ #include "RAJA/config.hpp" -#include "RAJA/index/ListSegment.hpp" -#include "RAJA/index/RangeSegment.hpp" - #include "RAJA/internal/Iterators.hpp" #include "RAJA/internal/RAJAVec.hpp" @@ -801,6 +798,16 @@ struct is_indexset_policy typename std::decay::type> {}; } // namespace type_traits +template +concept IndexSetType = //RAJA::type_traits::is_index_set::value; +//std::is_same(RAJA::type_traits::is_index_set::value);//, camp::true_type>::value; + + +template +concept IndexSetPolicy = //type_traits::is_indexset_policy::value; +//std::is_same(type_traits::is_indexset_policy::value);//, camp::true_type>::value; } // namespace RAJA diff --git a/include/RAJA/index/RangeSegment.hpp b/include/RAJA/index/RangeSegment.hpp index 2ed81d005f..73fecb60e1 100644 --- a/include/RAJA/index/RangeSegment.hpp +++ b/include/RAJA/index/RangeSegment.hpp @@ -615,7 +615,7 @@ DefineTypeTraitFromConcept(is_range_constructible, DefineTypeTraitFromConcept(is_range_stride_constructible, RAJA::concepts::RangeStrideConstructible); - + } // namespace type_traits } // namespace RAJA diff --git a/include/RAJA/pattern/concepts.hpp b/include/RAJA/pattern/concepts.hpp new file mode 100644 index 0000000000..e932bfb8a1 --- /dev/null +++ b/include/RAJA/pattern/concepts.hpp @@ -0,0 +1,33 @@ +#ifndef RAJA_type_concepts_HPP +#define RAJA_type_concepts_HPP + +#include "RAJA/config.hpp" +#include "RAJA/index/IndexSet.hpp" +namespace RAJA { +#define RAJA_DEFINE_TRAIT_FROM_TYPEDEF(TYPEDEF) \ + template \ + struct is_##TYPEDEF { \ + private: \ + template \ + using have_t = typename U::TYPEDEF; \ + template \ + using have_type_t = typename U::TYPEDEF##_type; \ + \ + public: \ + static constexpr bool value = \ + std::is_base_of_v, T> || \ + std::is_base_of_v, T>; \ + constexpr operator bool() const noexcept { return value; } \ + }; \ + template \ + inline constexpr bool is_##TYPEDEF##_v = is_##TYPEDEF::value; + +#define RAJA_DEFINE_CONCEPT_AND_TRAIT_FROM_TYPEDEF(TYPEDEF, \ + CXX20_CONCEPT) \ + RAJA_DEFINE_TRAIT_FROM_TYPEDEF(TYPEDEF) \ + template \ + concept CXX20_CONCEPT = is_##TYPEDEF##_v; + + +#endif +} \ No newline at end of file diff --git a/include/RAJA/pattern/forall.hpp b/include/RAJA/pattern/forall.hpp index 507afc4da4..81e38687a4 100644 --- a/include/RAJA/pattern/forall.hpp +++ b/include/RAJA/pattern/forall.hpp @@ -75,6 +75,7 @@ #include "RAJA/policy/sequential/forall.hpp" +#include "RAJA/pattern/concepts.hpp" #include "RAJA/pattern/detail/forall.hpp" #include "RAJA/pattern/detail/privatizer.hpp" #include "RAJA/pattern/params/kernel_name.hpp" @@ -87,6 +88,12 @@ namespace RAJA { +template +// concept Range = std::is_same>, std::true_type>::value; +concept Range = static_cast(type_traits::is_range>::value);// && !IndexSetType; + +template +concept RandomAccessRange = Range && static_cast(type_traits::is_random_access_range::value); // ////////////////////////////////////////////////////////////////////// // @@ -94,7 +101,10 @@ namespace RAJA // ////////////////////////////////////////////////////////////////////// // - +namespace type_traits { + template + concept Integer = static_cast(type_traits::is_integral>::value); +} namespace detail { /// Adapter to replace specific implementations for the icount variants @@ -174,15 +184,14 @@ namespace wrap * ****************************************************************************** */ + template + concept NotIndexSetPol = !IndexSetPolicy; template -RAJA_INLINE concepts::enable_if_t< - RAJA::resources::EventProxy, - concepts::negate>, - type_traits::is_range> +RAJA_INLINE RAJA::resources::EventProxy forall(Res r, ExecutionPolicy&& p, Container&& c, @@ -197,12 +206,10 @@ forall(Res r, template -RAJA_INLINE concepts::enable_if_t< - RAJA::resources::EventProxy, - concepts::negate>, - type_traits::is_range> +RAJA_INLINE RAJA::resources::EventProxy forall(Res r, ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) { RAJA_FORCEINLINE_RECURSIVE @@ -379,19 +386,13 @@ RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, * ****************************************************************************** */ -template -RAJA_INLINE concepts::enable_if_t< - resources::EventProxy, - type_traits::is_indexset_policy> +RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, Res r, IdxSet&& c, Params&&... params) { - static_assert(type_traits::is_index_set::value, - "Expected a TypedIndexSet but did not get one. Are you using " - "a TypedIndexSet policy by mistake?"); - auto f_params = expt::make_forall_param_pack(std::forward(params)...); std::string kernel_name = @@ -418,13 +419,11 @@ forall(ExecutionPolicy&& p, Res r, IdxSet&& c, Params&&... params) return e; } -template::type> -RAJA_INLINE concepts::enable_if_t< - resources::EventProxy, - type_traits::is_indexset_policy> +RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, IdxSet&& c, LoopBody&& loop_body) { auto r = Res::get_default(); @@ -440,13 +439,11 @@ forall(ExecutionPolicy&& p, IdxSet&& c, LoopBody&& loop_body) * ****************************************************************************** */ -template::type> -RAJA_INLINE concepts::enable_if_t, - type_traits::is_multi_policy, - type_traits::is_range> +RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) { static_assert(type_traits::is_random_access_range::value, @@ -470,12 +467,10 @@ forall(ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) template -RAJA_INLINE concepts::enable_if_t, - type_traits::is_range, - type_traits::is_integral> +RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, Res r, Container&& c, @@ -514,15 +509,11 @@ forall_Icount(ExecutionPolicy&& p, } template::type> -RAJA_INLINE concepts::enable_if_t< - resources::EventProxy, - type_traits::is_range, - concepts::negate>, - type_traits::is_integral> +RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, Container&& c, IndexType icount, @@ -542,19 +533,16 @@ forall_Icount(ExecutionPolicy&& p, ****************************************************************************** */ -template +concept SimplePolicy = !IndexSetPolicy && !type_traits::MultiPolicyConcept; + +template -RAJA_INLINE concepts::enable_if_t< - resources::EventProxy, - concepts::negate>, - concepts::negate>, - type_traits::is_range> +RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, Res r, Container&& c, Params&&... params) { - static_assert(type_traits::is_random_access_range::value, - "Container does not model RandomAccessIterator"); auto f_params = expt::make_forall_param_pack(std::forward(params)...); @@ -583,15 +571,11 @@ forall(ExecutionPolicy&& p, Res r, Container&& c, Params&&... params) return e; } -template::type> -RAJA_INLINE concepts::enable_if_t< - resources::EventProxy, - concepts::negate>, - concepts::negate>, - type_traits::is_range> +RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) { auto r = Res::get_default(); @@ -617,9 +601,8 @@ RAJA_INLINE resources::EventProxy forall(Args&&... args) std::forward(args)...); } -template -RAJA_INLINE concepts::enable_if_t, - type_traits::is_resource> +template +RAJA_INLINE resources::EventProxy forall(Res r, Args&&... args) { return ::RAJA::policy_by_value_interface::forall(ExecutionPolicy(), r, @@ -642,9 +625,8 @@ RAJA_INLINE resources::EventProxy forall_Icount(Args&&... args) ExecutionPolicy(), r, std::forward(args)...); } -template -RAJA_INLINE concepts::enable_if_t, - type_traits::is_resource> +template +RAJA_INLINE resources::EventProxy forall_Icount(Res r, Args&&... args) { return ::RAJA::policy_by_value_interface::forall_Icount( diff --git a/include/RAJA/policy/MultiPolicy.hpp b/include/RAJA/policy/MultiPolicy.hpp index ec847b55d1..5bee8e27d2 100644 --- a/include/RAJA/policy/MultiPolicy.hpp +++ b/include/RAJA/policy/MultiPolicy.hpp @@ -256,7 +256,9 @@ template struct is_multi_policy : ::RAJA::type_traits::SpecializationOf::type> -{}; + {}; +template +concept MultiPolicyConcept = static_cast(RAJA::type_traits::is_multi_policy::value); } // namespace type_traits } // end namespace RAJA diff --git a/include/RAJA/util/resource.hpp b/include/RAJA/util/resource.hpp index b1d86b267f..51fd1bf19d 100644 --- a/include/RAJA/util/resource.hpp +++ b/include/RAJA/util/resource.hpp @@ -23,6 +23,7 @@ #define RAJA_resource_HPP #include "camp/resource.hpp" +#include #if defined(RAJA_CUDA_ACTIVE) #include "RAJA/policy/cuda/policy.hpp" #endif @@ -246,6 +247,9 @@ struct is_resource : std::true_type #endif } // end namespace type_traits +template +concept Resource = type_traits::is_resource::value; + } // end namespace RAJA #endif // RAJA_resources_HPP# From 90cc065311f8a263f37155f1c250bd75cbfad954 Mon Sep 17 00:00:00 2001 From: john bowen Date: Wed, 18 Feb 2026 15:59:48 -0800 Subject: [PATCH 2/4] Replace pattern/forall.hpp SFINAE with concepts and requires --- include/RAJA/index/IndexSet.hpp | 15 ++-- include/RAJA/index/RangeSegment.hpp | 1 - include/RAJA/pattern/concepts.hpp | 33 -------- include/RAJA/pattern/forall.hpp | 126 ++++++++++++++-------------- include/RAJA/policy/MultiPolicy.hpp | 8 +- 5 files changed, 77 insertions(+), 106 deletions(-) delete mode 100644 include/RAJA/pattern/concepts.hpp diff --git a/include/RAJA/index/IndexSet.hpp b/include/RAJA/index/IndexSet.hpp index 8830aac32e..ae090412f0 100644 --- a/include/RAJA/index/IndexSet.hpp +++ b/include/RAJA/index/IndexSet.hpp @@ -798,16 +798,15 @@ struct is_indexset_policy typename std::decay::type> {}; } // namespace type_traits -template -concept IndexSetType = //RAJA::type_traits::is_index_set::value; -//std::is_same(RAJA::type_traits::is_index_set::value);//, camp::true_type>::value; + +template +concept IndexSetType = + static_cast(RAJA::type_traits::is_index_set::value); -template -concept IndexSetPolicy = //type_traits::is_indexset_policy::value; -//std::is_same(type_traits::is_indexset_policy::value);//, camp::true_type>::value; +template +concept IndexSetPolicy = + static_cast(type_traits::is_indexset_policy::value); } // namespace RAJA diff --git a/include/RAJA/index/RangeSegment.hpp b/include/RAJA/index/RangeSegment.hpp index 73fecb60e1..ad4700de1f 100644 --- a/include/RAJA/index/RangeSegment.hpp +++ b/include/RAJA/index/RangeSegment.hpp @@ -615,7 +615,6 @@ DefineTypeTraitFromConcept(is_range_constructible, DefineTypeTraitFromConcept(is_range_stride_constructible, RAJA::concepts::RangeStrideConstructible); - } // namespace type_traits } // namespace RAJA diff --git a/include/RAJA/pattern/concepts.hpp b/include/RAJA/pattern/concepts.hpp deleted file mode 100644 index e932bfb8a1..0000000000 --- a/include/RAJA/pattern/concepts.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef RAJA_type_concepts_HPP -#define RAJA_type_concepts_HPP - -#include "RAJA/config.hpp" -#include "RAJA/index/IndexSet.hpp" -namespace RAJA { -#define RAJA_DEFINE_TRAIT_FROM_TYPEDEF(TYPEDEF) \ - template \ - struct is_##TYPEDEF { \ - private: \ - template \ - using have_t = typename U::TYPEDEF; \ - template \ - using have_type_t = typename U::TYPEDEF##_type; \ - \ - public: \ - static constexpr bool value = \ - std::is_base_of_v, T> || \ - std::is_base_of_v, T>; \ - constexpr operator bool() const noexcept { return value; } \ - }; \ - template \ - inline constexpr bool is_##TYPEDEF##_v = is_##TYPEDEF::value; - -#define RAJA_DEFINE_CONCEPT_AND_TRAIT_FROM_TYPEDEF(TYPEDEF, \ - CXX20_CONCEPT) \ - RAJA_DEFINE_TRAIT_FROM_TYPEDEF(TYPEDEF) \ - template \ - concept CXX20_CONCEPT = is_##TYPEDEF##_v; - - -#endif -} \ No newline at end of file diff --git a/include/RAJA/pattern/forall.hpp b/include/RAJA/pattern/forall.hpp index 81e38687a4..c13577a811 100644 --- a/include/RAJA/pattern/forall.hpp +++ b/include/RAJA/pattern/forall.hpp @@ -89,11 +89,11 @@ namespace RAJA { template -// concept Range = std::is_same>, std::true_type>::value; -concept Range = static_cast(type_traits::is_range>::value);// && !IndexSetType; - +concept Range = static_cast(type_traits::is_range>::value); + template -concept RandomAccessRange = Range && static_cast(type_traits::is_random_access_range::value); +concept RandomAccessRange = Range && + static_cast(type_traits::is_random_access_range::value); // ////////////////////////////////////////////////////////////////////// // @@ -101,10 +101,10 @@ concept RandomAccessRange = Range && static_cast(type_traits::is_random // ////////////////////////////////////////////////////////////////////// // -namespace type_traits { - template - concept Integer = static_cast(type_traits::is_integral>::value); -} +template +concept Integer = + static_cast(type_traits::is_integral>::value); + namespace detail { /// Adapter to replace specific implementations for the icount variants @@ -184,19 +184,18 @@ namespace wrap * ****************************************************************************** */ - template - concept NotIndexSetPol = !IndexSetPolicy; template -RAJA_INLINE RAJA::resources::EventProxy -forall(Res r, - ExecutionPolicy&& p, - Container&& c, - LoopBody&& loop_body, - ForallParams&& f_params) + +requires(!IndexSetPolicy) + RAJA_INLINE RAJA::resources::EventProxy forall(Res r, + ExecutionPolicy&& p, + Container&& c, + LoopBody&& loop_body, + ForallParams&& f_params) { RAJA_FORCEINLINE_RECURSIVE return forall_impl( @@ -207,10 +206,12 @@ forall(Res r, template -RAJA_INLINE RAJA::resources::EventProxy -forall(Res r, ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) +RAJA_INLINE RAJA::resources::EventProxy forall(Res r, + ExecutionPolicy&& p, + Container&& c, + LoopBody&& loop_body) { RAJA_FORCEINLINE_RECURSIVE return forall_impl( @@ -329,16 +330,13 @@ inline namespace policy_by_value_interface */ template RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, Res r, IdxSet&& c, Params&&... params) { - static_assert(type_traits::is_index_set::value, - "Expected a TypedIndexSet but did not get one. Are you using " - "a TypedIndexSet policy by mistake?"); std::string kernel_name = expt::get_kernel_name(std::forward(params)...); @@ -390,8 +388,10 @@ template -RAJA_INLINE resources::EventProxy -forall(ExecutionPolicy&& p, Res r, IdxSet&& c, Params&&... params) +RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, + Res r, + IdxSet&& c, + Params&&... params) { auto f_params = expt::make_forall_param_pack(std::forward(params)...); @@ -423,8 +423,9 @@ template::type> -RAJA_INLINE resources::EventProxy -forall(ExecutionPolicy&& p, IdxSet&& c, LoopBody&& loop_body) +RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, + IdxSet&& c, + LoopBody&& loop_body) { auto r = Res::get_default(); return ::RAJA::policy_by_value_interface::forall( @@ -439,12 +440,13 @@ forall(ExecutionPolicy&& p, IdxSet&& c, LoopBody&& loop_body) * ****************************************************************************** */ -template::type> -RAJA_INLINE resources::EventProxy -forall(ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) +RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, + Container&& c, + LoopBody&& loop_body) { static_assert(type_traits::is_random_access_range::value, "Container does not model RandomAccessIterator"); @@ -466,20 +468,17 @@ forall(ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) */ template -RAJA_INLINE resources::EventProxy -forall_Icount(ExecutionPolicy&& p, - Res r, - Container&& c, - IndexType icount, - FirstParam&& first, - Params&&... params) +RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, + Res r, + Container&& c, + IndexType icount, + FirstParam&& first, + Params&&... params) { - static_assert(type_traits::is_random_access_range::value, - "Container does not model RandomAccessIterator"); auto f_params = expt::make_forall_param_pack(std::forward(first), std::forward(params)...); @@ -510,14 +509,15 @@ forall_Icount(ExecutionPolicy&& p, template::type> -RAJA_INLINE resources::EventProxy -forall_Icount(ExecutionPolicy&& p, - Container&& c, - IndexType icount, - LoopBody&& loop_body) + +requires(!IndexSetPolicy) + RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, + Container&& c, + IndexType icount, + LoopBody&& loop_body) { auto r = Res::get_default(); return ::RAJA::policy_by_value_interface::forall_Icount( @@ -533,15 +533,17 @@ forall_Icount(ExecutionPolicy&& p, ****************************************************************************** */ -template -concept SimplePolicy = !IndexSetPolicy && !type_traits::MultiPolicyConcept; - -template -RAJA_INLINE resources::EventProxy -forall(ExecutionPolicy&& p, Res r, Container&& c, Params&&... params) + +requires(!IndexSetPolicy && + !MultiPolicyConcept) + RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, + Res r, + Container&& c, + Params&&... params) { auto f_params = expt::make_forall_param_pack(std::forward(params)...); @@ -571,12 +573,16 @@ forall(ExecutionPolicy&& p, Res r, Container&& c, Params&&... params) return e; } -template::type> -RAJA_INLINE resources::EventProxy -forall(ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) + +requires(!IndexSetPolicy && + !MultiPolicyConcept) + RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, + Container&& c, + LoopBody&& loop_body) { auto r = Res::get_default(); return ::RAJA::policy_by_value_interface::forall( @@ -602,8 +608,7 @@ RAJA_INLINE resources::EventProxy forall(Args&&... args) } template -RAJA_INLINE resources::EventProxy -forall(Res r, Args&&... args) +RAJA_INLINE resources::EventProxy forall(Res r, Args&&... args) { return ::RAJA::policy_by_value_interface::forall(ExecutionPolicy(), r, std::forward(args)...); @@ -626,8 +631,7 @@ RAJA_INLINE resources::EventProxy forall_Icount(Args&&... args) } template -RAJA_INLINE resources::EventProxy -forall_Icount(Res r, Args&&... args) +RAJA_INLINE resources::EventProxy forall_Icount(Res r, Args&&... args) { return ::RAJA::policy_by_value_interface::forall_Icount( ExecutionPolicy(), r, std::forward(args)...); diff --git a/include/RAJA/policy/MultiPolicy.hpp b/include/RAJA/policy/MultiPolicy.hpp index 5bee8e27d2..fd8995e32f 100644 --- a/include/RAJA/policy/MultiPolicy.hpp +++ b/include/RAJA/policy/MultiPolicy.hpp @@ -256,11 +256,13 @@ template struct is_multi_policy : ::RAJA::type_traits::SpecializationOf::type> - {}; -template -concept MultiPolicyConcept = static_cast(RAJA::type_traits::is_multi_policy::value); +{}; } // namespace type_traits +template +concept MultiPolicyConcept = + static_cast(RAJA::type_traits::is_multi_policy::value); + } // end namespace RAJA #endif From 2ab3be4030839eec8e2817b80a3f09bcf2b4adc9 Mon Sep 17 00:00:00 2001 From: john bowen Date: Wed, 18 Feb 2026 16:06:02 -0800 Subject: [PATCH 3/4] remove include of old file --- include/RAJA/pattern/forall.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/RAJA/pattern/forall.hpp b/include/RAJA/pattern/forall.hpp index c13577a811..5c2fa9189c 100644 --- a/include/RAJA/pattern/forall.hpp +++ b/include/RAJA/pattern/forall.hpp @@ -75,7 +75,6 @@ #include "RAJA/policy/sequential/forall.hpp" -#include "RAJA/pattern/concepts.hpp" #include "RAJA/pattern/detail/forall.hpp" #include "RAJA/pattern/detail/privatizer.hpp" #include "RAJA/pattern/params/kernel_name.hpp" @@ -206,7 +205,6 @@ requires(!IndexSetPolicy) template RAJA_INLINE RAJA::resources::EventProxy forall(Res r, ExecutionPolicy&& p, From 7228b17c888d094f521608454103c9f7ba438784 Mon Sep 17 00:00:00 2001 From: john bowen Date: Thu, 19 Feb 2026 14:50:22 -0800 Subject: [PATCH 4/4] Isolate forall concepts into header, create policy and parameter concepts --- include/RAJA/pattern/detail/TypeTraits.hpp | 11 +++ include/RAJA/pattern/forall-concepts.hpp | 47 +++++++++++ include/RAJA/pattern/forall.hpp | 96 +++++++++------------- include/RAJA/policy/MultiPolicy.hpp | 4 - 4 files changed, 98 insertions(+), 60 deletions(-) create mode 100644 include/RAJA/pattern/forall-concepts.hpp diff --git a/include/RAJA/pattern/detail/TypeTraits.hpp b/include/RAJA/pattern/detail/TypeTraits.hpp index f02df2c3a6..fb62ccaaea 100644 --- a/include/RAJA/pattern/detail/TypeTraits.hpp +++ b/include/RAJA/pattern/detail/TypeTraits.hpp @@ -21,6 +21,7 @@ #ifndef RAJA_TYPETRAITS_HPP #define RAJA_TYPETRAITS_HPP +#include "RAJA/policy/PolicyBase.hpp" #include #include @@ -96,6 +97,16 @@ struct tuple_contains_Reducers> {}; } // namespace expt + +namespace type_traits +{ +template +consteval bool is_policy_forall() +{ + return std::is_base_of_v && + Policy {}.pattern == RAJA::Pattern::forall; +} +} // namespace type_traits } // namespace RAJA #endif // RAJA_TYPETRAITS_HPP diff --git a/include/RAJA/pattern/forall-concepts.hpp b/include/RAJA/pattern/forall-concepts.hpp new file mode 100644 index 0000000000..ca8a392ffb --- /dev/null +++ b/include/RAJA/pattern/forall-concepts.hpp @@ -0,0 +1,47 @@ +#ifndef RAJA_forall_concepts_HPP +#define RAJA_forall_concepts_HPP + +#include "RAJA/config.hpp" + +#include "RAJA/pattern/detail/TypeTraits.hpp" +#include "RAJA/index/IndexSet.hpp" +#include "RAJA/index/RangeSegment.hpp" +#include "RAJA/policy/MultiPolicy.hpp" +#include "detail/TypeTraits.hpp" + +namespace RAJA +{ +// TODO: Several of these are based on camp type_traits, which themselves are +// automatically generated by camp's pseudo-concept interface. We wish to +// simplify this chain of requirements, potentially moving the concepts +// themselves into camp + +// The Range concept is derived from camp. This concept is satisfied by any +// type with a begin() and end() iterator. +template +concept Range = static_cast(type_traits::is_range>::value); + +// RandomAccessRange is also derived from camp, and is satisfied by any type +// with begin/end iterators and random access. +template +concept RandomAccessRange = Range && static_cast( + type_traits::is_random_access_range>::value); + +template +concept MultiPolicyConcept = static_cast( + RAJA::type_traits::is_multi_policy>::value); + +template +concept Integer = + static_cast(type_traits::is_integral>::value); + +template +concept ForallPolicy = RAJA::type_traits::is_policy_forall(); + +template +concept ForallParameterPack = + RAJA::expt::type_traits::is_ForallParamPack>::value; + +} // namespace RAJA + +#endif diff --git a/include/RAJA/pattern/forall.hpp b/include/RAJA/pattern/forall.hpp index 5c2fa9189c..68426cc936 100644 --- a/include/RAJA/pattern/forall.hpp +++ b/include/RAJA/pattern/forall.hpp @@ -63,14 +63,10 @@ #include "RAJA/internal/Iterators.hpp" #include "RAJA/policy/PolicyBase.hpp" -#include "RAJA/policy/MultiPolicy.hpp" -#include "RAJA/index/IndexSet.hpp" #include "RAJA/index/ListSegment.hpp" -#include "RAJA/index/RangeSegment.hpp" +#include "RAJA/pattern/forall-concepts.hpp" -#include "RAJA/util/concepts.hpp" -#include "RAJA/util/Span.hpp" #include "RAJA/util/types.hpp" #include "RAJA/policy/sequential/forall.hpp" @@ -87,12 +83,6 @@ namespace RAJA { -template -concept Range = static_cast(type_traits::is_range>::value); - -template -concept RandomAccessRange = Range && - static_cast(type_traits::is_random_access_range::value); // ////////////////////////////////////////////////////////////////////// // @@ -100,9 +90,6 @@ concept RandomAccessRange = Range && // ////////////////////////////////////////////////////////////////////// // -template -concept Integer = - static_cast(type_traits::is_integral>::value); namespace detail { @@ -135,10 +122,10 @@ struct icount_adapter struct CallForall { template + Resource Res, + ForallParameterPack ForallParams> RAJA_INLINE camp::resources::EventProxy operator()(T const&, ExecPol, Body, @@ -151,10 +138,10 @@ struct CallForallIcount constexpr CallForallIcount(int s); template + Resource Res, + ForallParameterPack ForallParams> RAJA_INLINE camp::resources::EventProxy operator()(T const&, ExecPol, Body, @@ -183,11 +170,11 @@ namespace wrap * ****************************************************************************** */ -template + ForallParameterPack ForallParams> requires(!IndexSetPolicy) RAJA_INLINE RAJA::resources::EventProxy forall(Res r, @@ -202,8 +189,8 @@ requires(!IndexSetPolicy) std::forward(loop_body), std::forward(f_params)); } -template RAJA_INLINE RAJA::resources::EventProxy forall(Res r, @@ -224,12 +211,12 @@ RAJA_INLINE RAJA::resources::EventProxy forall(Res r, * ****************************************************************************** */ -template + ForallParameterPack ForallParams> RAJA_INLINE resources::EventProxy forall_Icount(Res r, ExecutionPolicy&& p, Container&& c, @@ -258,12 +245,12 @@ RAJA_INLINE resources::EventProxy forall_Icount(Res r, * ****************************************************************************** */ -template + ForallParameterPack ForallParams> RAJA_INLINE resources::EventProxy forall_Icount( Res r, ExecPolicy, @@ -282,12 +269,12 @@ RAJA_INLINE resources::EventProxy forall_Icount( return RAJA::resources::EventProxy(r); } -template + ForallParameterPack ForallParams> RAJA_INLINE resources::EventProxy forall( Res r, ExecPolicy, @@ -326,8 +313,8 @@ inline namespace policy_by_value_interface * ****************************************************************************** */ -template RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, @@ -361,7 +348,7 @@ RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, return e; } -template::type> @@ -383,7 +370,7 @@ RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, ****************************************************************************** */ template RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, @@ -439,16 +426,13 @@ RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, ****************************************************************************** */ template::type> RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) { - static_assert(type_traits::is_random_access_range::value, - "Container does not model RandomAccessIterator"); - auto r = Res::get_default(); // plugins handled in multipolicy policy_invoker @@ -464,8 +448,8 @@ RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, * ****************************************************************************** */ -template forall_Icount(ExecutionPolicy&& p, return e; } -template) ****************************************************************************** */ -template @@ -571,7 +555,7 @@ requires(!IndexSetPolicy && return e; } -template::type> @@ -595,7 +579,7 @@ requires(!IndexSetPolicy && * * this reduces implementation overhead and perfectly forwards all arguments */ -template::type> RAJA_INLINE resources::EventProxy forall(Args&&... args) @@ -605,7 +589,7 @@ RAJA_INLINE resources::EventProxy forall(Args&&... args) std::forward(args)...); } -template +template RAJA_INLINE resources::EventProxy forall(Res r, Args&&... args) { return ::RAJA::policy_by_value_interface::forall(ExecutionPolicy(), r, @@ -618,7 +602,7 @@ RAJA_INLINE resources::EventProxy forall(Res r, Args&&... args) * * this reduces implementation overhead and perfectly forwards all arguments */ -template::type> RAJA_INLINE resources::EventProxy forall_Icount(Args&&... args) @@ -628,7 +612,7 @@ RAJA_INLINE resources::EventProxy forall_Icount(Args&&... args) ExecutionPolicy(), r, std::forward(args)...); } -template +template RAJA_INLINE resources::EventProxy forall_Icount(Res r, Args&&... args) { return ::RAJA::policy_by_value_interface::forall_Icount( @@ -639,10 +623,10 @@ namespace detail { template + Resource Res, + ForallParameterPack ForallParams> RAJA_INLINE camp::resources::EventProxy CallForall::operator()( T const& segment, ExecutionPolicy, @@ -659,10 +643,10 @@ RAJA_INLINE camp::resources::EventProxy CallForall::operator()( constexpr CallForallIcount::CallForallIcount(int s) : start(s) {} template + Resource Res, + ForallParameterPack ForallParams> RAJA_INLINE camp::resources::EventProxy CallForallIcount::operator()( T const& segment, ExecutionPolicy, diff --git a/include/RAJA/policy/MultiPolicy.hpp b/include/RAJA/policy/MultiPolicy.hpp index fd8995e32f..ec847b55d1 100644 --- a/include/RAJA/policy/MultiPolicy.hpp +++ b/include/RAJA/policy/MultiPolicy.hpp @@ -259,10 +259,6 @@ struct is_multi_policy {}; } // namespace type_traits -template -concept MultiPolicyConcept = - static_cast(RAJA::type_traits::is_multi_policy::value); - } // end namespace RAJA #endif