C ------------------------------------------------------------------------
C pi_reduce.f
C FILES: pi_reduce.f, dboard.f, make.pi.f
C DESCRIPTION: MPI pi calculation example program. Fortran version.
C This program calculates pi using a "dartboard" algorithm. See
C Fox et al.(1988) Solving Problems on Concurrent Processors, vol.1
C page 207. All processes contribute to the calculation, with the
C master averaging the values for pi.
C
C SPMD Version: Conditional statements check if the process is the
C master or a worker.
C
C This version uses mpi_reduce to collect results
C
C AUTHOR: Roslyn Leibensperger (C program for PVM).
C REVISED: 05/11/93 Blaise Barney Ported to Fortran.
C 06/01/93 R. Leibensperger Ported to API.
C 01/10/94 S. Pendell Changed API to MPL.
C 05/18/94 R. Leibensperger Correction to comments.
C CONVERTED TO MPI: 11/12/94 by Xianneng Shen.
C ------------------------------------------------------------------------
C Explanation of constants and variables used in this program:
C DARTS = number of throws at dartboard
C ROUNDS = number of times "DARTS" is iterated
C MASTER = task ID of master task
C mytid = task ID of current task
C nproc = number of tasks
C homepi = value of pi calculated by current task
C pisum = sum of tasks' pi values
C pi = average of pi for this iteration
C avepi = average pi value for all iterations
C seednum = seed number - based on mytid
C sbytes = size of message being sent
C ------------------------------------------------------------------------
program pi_reduce
include 'mpif.h'
integer DARTS, ROUNDS, MASTER
parameter(DARTS = 5000)
parameter(ROUNDS = 10)
parameter(MASTER = 0)
integer ierr
integer mytid, nproc, sbytes, i
real*4 seednum
real*8 homepi, pi, avepi, pisum, dboard
C Obtain number of tasks and task ID
call mpi_init(ierr)
call mpi_comm_rank(MPI_COMM_WORLD, mytid, ierr)
call mpi_comm_size(MPI_COMM_WORLD, nproc, ierr)
write(*,*)'MPI task id = ', mytid
C Use the task id to set the seed number for the random number generator.
seednum = real(mytid)
call srand(seednum)
avepi = 0
do 40 i = 1, ROUNDS
C Calculate pi using dartboard algorithm
homepi = dboard(DARTS)
C Use mpi_reduce to sum values of homepi across all tasks
C Master will store the accumulated value in pisum
C - homepi is the send buffer
C - pisum is the receive buffer (used by the receiving task only)
C - sbytes is the size of the message
C - MASTER is the task that will receive the result of the reduction
C operation
sbytes = 8
call mpi_reduce(homepi, pisum, 1, MPI_DOUBLE_PRECISION,
. MPI_SUM, MASTER, MPI_COMM_WORLD, ierr)
C Master computes average for this iteration and all iterations
if (mytid .eq. MASTER) then
pi = pisum/nproc
avepi = ((avepi*(i-1)) + pi) / i
write(*,32) DARTS*i, avepi
32 format(' After',i6,' throws, average value of pi = ',f10.8)
endif
40 continue
call mpi_finalize(ierr)
end