42 KOKKOS_FUNCTION
void init() {
48 count[0] += values[0];
49 count[1] += values[1];
60 template <
typename T,
unsigned Dim,
class Mesh,
typename... Properties>
68 window_m.create(*Comm, nRecvs_m.begin(), nRecvs_m.end());
72 template <
typename T,
unsigned Dim,
class Mesh,
typename... Properties>
79 template <
typename T,
unsigned Dim,
class Mesh,
typename... Properties>
80 template <
class ParticleContainer>
93 int nRanks =
Comm->size();
116 locate_type particleRanks(
"particles' MPI ranks", localnum);
123 bool_type invalidParticles(
"validity of particles", localnum);
128 locate_type rankSendCount_dview(
"rankSendCount Device", nRanks);
133 locate_type destinationRanks_dview(
"destinationRanks Device", nRanks);
138 auto [nInvalid, nDestinationRanks] =
140 particleRanks, invalidParticles,
141 rankSendCount_dview, destinationRanks_dview);
144 auto rankSendCount_hview =
145 Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), rankSendCount_dview);
148 auto destinationRanks_hview =
149 Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), destinationRanks_dview);
165 for(
size_t ridx=0; ridx < nDestinationRanks; ridx++){
166 int rank = destinationRanks_hview[ridx];
167 if (rank ==
Comm->rank()){
171 const int* src_ptr = &rankSendCount_hview(rank);
172 window_m.put<
int>(src_ptr, rank,
Comm->rank());
183 std::vector<MPI_Request> requests(0);
187 for(
size_t ridx=0; ridx < nDestinationRanks; ridx++){
188 int rank = destinationRanks_hview[ridx];
189 if(rank ==
Comm->rank()){
192 hash_type hash(
"hash", rankSendCount_hview(rank));
193 fillHash(rank, particleRanks, hash);
215 for (
int rank = 0; rank < nRanks; ++rank) {
216 if (nRecvs_m[rank] > 0) {
225 if (requests.size() > 0) {
226 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
233 template <
typename T,
unsigned Dim,
class Mesh,
typename... Properties>
234 template <
size_t... Idx>
235 KOKKOS_INLINE_FUNCTION
constexpr bool
238 return ((pos[Idx] > region[Idx].
min()) && ...) && ((pos[Idx] <= region[Idx].max()) && ...);
244 template <
typename T,
unsigned Dim,
class Mesh,
typename... Properties>
249 for (
const auto& componentNeighbors : neighbors) {
250 totalSize += componentNeighbors.size();
273 template <
typename T,
unsigned Dim,
class Mesh,
typename... Properties>
274 template <
typename ParticleContainer>
279 auto positions = pc.
R.getView();
286 const auto is = std::make_index_sequence<Dim>{};
302 locate_type neighbors_view(
"Nearest neighbors IDs", neighborSize);
312 auto neighbors_mirror =
313 Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), neighbors_view);
317 for (
const auto& componentNeighbors : neighbors) {
318 for (
size_t j = 0; j < componentNeighbors.size(); ++j) {
319 neighbors_mirror(k) = componentNeighbors[j];
325 Kokkos::deep_copy(neighbors_view, neighbors_mirror);
336 Kokkos::parallel_scan(
337 "ParticleSpatialLayout::locateParticles()",
338 Kokkos::RangePolicy<size_t>(0, ranks.extent(0)),
347 bool inNeighbor =
false;
353 ranks(i) = inCurr * myRank;
354 invalid(i) = !inCurr;
355 found = inCurr || found;
358 for (
size_t j = 0; j < neighbors_view.extent(0); ++j) {
363 ranks(i) = !(inNeighbor) * ranks(i) + inNeighbor * rank;
364 found = inNeighbor || found;
371 if(
final && !found) {
372 outsideIds(val.
count[1]) = i;
375 increment[0] = invalid(i);
376 increment[1] = !found;
384 invalidCount = red_val.
count[0];
385 outsideCount = red_val.
count[1];
392 if (outsideCount > 0) {
393 Kokkos::parallel_for(
394 "ParticleSpatialLayout::leftParticles()",
395 mdrange_type({0, 0}, {outsideCount, Regions.extent(0)}),
396 KOKKOS_LAMBDA(
const size_t i,
const size_type j) {
410 Kokkos::parallel_for(
"Calculate nSends",
411 Kokkos::RangePolicy<size_t>(0, ranks.extent(0)),
412 KOKKOS_LAMBDA(
const size_t i){
414 Kokkos::atomic_fetch_add(&nSends_dview(rank),1);
419 Kokkos::View<size_type> rankSends(
"Number of Ranks we need to send to");
421 Kokkos::parallel_for(
"Calculate sends",
422 Kokkos::RangePolicy<size_t>(0, nSends_dview.extent(0)),
423 KOKKOS_LAMBDA(
const size_t rank){
424 if(nSends_dview(rank) != 0){
425 size_type index = Kokkos::atomic_fetch_add(&rankSends(), 1);
426 sends_dview(index) = rank;
431 Kokkos::deep_copy(temp, rankSends);
433 return {invalidCount, temp};
436 template <
typename T,
unsigned Dim,
class Mesh,
typename... Properties>
442 using policy_type = Kokkos::RangePolicy<position_execution_space>;
443 Kokkos::parallel_scan(
444 "ParticleSpatialLayout::fillHash()", policy_type(0, ranks.extent(0)),
445 KOKKOS_LAMBDA(
const size_t i,
int& idx,
const bool final) {
447 if (rank == ranks(i)) {
452 if (rank == ranks(i)) {
460 template <
typename T,
unsigned Dim,
class Mesh,
typename... Properties>
464 using policy_type = Kokkos::RangePolicy<position_execution_space>;
465 Kokkos::parallel_reduce(
466 "ParticleSpatialLayout::numberOfSends()", policy_type(0, ranks.extent(0)),
467 KOKKOS_LAMBDA(
const size_t i,
size_t& num) { num += size_t(rank == ranks(i)); },
ippl::detail::size_type size_type
KOKKOS_INLINE_FUNCTION Vector< T, Dim > min(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
std::unique_ptr< mpi::Communicator > Comm
typename detail::ViewType< int, 1, MemorySpace >::view_type hash_type
void internalDestroy(const Kokkos::View< bool *, Properties... > &invalid, const size_type destroyNum)
void recvFromRank(int rank, int tag, size_type nRecvs)
void sendToRank(int rank, int tag, std::vector< MPI_Request > &requests, const HashType &hash)
particle_position_type R
view of particle positions
size_type getLocalNum() const
void applyBC(const particle_position_type &R, const NDRegion< T, Dim > &nr)
typename particle_position_type::execution_space position_execution_space
mpi::rma::Window< mpi::rma::Active > window_m
RegionLayout_t rlayout_m
The RegionLayout which determines where our particles go.
size_t numberOfSends(int rank, const locate_type &ranks)
std::vector< size_type > nRecvs_m
void update(ParticleContainer &pc)
std::pair< detail::size_type, detail::size_type > locateParticles(const ParticleContainer &pc, locate_type &ranks, bool_type &invalid, locate_type &nSends_dview, locate_type &sends_dview) const
typename detail::ViewType< bool, 1, position_memory_space >::view_type bool_type
KOKKOS_INLINE_FUNCTION static constexpr bool positionInRegion(const std::index_sequence< Idx... > &, const vector_type &pos, const region_type ®ion)
size_type getNeighborSize(const neighbor_list &neighbors) const
detail::size_type size_type
typename region_view_type::value_type region_type
void fillHash(int rank, const locate_type &ranks, hash_type &hash)
typename detail::ViewType< int, 1, position_memory_space >::view_type locate_type
detail::hash_type< position_memory_space > hash_type
typename RegionLayout_t::view_type region_view_type
void updateLayout(FieldLayout< Dim > &, Mesh &)
std::pair< size_type, size_type > locateParticles(const ParticleContainer &pc, locate_type &ranks, bool_type &invalid, locate_type &nSends_dview, locate_type &sends_dview) const
typename FieldLayout_t::neighbor_list neighbor_list
Array of N rank lists, where N = number of hypercubes for the dimension Dim.
typename Base::vector_type vector_type
FieldLayout_t & flayout_m
KOKKOS_INLINE_FUNCTION increment_type & operator+=(increment_type values)
KOKKOS_FUNCTION void init()
KOKKOS_INLINE_FUNCTION increment_type & operator+=(bool *values)
Timing::TimerRef TimerRef
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)