nonblocking.cpp (1856B)
1 #include "IO.h" 2 #include <mpi.h> 3 #include <vector> 4 5 int main(int argc, char *argv[]) 6 { 7 int rank, size; 8 MPI_Init(&argc, &argv); 9 MPI_Comm_rank(MPI_COMM_WORLD, &rank); 10 MPI_Comm_size(MPI_COMM_WORLD, &size); 11 12 // source and destination (periodic boundaries) 13 const int left = (rank + size - 1) % size; 14 const int right = (rank + size + 1) % size; 15 16 const int nsteps = 1000; // number of time steps 17 const int N = 128; // number of cells in subdomain 18 const double Fo = 0.45; // Fourier number 19 std::vector<double> curr(N + 2); // +2 ghost cells 20 std::vector<double> next(N + 2); // +2 ghost cells 21 initialize(curr); 22 auto applyStencil = [&](int i) { 23 next[i] = curr[i] + Fo * (curr[i - 1] - 2.0 * curr[i] + curr[i + 1]); 24 }; 25 for (int step = 0; step < nsteps; ++step) { 26 MPI_Request reqs[4]; 27 // clang-format off 28 MPI_Irecv(&curr[0], 1, MPI_DOUBLE, left, 123, MPI_COMM_WORLD, &reqs[0]); 29 MPI_Irecv(&curr[N + 1], 1, MPI_DOUBLE, right, 123, MPI_COMM_WORLD, &reqs[1]); 30 MPI_Isend(&curr[1], 1, MPI_DOUBLE, left, 123, MPI_COMM_WORLD, &reqs[2]); 31 MPI_Isend(&curr[N], 1, MPI_DOUBLE, right, 123, MPI_COMM_WORLD, &reqs[3]); 32 // clang-format on 33 34 // compute internal domain 35 for (int i = 2; i < N; ++i) { 36 applyStencil(i); 37 } 38 39 // wait for completion 40 MPI_Waitall(4, reqs, MPI_STATUSES_IGNORE); 41 42 // complete boundary 43 applyStencil(1); // left 44 applyStencil(N); // right 45 46 if (step % 200 == 0) { 47 dump_posix(curr); 48 dump_rank(curr); 49 dump_mpi_binary(curr); 50 dump_mpi_ascii(curr); 51 dump_mpi_ascii_ordered(curr); 52 } 53 curr.swap(next); 54 } 55 56 MPI_Finalize(); 57 return 0; 58 }