1 #ifndef AMREX_NEIGHBORPARTICLESGPUIMPL_H_
2 #define AMREX_NEIGHBORPARTICLESGPUIMPL_H_
3 #include <AMReX_Config.H>
10 "Too many cells requested in getBoundaryBoxes");
13 "Box must be cell-centered");
16 for (
int i = 0; i < AMREX_SPACEDIM; ++i) {
20 face_boxes.push_back(hi_face_box); bl.push_back(hi_face_box);
21 face_boxes.push_back(lo_face_box); bl.push_back(lo_face_box);
22 for (
auto face_box : face_boxes) {
23 for (
int j = 0; j < AMREX_SPACEDIM; ++j) {
24 if (i == j) {
continue; }
28 edge_boxes.push_back(hi_edge_box); bl.push_back(hi_edge_box);
29 edge_boxes.push_back(lo_edge_box); bl.push_back(lo_edge_box);
30 for (
auto edge_box : edge_boxes) {
31 for (
int k = 0; k < AMREX_SPACEDIM; ++k) {
32 if ((j == k) || (i == k)) {
continue; }
35 bl.push_back(hi_corner_box);
36 bl.push_back(lo_corner_box);
48 template <
int NStructReal,
int NStructInt,
int NArrayReal,
int NArrayInt>
53 BL_PROFILE(
"NeighborParticleContainer<NStructReal, NStructInt, NArrayReal, NArrayInt>::buildNeighborMask");
54 m_neighbor_mask_initialized =
true;
56 const Geometry& geom = this->Geom(lev);
57 const BoxArray& ba = this->ParticleBoxArray(lev);
62 if (m_neighbor_mask_ptr ==
nullptr ||
63 ! BoxArray::SameRefs(m_neighbor_mask_ptr->boxArray(), ba) ||
64 ! DistributionMapping::SameRefs(m_neighbor_mask_ptr->DistributionMap(), dmap))
67 const std::vector<IntVect>& pshifts = periodicity.
shiftIntVect();
71 int grid = mfi.index();
73 std::set<NeighborTask> neighbor_grids;
74 for (
auto pshift : pshifts)
76 const Box box = ba[mfi] + pshift;
78 const bool first_only =
false;
79 auto isecs = ba.
intersections(box, first_only, m_num_neighbor_cells);
81 for (
auto& isec : isecs)
83 int nbor_grid = isec.first;
84 const Box isec_box = isec.second - pshift;
85 if ( (grid == nbor_grid) && (pshift == 0)) {
continue; }
86 neighbor_grids.insert(
NeighborTask(nbor_grid, isec_box, pshift));
87 const int global_rank = dmap[nbor_grid];
94 for (
auto nbor_grid : neighbor_grids)
97 code.
grid_id = nbor_grid.grid_id;
103 m_code_array[grid].resize(h_code_arr.
size());
105 m_code_array[grid].begin());
106 m_isec_boxes[grid].resize(h_isec_boxes.
size());
108 m_isec_boxes[grid].begin());
117 template <
int NStructReal,
int NStructInt,
int NArrayReal,
int NArrayInt>
122 BL_PROFILE(
"NeighborParticleContainer<NStructReal, NStructInt, NArrayReal, NArrayInt>::buildNeighborCopyOp()");
127 const auto& geom = this->Geom(lev);
128 const auto dxi = this->Geom(lev).InvCellSizeArray();
129 const auto plo = this->Geom(lev).ProbLoArray();
130 const auto domain = this->Geom(lev).Domain();
131 auto& plev = this->GetParticles(lev);
132 auto& ba = this->ParticleBoxArray(lev);
134 if (ba.size() == 1 && (! geom.isAnyPeriodic()) ) {
return; }
136 for(
MFIter mfi = this->MakeMFIter(lev); mfi.
isValid(); ++mfi)
138 int gid = mfi.index();
139 int tid = mfi.LocalTileIndex();
140 auto index = std::make_pair(gid, tid);
142 auto& src_tile = plev[index];
143 auto& aos = src_tile.GetArrayOfStructs();
144 const size_t np_real = aos.numParticles();
147 if (use_boundary_neighbor) {
148 np = m_boundary_particle_ids[lev][index].size();
151 m_boundary_particle_ids.resize(1);
152 m_boundary_particle_ids[lev][index];
155 const auto* p_bndry_pid = m_boundary_particle_ids[lev][index].dataPtr();
159 auto p_counts = counts.
dataPtr();
160 auto p_offsets = offsets.
dataPtr();
163 auto p_code_array = m_code_array[gid].dataPtr();
164 auto p_isec_boxes = m_isec_boxes[gid].dataPtr();
165 const int nisec_box = m_isec_boxes[gid].size();
173 if (use_boundary_neighbor) {
174 pid = p_bndry_pid[i];
177 for (
int j=0; j<nisec_box; ++j) {
178 if (p_isec_boxes[j].contains(iv)) {
190 neighbor_copy_op.resize(gid, lev, num_copies);
192 auto p_boxes = neighbor_copy_op.m_boxes[lev][gid].dataPtr();
193 auto p_levs = neighbor_copy_op.m_levels[lev][gid].dataPtr();
194 auto p_src_indices = neighbor_copy_op.m_src_indices[lev][gid].dataPtr();
195 auto p_periodic_shift = neighbor_copy_op.m_periodic_shift[lev][gid].dataPtr();
201 if (use_boundary_neighbor) {
202 pid = p_bndry_pid[i];
205 int k = p_offsets[i];
206 for (
int j=0; j<nisec_box; ++j) {
207 if (p_isec_boxes[j].contains(iv)) {
208 p_boxes[k] = p_code_array[j].grid_id;
210 p_periodic_shift[k] = p_code_array[j].periodic_shift;
211 p_src_indices[k] = pid;
222 template <
int NStructReal,
int NStructInt,
int NArrayReal,
int NArrayInt>
227 BL_PROFILE(
"NeighborParticleContainer::fillNeighbors");
232 this->defineBufferMap();
234 neighbor_copy_op.clear();
235 neighbor_copy_plan.clear();
236 buildNeighborCopyOp();
237 neighbor_copy_plan.build(*
this, neighbor_copy_op, ghost_int_comp,
238 ghost_real_comp,
true);
239 updateNeighborsGPU(
false);
242 template <
int NStructReal,
int NStructInt,
int NArrayReal,
int NArrayInt>
247 BL_PROFILE(
"NeighborParticleContainer::updateNeighborsGPU");
249 if (boundary_neighbors_only) {
250 neighbor_copy_op.clear();
251 neighbor_copy_plan.clear();
252 buildNeighborCopyOp(
true);
253 neighbor_copy_plan.build(*
this, neighbor_copy_op, ghost_int_comp,
254 ghost_real_comp,
true);
264 packBuffer(*
this, neighbor_copy_op, neighbor_copy_plan, snd_buffer);
267 neighbor_copy_plan.buildMPIFinish(this->BufferMap());
276 if (snd_buffer.arena()->isPinned()) {
277 neighbor_copy_plan.buildMPIFinish(this->BufferMap());
281 pinned_snd_buffer.resize(snd_buffer.size());
283 neighbor_copy_plan.buildMPIFinish(this->BufferMap());
288 rcv_buffer.resize(pinned_rcv_buffer.size());
298 template <
int NStructReal,
int NStructInt,
int NArrayReal,
int NArrayInt>
303 BL_PROFILE(
"NeighborParticleContainer::clearNeighborsGPU");
307 for (
int lev = 0; lev < this->numLevels(); ++lev)
309 for(
MFIter mfi = this->MakeMFIter(lev); mfi.
isValid(); ++mfi)
311 auto& ptile = this->DefineAndReturnParticleTile(lev, mfi);
312 ptile.setNumNeighbors(0);
#define BL_PROFILE(a)
Definition: AMReX_BLProfiler.H:551
#define AMREX_ASSERT_WITH_MESSAGE(EX, MSG)
Definition: AMReX_BLassert.H:37
#define AMREX_ASSERT(EX)
Definition: AMReX_BLassert.H:38
#define AMREX_ALWAYS_ASSERT(EX)
Definition: AMReX_BLassert.H:50
#define AMREX_FOR_1D(...)
Definition: AMReX_GpuLaunch.nolint.H:41
#define AMREX_D_DECL(a, b, c)
Definition: AMReX_SPACE.H:104
A collection of Boxes stored in an Array.
Definition: AMReX_BoxArray.H:550
std::vector< std::pair< int, Box > > intersections(const Box &bx) const
Return intersections of Box and BoxArray.
Long size() const noexcept
Return the number of boxes in the BoxArray.
Definition: AMReX_BoxArray.H:597
Calculates the distribution of FABs to MPI processes.
Definition: AMReX_DistributionMapping.H:41
Rectangular problem domain geometry.
Definition: AMReX_Geometry.H:73
bool isAnyPeriodic() const noexcept
Is domain periodic in any direction?
Definition: AMReX_Geometry.H:333
Periodicity periodicity() const noexcept
Definition: AMReX_Geometry.H:355
Definition: AMReX_MFIter.H:57
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition: AMReX_MFIter.H:141
Definition: AMReX_NeighborParticles.H:35
typename ParticleContainerType::ParticleType ParticleType
Definition: AMReX_NeighborParticles.H:38
Definition: AMReX_PODVector.H:246
size_type size() const noexcept
Definition: AMReX_PODVector.H:575
T * data() noexcept
Definition: AMReX_PODVector.H:593
iterator begin() noexcept
Definition: AMReX_PODVector.H:601
iterator end() noexcept
Definition: AMReX_PODVector.H:605
T * dataPtr() noexcept
Definition: AMReX_PODVector.H:597
void push_back(const T &a_value)
Definition: AMReX_PODVector.H:556
This provides length of period for periodic domains. 0 means it is not periodic in that direction....
Definition: AMReX_Periodicity.H:17
std::vector< IntVect > shiftIntVect(IntVect const &nghost=IntVect(0)) const
Definition: AMReX_Periodicity.cpp:8
void copyAsync(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
A host-to-device copy routine. Note this is just a wrapper around memcpy, so it assumes contiguous st...
Definition: AMReX_GpuContainers.H:233
OutIter exclusive_scan(InIter begin, InIter end, OutIter result)
Definition: AMReX_Scan.H:1377
static constexpr HostToDevice hostToDevice
Definition: AMReX_GpuContainers.H:98
void streamSynchronize() noexcept
Definition: AMReX_GpuDevice.H:237
void dtoh_memcpy_async(void *p_h, const void *p_d, const std::size_t sz) noexcept
Definition: AMReX_GpuDevice.H:265
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition: AMReX_GpuDevice.H:251
int global_to_local_rank(int rank) noexcept
Definition: AMReX_ParallelContext.H:98
bool UseGpuAwareMpi()
Definition: AMReX_ParallelDescriptor.H:111
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< dim > adjCellLo(const BoxND< dim > &b, int dir, int len=1) noexcept
Returns the cell centered BoxND of length len adjacent to b on the low end along the coordinate direc...
Definition: AMReX_Box.H:1591
void communicateParticlesStart(const PC &pc, ParticleCopyPlan &plan, const SndBuffer &snd_buffer, RcvBuffer &rcv_buffer)
Definition: AMReX_ParticleCommunication.H:496
BoxND< AMREX_SPACEDIM > Box
Definition: AMReX_BaseFwd.H:27
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE IntVect getParticleCell(P const &p, amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > const &plo, amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > const &dxi) noexcept
Returns the cell index for a given particle using the provided lower bounds and cell sizes.
Definition: AMReX_ParticleUtil.H:374
void unpackRemotes(PC &pc, const ParticleCopyPlan &plan, Buffer &rcv_buffer, UnpackPolicy const &policy)
Definition: AMReX_ParticleCommunication.H:596
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< dim > adjCellHi(const BoxND< dim > &b, int dir, int len=1) noexcept
Similar to adjCellLo but builds an adjacent BoxND on the high end.
Definition: AMReX_Box.H:1612
void communicateParticlesFinish(const ParticleCopyPlan &plan)
Definition: AMReX_ParticleCommunication.cpp:384
Arena * The_Comms_Arena()
Definition: AMReX_Arena.cpp:669
IntVectND< AMREX_SPACEDIM > IntVect
Definition: AMReX_BaseFwd.H:30
int numParticlesOutOfRange(Iterator const &pti, int nGrow)
Returns the number of particles that are more than nGrow cells from the box correspond to the input i...
Definition: AMReX_ParticleUtil.H:34
void RemoveDuplicates(Vector< T > &vec)
Definition: AMReX_Vector.H:190
void unpackBuffer(PC &pc, const ParticleCopyPlan &plan, const Buffer &snd_buffer, UnpackPolicy const &policy)
Definition: AMReX_ParticleCommunication.H:431
void packBuffer(const PC &pc, const ParticleCopyOp &op, const ParticleCopyPlan &plan, Buffer &snd_buffer)
Definition: AMReX_ParticleCommunication.H:332
Definition: AMReX_FabArrayCommI.H:896
Vector< Box > getBoundaryBoxes(const Box &box, int ncells)
Definition: AMReX_NeighborParticlesGPUImpl.H:7
Definition: AMReX_NeighborParticles.H:16
IntVect periodic_shift
Definition: AMReX_NeighborParticles.H:18
int grid_id
Definition: AMReX_NeighborParticles.H:17
Definition: AMReX_NeighborParticles.H:431
Definition: AMReX_ParticleCommunication.H:19