c     /***************************************************************/
c     /* please note the effect of the different send modes upon the */
c     /* execution of a non-matching, blocking send operation        */
c     /*                                                             */
c     /* standard    mode send - may not deliver an error            */
c     /* buffered    mode send - may not deliver an error            */
c     /* ready       mode send - may not deliver an error            */
c     /* synchronous mode send - _will_  deliver an error            */
c     /*                                                             */
c     /* essence: synchronous mode,blocking  send (MPI_SSEND) is     */
c     /*          the safest against bugs; however, it is also the   */
c     /*          slowest.                                           */
c     /***************************************************************/
      program sendmodes
      implicit none
      include "mpif.h"
      integer istat(MPI_STATUS_SIZE)
c     
      integer ierr,myid,numprocs,ival,iroot,idest
      parameter(iroot=0)
c-----|---------------------------------------------------------------|
c     /* initialize MPI */
      call MPI_INIT(ierr)
      call MPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)
      call MPI_COMM_SIZE(MPI_COMM_WORLD,numprocs,ierr)
c
c     /* write a welcome message to screen */
      write(*,*)'hello. I am ',myid,' out of ',numprocs
c
c     /* send a message which has no receiver */
      if(myid.eq.numprocs-1)then
         ival=134
         idest=0
c     /* "standard mode" send (MPI_SEND): does not guarantee that */
c     /* the corresponding receive operation has already started  */
c     /* when returning!                                          */
         write(*,*)myid,' about to MPI_SEND 1 integer to ',idest
         call MPI_SEND(ival,1,MPI_INTEGER,
     $        idest,myid,MPI_COMM_WORLD,istat,ierr)
         write(*,*)myid,' just MPI_SEND 1 integer to ',idest
c
c     /* "buffered mode" send (MPI_BSEND): does not guarantee */
c     /* anything! (data is only written into a buffer)       */
         write(*,*)myid,' about to MPI_BSEND 1 integer to ',idest
         call MPI_BSEND(ival,1,MPI_INTEGER,
     $        idest,myid,MPI_COMM_WORLD,istat,ierr)
         write(*,*)myid,' just MPI_BSEND 1 integer to ',idest
c
c     /* "ready mode" send (MPI_RSEND): does not guarantee     */
c     /* anything! (it is _assumed_ that a matching receive    */
c     /* operation has been posted; result may be erroneous if */
c     /* this was not the case)                                */
         write(*,*)myid,' about to MPI_RSEND 1 integer to ',idest
         call MPI_RSEND(ival,1,MPI_INTEGER,
     $        idest,myid,MPI_COMM_WORLD,istat,ierr)
         write(*,*)myid,' just MPI_RSEND 1 integer to ',idest
c
c     /* "synchronous mode" send (MPI_SSEND): _does_ guarantee  */
c     /* that there is a matching receive operation. returns    */
c     /* when the receive has actually started taking place and */
c     /* the buffer can be safely over-written.                 */
c     /* [here, the code will lock up]                          */
         write(*,*)myid,' about to MPI_SSEND 1 integer to ',idest,
     $        ' [this should LOCK UP!]'
         call MPI_SSEND(ival,1,MPI_INTEGER,
     $        idest,myid,MPI_COMM_WORLD,istat,ierr)
         write(*,*)myid,' just MPI_SSEND 1 integer to ',idest
      endif
c     
c     /* say 'bye' before finalizing MPI */
      write(*,*)myid,' about to finalize MPI'
      call MPI_FINALIZE(ierr)
      write(*,*)'bye. ',myid      
c
      stop
      end program sendmodes
c-----|---------------------------------------------------------------|
