diff --git a/include/boost/mpi/nonblocking.hpp b/include/boost/mpi/nonblocking.hpp index cf762d9..7b60783 100644 --- a/include/boost/mpi/nonblocking.hpp +++ b/include/boost/mpi/nonblocking.hpp @@ -59,10 +59,7 @@ wait_any(ForwardIterator first, ForwardIterator last) ForwardIterator current = first; while (true) { // Check if we have found a completed request. If so, return it. - bool current_is_active = - ( current->m_requests[0] != MPI_REQUEST_NULL || - current->m_requests[1] != MPI_REQUEST_NULL) ; - if (current_is_active) { + if (current->active()) { optional result = current->test(); if (bool(result)) { return std::make_pair(*result, current); @@ -75,10 +72,7 @@ wait_any(ForwardIterator first, ForwardIterator last) // We could probably ignore non trivial request that are inactive, // but we can assume that a mix of trivial and non trivial requests // is unlikely enough not to care. - bool current_trivial_request = - ( !bool(current->m_handler) && - current->m_requests[1] == MPI_REQUEST_NULL); - all_trivial_requests = all_trivial_requests && current_trivial_request; + all_trivial_requests = all_trivial_requests && current->trivial(); // Move to the next request. ++n; @@ -89,8 +83,9 @@ wait_any(ForwardIterator first, ForwardIterator last) if (all_trivial_requests) { std::vector requests; requests.reserve(n); - for (current = first; current != last; ++current) - requests.push_back(current->m_requests[0]); + for (current = first; current != last; ++current) { + requests.push_back(*current->trivial()); + } // Let MPI wait until one of these operations completes. int index; @@ -106,7 +101,7 @@ wait_any(ForwardIterator first, ForwardIterator last) // Find the iterator corresponding to the completed request. current = first; advance(current, index); - current->m_requests[0] = requests[index]; + *current->trivial() = requests[index]; return std::make_pair(stat, current); } @@ -209,10 +204,7 @@ wait_all(ForwardIterator first, ForwardIterator last, OutputIterator out) // Check if this request (and all others before it) are "trivial" // requests, e.g., they can be represented with a single // MPI_Request. - all_trivial_requests = - all_trivial_requests - && !current->m_handler - && current->m_requests[1] == MPI_REQUEST_NULL; + all_trivial_requests = all_trivial_requests && current->trivial(); } } } @@ -225,7 +217,7 @@ wait_all(ForwardIterator first, ForwardIterator last, OutputIterator out) std::vector requests; requests.reserve(num_outstanding_requests); for (ForwardIterator current = first; current != last; ++current) - requests.push_back(current->m_requests[0]); + requests.push_back(*current->trivial()); // Let MPI wait until all of these operations completes. std::vector stats(num_outstanding_requests); @@ -280,10 +272,7 @@ wait_all(ForwardIterator first, ForwardIterator last) // Check if this request (and all others before it) are "trivial" // requests, e.g., they can be represented with a single // MPI_Request. - all_trivial_requests = - all_trivial_requests - && !current->m_handler - && current->m_requests[1] == MPI_REQUEST_NULL; + all_trivial_requests = all_trivial_requests && current->trivial(); } } } @@ -296,7 +285,7 @@ wait_all(ForwardIterator first, ForwardIterator last) std::vector requests; requests.reserve(num_outstanding_requests); for (ForwardIterator current = first; current != last; ++current) - requests.push_back(current->m_requests[0]); + requests.push_back(*current->trivial()); // Let MPI wait until all of these operations completes. BOOST_MPI_CHECK_RESULT(MPI_Waitall, @@ -348,10 +337,10 @@ test_all(ForwardIterator first, ForwardIterator last, OutputIterator out) 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) + if (!first->trivial()) { return optional(); - - requests.push_back(first->m_requests[0]); + } + requests.push_back(*first->trivial()); } int flag = 0; @@ -381,10 +370,10 @@ test_all(ForwardIterator first, ForwardIterator last) 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) + if (!first->trivial()) { return false; - - requests.push_back(first->m_requests[0]); + } + requests.push_back(*first->trivial()); } int flag = 0; @@ -467,10 +456,7 @@ wait_some(BidirectionalIterator first, BidirectionalIterator last, // Check if this request (and all others before it) are "trivial" // requests, e.g., they can be represented with a single // MPI_Request. - all_trivial_requests = - all_trivial_requests - && !current->m_handler - && current->m_requests[1] == MPI_REQUEST_NULL; + all_trivial_requests = all_trivial_requests && current->trivial(); // Move to the next request. ++n; @@ -492,7 +478,7 @@ wait_some(BidirectionalIterator first, BidirectionalIterator last, std::vector stats(n); requests.reserve(n); for (current = first; current != last; ++current) - requests.push_back(current->m_requests[0]); + requests.push_back(*current->trivial()); // Let MPI wait until some of these operations complete. int num_completed; @@ -518,7 +504,7 @@ wait_some(BidirectionalIterator first, BidirectionalIterator last, // Finish up the request and swap it into the "completed // requests" partition. - current->m_requests[0] = requests[indices[index]]; + *current->trivial() = requests[indices[index]]; --start_of_completed; iter_swap(current, start_of_completed); } @@ -583,10 +569,7 @@ wait_some(BidirectionalIterator first, BidirectionalIterator last) // Check if this request (and all others before it) are "trivial" // requests, e.g., they can be represented with a single // MPI_Request. - all_trivial_requests = - all_trivial_requests - && !current->m_handler - && current->m_requests[1] == MPI_REQUEST_NULL; + all_trivial_requests = all_trivial_requests && current->trivial(); // Move to the next request. ++n; @@ -603,7 +586,7 @@ wait_some(BidirectionalIterator first, BidirectionalIterator last) std::vector indices(n); requests.reserve(n); for (current = first; current != last; ++current) - requests.push_back(current->m_requests[0]); + requests.push_back(*current->trivial()); // Let MPI wait until some of these operations complete. int num_completed; @@ -624,7 +607,7 @@ wait_some(BidirectionalIterator first, BidirectionalIterator last) // Finish up the request and swap it into the "completed // requests" partition. - current->m_requests[0] = requests[indices[index]]; + *current->trivial() = requests[indices[index]]; --start_of_completed; iter_swap(current, start_of_completed); } diff --git a/include/boost/mpi/request.hpp b/include/boost/mpi/request.hpp index 16a2fb1..a9204e4 100644 --- a/include/boost/mpi/request.hpp +++ b/include/boost/mpi/request.hpp @@ -59,6 +59,17 @@ class BOOST_MPI_DECL request * completed. */ void cancel(); + + /** + * The trivial MPI requet implenting this request, provided it's trivial. + * Probably irrelevant to most users. + */ + optional trivial(); + + /** + * Is this request potentialy pending ? + */ + bool active() const; private: enum request_action { ra_wait, ra_test, ra_cancel }; @@ -92,15 +103,9 @@ class BOOST_MPI_DECL request static optional handle_dynamic_primitive_array_irecv(request* self, request_action action); - public: // template friends are not portable - - /// INTERNAL ONLY - MPI_Request m_requests[2]; - - /// INTERNAL ONLY - handler_type m_handler; - - /// INTERNAL ONLY + private: + MPI_Request m_requests[2]; + handler_type m_handler; shared_ptr m_data; friend class communicator; diff --git a/src/request.cpp b/src/request.cpp index 9bc842f..5e5e9ab 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -18,6 +18,20 @@ request::request() m_requests[1] = MPI_REQUEST_NULL; } +optional +request::trivial() { + if ((!bool(m_handler) && m_requests[1] == MPI_REQUEST_NULL)) { + return m_requests[0]; + } else { + return boost::none; + } +} + +bool +request::active() const { + return m_requests[0] != MPI_REQUEST_NULL || m_requests[1] != MPI_REQUEST_NULL; +} + status request::wait() { if (m_handler) {