      PROGRAM ASSIGNMENT3
      INCLUDE 'mpif.h'
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c This program repeatedly passes a message (the process rank)around a 
c ring of processes until each process receives the message it 
c originally sent.  The program is implemented using MPI_SENDRECV.  
c The average time required to complete a round trip is calculated.  
c The number of processes can be adjusted by changing the parameter proc.
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c Setting the number of processors
c To use a different number of processes in the ring adjust proc.
      Integer           proc
      Parameter         (proc=40)

c
      Integer           status(MPI_STATUS_SIZE), i, ierr, sum
      Integer           rank, size, message, messagerecvd
      Double Precision  time(proc), begin, finish, mytime, avgtime

c Initializing MPI and obtaining the process no. and no. of processes.
      call MPI_INIT(ierr)
      call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
      call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)

c Initailizing some variables.
      messagerecvd=-1
      sum=0
      i=0
      message=rank

c Initally sending the processes rank to the neighbor on the right.
c Then, sending on any received messages until the processes receives
c its own rank.
      do while (messagerecvd .ne. rank)
         begin=MPI_WTIME(ierr)
         call MPI_SENDRECV(message,1,MPI_INTEGER,mod(rank+1,size),
     $            1,messagerecvd,1,MPI_INTEGER,mod(rank-1+size,size),
     $            1,MPI_COMM_WORLD,status,ierr)
         finish=MPI_WTIME(ierr)
         sum=sum+messagerecvd
         message=messagerecvd
         i=i+1
         time(i)=(finish-begin)
      enddo

c Printing the calculated sum of all the messages received by each process.
      print *,'The sum for process',rank,' is',sum

c Averaging the times for the five round trips messages.
      mytime=0.0
      do i=1,size
         mytime=mytime+time(i)
      enddo
      mytime=mytime/size

c Sending the average time from the processes to process 0
      call MPI_REDUCE(mytime,avgtime,1,MPI_DOUBLE_PRECISION,
     $         MPI_SUM,0,MPI_COMM_WORLD,ierr)

c Calculating the average time required for a message and
c printing the answer.
       if (rank .eq. 0) then
         avgtime=avgtime/size
         print *,"Average time required for a message is",avgtime
       endif

      call MPI_FINALIZE(ierr)

      end
