diff --git a/include/RAJA/pattern/forall-concepts.hpp b/include/RAJA/pattern/forall-concepts.hpp index ca8a392ffb..1042bd52c8 100644 --- a/include/RAJA/pattern/forall-concepts.hpp +++ b/include/RAJA/pattern/forall-concepts.hpp @@ -42,6 +42,71 @@ template concept ForallParameterPack = RAJA::expt::type_traits::is_ForallParamPack>::value; + + +// Concept for strongly typed index types. +template < typename T > +concept StrongIndexType = !std::integral && requires (T val) + { + { stripIndexType(val) } -> std::integral; + }; + +// Concept index types or strongly typed index types. +// TODO: improve the name +template < typename T > +concept IndexTypeConcept = std::integral || StrongIndexType; + +// Concept for types that may be callable. +// Use std::invokable when the full set of arguments is known. +template < typename B > +concept PotentialInvokable = + std::is_class_v> || + std::is_union_v> || + std::is_function_v> || + ( std::is_pointer_v> && + std::is_function_v>>> ); + +consteval bool testPotentialInvokable() noexcept +{ + using I = int; + using F = int(); + struct S{}; + union U{}; + using L = decltype([]{}); + static_assert(!PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(PotentialInvokable); + static_assert(!PotentialInvokable); + static_assert(!PotentialInvokable); + return true; +} +static_assert(testPotentialInvokable()); + +// Concept for forall param objects. +template < typename Arg > +concept ForallParam = std::is_base_of_v>; + +// Concept for forall arguments that may be forall param objects or callables. +template < typename Arg > +concept ForallParamsAndBody = ForallParam || PotentialInvokable; + } // namespace RAJA #endif diff --git a/include/RAJA/pattern/forall.hpp b/include/RAJA/pattern/forall.hpp index 68426cc936..6952cc6f40 100644 --- a/include/RAJA/pattern/forall.hpp +++ b/include/RAJA/pattern/forall.hpp @@ -94,16 +94,16 @@ namespace RAJA namespace detail { /// Adapter to replace specific implementations for the icount variants -template +template struct icount_adapter { using index_type = typename std::decay::type; typename std::decay::type body; - using container_type = typename std::decay::type; + using container_type = typename std::decay::type; typename container_type::iterator begin_it; Index_type icount; - icount_adapter(Range const& r, Body const& b, IndexT icount_) + icount_adapter(Container const& r, Body const& b, IndexT icount_) : body {b}, icount {icount_} { @@ -123,7 +123,7 @@ struct CallForall { template RAJA_INLINE camp::resources::EventProxy operator()(T const&, @@ -139,7 +139,7 @@ struct CallForallIcount template RAJA_INLINE camp::resources::EventProxy operator()(T const&, @@ -173,35 +173,35 @@ namespace wrap template requires(!IndexSetPolicy) RAJA_INLINE RAJA::resources::EventProxy forall(Res r, ExecutionPolicy&& p, Container&& c, - LoopBody&& loop_body, + Body&& loop_body, ForallParams&& f_params) { RAJA_FORCEINLINE_RECURSIVE return forall_impl( r, std::forward(p), std::forward(c), - std::forward(loop_body), std::forward(f_params)); + std::forward(loop_body), std::forward(f_params)); } template + PotentialInvokable Body> RAJA_INLINE RAJA::resources::EventProxy forall(Res r, ExecutionPolicy&& p, Container&& c, - LoopBody&& loop_body) + Body&& loop_body) { RAJA_FORCEINLINE_RECURSIVE return forall_impl( r, std::forward(p), std::forward(c), - std::forward(loop_body), expt::get_empty_forall_param_pack()); + std::forward(loop_body), expt::get_empty_forall_param_pack()); } /*! @@ -213,22 +213,22 @@ RAJA_INLINE RAJA::resources::EventProxy forall(Res r, */ template RAJA_INLINE resources::EventProxy forall_Icount(Res r, ExecutionPolicy&& p, Container&& c, IndexType&& icount, - LoopBody&& loop_body, + Body&& loop_body, ForallParams&& f_params) { using std::begin; using std::distance; using std::end; auto range = RangeSegment(0, distance(begin(c), end(c))); - detail::icount_adapter adapted(c, loop_body, + detail::icount_adapter adapted(c, loop_body, icount); using policy::sequential::forall_impl; RAJA_FORCEINLINE_RECURSIVE @@ -247,15 +247,15 @@ RAJA_INLINE resources::EventProxy forall_Icount(Res r, */ template RAJA_INLINE resources::EventProxy forall_Icount( Res r, ExecPolicy, const TypedIndexSet& iset, - LoopBody loop_body, + Body loop_body, ForallParams f_params) { // no need for icount variant here @@ -271,15 +271,15 @@ RAJA_INLINE resources::EventProxy forall_Icount( template RAJA_INLINE resources::EventProxy forall( Res r, ExecPolicy, const TypedIndexSet& iset, - LoopBody loop_body, + Body loop_body, ForallParams f_params) { auto segIterRes = @@ -316,7 +316,7 @@ inline namespace policy_by_value_interface template + ForallParamsAndBody... Params> RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, Res r, IdxSet&& c, @@ -349,17 +349,17 @@ RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, } template::type> + IndexSetType IdxSet, + PotentialInvokable Body, + Resource Res = typename resources::get_resource::type> RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, IdxSet&& c, - LoopBody&& loop_body) + Body&& loop_body) { auto r = Res::get_default(); return ::RAJA::policy_by_value_interface::forall_Icount( std::forward(p), r, std::forward(c), - std::forward(loop_body)); + std::forward(loop_body)); } /*! @@ -372,7 +372,7 @@ RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, template + ForallParamsAndBody... Params> RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, Res r, IdxSet&& c, @@ -405,17 +405,17 @@ RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, } template::type> + IndexSetType IdxSet, + PotentialInvokable Body, + Resource Res = typename resources::get_resource::type> RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, IdxSet&& c, - LoopBody&& loop_body) + Body&& loop_body) { auto r = Res::get_default(); return ::RAJA::policy_by_value_interface::forall( std::forward(p), r, std::forward(c), - std::forward(loop_body)); + std::forward(loop_body)); } /*! @@ -427,18 +427,18 @@ RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, */ template::type> + PotentialInvokable Body, + Resource Res = typename resources::get_resource::type> RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, Container&& c, - LoopBody&& loop_body) + Body&& loop_body) { auto r = Res::get_default(); // plugins handled in multipolicy policy_invoker return forall_impl(r, std::forward(p), std::forward(c), - std::forward(loop_body)); + std::forward(loop_body)); } /*! @@ -451,9 +451,9 @@ RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, template + IndexTypeConcept IndexType, + ForallParamsAndBody FirstParam, + ForallParamsAndBody... Params> RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, Res r, Container&& c, @@ -491,20 +491,20 @@ RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, template::type> + IndexTypeConcept IndexType, + PotentialInvokable Body, + Resource Res = typename resources::get_resource::type> requires(!IndexSetPolicy) RAJA_INLINE resources::EventProxy forall_Icount(ExecutionPolicy&& p, Container&& c, IndexType icount, - LoopBody&& loop_body) + Body&& loop_body) { auto r = Res::get_default(); return ::RAJA::policy_by_value_interface::forall_Icount( std::forward(p), r, std::forward(c), icount, - std::forward(loop_body)); + std::forward(loop_body)); } /*! @@ -518,7 +518,7 @@ requires(!IndexSetPolicy) template + ForallParamsAndBody... Params> requires(!IndexSetPolicy && !MultiPolicyConcept) @@ -557,19 +557,19 @@ requires(!IndexSetPolicy && template::type> + PotentialInvokable Body, + Resource Res = typename resources::get_resource::type> requires(!IndexSetPolicy && !MultiPolicyConcept) RAJA_INLINE resources::EventProxy forall(ExecutionPolicy&& p, Container&& c, - LoopBody&& loop_body) + Body&& loop_body) { auto r = Res::get_default(); return ::RAJA::policy_by_value_interface::forall( std::forward(p), r, std::forward(c), - std::forward(loop_body)); + std::forward(loop_body)); } } // namespace policy_by_value_interface @@ -580,8 +580,8 @@ requires(!IndexSetPolicy && * this reduces implementation overhead and perfectly forwards all arguments */ template::type> + NonResource... Args, + Resource Res = typename resources::get_resource::type> RAJA_INLINE resources::EventProxy forall(Args&&... args) { Res r = Res::get_default(); @@ -589,7 +589,9 @@ 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, @@ -603,8 +605,8 @@ RAJA_INLINE resources::EventProxy forall(Res r, Args&&... args) * this reduces implementation overhead and perfectly forwards all arguments */ template::type> + NonResource... Args, + Resource Res = typename resources::get_resource::type> RAJA_INLINE resources::EventProxy forall_Icount(Args&&... args) { Res r = Res::get_default(); @@ -612,7 +614,9 @@ 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( @@ -624,13 +628,13 @@ namespace detail template RAJA_INLINE camp::resources::EventProxy CallForall::operator()( T const& segment, ExecutionPolicy, - LoopBody body, + Body body, Res r, ForallParams f_params) const { @@ -644,13 +648,13 @@ constexpr CallForallIcount::CallForallIcount(int s) : start(s) {} template RAJA_INLINE camp::resources::EventProxy CallForallIcount::operator()( T const& segment, ExecutionPolicy, - LoopBody body, + Body body, Res r, ForallParams f_params) const { diff --git a/include/RAJA/util/resource.hpp b/include/RAJA/util/resource.hpp index 51fd1bf19d..23b1333f6a 100644 --- a/include/RAJA/util/resource.hpp +++ b/include/RAJA/util/resource.hpp @@ -250,6 +250,9 @@ struct is_resource : std::true_type template concept Resource = type_traits::is_resource::value; +template +concept NonResource = !Resource; + } // end namespace RAJA #endif // RAJA_resources_HPP#