Sample solution

Content

template<typename T, template<typename> class Matrix,
   Require<Ge<Matrix<T>>> = true>
void exchange_with_neighbors(Matrix<T>& A,
      /* ranks of the neighbors */
      int previous, int next,
      /* data type for an inner row, i.e. without the border */
      MPI_Datatype rowtype) {
   MPI_Request requests[4]; int request_index = 0;
   MPI_Irecv(&A(0, 1), 1, rowtype, previous, 0,
      MPI_COMM_WORLD, &requests[request_index++]);
   MPI_Irecv(&A(A.numRows()-1, 1), 1, rowtype, next, 0,
      MPI_COMM_WORLD, &requests[request_index++]);
   MPI_Isend(&A(1, 1), 1, rowtype, previous, 0,
      MPI_COMM_WORLD, &requests[request_index++]);
   MPI_Isend(&A(A.numRows()-2, 1), 1, rowtype, next, 0,
      MPI_COMM_WORLD, &requests[request_index++]);

   for (auto& request: requests) {
      MPI_Status status;
      MPI_Wait(&request, &status);
   }
}
theon$ mpic++ -g -O3 -std=c++17 \
>    -I/home/numerik/pub/pp/ss19/lib \
>    $(pkg-config --cflags gdk-pixbuf-2.0) \
>    -o jacobi jacobi.cpp $(pkg-config --libs gdk-pixbuf-2.0)
theon$ mpic++ -g -O3 -std=c++17 \
>    -I/home/numerik/pub/pp/ss19/lib \
>    $(pkg-config --cflags gdk-pixbuf-2.0) \
>    -o jacobi-nb jacobi-nb.cpp $(pkg-config --libs gdk-pixbuf-2.0)
theon$ time mpirun -np 4 jacobi
5080 iterations

real	0m1.953s
user	0m3.006s
sys	0m1.569s
theon$ time mpirun -np 4 jacobi-nb
5090 iterations

real	0m1.291s
user	0m2.534s
sys	0m1.139s
theon$