alfC
alfC

Reputation: 16242

What is exactly the count argument in MPI receiving functions?

This question is about the interpretation of the input parameter count for receiving operations.

In one part of the MPI manual it says (see here mine):

int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag,
             MPI_Comm comm, MPI_Status *status)

Output Parameters

count
    maximum number of elements in receive buffer (integer)  <-------- see here

In other part it says

int MPI_Sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
                 int dest, int sendtag,
                 void *recvbuf, int recvcount, MPI_Datatype recvtype,
                 int source, int recvtag, MPI_Comm comm, MPI_Status * status)
...
recvcount
    number of elements in receive buffer (integer)   <-------- see here

For a long time I ignored the difference in the wording and interpreted them as two ways to say the same thing, that is that is maximum count of elements that can possibly be received.

However, if I read literally recvcount (second case) is the number of elements available (allocated) in the buffer, not necessarily the maximum number of elements that can be received. In other words maybe what it is meant is that recvcount is the number of elements that the MPI implementation can use to store temporary data and for example end up with garbage in part of it.

There is another context in which it makes a difference: If I don't know exactly what is the number of elements received I could pass MAX_INT as argument an ensure the correctness by the logic of the program. But of course, MAX_INT is not the allocated memory in the receiving buffer, it is in principle just a way to say I can receive any number of elements others are sending.

Is there really a difference in the interpretation of count (Recv) and recvcount (SendRecv)?

Is it permitted to pass MAX_INT in either or both cases? if the number of receiving elements is not known (locally in a part of the program)

I experimented a bit with OpenMPI and the answer seems to be that passing MAX_INT is allowed and work as intended but I don't know if it is the prevalent interpretation.

(The opposite interpretation (count is only the allocated memory) would be sad because it would mean that only allocated buffer with their size can be passed to these functions effectively.)


EDIT:

To be clear, what I am asking is in this program what is in principle correct and well defined to receive the whole sent message:

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  MPI_Init(&argc, &argv);
 
  int count = 10;
  double xsend[count]; 
  double xrecv[123];

  for (int i=0; i<count; i++) {xsend[i] = (double)i;}

  int rank, nprocs;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
  assert (nprocs == 2);

  if(rank == 0) {MPI_Send(xsend, count, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD);}

  if(rank == 1) {
     MPI_Recv(xrecv, NN, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
     assert( xrecv[9] == 9 );
  }

  MPI_Finalize();
  return 0;
}

Which values of NN are semantically correct to receive the whole message:

  1. NN = 10
  2. NN = 20
  3. NN = 123
  4. NN = 100000
  5. NN = MAX_INT - 2
  6. NN = MAX_INT - 1
  7. NN = MAX_INT

I understand that option 1. is recommended, and that option 2. and 3. are correct for sure. My question is whether the other options are well defined.

Upvotes: 0

Views: 751

Answers (1)

Victor Eijkhout
Victor Eijkhout

Reputation: 5794

The count in case of the receive buffer is the size of the receive buffer, expressed in the specified type, and this is an upper bound on the size of the message that can be received. (Note that for the send buffer the count is of course the exact size of the message.) The phrase "maximum number of elements" probably refers to this upper bound behavior.

However, it is confusing and I note that in the most recent standard 4.0 it is not used. https://www.mpich.org/static/docs/v4.0a1/www3/MPI_Recv.html

So: 1. you can pass a count that is larger than the size of any message you will receive into that buffer (in which case, call MPI_Get_count on the status object), but 2. for proper error reporting you'd better specify the actual size of the buffer, otherwise you may get memory corruption.

EDIT out of the options you're giving, options 1, 2, and 3 are correct: they are 1. at least the size of the message 2. at most the size of the buffer.

Upvotes: 1

Related Questions