What is the purpose of boost mpi request's m_handler

182 Views Asked by At

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.

1

There are 1 best solutions below

0
On BEST ANSWER

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 by irecv() should complete once the data has been received and an std::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 the m_handler variable:

...
if (m_handler) {
  // This request is a receive for a serialized type. Use the
  // handler to test for completion.
  return m_handler(this, ra_test);
} else ...

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.