      program example13b
      include 'mpif.h'
      integer ierr, rank, size, N, nl
      parameter (N = 9)
      double precision a(N, N), b(N, N)
      call MPI_INIT(ierr)
      call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
      call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
      nl = (N-1)/size+1
      call work(a, b, N, nl, size, rank)
      call MPI_FINALIZE(ierr)
      end
      subroutine work(a, b, n, nl, size, rank)
      include 'mpif.h'
      integer ierr, rank, size, n, MAXPROC, nl
      integer i, j, ii, jj, ir, irr
      parameter (MAXPROC = 64)
      double precision a(nl, n), b(nl, n), c
      integer status(MPI_STATUS_SIZE), req(MAXPROC*2)
      do i = 1, nl
         ii = i+rank*nl
         if(ii .le. n) then
            do j = 1, n
                a(i, j) = 100*ii+j
            end do
         end if
      end do
      do ir = 0, size-1
         call MPI_IRECV(b(1, ir*nl+1), nl*nl,
     &                  MPI_DOUBLE_PRECISION, ir,
     &                  1, MPI_COMM_WORLD,
     &                  req(ir+1), ierr)
         call MPI_ISEND(a(1, ir*nl+1), nl*nl,
     &                  MPI_DOUBLE_PRECISION, ir,
     &                  1, MPI_COMM_WORLD,
     &                  req(ir+1+size), ierr)
      end do
      do irr = 0, size-1
         call MPI_WAITANY(size, req, ir, status, ierr)
         ir = status(MPI_SOURCE)
         do i = 1, nl
            ii = i+ir*nl
            do j = i+1, nl
               jj = j+ir*nl
               c = b(i, jj)
               b(i, jj) = b(j, ii)
               b(j, ii) = c
            end do
         end do
      end do
      do i = 1, nl
         ii = i+rank*nl
         if(ii .le. n) then
            do j = 1, n
               print *, 'process ', rank,
     &                  ': a(', ii, ', ', j, ') =', a(i,j),
     &                  ', b(', ii, ', ', j, ') =', b(i,j)
            end do
         end if
      end do
      end
