I write a serial program to calculate pi from tan(pi/4)=1 => pi = 4*(1/1+x^2) using the integral representation of arctan. Therefore, we can evaluate pi as the integral of f(x) from 0 to 1 with f(x)=4*(1/1+x*x). The integral is approximated by a sum of N intervals.
The number of intervals N should be read from stdin, and N and pi should be written to stdout. Parallelize this program with MPI, so that only the MPI process with rank=0 reads N from stdin and then distributes this information to all other processes. In the end only the MPI process with rank=0 should write size, N, and pi to stdout.
I didn't understand the following part, like how to assign the computation in the processes like this?
Pay attendion how you distribute the work & data, please program both options: n=0,1,2,3,4,5,6,7,... N-1 -> the intervals
1.a: p=0,1,2,3,0,1,2,3, ... -> process that computes this interval, here with size 4
1.b: p=0,0,0 ..., 1,1,1 ..., 2,2,2 ..., 3,3,3 ... -> process that computes this interval Which one is the better option and why?
#include <mpi.h>
#include <stdio.h>
#include <math.h>
double f(double a)
{
return (4.0 / (1.0 + a * a));
}
int main(int argc, char* argv[])
{
int done = 0, n, myid, numprocs, i;
double PI25DT = 3.141592653589793238462643;
double mypi, pi, h, sum, x;
double startwtime = 0.0, endwtime;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Get_processor_name(processor_name, &namelen);
fprintf(stderr, "Process %d on %s\n",
myid, processor_name);
n = 0;
while (!done)
{
if (myid == 0)
{
printf("Enter the number of intervals: (0 quits) ");
scanf("%d",&n);
if (n == 0)
n = 1024 * numprocs;
else
n = 0;
startwtime = MPI_Wtime();
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (n == 0)
done = 1;
else
{
h = 1.0 / (double)n;
sum = 0.0;
for (i = myid + 1; i <= n; i += numprocs)
{
x = h * ((double)i - 0.5);
sum += f(x);
}
mypi = h * sum;
MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (myid == 0)
{
printf("pi is approximately %.16f, Error is %.16f\n",
pi, fabs(pi - PI25DT));
endwtime = MPI_Wtime();
printf("wall clock time = %f\n",
endwtime - startwtime);
}
}
}
MPI_Finalize();
return 0;
}
scanf issue
After creating the executable file, I run the program:
mpiexec -n 4 .\pi.exe
And the program was stuck after printing this:
Process 3 on DESKTOP-2E69SSG
Process 2 on DESKTOP-2E69SSG
Process 1 on DESKTOP-2E69SSG
Process 0 on DESKTOP-2E69SSG
I couldn't understand why it was stuck. I add #define _CRT_SECURE_NO_DEPRECATE because it shows warning for scanf
Warning C6031 Return value ignored: 'scanf'.
If I comment out the scanf part, then the program run as expected,
Process 3 on DESKTOP-2E69SSG
Process 2 on DESKTOP-2E69SSG
Process 1 on DESKTOP-2E69SSG
Process 0 on DESKTOP-2E69SSG
pi is approximately 3.1415926585568474, Error is 0.0000000049670543
wall clock time = 0.001012
second part
I actually don't understand the second part of that question. Like how I distribute the calculation on processes like the mentioned pattern? One way would be for the 1.a: p=0,1,2,3,0,1,2,3, ... -> process that computes this interval,
for (int i = 0; i < size; i++)
{
if (i == rank) {
// do stuff
}
MPI_Barrier(MPI_COMM_WORLD);
}
How to resolve these issues?
Thanks in advance.