Boost C++ Libraries: Ticket #13043: Serialized MPI doesn't properly handle cancellation of a request https://svn.boost.org/trac10/ticket/13043 <p> Hi - Think I've found a bug - If you try version A with mpiexec -n 2 then you get a clean exit - if you try version B, it hangs indefinitely. request::handle_serialized_irecv isn't handling cancellation. This is bothersome when you have to MPI_comm_disconnect from things. I can workaround by wrapping the transmission but that's not optimal. Please advise if you need more info, I'm using MSMPI and MSVC. Had previously posted this on Stack Overflow who thought it was a bug. Thanks for the library and look forward to hearing from you all soon. </p> <pre class="wiki">#include "boost/mpi.hpp" #include "mpi.h" #include &lt;list&gt; #include "boost/serialization/list.hpp" int main() { MPI_Init(NULL, NULL); MPI_Comm regional; MPI_Comm_dup(MPI_COMM_WORLD, &amp;regional); boost::mpi::communicator comm = boost::mpi::communicator(regional, boost::mpi::comm_attach); if (comm.rank() == 1) { //VERSION A: std::list&lt;int&gt; q; boost::mpi::request z = comm.irecv&lt;std::list&lt;int&gt;&gt;(1, 0, q); z.cancel(); z.wait(); //VERSION B: // int q; // boost::mpi::request z = comm.irecv&lt;int&gt;(1, 0, q); // z.cancel(); // z.wait(); } MPI_Comm_disconnect(&amp;regional); MPI_Finalize(); return 0; } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/13043 Trac 1.4.3 michael.williams@… Tue, 23 May 2017 15:38:01 GMT <link>https://svn.boost.org/trac10/ticket/13043#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13043#comment:1</guid> <description> <p> The following changes seem to fix it, with analogous changes to the array version. I guarantee nothing, draw your own conclusions, of course. </p> <pre class="wiki">template&lt;typename T&gt; optional&lt;status&gt; request::handle_serialized_irecv(request* self, request_action action) { typedef detail::serialized_irecv_data&lt;T&gt; data_t; shared_ptr&lt;data_t&gt; data = static_pointer_cast&lt;data_t&gt;(self-&gt;m_data); if (action == ra_wait) { status stat; if (self-&gt;m_requests[1] == MPI_REQUEST_NULL) { // Wait for the count message to complete BOOST_MPI_CHECK_RESULT(MPI_Wait, (self-&gt;m_requests, &amp;stat.m_status)); if (stat.cancelled()) { return stat; } // Resize our buffer and get ready to receive its data data-&gt;ia.resize(data-&gt;count); BOOST_MPI_CHECK_RESULT(MPI_Irecv, (data-&gt;ia.address(), data-&gt;ia.size(), MPI_PACKED, stat.source(), stat.tag(), MPI_Comm(data-&gt;comm), self-&gt;m_requests + 1)); } // Wait until we have received the entire message BOOST_MPI_CHECK_RESULT(MPI_Wait, (self-&gt;m_requests + 1, &amp;stat.m_status)); data-&gt;deserialize(stat); return stat; } else if (action == ra_test) { status stat; int flag = 0; if (self-&gt;m_requests[1] == MPI_REQUEST_NULL) { // Check if the count message has completed BOOST_MPI_CHECK_RESULT(MPI_Test, (self-&gt;m_requests, &amp;flag, &amp;stat.m_status)); if (stat.cancelled()) { return stat; } if (flag) { // Resize our buffer and get ready to receive its data data-&gt;ia.resize(data-&gt;count); BOOST_MPI_CHECK_RESULT(MPI_Irecv, (data-&gt;ia.address(), data-&gt;ia.size(),MPI_PACKED, stat.source(), stat.tag(), MPI_Comm(data-&gt;comm), self-&gt;m_requests + 1)); } else return optional&lt;status&gt;(); // We have not finished yet } // Check if we have received the message data BOOST_MPI_CHECK_RESULT(MPI_Test, (self-&gt;m_requests + 1, &amp;flag, &amp;stat.m_status)); if (flag) { data-&gt;deserialize(stat); return stat; } else return optional&lt;status&gt;(); } else if (action == ra_cancel) { status stat; BOOST_MPI_CHECK_RESULT(MPI_Cancel, (&amp;self-&gt;m_requests[0])); return optional&lt;status&gt;(); } else { return optional&lt;status&gt;(); } } </pre> </description> <category>Ticket</category> </item> <item> <author>michael.williams@…</author> <pubDate>Tue, 23 May 2017 18:39:40 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13043#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13043#comment:2</guid> <description> <p> I was close, there was a mistake in it. </p> <pre class="wiki">template&lt;typename T&gt; optional&lt;status&gt; request::handle_serialized_irecv(request* self, request_action action) { typedef detail::serialized_irecv_data&lt;T&gt; data_t; shared_ptr&lt;data_t&gt; data = static_pointer_cast&lt;data_t&gt;(self-&gt;m_data); if (action == ra_wait) { status stat; if (self-&gt;m_requests[0] == MPI_REQUEST_NULL) { return optional&lt;status&gt;(); //done } if (self-&gt;m_requests[1] == MPI_REQUEST_NULL) { // Wait for the count message to complete BOOST_MPI_CHECK_RESULT(MPI_Wait, (self-&gt;m_requests, &amp;stat.m_status)); if (stat.cancelled()) { return stat; } // Resize our buffer and get ready to receive its data data-&gt;ia.resize(data-&gt;count); BOOST_MPI_CHECK_RESULT(MPI_Irecv, (data-&gt;ia.address(), data-&gt;ia.size(), MPI_PACKED, stat.source(), stat.tag(), MPI_Comm(data-&gt;comm), self-&gt;m_requests + 1)); } // Wait until we have received the entire message BOOST_MPI_CHECK_RESULT(MPI_Wait, (self-&gt;m_requests + 1, &amp;stat.m_status)); data-&gt;deserialize(stat); return stat; } else if (action == ra_test) { status stat; int flag = 0; if (self-&gt;m_requests[0] == MPI_REQUEST_NULL) { return optional&lt;status&gt;(); //done } if (self-&gt;m_requests[1] == MPI_REQUEST_NULL) { // Check if the count message has completed BOOST_MPI_CHECK_RESULT(MPI_Test, (self-&gt;m_requests, &amp;flag, &amp;stat.m_status)); if (stat.cancelled()) { return stat; } if (flag) { // Resize our buffer and get ready to receive its data data-&gt;ia.resize(data-&gt;count); BOOST_MPI_CHECK_RESULT(MPI_Irecv, (data-&gt;ia.address(), data-&gt;ia.size(),MPI_PACKED, stat.source(), stat.tag(), MPI_Comm(data-&gt;comm), self-&gt;m_requests + 1)); } else return optional&lt;status&gt;(); // We have not finished yet } // Check if we have received the message data BOOST_MPI_CHECK_RESULT(MPI_Test, (self-&gt;m_requests + 1, &amp;flag, &amp;stat.m_status)); if (flag) { data-&gt;deserialize(stat); return stat; } else return optional&lt;status&gt;(); } else if (action == ra_cancel) { status stat; BOOST_MPI_CHECK_RESULT(MPI_Cancel, (&amp;self-&gt;m_requests[0])); return optional&lt;status&gt;(); } else { return optional&lt;status&gt;(); } } </pre> </description> <category>Ticket</category> </item> <item> <author>michael.williams@…</author> <pubDate>Tue, 23 May 2017 20:09:37 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13043#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13043#comment:3</guid> <description> <p> Still had a mistake. Don't worry, this is the last one, till I find a mistake in it. </p> <pre class="wiki">template&lt;typename T&gt; optional&lt;status&gt; request::handle_serialized_irecv(request* self, request_action action) { typedef detail::serialized_irecv_data&lt;T&gt; data_t; shared_ptr&lt;data_t&gt; data = static_pointer_cast&lt;data_t&gt;(self-&gt;m_data); if (action == ra_wait) { status stat; if (self-&gt;m_requests[0] == MPI_REQUEST_NULL) { return optional&lt;status&gt;(); //done } if (self-&gt;m_requests[1] == MPI_REQUEST_NULL) { // Wait for the count message to complete BOOST_MPI_CHECK_RESULT(MPI_Wait, (self-&gt;m_requests, &amp;stat.m_status)); if (stat.cancelled()) { return stat; } // Resize our buffer and get ready to receive its data data-&gt;ia.resize(data-&gt;count); BOOST_MPI_CHECK_RESULT(MPI_Irecv, (data-&gt;ia.address(), data-&gt;ia.size(), MPI_PACKED, stat.source(), stat.tag(), MPI_Comm(data-&gt;comm), self-&gt;m_requests + 1)); } // Wait until we have received the entire message BOOST_MPI_CHECK_RESULT(MPI_Wait, (self-&gt;m_requests + 1, &amp;stat.m_status)); data-&gt;deserialize(stat); return stat; } else if (action == ra_test) { status stat; int flag = 0; if (self-&gt;m_requests[0] == MPI_REQUEST_NULL) { return optional&lt;status&gt;(); //done } if (self-&gt;m_requests[1] == MPI_REQUEST_NULL) { // Check if the count message has completed BOOST_MPI_CHECK_RESULT(MPI_Test, (self-&gt;m_requests, &amp;flag, &amp;stat.m_status)); if (flag) { if (stat.cancelled()) { return stat; } // Resize our buffer and get ready to receive its data data-&gt;ia.resize(data-&gt;count); BOOST_MPI_CHECK_RESULT(MPI_Irecv, (data-&gt;ia.address(), data-&gt;ia.size(),MPI_PACKED, stat.source(), stat.tag(), MPI_Comm(data-&gt;comm), self-&gt;m_requests + 1)); } else return optional&lt;status&gt;(); // We have not finished yet } // Check if we have received the message data BOOST_MPI_CHECK_RESULT(MPI_Test, (self-&gt;m_requests + 1, &amp;flag, &amp;stat.m_status)); if (flag) { data-&gt;deserialize(stat); return stat; } else return optional&lt;status&gt;(); } else if (action == ra_cancel) { status stat; BOOST_MPI_CHECK_RESULT(MPI_Cancel, (&amp;self-&gt;m_requests[0])); return optional&lt;status&gt;(); } else { return optional&lt;status&gt;(); } } </pre> </description> <category>Ticket</category> </item> <item> <author>michael.williams@…</author> <pubDate>Mon, 05 Jun 2017 13:24:20 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13043#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13043#comment:4</guid> <description> <p> I was wrong. It's simpler than all that. Sorry. </p> <pre class="wiki"> template&lt;typename T&gt; optional&lt;status&gt; request::handle_serialized_irecv(request* self, request_action action) { typedef detail::serialized_irecv_data&lt;T&gt; data_t; shared_ptr&lt;data_t&gt; data = static_pointer_cast&lt;data_t&gt;(self-&gt;m_data); if (action == ra_wait) { status stat; if (self-&gt;m_requests[1] == MPI_REQUEST_NULL) { // Wait for the count message to complete BOOST_MPI_CHECK_RESULT(MPI_Wait, (self-&gt;m_requests, &amp;stat.m_status)); if (stat.cancelled()) { return stat; } // Resize our buffer and get ready to receive its data data-&gt;ia.resize(data-&gt;count); BOOST_MPI_CHECK_RESULT(MPI_Irecv, (data-&gt;ia.address(), data-&gt;ia.size(), MPI_PACKED, stat.source(), stat.tag(), MPI_Comm(data-&gt;comm), self-&gt;m_requests + 1)); } // Wait until we have received the entire message BOOST_MPI_CHECK_RESULT(MPI_Wait, (self-&gt;m_requests + 1, &amp;stat.m_status)); if (stat.cancelled()) { return stat; } data-&gt;deserialize(stat); return stat; } else if (action == ra_test) { status stat; int flag = 0; if (self-&gt;m_requests[1] == MPI_REQUEST_NULL) { // Check if the count message has completed BOOST_MPI_CHECK_RESULT(MPI_Test, (self-&gt;m_requests, &amp;flag, &amp;stat.m_status)); if (flag) { if (stat.cancelled()) { return stat; } // Resize our buffer and get ready to receive its data data-&gt;ia.resize(data-&gt;count); BOOST_MPI_CHECK_RESULT(MPI_Irecv, (data-&gt;ia.address(), data-&gt;ia.size(),MPI_PACKED, stat.source(), stat.tag(), MPI_Comm(data-&gt;comm), self-&gt;m_requests + 1)); } else return optional&lt;status&gt;(); // We have not finished yet } // Check if we have received the message data BOOST_MPI_CHECK_RESULT(MPI_Test, (self-&gt;m_requests + 1, &amp;flag, &amp;stat.m_status)); if (flag) { if (stat.cancelled()) { return stat; } data-&gt;deserialize(stat); return stat; } else return optional&lt;status&gt;(); } else if (action == ra_cancel) { status stat; if (self-&gt;m_requests[0] != MPI_REQUEST_NULL) { BOOST_MPI_CHECK_RESULT(MPI_Cancel, (&amp;self-&gt;m_requests[0])); } if (self-&gt;m_requests[1] != MPI_REQUEST_NULL) { BOOST_MPI_CHECK_RESULT(MPI_Cancel, (&amp;self-&gt;m_requests[0])); } return optional&lt;status&gt;(); } else { return optional&lt;status&gt;(); } } </pre> </description> <category>Ticket</category> </item> </channel> </rss>