5 template <
class Field,
class Tp>
8 bf_m.initialize(mesh, fl);
12 template <
class Field,
class Tp>
13 template <
typename Attrib>
29 if (!isFirstRepartition) {
39 int nprocs = comm.
size();
42 std::vector<NDIndex<Dim>> domains = {fl.
getDomain()};
43 std::vector<int> procs = {nprocs};
46 std::vector<Tf> reduced, reducedRank;
50 int maxprocs = nprocs;
53 while (maxprocs > 1) {
61 reduced.resize(domains[it][cutAxis].length());
62 reducedRank.resize(domains[it][cutAxis].length());
64 std::fill(reducedRank.begin(), reducedRank.end(), 0.0);
65 std::fill(reduced.begin(), reduced.end(), 0.0);
73 comm.allreduce(reducedRank.data(), reduced.data(), reducedRank.size(), std::plus<Tf>());
85 cutDomain(domains, procs, it, cutAxis, median);
89 for (
unsigned int i = 0; i < procs.size(); i++) {
90 if (procs[i] > maxprocs) {
106 for (
const auto& domain : domains) {
107 for (
const auto& axis : domain) {
108 if (axis.length() == 1) {
118 bf_m.updateLayout(fl);
124 template <
class Field,
class Tp>
127 return std::distance(dom.
begin(), std::max_element(dom.
begin(), dom.
end(),
129 return a.length() < b.length();
133 template <
class Field,
class Tp>
135 std::vector<Tf>& rankWeights,
unsigned int cutAxis,
NDIndex<Dim>& dom) {
138 if (lDom[cutAxis].
first() > dom[cutAxis].last()
139 || lDom[cutAxis].last() < dom[cutAxis].
first()) {
144 int nghost =
bf_m.getNghost();
145 const auto data =
bf_m.getView();
149 std::max(lDom[cutAxis].
first(), dom[cutAxis].
first()) - lDom[cutAxis].
first() + nghost;
151 std::min(lDom[cutAxis].last(), dom[cutAxis].last()) - lDom[cutAxis].
first() + nghost;
154 unsigned int arrayStart = 0;
155 if (dom[cutAxis].
first() < lDom[cutAxis].
first()) {
156 arrayStart = lDom[cutAxis].
first() - dom[cutAxis].
first();
162 Kokkos::Array<index_type, Dim> begin, end;
163 for (
unsigned d = 0; d <
Dim; d++) {
168 int inf = std::max(lDom[d].
first(), dom[d].
first()) - lDom[d].
first() + nghost;
169 int sup = std::min(lDom[d].last(), dom[d].last()) - lDom[d].
first() + nghost;
181 for (
int i = cutAxisFirst; i <= cutAxisLast; i++) {
183 end[cutAxis] = i + 1;
191 KOKKOS_LAMBDA(
const index_array_type& args,
Tf& weight) {
192 weight +=
apply(data, args);
194 Kokkos::Sum<Tf>(tempRes));
198 rankWeights[arrayStart++] = tempRes;
202 template <
class Field,
class Tp>
209 Tf tot = std::accumulate(w.begin(), w.end(),
Tf(0));
215 for (
unsigned int i = 0; i < w.size() - 1; i++) {
222 Tf previous = curr - w[i];
224 if ((curr + previous) <= tot
226 if (i == w.size() - 2) {
232 return (i > 1) ? (i - 1) : 1;
240 template <
class Field,
class Tp>
242 std::vector<int>& procs,
int it,
243 int cutAxis,
int median) {
246 domains[it].
split(leftDom, rightDom, cutAxis, median + domains[it][cutAxis].
first());
247 domains[it] = leftDom;
248 domains.insert(domains.begin() + it + 1, rightDom);
251 int temp = procs[it];
252 procs[it] = procs[it] / 2;
253 procs.insert(procs.begin() + it + 1, temp - procs[it]);
256 template <
class Field,
class Tp>
257 template <
typename Attrib>
259 using vector_type =
typename mesh_type::vector_type;
261 Kokkos::SpaceAccessibility<
typename Attrib::memory_space,
263 "Particle attribute memory space must be accessible from ORB field memory space");
268 auto view =
bf_m.getView();
272 const int nghost =
bf_m.getNghost();
279 using policy_type = Kokkos::RangePolicy<size_t, typename Field::execution_space>;
281 Kokkos::parallel_for(
282 "ParticleAttrib::scatterR", policy_type(0, r.getParticleCount()),
283 KOKKOS_LAMBDA(
const size_t idx) {
293 scatterToField(std::make_index_sequence<1 <<
Dim>{}, view, wlo, whi, args);
296 bf_m.accumulateHalo();
constexpr KOKKOS_INLINE_FUNCTION auto first()
KOKKOS_INLINE_FUNCTION constexpr decltype(auto) apply(const View &view, const Coords &coords)
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)
void parallel_reduce(const std::string &name, const ExecPolicy &policy, const FunctorType &functor, ReducerArgument &&... reducer)
int size() const noexcept
void cutDomain(std::vector< NDIndex< Dim > > &domains, std::vector< int > &procs, int it, int cutAxis, int median)
void scatterR(const Attrib &r)
int findMedian(std::vector< Tf > &w)
void initialize(FieldLayout< Dim > &fl, mesh_type &mesh, const Field &rho)
void perpendicularReduction(std::vector< Tf > &rankWeights, unsigned int cutAxis, NDIndex< Dim > &dom)
bool binaryRepartition(const Attrib &R, FieldLayout< Dim > &fl, const bool &isFirstRepartition)
int findCutAxis(NDIndex< Dim > &dom)
typename Field::value_type Tf
typename Field::Mesh_t mesh_type
static constexpr unsigned Dim
view_type::memory_space memory_space
view_type::execution_space execution_space
const NDIndex< Dim > & getDomain() const
const NDIndex_t & getLocalNDIndex() const
void updateLayout(const std::vector< NDIndex_t > &domains)
KOKKOS_INLINE_FUNCTION constexpr iterator begin()
KOKKOS_INLINE_FUNCTION Vector< int, Dim > first() const
KOKKOS_INLINE_FUNCTION bool split(NDIndex< Dim > &l, NDIndex< Dim > &r, unsigned d, int i) const
KOKKOS_INLINE_FUNCTION constexpr iterator end()
KOKKOS_INLINE_FUNCTION vector_type getOrigin() const
virtual KOKKOS_INLINE_FUNCTION const vector_type & getMeshSpacing() const =0
Timing::TimerRef TimerRef
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)
::ippl::Vector< index_type, Dim > index_array_type
typename policy_type::array_index_type index_type