#include <stdio.h> #include "mpi.h" /* This example handles a 12 x 12 mesh, on 4 processors only. */ #define maxn 12 int main( argc, argv ) int argc; char **argv; { int rank, value, size, errcnt, toterr, i, j; int up_nbr, down_nbr; MPI_Status status; double x[12][12]; double xlocal[(12/4)+2][12]; MPI_Init( &argc, &argv ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); MPI_Comm_size( MPI_COMM_WORLD, &size ); if (size != 4) MPI_Abort( MPI_COMM_WORLD, 1 ); /* xlocal[][0] is lower ghostpoints, xlocal[][maxn+2] is upper */ /* Fill the data as specified */ for (i=1; i<=maxn/size; i++) for (j=0; j<maxn; j++) xlocal[i][j] = rank; for (j=0; j<maxn; j++) { xlocal[0][j] = -1; xlocal[maxn/size+1][j] = -1; } /* Processors 0 and 1 exchange, 2 and 3 exchange, etc. Then 1 and 2 exchange, 3 and 4, etc. The formula for this is if (even) exchng up else down if (odd) exchng up else down */ /* Note the use of xlocal[i] for &xlocal[i][0] */ /* Note that we use MPI_PROC_NULL to remove the if statements that would be needed without MPI_PROC_NULL */ up_nbr = rank + 1; if (up_nbr >= size) up_nbr = MPI_PROC_NULL; down_nbr = rank - 1; if (down_nbr < 0) down_nbr = MPI_PROC_NULL; if ((rank % 2) == 0) { /* exchange up */ MPI_Sendrecv( xlocal[maxn/size], maxn, MPI_DOUBLE, up_nbr, 0, xlocal[maxn/size+1], maxn, MPI_DOUBLE, up_nbr, 0, MPI_COMM_WORLD, &status ); } else { /* exchange down */ MPI_Sendrecv( xlocal[1], maxn, MPI_DOUBLE, down_nbr, 0, xlocal[0], maxn, MPI_DOUBLE, down_nbr, 0, MPI_COMM_WORLD, &status ); } /* Do the second set of exchanges */ if ((rank % 2) == 1) { /* exchange up */ MPI_Sendrecv( xlocal[maxn/size], maxn, MPI_DOUBLE, up_nbr, 1, xlocal[maxn/size+1], maxn, MPI_DOUBLE, up_nbr, 1, MPI_COMM_WORLD, &status ); } else { /* exchange down */ MPI_Sendrecv( xlocal[1], maxn, MPI_DOUBLE, down_nbr, 1, xlocal[0], maxn, MPI_DOUBLE, down_nbr, 1, MPI_COMM_WORLD, &status ); } /* Check that we have the correct results */ errcnt = 0; for (i=1; i<=maxn/size; i++) for (j=0; j<maxn; j++) if (xlocal[i][j] != rank) errcnt++; for (j=0; j<maxn; j++) { if (xlocal[0][j] != rank - 1) errcnt++; if (rank < size-1 && xlocal[maxn/size+1][j] != rank + 1) errcnt++; } MPI_Reduce( &errcnt, &toterr, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD ); if (rank == 0) { if (toterr) printf( "! found %d errors\n", toterr ); else printf( "No errors\n" ); } MPI_Finalize( ); return 0; }