272 const ParticleContainer& pc, locate_type& ranks, bool_type& invalid,
273 locate_type& nSends_dview, locate_type& sends_dview)
const {
274 auto positions = pc.R.getView();
277 using policy_type = Kokkos::RangePolicy<position_execution_space>;
278 using mdrange_type = Kokkos::MDRangePolicy<Kokkos::Rank<2>, position_execution_space>;
280 size_type myRank = Comm->rank();
282 const auto is = std::make_index_sequence<Dim>{};
287 locate_type outsideIds(
"Particles outside of neighborhood", size_type(pc.getLocalNum()));
290 size_type outsideCount = 0;
292 size_type invalidCount = 0;
295 const size_type neighborSize = getNeighborSize(neighbors);
298 locate_type neighbors_view(
"Nearest neighbors IDs", neighborSize);
308 auto neighbors_mirror =
309 Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), neighbors_view);
313 for (
const auto& componentNeighbors : neighbors) {
314 for (
size_t j = 0; j < componentNeighbors.size(); ++j) {
315 neighbors_mirror(k) = componentNeighbors[j];
321 Kokkos::deep_copy(neighbors_view, neighbors_mirror);
329 static IpplTimings::TimerRef neighborSearch = IpplTimings::getTimer(
"neighborSearch");
330 IpplTimings::startTimer(neighborSearch);
332 Kokkos::parallel_scan(
333 "ParticleSpatialLayout::locateParticles()",
334 policy_type(0, ranks.extent(0)),
335 KOKKOS_LAMBDA(
const size_type i,
increment_type& val,
const bool final) {
343 bool inNeighbor =
false;
347 inCurr = positionInRegion(is, positions(i), Regions(myRank));
349 ranks(i) = inCurr * myRank;
350 invalid(i) = !inCurr;
351 found = inCurr || found;
354 for (
size_t j = 0; j < neighbors_view.extent(0); ++j) {
355 size_type rank = neighbors_view(j);
357 inNeighbor = positionInRegion(is, positions(i), Regions(rank));
359 ranks(i) = !(inNeighbor)*ranks(i) + inNeighbor * rank;
360 found = inNeighbor || found;
367 if (
final && !found) {
368 outsideIds(val.count[1]) = i;
371 increment[0] = invalid(i);
372 increment[1] = !found;
379 invalidCount = red_val.count[0];
380 outsideCount = red_val.count[1];
382 IpplTimings::stopTimer(neighborSearch);
385 static IpplTimings::TimerRef nonNeighboringParticles =
386 IpplTimings::getTimer(
"nonNeighboringParticles");
387 IpplTimings::startTimer(nonNeighboringParticles);
388 if (outsideCount > 0) {
389 Kokkos::parallel_for(
390 "ParticleSpatialLayout::leftParticles()",
391 mdrange_type({0, 0}, {outsideCount, Regions.extent(0)}),
392 KOKKOS_LAMBDA(
const size_t i,
const size_type j) {
394 size_type pId = outsideIds(i);
397 bool inRegion = positionInRegion(is, positions(pId), Regions(j));
404 IpplTimings::stopTimer(nonNeighboringParticles);
406 Kokkos::parallel_for(
407 "Calculate nSends", policy_type(0, ranks.extent(0)),
408 KOKKOS_LAMBDA(
const size_t i) {
409 size_type rank = ranks(i);
410 Kokkos::atomic_fetch_add(&nSends_dview(rank), 1);
414 Kokkos::View<size_type, position_memory_space> rankSends(
415 "Number of Ranks we need to send to");
417 Kokkos::parallel_for(
418 "Calculate sends", policy_type(0, nSends_dview.extent(0)),
419 KOKKOS_LAMBDA(
const size_t rank) {
420 if (nSends_dview(rank) != 0) {
421 size_type index = Kokkos::atomic_fetch_add(&rankSends(), 1);
422 sends_dview(index) = rank;
426 Kokkos::deep_copy(temp, rankSends);
428 return {invalidCount, temp};