C ----------------------------------------------------------------------------- 
C FILE: poe_bandwidth.f
C DESCRIPTION:  
C   This code conducts timing tests on messages sent between 2 MPI tasks.
C   It sends/receives N roundtrips of incrementally sized messages
C   from start size J to finish size K by increment I.
C LAST REVISED:  06/04/06 Blaise Barney
C ----------------------------------------------------------------------------- 

      program bandwidth
      include 'mpif.h'

      integer MAXSIZE, task0, task1, tag0, tag1, tag2
      parameter(MAXSIZE = 2000000)
      parameter(task0 = 0)
      parameter(task1 = 1)
      parameter(tag0 = 0)
      parameter(tag1 = 1)

      integer numtasks, rank, n, i, rndtrps, start, end,
     &        incr, Stat(MPI_STATUS_SIZE), ierr, length
      real*8  t1, t2, nbytes, etime, bandwdth
      character c(MAXSIZE)
      character(MPI_MAX_PROCESSOR_NAME) host, host1
      character(30) tmp0, tmp1

C     Some initializations and error checking
      call MPI_INIT(ierr)
      call MPI_COMM_SIZE(MPI_COMM_WORLD, numtasks, ierr)
      if (numtasks .lt. 2) then
        print *, 'ERROR: Number of tasks= ', numtasks, 
     &           ' Need 2 tasks. Quitting...'
        call MPI_Abort(MPI_COMM_WORLD,ierr)
        stop
      else if (numtasks .gt. 2) then
        print *, 'Number of tasks= ', numtasks, 
     &           ' Only need 2 tasks. Ignoring extra tasks...'
      endif
      call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
      call MPI_GET_PROCESSOR_NAME(host, length, ierr)
      start = 100000;
      end = MAXSIZE;
      incr = 100000;
      rndtrps = 1000;

C**************************** task 0 ***********************************
      if (rank .eq. 0) then
      do i=1,MAXSIZE
        c(i) = "x"
      end do
      tmp0 = host
      call MPI_RECV(tmp1, 30, MPI_CHARACTER, 
     &              task1, tag1, MPI_COMM_WORLD, Stat, ierr)
  
      print *,' '
      print *,'****** MPI/POE Bandwidth Test ****** '
      print *,'Message start size= ',start
      print *,'Message finish size= ',end
      print *,'Incremented by ',incr,' bytes per iteration'
      print *,'Roundtrips per iteration= ',rndtrps
      print *,'Task 0 running on: ',tmp0
      print *,'Task 1 running on: ',tmp1
      print *,' '
      print *,'Message Size   Bandwidth (bytes/sec)'

      do n=start, end, incr
        t1 = MPI_WTIME()
        do i=1, rndtrps 
          call MPI_SEND(c, n, MPI_CHARACTER, task1, tag0, 
     &                  MPI_COMM_WORLD, ierr)
          call MPI_RECV(c, n, MPI_CHARACTER, task1, tag1, 
     &                  MPI_COMM_WORLD, Stat, ierr)
        end do
        t2 = MPI_WTIME()
        etime = t2-t1
        nbytes =  2.0 * (n * rndtrps)
        bandwdth = (1.0 * nbytes)/etime
      write(*,111) n, bandwdth
 111  format(i9, e16.4)
      end do
      endif

C ***************************  task 1 *************************************
      if (rank .eq. 1) then
        call MPI_SEND(host, 30, MPI_CHARACTER, 
     &                task0, tag1,  MPI_COMM_WORLD, ierr)

        do n=start, end, incr
          do i=1, rndtrps 
            call MPI_RECV(c, n, MPI_CHARACTER, task0, tag0, 
     &                    MPI_COMM_WORLD, Stat, ierr)
            call MPI_SEND(c, n, MPI_CHARACTER, task0, tag1, 
     &                    MPI_COMM_WORLD, ierr)
          end do
        end do
      endif


      call MPI_FINALIZE(ierr)
      end
