= 4
01 (1+x2)-1 dx by rectangular integration
c++ source ppi.cpp
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <math.h>
#include <mpi.h>
int main(int argc, char *argv[]) {
int n, rank, size ;
double PI25DT = 3.141592653589793238462643;
double mypi, pi, h, sum, x;
MPI::Init(argc, argv) ;
size = MPI::COMM_WORLD.Get_size() ;
rank = MPI::COMM_WORLD.Get_rank() ;
if (rank == 0) { //process 0 gets input
if (argc==2) { //number of intervals is on command line
n = atoi(argv[1]);
} else { //prompt for number of intervals
cout << "Enter the number of intervals: " ;
cin >> n;
}
}
/* share n with all of the processes */
MPI::COMM_WORLD.Bcast(&n, 1, MPI::INT, 0) ;
if (n < 1) {
if (rank==0) cout << "Must specify at least 1 interval (cannot use"
<< " n=" << n << ")." << endl;
MPI::Finalize();
return 1;
}
h = 1.0 / double(n) ;
sum = 0.0;
for (int i = rank + 1; i <= n; i += size) {
x = h * (double(i) - 0.5);
sum += (4.0 / (1.0 + x*x));
}
mypi = h * sum;
MPI::COMM_WORLD.Reduce(&mypi,&pi, 1, MPI::DOUBLE, MPI::SUM, 0) ;
if (rank == 0) {
cout << "pi (" << n << " intervals) is approximately " << pi
<< ", Error is " << fabs(pi - PI25DT) << endl;
}
MPI::Finalize() ;
return 0;
}
MPI::COMM_WORLD.Bcast shares the value of n with all processes in COMM_WORLD.
MPI::COMM_WORLD.Reduce collects results from all processes in COMM_WORLD.
Reduce(&mypi,&pi, 1, MPI::DOUBLE, MPI::SUM, 0) ;
combines values of mypi into pi, both of which are single MPI::DOUBLE variables.
The values of mypi are summed. (Other collective operations are max, min, and product).
The final "0" specifies the process on
which the resulting sum "pi" is to be placed.
compile and link
[psiders@beowulf source]$ mpiCC ppi.cpp
-o ppiC -llammpi++
execute
[psiders@beowulf source]$ mpirun -np 4 ppiC 1000
pi (1000 intervals) is approximately 3.14159, Error is 8.33333e-08