      PROGRAM ASSIGNMENT2
      INCLUDE 'mpif.h'
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c This program repeatedly passes a message between two processes and
c calculates the average time required to complete a round trip.  The
c length of the message can be adjusted by changing the parameter n.
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c Setting the length of the message to be sent. n is the number of
c eight byte chunks to be sent.
      Integer           n, length
      Parameter         (n=10)
      Parameter         (length=32*n)

      Character*(length) message
      Character*32      submessage
      Integer           status(MPI_STATUS_SIZE)
      Integer           i, rank, size, ierr, position
      Double Precision  time(5), begin, finish, mytime,mytime1


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 Sync processes before beginning to send and time messages.
c This is not necessary, but insures the processes are nearly
c in sync at the onset.  This allows the timings to reflect 
c the timings you would see on nearly synchronous processors.
c If the time of a truly synchronous round trip is desired, 
c some restructuring of the code is necessary.
      call MPI_BARRIER(MPI_COMM_WORLD, ierr)

c Beginning sending and timeing messages.  Five messages are 
c sent by each processes and the time required for a round
c trip is calculated.
      if (rank .eq. 0) then
          do i=1,5
             begin=MPI_WTIME(ierr)
             call MPI_SEND(message,length,MPI_CHARACTER,1,1,
     $                MPI_COMM_WORLD,ierr)
             call MPI_RECV(message,length,MPI_CHARACTER,1,1,
     $                MPI_COMM_WORLD,status,ierr)
             finish=MPI_WTIME(ierr)
             time(i)=(finish-begin)
             print *,"time(i) is",time(i)
          enddo

      elseif (rank .eq. 1) then
          do i=1,5
             begin=MPI_WTIME(ierr)
             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)
             finish=MPI_WTIME(ierr)
             time(i)=(finish-begin)
             print *,"time(i) is",time(i)
          enddo

      endif
c Averaging the times for the five round trips messages.
      mytime=0.0
      do i=1,5
         mytime=mytime+time(i)
      enddo
      mytime=mytime/5
      print *,"mytime is",mytime

      call MPI_BARRIER(MPI_COMM_WORLD, ierr)

c Sending the average time from processes 1 to process 0
      if (rank .ne. 0) then
         call MPI_SEND(mytime,1,MPI_DOUBLE_PRECISION,0,2,
     $            MPI_COMM_WORLD,ierr)
      elseif (rank .eq. 0) then
         call MPI_RECV(mytime1,1,MPI_DOUBLE_PRECISION,1,2,
     $            MPI_COMM_WORLD,status,ierr)

c Calculating the average time required for a round trip and
c printing the answer.
         print *,"mytime1 is",mytime1
         mytime=(mytime+mytime1)/2
         print *,"Average time required for a round trip message "
         print *," of",length," bytes is",mytime
         endif

      call MPI_FINALIZE(ierr)

      end
