9#include "Utility/IpplException.h"
11#include "Communicate/Communicator.h"
15 template <
typename T,
unsigned Dim,
class... ViewArgs>
16 HaloCells<T, Dim, ViewArgs...>::HaloCells() {}
18 template <
typename T,
unsigned Dim,
class... ViewArgs>
20 exchangeBoundaries<lhs_plus_assign>(view, layout, HALO_TO_INTERNAL);
23 template <
typename T,
unsigned Dim,
class... ViewArgs>
25 exchangeBoundaries<lhs_plus_assign>(view, layout, HALO_TO_INTERNAL_NOGHOST, nghost);
27 template <
typename T,
unsigned Dim,
class... ViewArgs>
29 exchangeBoundaries<assign>(view, layout, INTERNAL_TO_HALO);
32 template <
typename T,
unsigned Dim,
class... ViewArgs>
35 SendOrder order,
int nghost) {
36 using neighbor_list =
typename Layout_t::neighbor_list;
37 using range_list =
typename Layout_t::neighbor_range_list;
39 auto& comm = layout->comm;
41 const neighbor_list& neighbors = layout->getNeighbors();
42 const range_list &sendRanges = layout->getNeighborsSendRange(),
43 &recvRanges = layout->getNeighborsRecvRange();
45 auto ldom = layout->getLocalNDIndex();
46 for (
const auto& axis : ldom) {
47 if ((axis.length() == 1) && (Dim != 1)) {
48 throw std::runtime_error(
49 "HaloCells: Cannot do neighbour exchange when domain decomposition "
57 const auto domain = layout->getDomain();
58 const auto& ldomains = layout->getHostLocalDomains();
60 size_t totalRequests = 0;
61 for (
const auto& componentNeighbors : neighbors) {
62 totalRequests += componentNeighbors.size();
67 using memory_space =
typename view_type::memory_space;
68 using buffer_type = mpi::Communicator::buffer_type<memory_space>;
69 std::vector<MPI_Request> requests(totalRequests);
71 constexpr size_t cubeCount = detail::countHypercubes(Dim) - 1;
72 size_t requestIndex = 0;
73 for (
size_t index = 0; index < cubeCount; index++) {
74 int tag = mpi::tag::HALO + index;
75 const auto& componentNeighbors = neighbors[index];
76 for (
size_t i = 0; i < componentNeighbors.size(); i++) {
77 int targetRank = componentNeighbors[i];
80 if (order == INTERNAL_TO_HALO) {
86 range = sendRanges[index][i];
87 }
else if (order == HALO_TO_INTERNAL_NOGHOST) {
88 range = recvRanges[index][i];
90 for (
size_t j = 0; j < Dim; ++j) {
91 bool isLower = ((range.lo[j] + ldomains[me][j].first()
92 - nghost) == domain[j].min());
93 bool isUpper = ((range.hi[j] - 1 +
94 ldomains[me][j].first() - nghost)
96 range.lo[j] += isLower * (nghost);
97 range.hi[j] -= isUpper * (nghost);
100 range = recvRanges[index][i];
104 pack(range, view, haloData_m, nsends);
106 buffer_type buf = comm.template getBuffer<memory_space, T>(nsends);
108 comm.isend(targetRank, tag, haloData_m, *buf, requests[requestIndex++], nsends);
109 buf->resetWritePos();
114 for (
size_t index = 0; index < cubeCount; index++) {
115 int tag = mpi::tag::HALO + Layout_t::getMatchingIndex(index);
116 const auto& componentNeighbors = neighbors[index];
117 for (
size_t i = 0; i < componentNeighbors.size(); i++) {
118 int sourceRank = componentNeighbors[i];
121 if (order == INTERNAL_TO_HALO) {
122 range = recvRanges[index][i];
123 }
else if (order == HALO_TO_INTERNAL_NOGHOST) {
124 range = sendRanges[index][i];
126 for (
size_t j = 0; j < Dim; ++j) {
127 bool isLower = ((range.lo[j] + ldomains[me][j].first()
128 - nghost) == domain[j].min());
129 bool isUpper = ((range.hi[j] - 1 +
130 ldomains[me][j].first() - nghost)
132 range.lo[j] += isLower * (nghost);
133 range.hi[j] -= isUpper * (nghost);
136 range = sendRanges[index][i];
139 size_type nrecvs = range.size();
141 buffer_type buf = comm.template getBuffer<memory_space, T>(nrecvs);
143 comm.recv(sourceRank, tag, haloData_m, *buf, nrecvs *
sizeof(T), nrecvs);
146 unpack<Op>(range, view, haloData_m);
150 if (totalRequests > 0) {
151 MPI_Waitall(totalRequests, requests.data(), MPI_STATUSES_IGNORE);
154 comm.freeAllBuffers();
157 template <
typename T,
unsigned Dim,
class... ViewArgs>
160 auto subview = makeSubview(view, range);
162 auto& buffer = fd.buffer;
164 size_t size = subview.size();
166 if (buffer.size() < size) {
167 int overalloc = Comm->getDefaultOverallocation();
168 Kokkos::realloc(buffer, size * overalloc);
171 using index_array_type =
175 KOKKOS_LAMBDA(
const index_array_type& args) {
178 for (
unsigned d1 = 0; d1 < Dim; d1++) {
180 for (
unsigned d2 = 0; d2 < d1; d2++) {
181 next *= subview.extent(d2);
186 buffer(l) =
apply(subview, args);
191 template <
typename T,
unsigned Dim,
class... ViewArgs>
192 template <
typename Op>
195 auto subview = makeSubview(view, range);
196 auto buffer = fd.buffer;
202 using index_array_type =
206 KOKKOS_LAMBDA(
const index_array_type& args) {
209 for (
unsigned d1 = 0; d1 < Dim; d1++) {
211 for (
unsigned d2 = 0; d2 < d1; d2++) {
212 next *= subview.extent(d2);
217 op(
apply(subview, args), buffer(l));
222 template <
typename T,
unsigned Dim,
class... ViewArgs>
224 const bound_type& intersect) {
225 auto makeSub = [&]<
size_t... Idx>(
const std::index_sequence<Idx...>&) {
226 return Kokkos::subview(view,
227 Kokkos::make_pair(intersect.lo[Idx], intersect.hi[Idx])...);
229 return makeSub(std::make_index_sequence<Dim>{});
232 template <
typename T,
unsigned Dim,
class... ViewArgs>
233 template <
typename Op>
237 int myRank = layout->comm.rank();
238 const auto& lDomains = layout->getHostLocalDomains();
239 const auto& domain = layout->getDomain();
241 using exec_space =
typename view_type::execution_space;
242 using index_type =
typename RangePolicy<Dim, exec_space>::index_type;
244 Kokkos::Array<index_type, Dim> ext, begin, end;
246 for (
size_t i = 0; i < Dim; ++i) {
247 ext[i] = view.extent(i);
253 for (
unsigned d = 0; d < Dim; ++d) {
257 if (lDomains[myRank][d].length() == domain[d].length()) {
258 int N = view.extent(d) - 1;
260 using index_array_type =
262 typename view_type::execution_space>::index_array_type;
264 "applyPeriodicSerialDim", createRangePolicy<Dim, exec_space>(begin, end),
265 KOKKOS_LAMBDA(index_array_type & coords) {
273 auto&& left =
apply(view, coords);
276 coords[d] = N - coords[d];
277 auto&& right =
apply(view, coords);
280 coords[d] += 2 * nghost - 1 - N;
281 op(
apply(view, coords), right);
284 coords[d] = N - coords[d];
285 op(
apply(view, coords), left);
Definition FieldLayout.h:166
Definition HaloCells.h:39
void accumulateHalo_noghost(view_type &view, Layout_t *layout, int nghost)
Definition HaloCells.hpp:24
void applyPeriodicSerialDim(view_type &view, const Layout_t *layout, const int nghost)
Definition HaloCells.hpp:234
void pack(const bound_type &range, const view_type &view, databuffer_type &fd, size_type &nsends)
Definition HaloCells.hpp:158
void unpack(const bound_type &range, const view_type &view, databuffer_type &fd)
Definition HaloCells.hpp:193
void accumulateHalo(view_type &view, Layout_t *layout)
Definition HaloCells.hpp:19
void fillHalo(view_type &, Layout_t *layout)
Definition HaloCells.hpp:28
KOKKOS_INLINE_FUNCTION constexpr decltype(auto) apply(const View &view, const Coords &coords)
Definition IpplOperations.h:64
RangePolicy< View::rank, typenameView::execution_space, PolicyArgs... >::policy_type getRangePolicy(const View &view, int shift=0)
Definition ParallelDispatch.h:56
Definition ParallelDispatch.h:24