/* Program pilul.c */ #include "mpi.h" #include #include int main( int argc, char *argv[] ) { int n, myid, numprocs, i; double PI25DT = 3.141592653589793238462643; double mypi, pi, h, sum, x; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&numprocs); MPI_Comm_rank(MPI_COMM_WORLD,&myid); MPI_Win winn, winpi; if (myid == 0) { /* Two windows, one for n and one for pi */ MPI_Win_create(&n,sizeof(int),sizeof(int), MPI_INFO_NULL,MPI_COMM_WORLD,&winn); MPI_Win_create(&pi,sizeof(double), sizeof(double),MPI_INFO_NULL,MPI_COMM_WORLD,&winpi); } else { MPI_Win_create(NULL,0,sizeof(int), MPI_INFO_NULL,MPI_COMM_WORLD,&winn); MPI_Win_create(NULL,0,sizeof(double), MPI_INFO_NULL,MPI_COMM_WORLD,&winpi); } while (1) { if (myid == 0) { printf("Enter the number of intervals: (0 quits) "); scanf("%d",&n); pi = 0; } /* Sync here so all processes get n AFTER it is input */ MPI_Barrier(MPI_COMM_WORLD); /* (Alternative: rank 0 could do a put to each rank here) */ if (myid > 0) { MPI_Win_lock(MPI_LOCK_SHARED,0,0,winn); MPI_Get(&n,1,MPI_INT,0,0,1,MPI_INT,winn); MPI_Win_unlock(0,winn); } if (n == 0) break; else { h = 1.0 / (double) n; sum = 0.0; for (i = myid + 1; i <= n; i += numprocs) { x = h * ((double)i - 0.5); sum += (4.0 / (1.0 + x*x)); } mypi = h * sum; if (myid > 0) { /* Send pi for summing into buffer on rank 0 */ MPI_Win_lock(MPI_LOCK_SHARED,0,0,winpi); MPI_Accumulate(&mypi,1,MPI_DOUBLE,0,0,1,MPI_DOUBLE, MPI_SUM,winpi); MPI_Win_unlock(0,winpi); } /* Sync here so rank 0 adds mypi to pi last of all */ MPI_Barrier(MPI_COMM_WORLD); if (myid == 0) { pi += mypi; printf("pi is approximately %.16f, Error is %.16f\n", pi, fabs(pi - PI25DT)); } } } MPI_Finalize(); return 0; }