#include #include #include #include #include #include #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) #define TOLERANCE 0.00002 /* termination criterion */ #define MAGIC 0.8 /* magic factor */ int N; /* problem size */ double **G; /* the grid */ double **buff; MPI_Status istatus; MPI_Request ireqs1, ireqs2, ireqr1, ireqr2; int mynode, totalnodes; int jsta, jend, inext, iprev; double *bufs1, *bufr1; double *bufs2, *bufr2; double stopdiff, maxdiff, diff; /* differences btw grid points in iters */ int even (int i) { return !(i & 1); } double stencil (double** G, int row, int col) { return (G[row-1][col] + G[row+1][col] + G[row][col-1] + G[row][col+1] ) / 4.0; } void alloc_grid(double ***Gptr, int N) { int i; double** G = (double**)malloc(N*sizeof(double*)); if ( G == 0 ) { fprintf(stderr, "malloc failed\n"); exit(42); } for (i = 0; i irank) { end = end + 1; } *ista = start; *iend = end; } void exchange(int phase) { int is1 = ((jsta + phase) % 2) + 1; int is2 = ((jend + phase) % 2) + 1; int ir1 = fabs(3 - is1); int ir2 = fabs(3 - is2); int icnt = 0; int icnt1 = 0, icnt2 = 0; int m = N - 1; int i; if (mynode != 0) { icnt1 = 0; for (i = is1; i <= m; i += 2) { bufs1[icnt1] = G[i][jsta]; icnt1 = icnt1 + 1; } } if (mynode != (totalnodes - 1)) { icnt2 = 0; for (i = is2; i <= m; i += 2) { bufs2[icnt2] = G[i][jend]; icnt2 = icnt2 + 1; } } MPI_Isend(bufs1, icnt1, MPI_DOUBLE, iprev, 1, MPI_COMM_WORLD, &ireqs1); MPI_Isend(bufs2, icnt2, MPI_DOUBLE, inext, 1, MPI_COMM_WORLD, &ireqs2); MPI_Irecv(bufr1, N, MPI_DOUBLE, iprev, 1, MPI_COMM_WORLD, &ireqr1); MPI_Irecv(bufr2, N, MPI_DOUBLE, inext, 1, MPI_COMM_WORLD, &ireqr2); MPI_Wait(&ireqs1, &istatus); MPI_Wait(&ireqs2, &istatus); MPI_Wait(&ireqr1, &istatus); MPI_Wait(&ireqr2, &istatus); if (mynode != 0) { icnt = 0; for (i = ir1; i <= m; i += 2) { G[i][jsta - 1] = bufr1[icnt]; icnt = icnt + 1; } } if (mynode != (totalnodes - 1)) { icnt = 0; for (i = ir2; i <= m; i += 2) { G[i][jend + 1] = bufr2[icnt]; icnt = icnt + 1; } } } int main (int argc, char *argv[]) { int ncol,nrow; /* number of rows and columns */ double Gnew,r,omega, /* some float values */ stopdiff,maxdiff,diff; /* differences btw grid points in iters */ int i,j,phase,iteration; /* counters */ int print = 0; double inittime, totaltime; /* Initializing MPI */ MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &totalnodes); MPI_Comm_rank(MPI_COMM_WORLD, &mynode); /* set up problem size */ N = 1000; for(i=1; i maxdiff ) maxdiff = diff; G[i][j] = G[i][j] + omega * (Gnew-G[i][j]); } } } MPI_Allreduce(&maxdiff, &diff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); maxdiff = diff; iteration++; } while (maxdiff > stopdiff); totaltime = MPI_Wtime() - inittime; MPI_Barrier(MPI_COMM_WORLD); if(print == 1) { printf("Node: %d\n", mynode); print_grid(G, N); printf("\n"); } MPI_Finalize(); return 0; }