c c------------------------------------------------------------------- c This program times blocking send/receives, and reports the c latency and bandwidth of the communication system. It is c designed to run on an even number of nodes. c c CME342 / AA220 / CS238 c Juan J. Alonso, Spring 2004-05 c c------------------------------------------------------------------- c program bounce parameter (maxcount=1000000) parameter (nRepeats=100) parameter (nsizes=7) implicit real*8 (a-h,o-z) include "mpif.h" dimension sbuf(maxcount), rbuf(maxcount) dimension length(nsizes) integer status(MPI_STATUS_SIZE) c--------------------------------------- c define an array of message lengths c--------------------------------------- length(1) = 0 length(2) = 1 length(2) = 10 length(3) = 100 length(4) = 1000 length(5) = 10000 length(6) = 100000 length(7) = 1000000 c---------------------------------------------------- c initialize the send and receive buffers to zero c---------------------------------------------------- do n=1,maxcount sbuf(n) = 0.0D0 rbuf(n) = 0.0D0 end do c------------------------------------- c set up the parallel environment c------------------------------------- call mpi_init(ierr) call mpi_comm_size(mpi_comm_world,nNodes,ierr) call mpi_comm_rank(mpi_comm_world,nodeID,ierr) write(*,*)'Running executable bounce' if (nodeID.eq.0) write(*,*)'Number of processors =',nNodes c c print relevant environment variables c if (mod(nNodes,2) .ne. 0) then if (nodeID .eq. 0) then write(*,*) ' You must specify an even number of nodes.' end if call mpi_finalize(ierr) stop end if c--------------------------------------------------------- c send or receive messages, and time them. c even nodes send, odd nodes receive, then the reverse c--------------------------------------------------------- do ns=1, nsizes call mpi_barrier(MPI_COMM_WORLD,ierr) time1 = MPI_WTIME() do nr=1, nRepeats c---------------------------------------------- c send in one direction i->i+1 c---------------------------------------------- if (mod(nodeID,2) .eq. 0) then call mpi_send(sbuf, length(ns), MPI_REAL8, nodeID+1, 1, . MPI_COMM_WORLD, ierr) else call mpi_recv(rbuf, length(ns), MPI_REAL8, nodeID-1, 1, . MPI_COMM_WORLD, status, ierr) end if c--------------------------------------------------- c send in the reverse direction i+1->i c--------------------------------------------------- if (mod(nodeID,2) .eq. 1) then call mpi_send(sbuf, length(ns), MPI_REAL8, nodeID-1, 1, . MPI_COMM_WORLD, ierr) else call mpi_recv(rbuf, length(ns), MPI_REAL8, nodeID+1, 1, . MPI_COMM_WORLD, status, ierr) end if end do call mpi_barrier(MPI_COMM_WORLD,ierr) time2 = MPI_WTIME() if (nodeID .eq. 0) then write(6,fmt='(A,I9,A,10X,A,F10.4,A)') 'msglen =',8*length(ns), & ' bytes,','elapsed time =',0.5D3*(time2-time1)/nRepeats,' msec' call flush(6) end if if (ns .eq. 1) then tlatency = 0.5D6*(time2-time1)/nRepeats end if if (ns .eq. nsizes) then bw = 8.*length(ns)/(0.5D6*(time2-time1)/nRepeats) end if end do c--------------------------------------------------------- c report approximate numbers for bandwidth and latency c--------------------------------------------------------- if (nodeID .eq. 0) then write(6,fmt='(A,F6.1,A)') 'latency =',tlatency,' microseconds' write(6,*) 'bandwidth =',bw,' MBytes/sec' write(6,fmt='(A)') '(approximate values for mp_bsend/mp_brecv)' end if call mpi_finalize(ierr) end