I am trying to test an mpi request if it is done or not. However, there is a problem that I could not figure out. If I use test_all method as below, then I see that request is not done.
string msg;
boost::mpi::request req = world->irecv(some_rank, 0, msg);
vector<boost::mpi::request> waitingRequests;
waitingRequests.push_back(req);
if(boost::mpi::test_all(waitingRequests.begin(), waitingRequests.end()))
cout << "test_all done" << endl;
When I try this code, I see that request is done:
string msg;
boost::mpi::request req = world->irecv(some_rank, 0, msg);
if(req.test())
cout << "test done" << endl;
So, I looked at the code in test_all function and realized that it returns false because of the condition "first->m_handler" (line 5 in the below code).
template<typename ForwardIterator> bool test_all(ForwardIterator first, ForwardIterator last) {
std::vector<MPI_Request> requests;
for (; first != last; ++first) {
// If we have a non-trivial request, then no requests can be completed.
if (first->m_handler || first->m_requests[1] != MPI_REQUEST_NULL)
return false;
requests.push_back(first->m_requests[0]);
}
int flag = 0;
int n = requests.size();
BOOST_MPI_CHECK_RESULT(MPI_Testall,
(n, &requests[0], &flag, MPI_STATUSES_IGNORE));
return flag != 0;
}
Now, I wonder what m_handler is for.
MPI does not support intrinsicly complex C++ objects such as
std::string
. That's why Boost.MPI serialises and correspondingly deserialises such objects when passing them around in the form of MPI messages. From a semantic point of view, the non-blocking operation started byirecv()
should complete once the data has been received and anstd::string
object has been filled in appropriately. The additional step of processing the received message and deserialising it is performed by a special handler method, pointer to which is stored in them_handler
variable:No such handling is needed for simple datatypes.
The same applies to
isend()
when it operates on C++ objects. In that case a handler is not attached, but the class data is sent in the form of two separate messages and special care is taken for both sends to complete. That's what the second boolean expression (m_requests[1] != MPI_REQUEST_NULL
) is for.