program main
      use mpi
      integer MAX_ROWS, MAX_COLS, rows, cols
      parameter (MAX_ROWS = 1000, MAX_COLS = 1000)
      double precision a(MAX_ROWS,MAX_COLS), b(MAX_COLS), c(MAX_ROWS)
      double precision buffer(MAX_COLS), ans

integer myid, master, numprocs, ierr, status(MPI_STATUS_SIZE) integer i, j, numsent, sender integer anstype, row

call MPI_INIT( ierr ) call MPI_COMM_RANK( MPI_COMM_WORLD, myid, ierr ) call MPI_COMM_SIZE( MPI_COMM_WORLD, numprocs, ierr ) master = 0 rows = 100 cols = 100

if ( myid .eq. master ) then ! master initializes and then dispatches ! initialize a and b (arbitrary) do 20 j = 1,cols b(j) = 1 do 10 i = 1,rows a(i,j) = i 10 continue 20 continue numsent = 0 ! send b to each slave process call MPI_BCAST(b, cols, MPI_DOUBLE_PRECISION, master, & MPI_COMM_WORLD, ierr) ! send a row to each slave process; tag with row number do 40 i = 1,min(numprocs-1,rows) do 30 j = 1,cols buffer(j) = a(i,j) 30 continue call MPI_SEND(buffer, cols, MPI_DOUBLE_PRECISION, i, & i, MPI_COMM_WORLD, ierr) numsent = numsent+1 40 continue do 70 i = 1,rows call MPI_RECV(ans, 1, MPI_DOUBLE_PRECISION, & MPI_ANY_SOURCE, MPI_ANY_TAG, & MPI_COMM_WORLD, status, ierr) sender = status(MPI_SOURCE) anstype = status(MPI_TAG) ! row is tag value c(anstype) = ans if (numsent .lt. rows) then ! send another row do 50 j = 1,cols buffer(j) = a(numsent+1,j) 50 continue call MPI_SEND(buffer, cols, MPI_DOUBLE_PRECISION, & sender, numsent+1, MPI_COMM_WORLD, ierr) numsent = numsent+1 else ! Tell sender that there is no more work call MPI_SEND(MPI_BOTTOM, 0, MPI_DOUBLE_PRECISION, & sender, 0, MPI_COMM_WORLD, ierr) endif 70 continue else ! slaves receive b, then compute dot products until ! done message received call MPI_BCAST(b, cols, MPI_DOUBLE_PRECISION, master, & MPI_COMM_WORLD, ierr) if (rank .gt. rows) & goto 200 ! skip if more processes than work 90 call MPI_RECV(buffer, cols, MPI_DOUBLE_PRECISION, master, & MPI_ANY_TAG, MPI_COMM_WORLD, status, ierr) if (status(MPI_TAG) .eq. 0) then go to 200 else row = status(MPI_TAG) ans = 0.0 do 100 i = 1,cols ans = ans+buffer(i)*b(i) 100 continue call MPI_SEND(ans, 1, MPI_DOUBLE_PRECISION, master, & row, MPI_COMM_WORLD, ierr) go to 90 endif 200 continue endif

call MPI_FINALIZE(ierr) stop end