diff --git a/include/RAJA/index/IndexSet.hpp b/include/RAJA/index/IndexSet.hpp index 42bcd358c4..ae090412f0 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" @@ -802,6 +799,15 @@ struct is_indexset_policy {}; } // namespace type_traits +template +concept IndexSetType = + static_cast(RAJA::type_traits::is_index_set::value); + + +template +concept IndexSetPolicy = + static_cast(type_traits::is_indexset_policy::value); + } // namespace RAJA #endif // closing endif for header file include guard diff --git a/include/RAJA/index/RangeSegment.hpp b/include/RAJA/index/RangeSegment.hpp index 2ed81d005f..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/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 507afc4da4..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" @@ -126,10 +122,10 @@ struct icount_adapter struct CallForall { template + Resource Res, + ForallParameterPack ForallParams> RAJA_INLINE camp::resources::EventProxy operator()(T const&, ExecPol, Body, @@ -142,10 +138,10 @@ struct CallForallIcount constexpr CallForallIcount(int s); template + Resource Res, + ForallParameterPack ForallParams> RAJA_INLINE camp::resources::EventProxy operator()(T const&, ExecPol, Body, @@ -174,20 +170,18 @@ namespace wrap * ****************************************************************************** */ -template -RAJA_INLINE concepts::enable_if_t< - RAJA::resources::EventProxy, - concepts::negate>, - type_traits::is_range> -forall(Res r, - ExecutionPolicy&& p, - Container&& c, - LoopBody&& loop_body, - ForallParams&& f_params) + ForallParameterPack ForallParams> + +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( @@ -195,15 +189,14 @@ forall(Res r, std::forward(loop_body), std::forward(f_params)); } -template -RAJA_INLINE concepts::enable_if_t< - RAJA::resources::EventProxy, - concepts::negate>, - type_traits::is_range> -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( @@ -218,12 +211,12 @@ forall(Res r, ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) * ****************************************************************************** */ -template + ForallParameterPack ForallParams> RAJA_INLINE resources::EventProxy forall_Icount(Res r, ExecutionPolicy&& p, Container&& c, @@ -252,12 +245,12 @@ RAJA_INLINE resources::EventProxy forall_Icount(Res r, * ****************************************************************************** */ -template + ForallParameterPack ForallParams> RAJA_INLINE resources::EventProxy forall_Icount( Res r, ExecPolicy, @@ -276,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, @@ -320,18 +313,15 @@ 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)...); @@ -358,7 +348,7 @@ RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, return e; } -template::type> @@ -379,19 +369,15 @@ RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, * ****************************************************************************** */ -template -RAJA_INLINE concepts::enable_if_t< - resources::EventProxy, - type_traits::is_indexset_policy> -forall(ExecutionPolicy&& p, Res r, IdxSet&& c, Params&&... params) +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,14 +404,13 @@ 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> -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( @@ -440,18 +425,14 @@ 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> -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"); - auto r = Res::get_default(); // plugins handled in multipolicy policy_invoker @@ -467,24 +448,19 @@ forall(ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) * ****************************************************************************** */ -template -RAJA_INLINE concepts::enable_if_t, - type_traits::is_range, - type_traits::is_integral> -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"); +RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, + Res r, + Container&& c, + IndexType icount, + FirstParam&& first, + Params&&... params) +{ auto f_params = expt::make_forall_param_pack(std::forward(first), std::forward(params)...); @@ -513,20 +489,17 @@ forall_Icount(ExecutionPolicy&& p, return e; } -template::type> -RAJA_INLINE concepts::enable_if_t< - resources::EventProxy, - type_traits::is_range, - concepts::negate>, - type_traits::is_integral> -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( @@ -542,19 +515,18 @@ forall_Icount(ExecutionPolicy&& p, ****************************************************************************** */ -template -RAJA_INLINE concepts::enable_if_t< - resources::EventProxy, - concepts::negate>, - concepts::negate>, - type_traits::is_range> -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) { - 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,16 +555,16 @@ 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> -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( @@ -607,7 +579,7 @@ forall(ExecutionPolicy&& p, Container&& c, LoopBody&& loop_body) * * this reduces implementation overhead and perfectly forwards all arguments */ -template::type> RAJA_INLINE resources::EventProxy forall(Args&&... args) @@ -617,10 +589,8 @@ RAJA_INLINE resources::EventProxy forall(Args&&... args) std::forward(args)...); } -template -RAJA_INLINE concepts::enable_if_t, - type_traits::is_resource> -forall(Res r, Args&&... args) +template +RAJA_INLINE resources::EventProxy forall(Res r, Args&&... args) { return ::RAJA::policy_by_value_interface::forall(ExecutionPolicy(), r, std::forward(args)...); @@ -632,7 +602,7 @@ forall(Res r, Args&&... args) * * this reduces implementation overhead and perfectly forwards all arguments */ -template::type> RAJA_INLINE resources::EventProxy forall_Icount(Args&&... args) @@ -642,10 +612,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> -forall_Icount(Res r, Args&&... args) +template +RAJA_INLINE resources::EventProxy forall_Icount(Res r, Args&&... args) { return ::RAJA::policy_by_value_interface::forall_Icount( ExecutionPolicy(), r, std::forward(args)...); @@ -655,10 +623,10 @@ namespace detail { template + Resource Res, + ForallParameterPack ForallParams> RAJA_INLINE camp::resources::EventProxy CallForall::operator()( T const& segment, ExecutionPolicy, @@ -675,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/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#