Subject: NRECV example explained.

From: [email-masked] (Al Geist)
Date: Mon, 4 Jan 93 10:25:20 -0500

Hi Jim,

Your points are well taken given your suggested additional goals for MPI.
You asked some questions about an example you gave.

      char buffer[100];
      int i;

      for (i=0; i<10; i++)
      {
          if (MPI_NRECV(&buffer[10*i],10,1,1,1))
             break;
      }

> 1) Into which elements of buffer will the receive occur ?

  The MPI_NRECV call says I want to receive a message not to exceed 10 bytes
  which matches type = 1, groupID = 1, source = 1.
  If the message has already arrived before the NRECV call,
  then it will be placed in buffer[0:9].
  If it arrives while the 'for' loop is still executing,
  then it will be placed in buffer[10*i:10*i+10].
  If it arrives later, then the user will need to ask for it later
  with either MPI_NRECV or MPI_RECV. All he can say for sure is
  the message did not arrive while I was polling for it.

  It is a strange example in that the user asks for a single message
  but specifies 10 different places where it should be stored.
  Ultimately, it the successful RECV or NRECV that specifies
  where the message is stored. 

> 2) Should I now do a blocking MPI_RECV as well ? Or does this only
>    make sense if the MPI_NRECVs all fail ? But if they do fail, is
>    the receive buffer still queued to receive a matching message when
>    it becomes available ? (and if so how do I cancel the outstanding
>    receive and get back ownership of my buffer ?)

  It only makes sense to call MPI_RECV if all MPI_NRECVs fail.
  It is not specified that the recv buffer ever has to be queued.
  An efficient immplementation may queue a failed NRECV in the
  educated guess that the user will ask for the message later
  in the same buffer. Then when the user does ask and the RECV or
  NRECV is successful the system avoids one copy of the message.
  Technically the user never loses ownership of the buffer.
  He can do anything he wants with it. If he is sure the posted
  message will never arrive, then he can post a message from 
  another source to that same buffer.

Cheers!
 Al

---

From: [email-masked] (James Cownie)
Date: Mon, 4 Jan 93 15:44:00 GMT

Thanks Al,

I now understand what you're trying to do, but I still don't think
that your suggested "efficient implementation" is safe. Consider an
example like this (less perverted than my previous one, which was of
course constructed solely to make a point).

	strcpy(buffer0,"Something");
	
	if (MPI_NRECV(buffer0, 10, 1, 1, 1))
	   /* Whatever */
	else
	{
	    sleep(20);   /* Wait for the message to arrive,
		          * For the sake of argument assume it does.
			  */
	    MPI_RECV(buffer1, 10, 1, 1, 1);

	    if (strcmp(buffer0,"Something") != SAME)
		bug("Buffer changed");
	}	

Your suggested "efficient" implementation will surely overwrite
buffer0 (which it should NOT do in your semantic model, since
"Ultimately, it the successful RECV or NRECV that specifies where the
message is stored.").

I have to say I much prefer a model in which the queuing and dequeuing
of buffers is explicit. Then it is clear where the current ownership
of the buffer resides at any time, and when the additional copy can be
avoided. (Though of course there is a lovely race to be resolved in
the cancel...)

Maybe we can talk about this further over a beer if you're going to be
in Dallas.

-- Jim
James Cownie 
Meiko Limited
650 Aztec West
Bristol BS12 4SD
England

Phone : +44 454 616171
FAX   : +44 454 618188
E-Mail: [email-masked] or [email-masked]