//============================================================================ // Name : parallel_pi_calc.c // Author : Morteza Zakeri // Version : 1.0.0 // Copyright : All right received. // Description : SERIAL PI CACULATION in C, Ansi-style //============================================================================ #include #include #include // include rand function #define sqr(x) ((x)*(x)) double cal_pi(int darts) { double x_coord, /* x coordinate, between -1 and 1 */ y_coord, /* y coordinate, between -1 and 1 */ pi, /* value of pi */ r; /* random number scaled between 0 and 1 */ int score, /* number of darts that hit circle */ n; score = 0; for (n = 1; n <= darts; n++) { /* generate random numbers for x and y coordinates */ r = (double) rand() / (double) RAND_MAX; x_coord = (2.0 * r) - 1.0; r = (double) rand() / (double) RAND_MAX; y_coord = (2.0 * r) - 1.0; /* if dart lands in circle, increment score */ if ((sqr(x_coord) + sqr(y_coord)) <= 1.0) score++; } /* calculate pi */ pi = 4.0 * (double) score / (double) darts; return (pi); } #define DARTS 100000 /* number of throws at dartboard */ #define ROUNDS 100 /* number of times "darts" is iterated */ #define MASTER 0 /* master process ID */ int main(int argc, char *argv[]) { double home_pi, /* value of pi calculated by current task */ pi, /* average of pi after "darts" is thrown */ avepi, /* average pi value for all iterations */ pirecv, /* pi received from worker */ pisum; /* sum of workers pi values */ int taskid, /* process ID or task ID */ numtasks, /* number of process */ source, /* source of incoming message */ mtype, /* message type */ rc, /* return code */ i, n; MPI_Status status; /* Obtain number of tasks and task ID */ MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); MPI_Comm_rank(MPI_COMM_WORLD, &taskid); printf("MPI task %d has started \n", taskid); /* Set seed for random number generator equal to task ID */ srandom(taskid); avepi = 0; for (i = 0; i < ROUNDS; i++) { /* All proccess calculate pi using dartboard algorithm */ home_pi = cal_pi(DARTS); /* Workers send homepi to master */ /* - Message type will be set to the iteration count */ if (taskid != MASTER) { //do in slaves mtype = i; rc = MPI_Send(&home_pi, 1, MPI_DOUBLE, MASTER, mtype,MPI_COMM_WORLD); if (rc != MPI_SUCCESS) { printf("%d: Send failure on round %d\n", taskid, mtype); } } else { //do in master mtype = i; pisum = 0; for (n = 1; n < numtasks; n++) { rc = MPI_Recv(&pirecv, 1, MPI_DOUBLE, MPI_ANY_SOURCE, mtype,MPI_COMM_WORLD, &status); if (rc != MPI_SUCCESS) printf("%d: Receive failure on round %d\n", taskid, mtype); /* keep running total of pi */ pisum = pisum + pirecv; } /* Master calculates the average value of pi for this iteration */ pi = (pisum + home_pi) / numtasks; /* Master calculates the average value of pi over all iterations */ avepi = ((avepi * i) + pi) / (i + 1); printf(" After %4d rounds, average value of PI is: %10.8f\n", ((i + 1)), avepi); } } if (taskid == MASTER) printf("Real value of PI: 3.1415926535897 \n"); MPI_Finalize(); return 0; }