C to calculate pi and find error between calculated pi and actual pi

Hi, my first time writing in C to calculate pi and get the error from the actual pi, I have to write it with MPI, whenever I change the input from scanf to fgets() it will start outputting 2 times. But if it in scanf() it will output the wrong number but with only 1 output

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <math.h> //include files
#include <stdio.h>
#include "mpi.h"
void printit()
{
   printf("\n*********************************\n");
   printf("Welcome to the pi calculator!\n");
   printf("Programmer: K. Spry\n");
   printf("You set the number of divisions\n");
   printf("for estimating the integral: \n\tf(x)=4/(1+x^2)");
   printf("\n");
   printf("*********************************\n");
}                      //end printit
                                                          //function prototypes

int main(int argc, char* argv[])
{
   double actual_pi = 3.141592653589793238462643;
   char response = 'y';                                                                            //for comparison later
   int n, rank, num_proc, i;
   double temp_pi, calc_pi, int_size, part_sum, x;

   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Comm_size(MPI_COMM_WORLD, &num_proc);
   if (rank == 0)
   {
        printit();
   }             /* I am root node, print out welcome */

   while (response == 'y')
   {
      if (rank == 0)
      {            /*I am root node*/
         printf("__________________________________\n");
         printf("\nEnter the number of intervals: (0 will exit)\n");
         scanf("%d",&n);
      }
      else
      {
         n = 0;
      }

      MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);     //broadcast n
      if (n==0)
      {
         break;
      } //check for quit condition

      else
      {
         int_size = 1.0 / (double) n;                  //calcs interval size
         part_sum = 0.0;

         for (i = rank * n / num_proc; i <= (rank + 1)* n / num_proc; i += 1)
         {                                                         //calcs partial sums
              x = int_size * ((double)i - 0.5);
              part_sum += (4.0 / (1.0 + x*x));
	 }
         temp_pi = int_size * part_sum;
                                       //collects all partial sums computes pi

         MPI_Reduce(&temp_pi,&calc_pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
         if (rank == 0)
         {                                                     /*I am server*/
            printf("pi is approximately %f", calc_pi);
            printf(". Error is %f", fabs(calc_pi - actual_pi));
            printf("\n");
            printf("_______________________________________");
         }
      }
   }                                                            //end else
   MPI_Finalize();                                              //terminate MPI
   return 0;
}
@silver11235,
My implementation of MPI (mpich) didn't like scanf either. I switched to c++-style input (see the code below) and it worked. I have never used C-style input with MPI, I'm afraid.

If you have set your heart on using printf and scanf, then try flushing stdout with
fflush( stdout );
between your lines 36 and 37. See
https://stackoverflow.com/questions/28848998/mpi-program-hanged-at-scanf


Note that, besides this, you have minor and unrelated problems with your numerical integration which WILL cause an inaccurate answer:
- It should be <, not <= on your line 55
- On your line 57 the mid-ordinate requires +0.5, not -0.5. Otherwise the first ordinate for the root processor (rank=0) will give you a negative x, which is not part of your [0,1] interval.

Note also that, unless your number of intervals is a multiple of the number of processors, you will suffer from integer division problems on your line 55 (line 53 in the program below). Either make this clear to the user, or let the last processor close up the number of intervals correctly.

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <cmath>
#include <iostream>
#include "mpi.h"
using namespace std;


void printit()
{
   cout << "\n*********************************\n";
   cout << "Welcome to the pi calculator!\n";
   cout << "Programmer: *******\n";
   cout << "You set the number of divisions\n";
   cout << "for estimating the integral: \n  f(x)=4/(1+x^2)";
   cout << "\n";
   cout << "*********************************\n";
}
 

int main( int argc, char* argv[] )
{
   double actual_pi = 3.141592653589793238462643;
   int n, rank, num_proc, i;
   double temp_pi, calc_pi, int_size, part_sum, x;

   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Comm_size(MPI_COMM_WORLD, &num_proc);
   if (rank == 0) printit();

   while( true )
   {
      if ( rank == 0 )
      {     
         cout << "__________________________________\n";
         cout << "\nEnter the number of intervals: (0 will exit)\n";
         cin >> n;
      }
      else
      {
         n = 0;
      }

      MPI_Bcast( &n, 1, MPI_INT, 0, MPI_COMM_WORLD );
      if ( n==0 )
      {
         break;
      }
      else
      {
         int_size = 1.0 / n;
         part_sum = 0.0;

         for ( i = rank * n / num_proc; i < (rank + 1) * n / num_proc; i += 1)    // *** NOTE CORRECTION: < not <=
         {                                                    
            x = int_size * ( i + 0.5 );                                           // *** NOTE CORRECTION: +, not -
            part_sum += (4.0 / (1.0 + x*x));
         }
         temp_pi = int_size * part_sum;
                                       
         MPI_Reduce(&temp_pi,&calc_pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
         if ( rank == 0 )
         {                                                    
            cout << "pi is approximately " << calc_pi;
            cout << ". Error is " << abs( calc_pi - actual_pi );                  // *** Just use abs, not fabs
            cout << "\n";
            cout << "_______________________________________";
         }
      }
   }                    
   MPI_Finalize();      
   return 0;
}


mpiexec -n 8 temp.exe

*********************************
Welcome to the pi calculator!
Programmer: *******
You set the number of divisions
for estimating the integral: 
  f(x)=4/(1+x^2)
*********************************
__________________________________

Enter the number of intervals: (0 will exit) 256
pi is approximately 3.14159. Error is 1.27157e-06
_________________________________________________________________________

Enter the number of intervals: (0 will exit) 1024
pi is approximately 3.14159. Error is 7.94729e-08
_________________________________________________________________________

Enter the number of intervals: (0 will exit) 0
Last edited on
Topic archived. No new replies allowed.