136 if (status != MPI_CART) {
138 __FILE__, __func__, __LINE__,
139 "Cartesian MPI communicator required, passed communicator not "
148 this->periodicity.data(), this->local_coords.data());
154 for (
int i = 0; i < dim; ++i) {
160 if (std::is_same<T, double>::value)
161 MPIDataTypeT = MPI_DOUBLE;
162 else if (std::is_same<T, float>::value)
163 MPIDataTypeT = MPI_FLOAT;
164 else if (std::is_same<T, int>::value)
165 MPIDataTypeT = MPI_INT;
166 else if (std::is_same<T, long>::value)
167 MPIDataTypeT = MPI_LONG;
170 if (std::is_same<W, double>::value)
171 MPIDataTypeW = MPI_DOUBLE;
172 else if (std::is_same<W, float>::value)
173 MPIDataTypeW = MPI_FLOAT;
174 else if (std::is_same<W, int>::value)
175 MPIDataTypeW = MPI_INT;
176 else if (std::is_same<W, long>::value)
177 MPIDataTypeW = MPI_LONG;
180 int rank_left, rank_right;
183 for (
int i = 0; i < dim; ++i) {
184 MPI_Cart_shift(this->
globalComm, i, 1, &rank_left, &rank_right);
185 neighbors.push_back(rank_left);
186 neighbors.push_back(rank_right);
187 nNeighbors[2 * i] = 1;
188 nNeighbors[2 * i + 1] = 1;
194 std::vector<Point<T>> newVertices = this->
vertices;
197 bool localIsSum = reductionMode == MPI_SUM;
198 bool localIsMax = reductionMode == MPI_MAX;
201 for (
int i = 0; i < dim; ++i) {
204 MPI_Allreduce(this->
getWork().data(), &work_local_plane, 1, MPIDataTypeW,
205 reductionMode, communicators.at(i));
213 int rank_left, rank_right;
215 MPI_Cart_shift(this->
globalComm, i, 1, &rank_left, &rank_right);
218 MPI_Request sreq, rreq;
219 MPI_Status sstat, rstat;
221 MPI_Irecv(&remote_work, 1, MPIDataTypeW, rank_right, 0, this->
globalComm,
223 MPI_Isend(&work_local_plane, 1, MPIDataTypeW, rank_left, 0,
225 MPI_Wait(&sreq, &sstat);
226 MPI_Wait(&rreq, &rstat);
232 MPI_Irecv(&remote_size, 1, MPIDataTypeT, rank_right, 0, this->
globalComm,
234 MPI_Isend(&local_size, 1, MPIDataTypeT, rank_left, 0, this->
globalComm,
236 MPI_Wait(&sreq, &sstat);
237 MPI_Wait(&rreq, &rstat);
243 std::max(4.1, 2.0 * (1.0 + std::max(local_size, remote_size) /
244 std::min(local_size, remote_size)));
248 rank_right, this->
local_coords.at(i), this->global_dims.at(i),
249 work_local_plane, remote_work, local_size, remote_size, this->gamma,
253 T remote_shift = (T)0;
255 MPI_Irecv(&remote_shift, 1, MPIDataTypeT, rank_left, 0, this->
globalComm,
257 MPI_Isend(&shift, 1, MPIDataTypeT, rank_right, 0, this->
globalComm, &sreq);
258 MPI_Wait(&sreq, &sstat);
259 MPI_Wait(&rreq, &rstat);
262 if (rank_left != MPI_PROC_NULL && this->
local_coords[i] != 0)
263 newVertices.at(0)[i] = this->
prevVertices.at(0)[i] + remote_shift;
268 if (rank_right != MPI_PROC_NULL &&
270 newVertices.at(1)[i] = this->
prevVertices.at(1)[i] + shift;
T borderShift1d(const int remote_rank, const int local_coord, const int global_dim, const W local_work, const W remote_work, const T local_size, const T remote_size, const T gamma, const T minSize)