parallel_reduce¶
Header File: <Kokkos_Core.hpp>
Usage¶
Kokkos::parallel_reduce(name, policy, functor, reducer...);
Kokkos::parallel_reduce(name, policy, functor, result...);
Kokkos::parallel_reduce(name, policy, functor);
Kokkos::parallel_reduce(policy, functor, reducer...);
Kokkos::parallel_reduce(policy, functor, result...);
Kokkos::parallel_reduce(policy, functor);
Dispatches parallel work defined by functor according to the ExecutionPolicy and performs a reduction of the contributions provided by workers as defined by the execution policy. The optional label name is used by profiling and debugging tools. The reduction type is either a sum, is defined by the reducer or is deduced from an optional join operator on the functor. The reduction result is stored in result, or through the reducer handle. It is also provided to the functor.final() function if such a function exists. Multiple reducers can be used in a single parallel_reduce and thus, it is possible to compute the min and the max values in a single parallel_reduce.
Interface¶
template <class ExecPolicy, class FunctorType>
Kokkos::parallel_reduce(const std::string& name,
const ExecPolicy& policy,
const FunctorType& functor);
template <class ExecPolicy, class FunctorType>
Kokkos::parallel_reduce(const ExecPolicy& policy,
const FunctorType& functor);
template <class ExecPolicy, class FunctorType, class... ReducerArgument>
Kokkos::parallel_reduce(const std::string& name,
const ExecPolicy& policy,
const FunctorType& functor,
const ReducerArgument&... reducer);
template <class ExecPolicy, class FunctorType, class... ReducerArgument>
Kokkos::parallel_reduce(const ExecPolicy& policy,
const FunctorType& functor,
const ReducerArgument&... reducer);
template <class ExecPolicy, class FunctorType, class... ReducerArgumentNonConst>
Kokkos::parallel_reduce(const std::string& name,
const ExecPolicy& policy,
const FunctorType& functor,
ReducerArgumentNonConst&... reducer);
template <class ExecPolicy, class FunctorType, class... ReducerArgumentNonConst>
Kokkos::parallel_reduce(const ExecPolicy& policy,
const FunctorType& functor,
ReducerArgumentNonConst&... reducer);
Parameters:¶
name: A user provided string which is used in profiling and debugging tools via the Kokkos Profiling Hooks.ExecPolicy: An ExecutionPolicy which defines iteration space and other execution properties. Valid policies are:
IntegerType: defines a 1D iteration range, starting from 0 and going to a count.RangePolicy: defines a 1D iteration range.
MDRangePolicy: defines a multi-dimensional iteration space.
TeamPolicy: defines a 1D iteration range, each of which is assigned to a thread team.
TeamVectorRange: defines a 1D iteration range to be executed by a thread-team. Only valid inside a parallel region executed through a
TeamPolicyor aTaskTeam.TeamVectorMDRange: defines a multi-dimensional iteration space to be executed by a thread-team. Only valid inside a parallel region executed through a
TeamPolicyor aTaskTeam.TeamThreadRange: defines a 1D iteration range to be executed by a thread-team. Only valid inside a parallel region executed through a
TeamPolicyor aTaskTeam.TeamThreadMDRange: defines a multi-dimensional iteration space to be executed by a thread-team. Only valid inside a parallel region executed through a
TeamPolicyor aTaskTeam.ThreadVectorRange: defines a 1D iteration range to be executed through vector parallelization dividing the threads within a team. Only valid inside a parallel region executed through a
TeamPolicyor aTaskTeam.ThreadVectorMDRange: defines a multi-dimensional iteration space to be executed through vector parallelization dividing the threads within a team. Only valid inside a parallel region executed through a
TeamPolicyor aTaskTeam.
FunctorType: A valid functor with (at minimum) an
operator()with a matching signature for theExecPolicycombined with the reduced type.ReducerArgument: Either a class fulfilling the “Reducer” concept or a
Kokkos::View.ReducerArgumentNonConst: A scalar type or an array type; see below for functor requirements.
Requirements:¶
If
ExecPolicyis notMDRangePolicy, thefunctorhas a member function of the formoperator() (const HandleType& handle, ReducerValueType& value) constoroperator() (const WorkTag, const HandleType& handle, ReducerValueType& value) const.If
ExecPolicy::work_tagisvoidor ifExecPolicyis anIntegerType, the overload without aWorkTagargument is used.HandleTypeis anIntegerTypeifExecPolicyis anIntegerTypeelse it isExecPolicy::member_type.
If
ExecPolicyisMDRangePolicythefunctorhas a member function of the formoperator() (const IntegerType& i0, ... , const IntegerType& iN, ReducerValueType& value) constoroperator() (const WorkTag, const IntegerType& i0, ... , const IntegerType& iN, ReducerValueType& value) const.If
ExecPolicy::work_tagisvoid, the overload without aWorkTagargument is used.Nmust matchExecPolicy::rank.
If the
functoris a lambda,ReducerArgumentmust satisfy theReducerconcept orReducerArgumentNonConstmust be a POD type withoperator +=andoperator =or aKokkos::View. In the latter case, a sum reduction is applied where the identity is assumed to be given by the default constructor of the value type (and not byreduction_identity`). If provided, theinit/join/finalmember functions must not take aWorkTagargument even for tagged reductions.If
ExecPolicyisTeamThreadRangea “reducing”functoris not allowed and theReducerArgumentmust satisfy theReducerconcept orReducerArgumentNonConstmust be a POD type withoperator +=andoperator =or aKokkos::View. In the latter case, a sum reduction is applied where the identity is assumed to be given by the default constructor of the value type (and not byreduction_identity`).If
ExecPolictyisTeamVectorMDRange,TeamThreadMDRange, orThreadVectorMDRange, only aReducerArgumentNonConstis allowed, and it must be a POD type withoperator +=andoperator =.The reduction argument type
ReducerValueTypeof thefunctoroperator must be compatible with theReducerArgument(orReducerArgumentNonConst) and must match the arguments of theinit,joinandfinalfunctions of the functor if those exist and no reducer is specified (ReducerArgumentdoesn’t satisfy theReducerconcept but is a scalar, array orKokkos::View). In case of tagged reductions, i.e., when specifying a tag in the policy, the functor’s potentialinit/join/finalmember functions must also be tagged.If
ReducerArgument(orReducerArgumentNonConst)is a scalar type then
ReducerValueTypemust be of the same type.is a
Kokkos::ViewthenReducerArgument::rankmust be 0 andReducerArgument::non_const_value_typemust matchReducerValueType.satisfies the
Reducerconcept thenReducerArgument::value_typemust matchReducerValueType.is an array
ReducerValueType must match the array signature.
the functor must define FunctorType::value_type the same as ReducerValueType.
the functor must declare a public member variable
int value_countwhich is the length of the array.the functor must implement the function
void init( ReducerValueType dst[] ) const.the functor must implement the function
void join( ReducerValueType dst[], ReducerValueType src[] ) const.If the functor implements the
finalfunction, the argument must also match those of init and join.
Semantics¶
For every element of the iteration space defined in
policythe functors call operator is invoked exactly once, except forTeamPolicyandTeamThreadRangewhere the call operator is invoked by each vector lane of the team and thread respectively.Neither concurrency nor order of execution are guaranteed.
The call is potentially asynchronous if the
ReducerArgumentis not a scalar type.The
ReducerArgumentcontent will be overwritten, i.e. the value does not need to be initialized to the reduction-neutral element.The input value to the operator may contain a partial reduction result, Kokkos may only combine the thread local contributions in the end. The operator must modify the input reduction value according to the requested reduction type.
Examples¶
Further examples are provided in the Custom Reductions and ExecutionPolicy documentation.
#include <Kokkos_Core.hpp>
#include <cstdio>
int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
int N = atoi(argv[1]);
double result;
Kokkos::parallel_reduce("Loop1", N, KOKKOS_LAMBDA (const int& i, double& lsum) {
lsum += 1.0*i;
}, result);
printf("Result: %i %lf\n", N, result);
Kokkos::finalize();
}
#include <Kokkos_Core.hpp>
#include <cstdio>
int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
int N = atoi(argv[1]);
double sum, min;
Kokkos::parallel_reduce("Loop1", N, KOKKOS_LAMBDA (const int& i, double& lsum, double& lmin) {
lsum += 1.0*i;
lmin = lmin < 1.0*i ? lmin : 1.0*i;
}, sum, Kokkos::Min<double>(min));
printf("Result: %i %lf %lf\n", N, sum, min);
Kokkos::finalize();
}
#include <Kokkos_Core.hpp>
#include <cstdio>
struct TagMax {};
struct TagMin {};
struct Foo {
KOKKOS_INLINE_FUNCTION
void operator() (const TagMax, const Kokkos::TeamPolicy<>::member_type& team, double& lmax) const {
if (team.league_rank() % 17 + team.team_rank() % 13 > lmax)
lmax = team.league_rank() % 17 + team.team_rank() % 13;
}
KOKKOS_INLINE_FUNCTION
void operator() (const TagMin, const Kokkos::TeamPolicy<>::member_type& team, double& lmin) const {
if (team.league_rank() % 17 + team.team_rank() % 13 < lmin)
lmin = team.league_rank() % 17 + team.team_rank() % 13;
}
};
int main(int argc, char* argv[]) {
Kokkos::initialize(argc, argv);
int N = atoi(argv[1]);
Foo foo;
double max, min;
Kokkos::parallel_reduce(Kokkos::TeamPolicy<TagMax>(N,Kokkos::AUTO), foo, Kokkos::Max<double>(max));
Kokkos::parallel_reduce("Loop2", Kokkos::TeamPolicy<TagMin>(N,Kokkos::AUTO), foo, Kokkos::Min<double>(min));
Kokkos::fence();
printf("Result: %lf %lf\n", min, max);
Kokkos::finalize();
}