rendered paste body#include <mpi.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/time.h>int main(int argc, char *argv[]){ int numprocs; int myid; double *a, *b, *c; int n = 900000; // horyzon nsteps double time = 0.0001; //, tau = 0.001; int i, j, iter = 0; double k = 0.0001; // heat conduction double h = 1.0 / (n - 1); // horyzon step int remain; double tau = 0.5 * h * h / k; int ncur; // num of horyzon points in cur proc int ncurn = 0; struct timeval before, after; struct { struct timeval x; struct timeval y; } balance[3]; MPI_Status stat; MPI_Init (&argc, &argv); MPI_Comm_size (MPI_COMM_WORLD, &numprocs); MPI_Comm_rank (MPI_COMM_WORLD, &myid); ncur = n / numprocs; remain = n - numprocs * ncur; ncur += 2; while (remain--) if (remain == myid) ncur++; a = (double *) calloc (ncur, sizeof (double)); b = (double *) calloc (ncur, sizeof (double)); bzero (a, ncur * sizeof (double)); bzero (b, ncur * sizeof (double)); if (myid == numprocs - 1) { a[ncur - 2] = 1.0; b[ncur - 2] = 1.0; } if (myid == 0) gettimeofday(&before, NULL); printf ("Time = %f, tau = %f\n", time, tau); while ((time -= tau) > 0) {// printf ("%d %f\n ", myid, time); iter++; if (!(myid % 2)) { if (myid != numprocs - 1) { MPI_Send (&balance[myid].x, 1, MPI_LONG, myid + 1, 0, MPI_COMM_WORLD); MPI_Send (&a[ncur - 2], 1, MPI_DOUBLE, myid + 1, 0, MPI_COMM_WORLD); MPI_Recv (&balance[myid + 1].x, 1, MPI_LONG, myid + 1, 0, MPI_COMM_WORLD, &stat); MPI_Recv (&a[ncur - 1], 1, MPI_DOUBLE, myid + 1, 0, MPI_COMM_WORLD, &stat); } if (myid != 0) { MPI_Send (&balance[myid].x, 1, MPI_LONG, myid - 1, 0, MPI_COMM_WORLD); MPI_Send (&a[1], 1, MPI_DOUBLE, myid - 1, 0, MPI_COMM_WORLD); MPI_Recv (&balance[myid - 1].x, 1, MPI_LONG, myid - 1, 0, MPI_COMM_WORLD, &stat); MPI_Recv (&a[0], 1, MPI_DOUBLE, myid - 1, 0, MPI_COMM_WORLD, &stat); } } else { if (myid != 0) { MPI_Recv (&a[0], 1, MPI_DOUBLE, myid - 1, 0, MPI_COMM_WORLD, &stat); MPI_Recv (&balance[myid - 1].x, 1, MPI_LONG, myid - 1, 0, MPI_COMM_WORLD, &stat); MPI_Send (&a[1], 1, MPI_DOUBLE, myid - 1, 0, MPI_COMM_WORLD); MPI_Send (&balance[myid].x, 1, MPI_LONG, myid - 1, 0, MPI_COMM_WORLD); } if (myid != numprocs - 1) { MPI_Recv (&a[ncur - 1], 1, MPI_DOUBLE, myid + 1, 0, MPI_COMM_WORLD, &stat); MPI_Recv (&balance[myid + 1].x, 1, MPI_LONG, myid + 1, 0, MPI_COMM_WORLD, &stat); MPI_Send (&a[ncur - 2], 1, MPI_DOUBLE, myid + 1, 0, MPI_COMM_WORLD); MPI_Send (&balance[myid].x, 1, MPI_LONG, myid + 1, 0, MPI_COMM_WORLD); } } if (iter == 1000) { iter = -1; gettimeofday(&balance[myid].x, NULL); } if (((ncur == 3) && (myid != 0) && (myid != numprocs - 1)) || ((ncur > 3) && (myid != 0))) b[1] = a[1] + k * tau / h / h * (a[2] + a[0] - 2 * a[1]); for (i = 2; i < ncur - 2; ++i) b[i] = a[i] + k * tau / h / h * (a[i + 1] + a[i - 1] - 2 * a[i]); if ((ncur > 3) && (myid != numprocs - 1)) b[ncur - 2] = a[ncur - 2] + k * tau / h / h * (a[ncur - 1] + a[ncur - 3] - 2 * a[ncur - 2]); c = a; a = b; b = c; if (iter == -1) { iter = 0; gettimeofday(&balance[myid].y, NULL); printf ("%f %ld %ld\n ", time, balance[myid].x.tv_usec, balance[myid].y.tv_usec); } } if(myid == 0) gettimeofday (&after, NULL); if (myid == 0) { ncurn += (ncur - 2); MPI_Send (&ncurn, 1, MPI_INT, myid + 1, 0, MPI_COMM_WORLD); } for (i = 1; i < numprocs - 1; ++i) if (myid == i) { MPI_Recv (&ncurn, 1, MPI_INT, myid - 1, 0, MPI_COMM_WORLD, &stat); ncurn += (ncur - 2); MPI_Send (&ncurn, 1, MPI_INT, myid + 1, 0, MPI_COMM_WORLD); } if (myid == numprocs - 1) { MPI_Recv (&ncurn, 1, MPI_INT, myid - 1, 0, MPI_COMM_WORLD, &stat); ncurn += (ncur - 2); } if (myid == 0) {// for (i = 1; i < ncur - 1; ++i) ;// printf ("b[%d]=%f\n", i + ncurn - ncur + 2 - 1, b[i]); for (j = 1; j < numprocs; ++j) { MPI_Recv (&ncur, 1, MPI_INT, j, 0, MPI_COMM_WORLD, &stat); MPI_Recv ( b, ncur, MPI_DOUBLE, j, 0, MPI_COMM_WORLD, &stat); ncurn += (ncur - 2);// for (i = 1; i < ncur - 1; ++i) ;// printf ("b[%d]=%f\n", i + ncurn - ncur + 2 - 1, b[i]); } } else { MPI_Send (&ncur, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); MPI_Send ( b, ncur, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); } if(myid == 0) { printf ("%ld.%ld\n", after.tv_usec > before.tv_usec ? after.tv_sec - before.tv_sec : after.tv_sec - before.tv_sec - 1, after.tv_usec > before.tv_usec ? after.tv_usec - before.tv_usec : 1000000 - (before.tv_usec - after.tv_usec)); } MPI_Finalize(); return EXIT_SUCCESS;}