On Aug 17, 2005, at 7:45 AM, Michael Lees wrote:
> So I've been trying to think of a safe solution to the problem above. I
> came up with
>
> inOutThread
> {
> MPI_IRecv
> if(!outQ.empty())
> MPI_ISend
>
> MPI_Waitany(index)
>
> if(index = recv)
> inQ.push()
> }
>
> This is incomplete - I think I'd have to cancel whichever of the Irecv
> and Isend didn't complete at the beginning of each loop? Would this be
> inefficient? The other option would be to check which of the operations
> completed and post a new one.
The latter would be better. Plus, you don't want to cancel the Isend
-- you want to let it complete. Hence, you want to post a new Isend
every time there's something in the outQ and then just complete them,
but post a new Irecv every time it completes. Perhaps something like
this:
-----
inOutThread(...) {
MPI_Recv_init(recv_buffer, ..., &array_req[0]);
MPI_Start(
while (!done) {
while (!outQ.empty()) {
foo = outQ.pop();
MPI_Isend(foo, ..., &array_req[some_free_index]);
}
do {
MPI_Waitany(size, array_req, &index, &status);
if (MPI_UNDEFINED != index) {
if (0 == index) {
inQ.push(recv_buffer);
} else {
// ...index/array management...
}
}
}
}
}
-----
This is off the top of my head, so it's kinda rough (and not guaranteed
to be 100% correct!). Clearly, too, you'll need to add some request
array management in there (e.g., to find a free index in the array and
to maintain the correct value of "size"). I made it loop to send until
the outQ is drained -- an optimization that might help, but that adds
some complexity to the request array management.
This also assumes that your queue management stuff is
thread-safe/concurrent (empty, push, pop).
Make sense?
--
{+} Jeff Squyres
{+} jsquyres_at_[hidden]
{+} http://www.lam-mpi.org/
|