15#ifndef PECLET_CORE_HALO_PARTICLE_HALO_HPP
16#define PECLET_CORE_HALO_PARTICLE_HALO_HPP
39 sendRanks_ =
t.sendRanks;
40 sendCounts_ =
t.sendCounts;
41 sendOff_ =
t.sendOffsets;
42 recvRanks_ =
t.recvRanks;
43 recvCounts_ =
t.recvCounts;
44 recvOff_.assign(
t.recvOffsets.begin(),
46 nSend_ =
static_cast<Index>(
t.sendIdx.size());
48 numReceived_ =
t.numReceived;
49 numSelf_ = numGhost_ - numReceived_;
50 d_sendIdx_ =
toDevice(
t.sendIdx,
"peclet::core::halo::p_sendIdx");
51 d_selfIdx_ =
toDevice(
t.selfIdx,
"peclet::core::halo::p_selfIdx");
64 "peclet::core::halo::p_gather", Kokkos::RangePolicy<ExecSpace>(0, nSend_),
78 hSend.resize(
static_cast<std::size_t
>(nSend_));
79 hRecv.resize(
static_cast<std::size_t
>(numReceived_));
85 std::vector<MPI_Request>
reqs;
91 if (!
aware && numReceived_) {
92 auto sub = Kokkos::subview(
93 ghost, std::pair<std::size_t, std::size_t>(0,
static_cast<std::size_t
>(numReceived_)));
94 Kokkos::View<const T*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>>
hv(
96 Kokkos::deep_copy(sub,
hv);
105 Kokkos::parallel_for(
106 "peclet::core::halo::p_selfGather", Kokkos::RangePolicy<ExecSpace>(0, numSelf_),
130 hGhost.resize(
static_cast<std::size_t
>(numReceived_));
131 hRecv.resize(
static_cast<std::size_t
>(nSend_));
133 copyToHost(Kokkos::subview(ghost, std::pair<std::size_t, std::size_t>(
134 0,
static_cast<std::size_t
>(numReceived_))),
142 std::vector<MPI_Request>
reqs;
155 Kokkos::parallel_for(
156 "peclet::core::halo::p_scatter", Kokkos::RangePolicy<ExecSpace>(0, nSend_),
165 Kokkos::parallel_for(
166 "peclet::core::halo::p_selfScatter", Kokkos::RangePolicy<ExecSpace>(0, numSelf_),
175 template <
class SrcView,
class T>
176 static void copyToHost(
const SrcView& d, std::vector<T>&
h) {
179 Kokkos::View<T*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>>
hv(
h.data(),
181 Kokkos::deep_copy(
hv, d);
189 View<T> scratchAs(
const char* label) {
190 const std::size_t
bytes =
static_cast<std::size_t
>(nSend_) *
sizeof(
T);
191 if (scratch_.size() <
bytes)
192 scratch_ = Kokkos::View<char*, MemSpace>(
193 Kokkos::view_alloc(std::string(label), Kokkos::WithoutInitializing),
bytes);
194 return View<T>(
reinterpret_cast<T*
>(scratch_.data()),
static_cast<std::size_t
>(nSend_));
197 static void copyToDevice(
const std::vector<T>&
h,
const View<T>& d) {
200 Kokkos::View<const T*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>>
hv(
h.data(),
202 Kokkos::deep_copy(d,
hv);
207 void postRecv(
T*
base,
const std::vector<int>&
ranks,
const std::vector<int>& off,
208 const std::vector<int>&
cnt,
int tag, std::vector<MPI_Request>&
reqs) {
209 for (std::size_t k = 0; k <
ranks.size(); ++k) {
216 void postSend(
T*
base,
const std::vector<int>&
ranks,
const std::vector<int>& off,
217 const std::vector<int>&
cnt,
int tag, std::vector<MPI_Request>&
reqs) {
218 for (std::size_t k = 0; k <
ranks.size(); ++k) {
226 std::vector<int> sendRanks_, sendCounts_, sendOff_;
227 std::vector<int> recvRanks_, recvCounts_, recvOff_;
228 Index nSend_ = 0, numGhost_ = 0, numReceived_ = 0, numSelf_ = 0;
230 Kokkos::View<char*, MemSpace> scratch_;
std::size_t numGhost() const
ParticleHalo & operator=(const ParticleHalo &)=delete
void forward(const View< T > &owned, const View< T > &ghost, int tag=7603)
owned[N] -> ghost[G], verbatim. Both live on the device.
void init(const ParticleHaloTopology< Dim > &halo)
Capture the (already-built) host halo's topology in device-friendly form.
ParticleHalo(const ParticleHalo &)=delete
void reverse(const View< T > &ghost, const View< T > &owned, int tag=7604)
ghost[G] -> owned[N], accumulated (owned += contributions). T must support Kokkos::atomic_add.
int MPI_Waitall(int, MPI_Request *, MPI_Status *)
#define MPI_STATUSES_IGNORE
int MPI_Isend(const void *, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request *)
int MPI_Irecv(void *, int, MPI_Datatype, int, int, MPI_Comm, MPI_Request *)
bool gpuAwareMpi()
Whether to hand DEVICE pointers straight to MPI (GPU-aware MPI) instead of host-staging.
View< T > toDevice(const std::vector< T > &h, const std::string &label)
Upload a host std::vector into a freshly-sized device View (empty vector => empty view).
Kokkos::View< T *, MemSpace > View
1D device array.
Kokkos::View< Index *, MemSpace > IndexView
Device array of grid/particle indices (the matched send/recv/self-copy lists).
std::int64_t Index
Signed index type for grids and particles (supersedes block_decomposer's long int IndxT).