1#ifndef AMREX_NEIGHBORPARTICLESCPUIMPL_H_
2#define AMREX_NEIGHBORPARTICLESCPUIMPL_H_
3#include <AMReX_Config.H>
16void applyNeighborPeriodicShift (T& value,
int dir,
const IntVect& periodic_shift,
17 const Periodicity& periodicity,
18 const RealBox& prob_domain)
noexcept
20 if (!periodicity.isPeriodic(dir)) {
return; }
21 if (periodic_shift[dir] < 0) {
22 value +=
static_cast<T
>(prob_domain.length(dir));
23 }
else if (periodic_shift[dir] > 0) {
24 value -=
static_cast<T
>(prob_domain.length(dir));
28template <
typename PTD>
30void shiftNeighborParticlePositions (PTD
const& ptd,
int index,
const IntVect& periodic_shift,
31 const Periodicity& periodicity,
32 const RealBox& prob_domain)
noexcept
34 for (
int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
35 applyNeighborPeriodicShift(ptd.pos(dir, index), dir, periodic_shift, periodicity, prob_domain);
39template <
typename PTD>
41void packNeighborParticleData (
char*& dst, PTD
const& src,
int src_index,
42 int num_real_comps,
int num_int_comps,
43 const Vector<int>& ghost_real_comp,
44 const Vector<int>& ghost_int_comp,
46 const Periodicity& periodicity,
47 const RealBox& prob_domain)
noexcept
49 using ParticleType =
typename std::decay_t<PTD>::ParticleType;
50 constexpr int real_comm_comp_start =
51 ParticleType::is_soa_particle ? 0 : AMREX_SPACEDIM + ParticleType::NReal;
52 constexpr int int_comm_comp_start = 2 + ParticleType::NInt;
54 if constexpr (!ParticleType::is_soa_particle) {
55 auto const p = src[src_index];
56 for (
int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
57 if (!ghost_real_comp[dir]) {
continue; }
58 auto value = p.pos(dir);
59 applyNeighborPeriodicShift(value, dir, periodic_shift, periodicity, prob_domain);
60 std::memcpy(dst, &value,
sizeof(
typename ParticleType::RealType));
61 dst +=
sizeof(
typename ParticleType::RealType);
63 for (
int ii = 0; ii < ParticleType::NReal; ++ii) {
64 if (!ghost_real_comp[AMREX_SPACEDIM + ii]) {
continue; }
65 auto value = p.rdata(ii);
66 std::memcpy(dst, &value,
sizeof(
typename ParticleType::RealType));
67 dst +=
sizeof(
typename ParticleType::RealType);
71 for (
int ii = 0; ii < num_real_comps; ++ii) {
72 if (!ghost_real_comp[real_comm_comp_start + ii]) {
continue; }
75 if (ii < std::decay_t<PTD>::NAR) {
76 value = src.rdata(ii)[src_index];
78 value = src.m_runtime_rdata[ii - std::decay_t<PTD>::NAR][src_index];
80 if constexpr (ParticleType::is_soa_particle) {
81 if (ii < AMREX_SPACEDIM) {
82 applyNeighborPeriodicShift(value, ii, periodic_shift, periodicity, prob_domain);
89 std::array<int,2> idcpu_parts{};
90 auto const idcpu = src.idcpu(src_index);
91 std::memcpy(idcpu_parts.data(), &idcpu,
sizeof(idcpu));
92 for (
int ii = 0; ii < 2; ++ii) {
93 if (!ghost_int_comp[ii]) {
continue; }
94 std::memcpy(dst, &idcpu_parts[ii],
sizeof(
int));
98 if constexpr (!ParticleType::is_soa_particle) {
99 auto const p = src[src_index];
100 for (
int ii = 0; ii < ParticleType::NInt; ++ii) {
101 if (!ghost_int_comp[2 + ii]) {
continue; }
102 auto value = p.idata(ii);
103 std::memcpy(dst, &value,
sizeof(
int));
108 for (
int ii = 0; ii < num_int_comps; ++ii) {
109 if (!ghost_int_comp[int_comm_comp_start + ii]) {
continue; }
112 if (ii < std::decay_t<PTD>::NAI) {
113 value = src.idata(ii)[src_index];
115 value = src.m_runtime_idata[ii - std::decay_t<PTD>::NAI][src_index];
117 std::memcpy(dst, &value,
sizeof(
int));
122template <
typename PTD>
124void unpackNeighborParticleData (PTD
const& dst_ptd,
int dst_index,
const char*& src,
125 int num_real_comps,
int num_int_comps,
126 const Vector<int>& ghost_real_comp,
127 const Vector<int>& ghost_int_comp)
noexcept
129 using ParticleType =
typename std::decay_t<PTD>::ParticleType;
130 constexpr int real_comm_comp_start =
131 ParticleType::is_soa_particle ? 0 : AMREX_SPACEDIM + ParticleType::NReal;
132 constexpr int int_comm_comp_start = 2 + ParticleType::NInt;
134 if constexpr (!ParticleType::is_soa_particle) {
135 for (
int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
136 if (!ghost_real_comp[dir]) {
continue; }
137 std::memcpy(&(dst_ptd.pos(dir, dst_index)), src,
sizeof(
typename ParticleType::RealType));
138 src +=
sizeof(
typename ParticleType::RealType);
140 for (
int ii = 0; ii < ParticleType::NReal; ++ii) {
141 if (!ghost_real_comp[AMREX_SPACEDIM + ii]) {
continue; }
142 std::memcpy(&(dst_ptd[dst_index].rdata(ii)), src,
sizeof(
typename ParticleType::RealType));
143 src +=
sizeof(
typename ParticleType::RealType);
147 for (
int ii = 0; ii < num_real_comps; ++ii) {
148 if (!ghost_real_comp[real_comm_comp_start + ii]) {
continue; }
150 if (ii < std::decay_t<PTD>::NAR) {
151 std::memcpy(dst_ptd.rdata(ii) + dst_index, src,
sizeof(
ParticleReal));
153 std::memcpy(dst_ptd.m_runtime_rdata[ii - std::decay_t<PTD>::NAR] + dst_index, src,
159 std::array<int,2> idcpu_parts{};
160 std::memcpy(idcpu_parts.data(), &(dst_ptd.idcpu(dst_index)),
sizeof(uint64_t));
161 for (
int ii = 0; ii < 2; ++ii) {
162 if (!ghost_int_comp[ii]) {
continue; }
163 std::memcpy(&idcpu_parts[ii], src,
sizeof(
int));
166 std::memcpy(&(dst_ptd.idcpu(dst_index)), idcpu_parts.data(),
sizeof(uint64_t));
168 if constexpr (!ParticleType::is_soa_particle) {
169 for (
int ii = 0; ii < ParticleType::NInt; ++ii) {
170 if (!ghost_int_comp[2 + ii]) {
continue; }
171 std::memcpy(&(dst_ptd[dst_index].idata(ii)), src,
sizeof(
int));
176 for (
int ii = 0; ii < num_int_comps; ++ii) {
177 if (!ghost_int_comp[int_comm_comp_start + ii]) {
continue; }
179 if (ii < std::decay_t<PTD>::NAI) {
180 std::memcpy(dst_ptd.idata(ii) + dst_index, src,
sizeof(
int));
182 std::memcpy(dst_ptd.m_runtime_idata[ii - std::decay_t<PTD>::NAI] + dst_index, src,
189template <
typename PTD>
191ParticleReal getSummedRealComp (PTD
const& ptd,
int index,
int comp)
noexcept
193 using ParticleType =
typename std::decay_t<PTD>::ParticleType;
195 if constexpr (!ParticleType::is_soa_particle) {
196 if (comp < ParticleType::NReal) {
197 return ptd[index].rdata(comp);
199 comp -= ParticleType::NReal;
202 if (comp < std::decay_t<PTD>::NAR) {
203 return ptd.rdata(comp)[index];
206 return ptd.m_runtime_rdata[comp - std::decay_t<PTD>::NAR][index];
209template <
typename PTD>
211int getSummedIntComp (PTD
const& ptd,
int index,
int comp)
noexcept
213 using ParticleType =
typename std::decay_t<PTD>::ParticleType;
215 if constexpr (!ParticleType::is_soa_particle) {
216 if (comp < ParticleType::NInt) {
217 return ptd[index].idata(comp);
219 comp -= ParticleType::NInt;
222 if (comp < std::decay_t<PTD>::NAI) {
223 return ptd.idata(comp)[index];
226 return ptd.m_runtime_idata[comp - std::decay_t<PTD>::NAI][index];
229template <
typename PTD>
231void addSummedRealComp (PTD
const& ptd,
int index,
int comp,
ParticleReal value)
noexcept
233 using ParticleType =
typename std::decay_t<PTD>::ParticleType;
235 if constexpr (!ParticleType::is_soa_particle) {
236 if (comp < ParticleType::NReal) {
237 ptd[index].rdata(comp) += value;
240 comp -= ParticleType::NReal;
243 if (comp < std::decay_t<PTD>::NAR) {
244 ptd.rdata(comp)[index] += value;
248 ptd.m_runtime_rdata[comp - std::decay_t<PTD>::NAR][index] += value;
251template <
typename PTD>
253void addSummedIntComp (PTD
const& ptd,
int index,
int comp,
int value)
noexcept
255 using ParticleType =
typename std::decay_t<PTD>::ParticleType;
257 if constexpr (!ParticleType::is_soa_particle) {
258 if (comp < ParticleType::NInt) {
259 ptd[index].idata(comp) += value;
262 comp -= ParticleType::NInt;
265 if (comp < std::decay_t<PTD>::NAI) {
266 ptd.idata(comp)[index] += value;
270 ptd.m_runtime_idata[comp - std::decay_t<PTD>::NAI][index] += value;
275template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt,
276 template<
class>
class Allocator,
class CellAssignor>
278NeighborParticleContainer_impl<T_ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
279::fillNeighborsCPU () {
280 BL_PROFILE(
"NeighborParticleContainer::fillNeighborsCPU");
281 if (!areMasksValid()) {
283 GetNeighborCommTags();
286 updateNeighborsCPU(
false);
289template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt,
290 template<
class>
class Allocator,
class CellAssignor>
292NeighborParticleContainer_impl<T_ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
293::sumNeighborsCPU (
int real_start_comp,
int real_num_comp,
294 int int_start_comp,
int int_num_comp)
296 BL_PROFILE(
"NeighborParticleContainer::sumNeighborsCPU");
298 if ( ! enableInverse() )
300 amrex::Abort(
"Need to enable inverse to true to use sumNeighbors. \n");
305 std::map<int, Vector<char> > isend_data;
307 for (
int lev = 0; lev < this->numLevels(); ++lev)
309 for (MyParIter pti(*
this, lev); pti.isValid(); ++pti)
311 PairIndex src_index(pti.index(), pti.LocalTileIndex());
312 const auto& tags = inverse_tags[lev][src_index];
313 const auto& neighb_tile = neighbors[lev][src_index];
314 const auto neighbs = neighb_tile.getConstParticleTileData();
315 const Long num_neighbs =
static_cast<Long>(neighb_tile.size());
318 for (
int i = 0; i < static_cast<int>(num_neighbs); ++i)
320 const auto& tag = tags[i];
321 const int dst_grid = tag.src_grid;
322 const int global_rank = this->ParticleDistributionMap(lev)[dst_grid];
324 const int dst_tile = tag.src_tile;
325 const int dst_index = tag.src_index;
326 const int dst_level = tag.src_level;
328 if (dst_proc == MyProc)
330 auto pair = std::make_pair(dst_grid, dst_tile);
331 auto& dst_ptile = this->GetParticles(dst_level)[pair];
332 auto dst_ptd = dst_ptile.getParticleTileData();
334 for (
int comp = real_start_comp; comp < real_start_comp + real_num_comp; ++comp)
336 detail::addSummedRealComp(
337 dst_ptd, dst_index, comp, detail::getSummedRealComp(neighbs, i, comp));
340 for (
int comp = int_start_comp; comp < int_start_comp + int_num_comp; ++comp)
342 detail::addSummedIntComp(
343 dst_ptd, dst_index, comp, detail::getSummedIntComp(neighbs, i, comp));
349 auto& sdata = isend_data[dst_proc];
350 auto old_size = sdata.size();
351 auto new_size = old_size + real_num_comp*
sizeof(
ParticleReal) + int_num_comp*
sizeof(
int)
353 sdata.resize(new_size);
354 char* dst = &sdata[old_size];
355 std::memcpy(dst, &dst_grid,
sizeof(
int)); dst +=
sizeof(
int);
356 std::memcpy(dst, &dst_tile,
sizeof(
int)); dst +=
sizeof(
int);
357 std::memcpy(dst, &dst_index,
sizeof(
int)); dst +=
sizeof(
int);
358 std::memcpy(dst, &dst_level,
sizeof(
int)); dst +=
sizeof(
int);
359 for (
int comp = real_start_comp; comp < real_start_comp + real_num_comp; ++comp)
361 ParticleReal data = detail::getSummedRealComp(neighbs, i, comp);
365 for (
int comp = int_start_comp; comp < int_start_comp + int_num_comp; ++comp)
367 int data = detail::getSummedIntComp(neighbs, i, comp);
368 std::memcpy(dst, &data,
sizeof(
int));
376 sumNeighborsMPI(isend_data, real_start_comp, real_num_comp, int_start_comp, int_num_comp);
379template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt,
380 template<
class>
class Allocator,
class CellAssignor>
384 int real_start_comp,
int real_num_comp,
385 int int_start_comp,
int int_num_comp)
387 BL_PROFILE(
"NeighborParticleContainer::sumNeighborsMPI");
392 Vector<Long> isnds(NProcs, 0);
393 Vector<Long> ircvs(NProcs, 0);
394 for (
int i = 0; i <
NProcs; ++i) {
403 for (
const auto& kv : not_ours)
405 num_isnds += kv.second.size();
406 isnds[kv.first] = kv.second.size();
411 if (num_isnds == 0) {
return; }
413 const int num_ircvs = neighbor_procs.size();
414 Vector<MPI_Status> stats(num_ircvs);
415 Vector<MPI_Request> rreqs(num_ircvs);
420 for (
int i = 0; i < num_ircvs; ++i)
422 const int Who = neighbor_procs[i];
432 for (
int i = 0; i < num_ircvs; ++i) {
433 const int Who = neighbor_procs[i];
446 Vector<std::size_t> rOffset;
447 std::size_t TotRcvBytes = 0;
448 for (
int i = 0; i <
NProcs; ++i) {
450 RcvProc.push_back(i);
451 rOffset.push_back(TotRcvBytes);
452 TotRcvBytes += ircvs[i];
456 const auto nrcvs =
int(RcvProc.size());
457 Vector<MPI_Status> stats(nrcvs);
458 Vector<MPI_Request> rreqs(nrcvs);
463 Vector<char> recvdata(TotRcvBytes);
466 for (
int i = 0; i < nrcvs; ++i) {
467 const auto Who = RcvProc[i];
468 const auto offset = rOffset[i];
469 const auto Cnt = ircvs[Who];
480 for (
const auto& kv : not_ours) {
481 const auto Who = kv.first;
482 const auto Cnt = kv.second.size();
497 const size_t data_size =
498 real_num_comp*
sizeof(
ParticleReal) + int_num_comp*
sizeof(
int) + 4 *
sizeof(
int);
500 if (recvdata.size() % data_size != 0) {
501 amrex::Print() << recvdata.size() <<
" " << data_size <<
"\n";
502 if (this->m_verbose) {
504 << recvdata.size() <<
", " << data_size <<
"\n";
506 amrex::Abort(
"NeighborParticles::sumNeighbors: How did this happen?");
509 auto npart =
int(recvdata.size() / data_size);
511 char* buffer = recvdata.data();
512 for (
int j = 0; j < npart; ++j)
514 int grid, tile, index, lev;
515 std::memcpy(&grid, buffer,
sizeof(
int)); buffer +=
sizeof(
int);
516 std::memcpy(&tile, buffer,
sizeof(
int)); buffer +=
sizeof(
int);
517 std::memcpy(&index, buffer,
sizeof(
int)); buffer +=
sizeof(
int);
518 std::memcpy(&lev, buffer,
sizeof(
int)); buffer +=
sizeof(
int);
520 auto pair = std::make_pair(grid, tile);
521 auto& ptile = this->GetParticles(lev)[pair];
522 auto dst_ptd = ptile.getParticleTileData();
524 for (
int comp = real_start_comp; comp < real_start_comp + real_num_comp; ++comp)
528 detail::addSummedRealComp(dst_ptd, index, comp, data);
532 for (
int comp = int_start_comp; comp < int_start_comp + int_num_comp; ++comp)
535 std::memcpy(&data, buffer,
sizeof(
int));
536 detail::addSummedIntComp(dst_ptd, index, comp, data);
537 buffer +=
sizeof(
int);
546template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt,
547 template<
class>
class Allocator,
class CellAssignor>
549NeighborParticleContainer_impl<T_ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
550::updateNeighborsCPU (
bool reuse_rcv_counts) {
552 BL_PROFILE_VAR(
"NeighborParticleContainer::updateNeighborsCPU", update);
556 for (
int lev = 0; lev < this->numLevels(); ++lev) {
557 const Periodicity& periodicity = this->Geom(lev).periodicity();
558 const RealBox& prob_domain = this->Geom(lev).ProbDomain();
562 for (MyParIter pti(*
this, lev); pti.isValid(); ++pti) {
563 PairIndex src_index(pti.index(), pti.LocalTileIndex());
564 auto const src = pti.GetParticleTile().getConstParticleTileData();
565 for (
int j = 0; j < num_threads; ++j) {
566 auto& tags = buffer_tag_cache[lev][src_index][j];
567 int num_tags = tags.size();
569#pragma omp parallel for
571 for (
int i = 0; i < num_tags; ++i) {
572 const NeighborCopyTag& tag = tags[i];
573 const int global_who = this->ParticleDistributionMap(tag.level)[tag.grid];
576 PairIndex dst_index(tag.grid, tag.tile);
577 auto dst = neighbors[tag.level][dst_index].getParticleTileData();
579 if (periodicity.isAnyPeriodic()) {
580 detail::shiftNeighborParticlePositions(dst, tag.dst_index, tag.periodic_shift,
581 periodicity, prob_domain);
584 if ( enableInverse() )
586 auto& itags = inverse_tags[tag.level][dst_index];
588 itags[tag.dst_index].src_grid = src_index.first;
589 itags[tag.dst_index].src_tile = src_index.second;
590 itags[tag.dst_index].src_index = tag.src_index;
591 itags[tag.dst_index].src_level = lev;
594 char* dst_ptr = &send_data[who][tag.dst_index];
595 detail::packNeighborParticleData(dst_ptr, src, tag.src_index,
596 this->NumRealComps(), this->NumIntComps(),
597 ghost_real_comp, ghost_int_comp,
598 tag.periodic_shift, periodicity, prob_domain);
599 if ( enableInverse() )
601 std::memcpy(dst_ptr,&(src_index.first),
sizeof(
int)); dst_ptr +=
sizeof(
int);
602 std::memcpy(dst_ptr,&(src_index.second),
sizeof(
int)); dst_ptr +=
sizeof(
int);
603 std::memcpy(dst_ptr,&(tag.src_index),
sizeof(
int)); dst_ptr +=
sizeof(
int);
604 std::memcpy(dst_ptr,&(lev),
sizeof(
int)); dst_ptr +=
sizeof(
int);
614 for (MFIter mfi = this->MakeMFIter(lev); mfi.isValid(); ++mfi) {
615 const int grid = mfi.index();
616 const int tile = mfi.LocalTileIndex();
617 PairIndex dst_index(grid, tile);
618 neighbors[lev][dst_index].resize(local_neighbor_sizes[lev][dst_index]);
619 if ( enableInverse() ) {
620 inverse_tags[lev][dst_index].resize(local_neighbor_sizes[lev][dst_index]);
626 fillNeighborsMPI(reuse_rcv_counts);
628 for (
int lev = 0; lev < this->numLevels(); ++lev)
630 for(MFIter mfi = this->MakeMFIter(lev); mfi.isValid(); ++mfi)
632 int src_grid = mfi.index();
633 int src_tile = mfi.LocalTileIndex();
634 auto index = std::make_pair(src_grid, src_tile);
635 auto& ptile = this->GetParticles(lev)[index];
636 ptile.setNumNeighbors(neighbors[lev][index].size());
638 ptile.numRealParticles(), ptile.numNeighborParticles());
644template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt,
645 template<
class>
class Allocator,
class CellAssignor>
647NeighborParticleContainer_impl<T_ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
648::clearNeighborsCPU ()
650 BL_PROFILE(
"NeighborParticleContainer::clearNeighborsCPU");
652 resizeContainers(this->numLevels());
653 for (
int lev = 0; lev < this->numLevels(); ++lev) {
654 neighbors[lev].clear();
655 if ( enableInverse() ) { inverse_tags[lev].clear(); }
656 buffer_tag_cache[lev].clear();
658 for(MFIter mfi = this->MakeMFIter(lev); mfi.isValid(); ++mfi)
660 int src_grid = mfi.index();
661 int src_tile = mfi.LocalTileIndex();
662 auto index = std::make_pair(src_grid, src_tile);
663 auto& ptile = this->GetParticles(lev)[index];
664 ptile.setNumNeighbors(0);
671template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt,
672 template<
class>
class Allocator,
class CellAssignor>
677 BL_PROFILE(
"NeighborParticleContainer::getRcvCountsMPI");
684 Vector<Long> snds(NProcs, 0);
686 for (
int i = 0; i <
NProcs; ++i) {
691 for (
const auto& kv : send_data) {
692 num_snds += kv.second.size();
693 snds[kv.first] = kv.second.size();
698 if (num_snds == 0) {
return; }
700 const int num_rcvs = neighbor_procs.size();
701 Vector<MPI_Status> stats(num_rcvs);
702 Vector<MPI_Request> rreqs(num_rcvs);
707 for (
int i = 0; i < num_rcvs; ++i) {
708 const int Who = neighbor_procs[i];
718 for (
int i = 0; i < num_rcvs; ++i) {
719 const int Who = neighbor_procs[i];
733template <
typename T_ParticleType,
int NArrayReal,
int NArrayInt,
734 template<
class>
class Allocator,
class CellAssignor>
739 BL_PROFILE(
"NeighborParticleContainer::fillNeighborsMPI");
746 if (!reuse_rcv_counts) { getRcvCountsMPI(); }
747 if (num_snds == 0) {
return; }
750 Vector<std::size_t> rOffset;
751 std::size_t TotRcvBytes = 0;
752 for (
int i = 0; i <
NProcs; ++i) {
754 RcvProc.push_back(i);
755 rOffset.push_back(TotRcvBytes);
756 TotRcvBytes += rcvs[i];
760 const auto nrcvs =
int(RcvProc.size());
761 Vector<MPI_Status> stats(nrcvs);
762 Vector<MPI_Request> rreqs(nrcvs);
767 Vector<char> recvdata(TotRcvBytes);
770 for (
int i = 0; i < nrcvs; ++i) {
771 const auto Who = RcvProc[i];
772 const auto offset = rOffset[i];
773 const auto Cnt = rcvs[Who];
784 for (
const auto& kv : send_data) {
785 const auto Who = kv.first;
786 const auto Cnt = kv.second.size();
799 for (
int i = 0; i < nrcvs; ++i) {
800 const std::size_t
offset = rOffset[i];
801 char* buffer = &recvdata[
offset];
802 int num_tiles, lev, gid, tid, size, np;
803 std::memcpy(&num_tiles, buffer,
sizeof(
int)); buffer +=
sizeof(
int);
804 for (
int j = 0; j < num_tiles; ++j) {
805 std::memcpy(&lev, buffer,
sizeof(
int)); buffer +=
sizeof(
int);
806 std::memcpy(&gid, buffer,
sizeof(
int)); buffer +=
sizeof(
int);
807 std::memcpy(&tid, buffer,
sizeof(
int)); buffer +=
sizeof(
int);
808 std::memcpy(&size, buffer,
sizeof(
int)); buffer +=
sizeof(
int);
810 if (size == 0) {
continue; }
812 np = size / cdata_size;
816 PairIndex dst_index(gid, tid);
817 size_t old_size = neighbors[lev][dst_index].size();
818 size_t new_size = neighbors[lev][dst_index].size() + np;
819 if ( enableInverse() )
822 size_t(inverse_tags[lev][dst_index].size()));
823 inverse_tags[lev][dst_index].resize(new_size);
825 neighbors[lev][dst_index].resize(new_size);
827 auto dst_ptd = neighbors[lev][dst_index].getParticleTileData();
828 char const* src = buffer;
829 for (
int n = 0; n < np; ++n) {
830 detail::unpackNeighborParticleData(dst_ptd,
int(old_size+n), src,
831 this->NumRealComps(), this->NumIntComps(),
832 ghost_real_comp, ghost_int_comp);
834 if ( enableInverse() )
836 auto& tag = inverse_tags[lev][dst_index][old_size+n];
837 std::memcpy(&(tag.src_grid),src,
sizeof(
int));
840 std::memcpy(&(tag.src_tile),src,
sizeof(
int));
843 std::memcpy(&(tag.src_index),src,
sizeof(
int));
846 std::memcpy(&(tag.src_level),src,
sizeof(
int));
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define BL_PROFILE_VAR_STOP(vname)
Definition AMReX_BLProfiler.H:563
#define BL_PROFILE_VAR(fname, vname)
Definition AMReX_BLProfiler.H:560
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Array4< int const > offset
Definition AMReX_HypreMLABecLap.cpp:1139
Print on all processors of the default communicator.
Definition AMReX_Print.H:113
void fillNeighborsMPI(bool reuse_rcv_counts)
void sumNeighborsMPI(std::map< int, Vector< char > > ¬_ours, int real_start_comp, int real_num_comp, int int_start_comp, int int_num_comp)
MPI_Request req() const
Definition AMReX_ParallelDescriptor.H:74
This class provides the user with a few print options.
Definition AMReX_Print.H:35
amrex_particle_real ParticleReal
Floating Point Type for Particles.
Definition AMReX_REAL.H:90
amrex_long Long
Definition AMReX_INT.H:30
void Max(KeyValuePair< K, V > &vi, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:133
int NProcs()
Process ID in MPI_COMM_WORLD.
Definition AMReX_MPMD.cpp:122
int MyProc()
Definition AMReX_MPMD.cpp:117
constexpr int get_max_threads()
Definition AMReX_OpenMP.H:36
MPI_Comm CommunicatorSub() noexcept
sub-communicator for current frame
Definition AMReX_ParallelContext.H:70
int MyProcSub() noexcept
my sub-rank in current frame
Definition AMReX_ParallelContext.H:76
int global_to_local_rank(int rank) noexcept
Definition AMReX_ParallelContext.H:98
int NProcsSub() noexcept
number of ranks in current frame
Definition AMReX_ParallelContext.H:74
void Waitall(Vector< MPI_Request > &, Vector< MPI_Status > &)
Definition AMReX_ParallelDescriptor.cpp:1308
Message Send(const T *buf, size_t n, int dst_pid, int tag)
Definition AMReX_ParallelDescriptor.H:1193
int SeqNum() noexcept
Returns sequential message sequence numbers, usually used as tags for send/recv.
Definition AMReX_ParallelDescriptor.H:696
Message Arecv(T *, size_t n, int pid, int tag)
Definition AMReX_ParallelDescriptor.H:1214
Definition AMReX_Amr.cpp:50
__host__ __device__ void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:139
__host__ __device__ void copyParticle(const ParticleTileData< T_ParticleType, NAR, NAI > &dst, const ConstParticleTileData< T_ParticleType, NAR, NAI > &src, int src_i, int dst_i) noexcept
A general single particle copying routine that can run on the GPU.
Definition AMReX_ParticleTransformation.H:32
void copyParticles(DstTile &dst, const SrcTile &src) noexcept
Copy particles from src to dst. This version copies all the particles, writing them to the beginning ...
Definition AMReX_ParticleTransformation.H:222
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:33
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:241
const int[]
Definition AMReX_BLProfiler.cpp:1664