program int_pi2
c
c For API
c
c This simple program approximates pi by computing pi = integral
c from 0 to 1 of 4/(1+x*x)dx which is approximated by sum from
c k=1 to N of 4 / ((1 + (k-1/2)**2 ).  The only input data required is N.
c
c Parallel version number 2:                 (int_pi2.f)
c RLF 4/6/93 17:00
c revised: 6/4/93 riordan
c Completely parallelized version
c Converted to MPI: 11/12/94 by Xianneng Shen
c
       include "mpif.h"
       integer ierr, status(MPI_STATUS_SIZE)
       real err, f, pi, sum, w
       integer i, N, info, mynum, nprocs, source, dest, type
       integer nbytes, len, dontcare, nbuf(4)
       f(x) = 4.0/(1.0+x*x)
       pi = 4.0*atan(1.0)
       N = 1000
       print *,'Approximation intervals, N, is set to 1000'


       dest = 0
       type = 2
       len = 4
       nbytes = 0

c All instances call the startup routine to get their instance number (mynum)
       call MPI_INIT(ierr)
       call MPI_COMM_RANK(MPI_COMM_WORLD, mynum, ierr)
       call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)

c -------  Each new approximation to pi begins here. -------------------

c Do the computation in N steps
c Parallel Version: there are "nprocs" instances participating.  Each
c instance should do 1/nprocs of the calculation.  Since we want
c i = 1..n but mynum = 0, 1, 2..., we start off with mynum+1.

       w = 1.0/N
       sum = 0.0
       do i = mynum+1,N,nprocs
  sum = sum + f((i-0.5)*w)
       enddo
       sum = sum * w

c Print the results 
c (Parallel version: collect partial results and let master instance print it)
       if (mynum.eq.0) then
  print *,'host calculated x=',sum
  do i = 1,nprocs-1
             nbytes = len
             call MPI_RECV(x, 1, MPI_REAL, MPI_ANY_SOURCE,
     .        type, MPI_COMM_WORLD, status, ierr)
             print *,'host got x=',x
     sum=sum+x
  enddo
          err = sum - pi
          print *, 'sum, err =', sum, err
c Other instances just send their sum and go back to 5 and wait for more input
       else
          call MPI_SEND(sum, 1, MPI_REAL, dest, type,
     .       MPI_COMM_WORLD, ierr)
  print *,'instance',mynum,' sent partial sum',sum,
     .            ' to instance 0'
       endif
       call MPI_FINALIZE(ierr)
       end