IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
ParallelDispatch.h
Go to the documentation of this file.
1//
2// Parallel dispatch
3// Utility functions relating to parallel dispatch in IPPL
4//
5
6#ifndef IPPL_PARALLEL_DISPATCH_H
7#define IPPL_PARALLEL_DISPATCH_H
8
9#include <Kokkos_Core.hpp>
10
11#include <tuple>
12
13#include "Types/Vector.h"
14
16
17namespace ippl {
23 template <unsigned Dim, class... PolicyArgs>
24 struct RangePolicy {
25 // The range policy type
26 using policy_type = Kokkos::MDRangePolicy<PolicyArgs..., Kokkos::Rank<Dim>>;
27 // The index type used by the range policy
28 using index_type = typename policy_type::array_index_type;
29 // A vector type containing the index type
31 };
32
36 template <class... PolicyArgs>
37 struct RangePolicy<1, PolicyArgs...> {
38 using policy_type = Kokkos::RangePolicy<PolicyArgs...>;
39 using index_type = typename policy_type::index_type;
41 };
42
54 template <class... PolicyArgs, typename View>
55 typename RangePolicy<View::rank, typename View::execution_space, PolicyArgs...>::policy_type
56 getRangePolicy(const View& view, int shift = 0) {
57 constexpr unsigned Dim = View::rank;
58 using exec_space = typename View::execution_space;
59 using policy_type = typename RangePolicy<Dim, exec_space, PolicyArgs...>::policy_type;
60 if constexpr (Dim == 1) {
61 return policy_type(shift, view.size() - shift);
62 } else {
63 using index_type = typename RangePolicy<Dim, exec_space, PolicyArgs...>::index_type;
64 Kokkos::Array<index_type, Dim> begin, end;
65 for (unsigned int d = 0; d < Dim; d++) {
66 begin[d] = shift;
67 end[d] = view.extent(d) - shift;
68 }
69 return policy_type(begin, end);
70 }
71 // Silences incorrect nvcc warning: missing return statement at end of non-void function
72 throw IpplException("detail::getRangePolicy", "Unreachable state");
73 }
74
87 template <size_t Dim, class... PolicyArgs>
88 typename RangePolicy<Dim, PolicyArgs...>::policy_type createRangePolicy(
89 const Kokkos::Array<typename RangePolicy<Dim, PolicyArgs...>::index_type, Dim>& begin,
90 const Kokkos::Array<typename RangePolicy<Dim, PolicyArgs...>::index_type, Dim>& end) {
91 using policy_type = typename RangePolicy<Dim, PolicyArgs...>::policy_type;
92 if constexpr (Dim == 1) {
93 return policy_type(begin[0], end[0]);
94 } else {
95 return policy_type(begin, end);
96 }
97 // Silences incorrect nvcc warning: missing return statement at end of non-void function
98 throw IpplException("detail::createRangePolicy", "Unreachable state");
99 }
100
101 namespace detail {
108 template <unsigned Dim, typename T = size_t>
109 struct Coords {
110 // https://stackoverflow.com/a/53398815/2773311
111 // https://en.cppreference.com/w/cpp/utility/declval
112 using type =
113 decltype(std::tuple_cat(std::declval<typename Coords<1, T>::type>(),
114 std::declval<typename Coords<Dim - 1, T>::type>()));
115 };
116
117 template <typename T>
118 struct Coords<1, T> {
119 using type = std::tuple<T>;
120 };
121
127
128 template <e_functor_type, typename, typename, typename, typename...>
130
140 template <typename Functor, typename Policy, typename... T, typename... Acc>
141 struct FunctorWrapper<REDUCE, Functor, Policy, std::tuple<T...>, Acc...> {
142 Functor f;
143
151 KOKKOS_INLINE_FUNCTION void operator()(T... x, Acc&... res) const {
152 using index_type = typename Policy::index_type;
153 typename Policy::index_array_type args = {static_cast<index_type>(x)...};
154 f(args, res...);
155 }
156 };
157
158 template <typename Functor, typename Policy, typename... T>
159 struct FunctorWrapper<FOR, Functor, Policy, std::tuple<T...>> {
160 Functor f;
161
162 KOKKOS_INLINE_FUNCTION void operator()(T... x) const {
163 using index_type = typename Policy::index_type;
164 typename Policy::index_array_type args = {static_cast<index_type>(x)...};
165 f(args);
166 }
167 };
168
169 // Extracts the rank of a Kokkos range policy
170 template <typename>
172
173 template <typename... T>
175 static constexpr int rank = 1;
176 };
177 template <typename... T>
178 struct ExtractRank<Kokkos::MDRangePolicy<T...>> {
179 static constexpr int rank = Kokkos::MDRangePolicy<T...>::rank;
180 };
181 template <typename T>
182 concept HasMemberValueType = requires() {
183 { typename T::value_type() };
184 };
185 template <typename T>
187 using type = T;
188 };
189 template <HasMemberValueType T>
191 using type = typename T::value_type;
192 };
193
202 template <e_functor_type Type, typename Policy, typename... Acc, typename Functor>
203 auto functorize(const Functor& f) {
204 constexpr unsigned Dim = ExtractRank<Policy>::rank;
206 using index_type = typename PolicyProperties::index_type;
207 return FunctorWrapper<Type, Functor, PolicyProperties,
208 typename Coords<Dim, index_type>::type, Acc...>{f};
209 }
210 } // namespace detail
211
212 // Wrappers for Kokkos' parallel dispatch functions that use
213 // the IPPL functor wrapper
214 template <class ExecPolicy, class FunctorType>
215 void parallel_for(const std::string& name, const ExecPolicy& policy,
216 const FunctorType& functor) {
217 Kokkos::parallel_for(name, policy, detail::functorize<detail::FOR, ExecPolicy>(functor));
218 }
219
220 template <class ExecPolicy, class FunctorType, class... ReducerArgument>
221 void parallel_reduce(const std::string& name, const ExecPolicy& policy,
222 const FunctorType& functor, ReducerArgument&&... reducer) {
223 Kokkos::parallel_reduce(
224 name, policy,
227 functor),
228 std::forward<ReducerArgument>(reducer)...);
229 }
230} // namespace ippl
231
232#endif
constexpr unsigned Dim
STL namespace.
Definition Archive.h:20
RangePolicy< Dim, PolicyArgs... >::policy_type createRangePolicy(const Kokkos::Array< typename RangePolicy< Dim, PolicyArgs... >::index_type, Dim > &begin, const Kokkos::Array< typename RangePolicy< Dim, PolicyArgs... >::index_type, Dim > &end)
RangePolicy< View::rank, typenameView::execution_space, PolicyArgs... >::policy_type getRangePolicy(const View &view, int shift=0)
void parallel_for(const std::string &name, const ExecPolicy &policy, const FunctorType &functor)
void parallel_reduce(const std::string &name, const ExecPolicy &policy, const FunctorType &functor, ReducerArgument &&... reducer)
auto functorize(const Functor &f)
::ippl::Vector< index_type, Dim > index_array_type
Kokkos::MDRangePolicy< PolicyArgs..., Kokkos::Rank< Dim > > policy_type
typename policy_type::array_index_type index_type
::ippl::Vector< index_type, 1 > index_array_type
typename policy_type::index_type index_type
Kokkos::RangePolicy< PolicyArgs... > policy_type
decltype(std::tuple_cat(std::declval< typename Coords< 1, T >::type >(), std::declval< typename Coords< Dim - 1, T >::type >())) type