Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <stdio.h> // printf
#include <stdlib.h> // EXIT_SUCCESS, srand
#include <math.h> // M_PI, fabs
#include <mpi.h>
#include "pi_shared.h"
int main(int argc, char* argv[]) {
int seed;
int N;
int hits;
int hits_sum;
double my_pi;
int number_of_workers;
int this_worker;
int N_per_worker;
// initialize MPI sybsystem
MPI_Init(&argc,&argv);
// get number of available processes, and a unique id for this process
MPI_Comm_rank(MPI_COMM_WORLD, &this_worker);
MPI_Comm_size(MPI_COMM_WORLD, &number_of_workers);
// get parameters from command line arguments
read_arguments(&seed, &N, argc, argv);
// divide the workload equally among processes
N_per_worker = N / number_of_workers;
N = N_per_worker * number_of_workers;
// generate N_per_worker random coordinates, get number of hits
// (see count_hits() function for details)
// please note that every process will start with a different seed value
hits = count_hits(seed + this_worker, N_per_worker);
// sum hits values from different processes
MPI_Reduce(&hits, &hits_sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
// process the combined result (on root process only)
if(this_worker == 0) {
// estimate PI based on following assumptions
// area of circle = PI * r^2 ~= hits
// area of square around circle = (2 * r)^2 ~= N
// r = 1
my_pi = 4. * ((double) hits_sum / (double) N);
// print seed, N, number_of_workers, result, error
printf("%d\t%d\t%d\t%f\t%f\n", seed, N, number_of_workers, my_pi, fabs(my_pi-M_PI));
}
// cleanly terminate MPI subsystem
MPI_Finalize();
return EXIT_SUCCESS;
}