      PROGRAM ASSIGNMENT3
      INCLUDE 'mpif.h'
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c This program repeatedly broadcasts the same message to all processes 
c and waits for the message to be returned.  The program is implemented
c using only MPI_SEND and MPI_RECV as communication calls.  The average
c time required for a round trip the message is calculated.
c
c The size of the message being passed can be adjusted by adjusting the
c parameter n.
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c Setting the length of the message to be sent. n is the number of 
c thirty-two byte chunks to be sent.
      Integer           n, length
      Parameter         (n=512)
      Parameter         (length=32*n)

c Declaring other variables.
      Character*(length) message
      Character*(length) messagerecvd
      Character*32      submessage
      Integer           status(MPI_STATUS_SIZE)
      Integer           i, j, rank, size, ierr, position
      Double Precision  time(5), begin, finish, 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 Constructing the message.
      submessage='This is the message being sent. '
      do i=1,n 
         position=32*(i-1)+1
         message(position:position+31)=submessage
      enddo
 
c Beginning sending and timing messages.  Five messages are
c sent by the root process and received back from the other 
c processes.  The time for each round trip is calculated.
      if (rank .eq. 0) then
          do i=1,5
             begin=MPI_WTIME(ierr)
             do j=1,size-1
                call MPI_SEND(message,length,MPI_CHARACTER,j,1,
     $                   MPI_COMM_WORLD,ierr)
             enddo
             do j=1,size-1
                call MPI_RECV(messagerecvd,length,MPI_CHARACTER,
     $                   MPI_ANY_SOURCE,1,MPI_COMM_WORLD,
     $                   status,ierr)
            enddo
             finish=MPI_WTIME(ierr)
             time(i)=(finish-begin)
c The time for each round trip is printed
             print *,"time(i) is",time(i)
          enddo

c All processes other than root receive the message from root
c send it back to root.
      else
          do i=1,5
             call MPI_RECV(message,length,MPI_CHARACTER,0,1,
     $                MPI_COMM_WORLD,status,ierr)
             call MPI_SEND(message,length,MPI_CHARACTER,0,1,
     $                MPI_COMM_WORLD,ierr)
          enddo
      endif

c Averaging the times for the round trip messages. 
      if (rank .eq. 0) then
         do i=1,5
            avgtime=avgtime+time(i)
         enddo
         print *,"Average time required for a round trip message "
         print *," of",length," bytes is",avgtime 
      endif

      call MPI_FINALIZE(ierr)

      end

