15 template <
typename T,
unsigned Dim,
class... ViewArgs>
18 template <
typename T,
unsigned Dim,
class... ViewArgs>
23 template <
typename T,
unsigned Dim,
class... ViewArgs>
27 template <
typename T,
unsigned Dim,
class... ViewArgs>
32 template <
typename T,
unsigned Dim,
class... ViewArgs>
39 auto& comm = layout->
comm;
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 "
60 size_t totalRequests = 0;
61 for (
const auto& componentNeighbors : neighbors) {
62 totalRequests += componentNeighbors.size();
67 using memory_space =
typename view_type::memory_space;
69 std::vector<MPI_Request> requests(totalRequests);
72 size_t requestIndex = 0;
73 for (
size_t index = 0; index < cubeCount; index++) {
75 const auto& componentNeighbors = neighbors[index];
76 for (
size_t i = 0; i < componentNeighbors.size(); i++) {
77 int targetRank = componentNeighbors[i];
86 range = sendRanges[index][i];
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];
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++) {
116 const auto& componentNeighbors = neighbors[index];
117 for (
size_t i = 0; i < componentNeighbors.size(); i++) {
118 int sourceRank = componentNeighbors[i];
122 range = recvRanges[index][i];
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];
141 buffer_type buf = comm.template getBuffer<memory_space, T>(nrecvs);
143 comm.recv(sourceRank, tag,
haloData_m, *buf, nrecvs *
sizeof(
T), nrecvs);
150 if (totalRequests > 0) {
151 MPI_Waitall(totalRequests, requests.data(), MPI_STATUSES_IGNORE);
154 comm.freeAllBuffers();
157 template <
typename T,
unsigned Dim,
class... ViewArgs>
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>
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>
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>
239 const auto& domain = layout->
getDomain();
241 using exec_space =
typename view_type::execution_space;
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;
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);
void unpack(const ippl::NDIndex< 3 > intersect, const Kokkos::View< Tf *** > &view, ippl::detail::FieldBufferData< Tb > &fd, int nghost, const ippl::NDIndex< 3 > ldom, bool x=false, bool y=false, bool z=false)
void pack(const ippl::NDIndex< 3 > intersect, Kokkos::View< Tf *** > &view, ippl::detail::FieldBufferData< Tb > &fd, int nghost, const ippl::NDIndex< 3 > ldom, ippl::mpi::Communicator::size_type &nsends)
KOKKOS_INLINE_FUNCTION constexpr decltype(auto) apply(const View &view, const Coords &coords)
RangePolicy< Dim, PolicyArgs... >::policy_type createRangePolicy(const Kokkos::Array< typename RangePolicy< Dim, PolicyArgs... >::index_type, Dim > &begin, const Kokkos::Array< typename RangePolicy< Dim, PolicyArgs... >::index_type, Dim > &end)
RangePolicy< View::rank, typenameView::execution_space, PolicyArgs... >::policy_type getRangePolicy(const View &view, int shift=0)
KOKKOS_INLINE_FUNCTION Vector< T, Dim > min(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
void parallel_for(const std::string &name, const ExecPolicy &policy, const FunctorType &functor)
std::unique_ptr< mpi::Communicator > Comm
KOKKOS_INLINE_FUNCTION constexpr unsigned int countHypercubes(unsigned int dim)
bool isUpper(unsigned int face)
int rank() const noexcept
std::shared_ptr< archive_type< MemorySpace > > buffer_type
auto makeSubview(const view_type &view, const bound_type &intersect)
void accumulateHalo_noghost(view_type &view, Layout_t *layout, int nghost)
typename detail::ViewType< T, Dim, ViewArgs... >::view_type view_type
databuffer_type haloData_m
void applyPeriodicSerialDim(view_type &view, const Layout_t *layout, const int nghost)
@ HALO_TO_INTERNAL_NOGHOST
void pack(const bound_type &range, const view_type &view, databuffer_type &fd, size_type &nsends)
FieldLayout< Dim > Layout_t
void exchangeBoundaries(view_type &view, Layout_t *layout, SendOrder order, int nghost=1)
FieldBufferData< T, ViewArgs... > databuffer_type
void unpack(const bound_type &range, const view_type &view, databuffer_type &fd)
typename Layout_t::bound_type bound_type
void accumulateHalo(view_type &view, Layout_t *layout)
void fillHalo(view_type &, Layout_t *layout)
const neighbor_list & getNeighbors() const
const host_mirror_type getHostLocalDomains() const
const NDIndex< Dim > & getDomain() const
std::array< rank_list, detail::countHypercubes(Dim) - 1 > neighbor_list
const NDIndex_t & getLocalNDIndex() const
std::array< bounds_list, detail::countHypercubes(Dim) - 1 > neighbor_range_list
const neighbor_range_list & getNeighborsSendRange() const
const neighbor_range_list & getNeighborsRecvRange() const
static int getMatchingIndex(int index)
::ippl::Vector< index_type, Dim > index_array_type
typename policy_type::array_index_type index_type