Additionally, if you know an upper bound on the size that will be sent
(e.g., your application will never send more than 16k in this case),
then you can post a receive for 16k. Specifically, MPI says that you
can post a receive of size N and receive a message that is smaller than
or equal to size N. MPI_Get_count can be used to determine the size of
the message that was actually received.
However, if you don't have an upper bound, then MPI_Probe may be your
best bet.
I'm not generally in favor of probing, however, because it tends to
force the MPI to do an unexpected receive (i.e., MPI has to receive the
message into a temporary buffer), and simply increases latency. For
large messages, this can be costly. If you're always sending around
large messages, you can simply send another message with the size that
the receiver should receive. Since the message is large, the cost of
this second message is probably negligible compared to the transfer
time of the large message. This is clearly not a good idea for short
messages, though.
You might want to combine these strategies -- perhaps something like
(this is pseudocode off the top of my head -- pardon any
typos/mistakes!):
-----
if (i_am_sender) {
if (size > small_size) {
MPI_Send(&size, 1, MPI_INT, dest, SIZE_TAG, comm);
data_tag = BIG_DATA_TAG;
} else {
data_tag = SMALL_DATA_TAG;
}
MPI_Send(&buffer, size, ..., dest, data_tag, comm);
} else {
MPI_Irecv(&size, 1, MPI_INT, src, SIZE_TAG, comm, &req[0]);
MPI_Irecv(&small_buffer, small_size, ..., src, SMALL_DATA_TAG,
comm, &req[1]);
MPI_Waitany(2, req, &index, statuses);
if (index == 0) {
recv_buffer = malloc(size);
MPI_Recv(recv_buffer, size, ..., src, BIG_DATA_TAG, comm,
&status);
} else {
recv_buffer = small_buffer;
}
MPI_Cancel(&req[1 - index]);
MPI_Wait(&req[1 - index], MPI_STATUS_IGNORE);
/* ... do something with recv_buffer ... */
}
-----
This works fine with pairwise exchanges -- you'll run into race
conditions if you are using MPI_ANY_SOURCE with src (you can be a
little more clever with the logic if you need MPI_ANY_SOURCE).
Likewise, if you're looping over this, you don't necessarily need to
cancel the unused receive request; you likely just want to re-post the
already-used receive, etc.
You get the general idea from the above pseudocode. :-)
On May 20, 2005, at 9:48 AM, Heiko Bauke wrote:
> Hi,
>
> On Thu, 19 May 2005 12:32:02 -0700 (PDT)
> ThanhVu Nguyen <tvn_email-debianml_at_[hidden]> wrote:
>
> check with MPI_Probe and MPI_Get_count the number of elements before
> calling MPI_Recv.
>
>> vector<int> data; //unknown size
>>
>> if (taskID == Sender){
>> data.push_back(1);
>> data.push_back(2);
>>
>> MPI_Send(&data[0],data.size(),MPI_INT .... ); // send
>> }
>> if (taskId == Receiver){
>> // QUESTION here -> how to receive the sending data ? the
>> receiver
>
> MPI_Probe(0, tag, MPI_COMM_WORLD, &status);
> MPI_Get_count(&status, MPI_INT, &count);
> data.resize(count);
> MPI_Recv(&data[0],data.size(),MPI_INT .... ); // recv
>
>> }
>
>
> Heiko
>
> --
> -- Der Poet versteht die Natur besser als der wissenschaftliche Kopf.
> -- (Novalis)
> -- Supercomputing in Magdeburg @ http://tina.nat.uni-magdeburg.de
> -- Heiko Bauke @ http://www.uni-magdeburg.de/bauke
> _______________________________________________
> This list is archived at http://www.lam-mpi.org/MailArchives/lam/
>
--
{+} Jeff Squyres
{+} jsquyres_at_[hidden]
{+} http://www.lam-mpi.org/
|