| [5773b57e] | 1 | /*
|
|---|
| 2 | MPI example program that computes the value of Pi using a Monte Carlo
|
|---|
| 3 | simulation. The program samples points inside the rectangle delimited
|
|---|
| 4 | by (0,0) and (1,1) and counts how many of these are within a circle
|
|---|
| 5 | with a radius of 1. The ratio between the number of points inside the
|
|---|
| 6 | circle and the total number of samples is Pi/4.
|
|---|
| 7 |
|
|---|
| 8 | Compile with mpicc -O3 cpi_mc.c -o cpi_mc
|
|---|
| 9 | */
|
|---|
| 10 |
|
|---|
| 11 | #include "mpi.h"
|
|---|
| 12 | #include <stdio.h>
|
|---|
| 13 | #include <stdlib.h>
|
|---|
| 14 | #include <unistd.h>
|
|---|
| 15 | #include <math.h>
|
|---|
| 16 |
|
|---|
| 17 | int main(int argc,char *argv[])
|
|---|
| 18 | {
|
|---|
| 19 | const double PI24 = 3.141592653589793238462643;
|
|---|
| 20 |
|
|---|
| 21 | int n, myid, numprocs, i;
|
|---|
| 22 | double pi, maxval;
|
|---|
| 23 | double sum_n, in_circle, sum_c;
|
|---|
| 24 | double starttime, endtime;
|
|---|
| 25 |
|
|---|
| 26 | MPI_Init(&argc,&argv);
|
|---|
| 27 | MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
|
|---|
| 28 | MPI_Comm_rank(MPI_COMM_WORLD,&myid);
|
|---|
| 29 |
|
|---|
| 30 | maxval = (double)RAND_MAX; /* The largest value returned by random() */
|
|---|
| 31 | srandom(myid); /* Seed the random number generator */
|
|---|
| 32 |
|
|---|
| 33 | /* Read the number of random samples in each process */
|
|---|
| 34 | if (myid == 0) {
|
|---|
| 35 | printf("Give number of samples in each process: \n"); fflush(stdout);
|
|---|
| 36 | scanf("%d", &n);
|
|---|
| 37 | }
|
|---|
| 38 | /* Send n to all proceses */
|
|---|
| 39 | MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|---|
| 40 | if (myid == 0)
|
|---|
| 41 | printf("Number of samples is %d\n", n);
|
|---|
| 42 | fflush(stdout);
|
|---|
| 43 |
|
|---|
| 44 | /* Start measuring time */
|
|---|
| 45 | if (myid == 0) starttime = MPI_Wtime();
|
|---|
| 46 |
|
|---|
| 47 | in_circle = 0.0;
|
|---|
| 48 |
|
|---|
| 49 | /* Draw n random points and count how many are inside the circle */
|
|---|
| 50 | for (i=0; i<n; i++) {
|
|---|
| 51 | double x, y, dist;
|
|---|
| 52 | x = (double)random()/maxval; /* Draw a random point */
|
|---|
| 53 | y = (double)random()/maxval;
|
|---|
| 54 | dist = sqrt(x*x+y*y); /* Compute distance of the point (x,y) to origo */
|
|---|
| 55 | if (dist<=1.0) in_circle++; /* Count how many points are inside the circle */
|
|---|
| 56 | }
|
|---|
| 57 |
|
|---|
| 58 | /* Sum all the samples inside the circle */
|
|---|
| 59 | MPI_Reduce(&in_circle, &sum_c, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
|
|---|
| 60 |
|
|---|
| 61 | if (myid == 0) {
|
|---|
| 62 | sum_n = (double) (n*numprocs); /* Total nr of random points */
|
|---|
| 63 | pi = (sum_c/sum_n)*4.0;
|
|---|
| 64 | endtime = MPI_Wtime();
|
|---|
| 65 | printf("The computed value of Pi is %2.24f\n", pi);
|
|---|
| 66 | printf("The \"exact\" value of Pi is %2.24f\n", PI24);
|
|---|
| 67 | printf("The difference is %e\n", fabs(PI24-pi));
|
|---|
| 68 | printf("Wall clock time = %f s\n", endtime-starttime);
|
|---|
| 69 | fflush(stdout);
|
|---|
| 70 | }
|
|---|
| 71 |
|
|---|
| 72 | MPI_Finalize();
|
|---|
| 73 | exit(0);
|
|---|
| 74 | }
|
|---|