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