12#ifndef PECLET_CORE_HALO_GRID_HALO_HPP
13#define PECLET_CORE_HALO_GRID_HALO_HPP
30 static const bool v = [] {
31 const char*
e = std::getenv(
"PECLET_CORE_GPU_AWARE_MPI");
33 e = std::getenv(
"PECLET_CORE_CUDA_AWARE_MPI");
34 return e && std::atoi(
e) != 0;
54 sendRanks_ =
t.sendRanks;
55 recvRanks_ =
t.recvRanks;
56 sendCounts_ =
t.sendCounts;
57 recvCounts_ =
t.recvCounts;
59 sendOff_.assign(sendCounts_.size() + 1, 0);
60 for (std::size_t k = 0; k < sendCounts_.size(); ++k)
61 sendOff_[k + 1] = sendOff_[k] + sendCounts_[k];
62 recvOff_.assign(recvCounts_.size() + 1, 0);
63 for (std::size_t k = 0; k < recvCounts_.size(); ++k)
64 recvOff_[k + 1] = recvOff_[k] + recvCounts_[k];
66 nSend_ =
static_cast<Index>(
t.sendIdx.size());
67 nRecv_ =
static_cast<Index>(
t.recvIdx.size());
68 nSelf_ =
static_cast<Index>(
t.selfSrc.size());
70 d_sendIdx_ =
toDevice(
t.sendIdx,
"peclet::core::halo::sendIdx");
71 d_recvIdx_ =
toDevice(
t.recvIdx,
"peclet::core::halo::recvIdx");
72 d_selfSrc_ =
toDevice(
t.selfSrc,
"peclet::core::halo::selfSrc");
73 d_selfDst_ =
toDevice(
t.selfDst,
"peclet::core::halo::selfDst");
75 View<T>(Kokkos::view_alloc(
"peclet::core::halo::sendBuf", Kokkos::WithoutInitializing),
76 static_cast<std::size_t
>(nSend_));
78 View<T>(Kokkos::view_alloc(
"peclet::core::halo::recvBuf", Kokkos::WithoutInitializing),
79 static_cast<std::size_t
>(nRecv_));
80 h_sendBuf_ = Kokkos::create_mirror_view(d_sendBuf_);
81 h_recvBuf_ = Kokkos::create_mirror_view(d_recvBuf_);
93 "peclet::core::halo::selfCopy", Kokkos::RangePolicy<ExecSpace>(0, nSelf_),
101 Kokkos::parallel_for(
102 "peclet::core::halo::pack", Kokkos::RangePolicy<ExecSpace>(0, nSend_),
105 Kokkos::deep_copy(h_sendBuf_, d_sendBuf_);
113 std::vector<MPI_Request>
reqs;
114 reqs.reserve(recvRanks_.size() + sendRanks_.size());
115 for (std::size_t k = 0; k < recvRanks_.size(); ++k) {
118 recvRanks_[k],
tag, comm_, &
reqs.back());
120 for (std::size_t k = 0; k < sendRanks_.size(); ++k) {
123 sendRanks_[k],
tag, comm_, &
reqs.back());
131 Kokkos::deep_copy(d_recvBuf_, h_recvBuf_);
135 Kokkos::parallel_for(
136 "peclet::core::halo::unpack", Kokkos::RangePolicy<ExecSpace>(0, nRecv_),
144 std::vector<int> sendRanks_, recvRanks_, sendCounts_, recvCounts_;
145 std::vector<int> sendOff_, recvOff_;
146 Index nSend_ = 0, nRecv_ = 0, nSelf_ = 0;
147 IndexView d_sendIdx_, d_recvIdx_, d_selfSrc_, d_selfDst_;
148 View<T> d_sendBuf_, d_recvBuf_;
FlatTopology flatten() const
GPU ghost-layer exchange for a contiguous device field peclet::core::View<T> (one element per extende...
GridHalo & operator=(const GridHalo &)=delete
void exchange(const View< T > &field, int tag=0)
Exchange ghost layers of the device field field. Blocking.
GridHalo(const GridHalo &)=delete
void init(const GridHaloTopology< Dim > &halo)
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).