From c6769cae3bc7f0bf1ad922dad9a7db2e77a669b1 Mon Sep 17 00:00:00 2001 From: Alain Miniussi Date: Mon, 28 Oct 2019 10:04:12 +0100 Subject: [PATCH 1/5] doxygen typo --- include/boost/mpi/config.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/mpi/config.hpp b/include/boost/mpi/config.hpp index 1fd093bf..91ea093d 100644 --- a/include/boost/mpi/config.hpp +++ b/include/boost/mpi/config.hpp @@ -45,7 +45,7 @@ #endif #if defined MPI_SUBVERSION -/** @brief Major version of the underlying MPI implementation supproted standard. +/** @brief Major version of the underlying MPI implementation supported standard. * * If, for some reason, MPI_SUBVERSION is not supported, you should probably set that * according to your MPI documentation From 8239d5d29a5c86c739bd64ac9e6ab4b631dda32a Mon Sep 17 00:00:00 2001 From: Alain Miniussi Date: Mon, 28 Oct 2019 10:41:40 +0100 Subject: [PATCH 2/5] comment typo --- test/sendrecv_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sendrecv_test.cpp b/test/sendrecv_test.cpp index 801b2629..a7fe3a3e 100644 --- a/test/sendrecv_test.cpp +++ b/test/sendrecv_test.cpp @@ -1,4 +1,4 @@ -// Copyright Alain Miniussi 20014. +// Copyright Alain Miniussi 2014. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) From 0b7f6785759272153e369be35f7620aa425fe18d Mon Sep 17 00:00:00 2001 From: Alain Miniussi Date: Mon, 28 Oct 2019 17:59:42 +0100 Subject: [PATCH 3/5] Add implementation for ibarrier and associated test. Only enable if BOOST_MPI_VERSION >= 3 refs #100 --- include/boost/mpi/communicator.hpp | 9 ++++ include/boost/mpi/detail/request_handlers.hpp | 3 ++ include/boost/mpi/request.hpp | 2 + src/communicator.cpp | 11 ++++- test/Jamfile.v2 | 4 +- test/ibarrier_test.cpp | 42 +++++++++++++++++++ 6 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 test/ibarrier_test.cpp diff --git a/include/boost/mpi/communicator.hpp b/include/boost/mpi/communicator.hpp index 8663ba3f..46349c57 100644 --- a/include/boost/mpi/communicator.hpp +++ b/include/boost/mpi/communicator.hpp @@ -775,6 +775,15 @@ class BOOST_MPI_DECL communicator void barrier() const; #endif +#if BOOST_MPI_VERSION >= 3 + /** + * @brief Non blocking version of barrier. + * + * This version will return immediatly. The request completes + * once all participants have reached the barrier. + */ + request ibarrier() const; +#endif /** @brief Determine if this communicator is valid for * communication. * diff --git a/include/boost/mpi/detail/request_handlers.hpp b/include/boost/mpi/detail/request_handlers.hpp index 50a22ec3..2f14a24f 100644 --- a/include/boost/mpi/detail/request_handlers.hpp +++ b/include/boost/mpi/detail/request_handlers.hpp @@ -509,6 +509,9 @@ class BOOST_MPI_DECL request::trivial_handler : public request::handler { private: friend class request; +#if BOOST_MPI_VERSION >= 3 + friend class communicator; +#endif MPI_Request m_request; }; diff --git a/include/boost/mpi/request.hpp b/include/boost/mpi/request.hpp index 6edccc9b..548bead0 100644 --- a/include/boost/mpi/request.hpp +++ b/include/boost/mpi/request.hpp @@ -150,7 +150,9 @@ class BOOST_MPI_DECL request template class legacy_dynamic_primitive_array_handler; #if BOOST_MPI_VERSION >= 3 template class probe_handler; + friend class communicator; #endif + private: shared_ptr m_handler; shared_ptr m_preserved; diff --git a/src/communicator.cpp b/src/communicator.cpp index 016c6af4..07853857 100644 --- a/src/communicator.cpp +++ b/src/communicator.cpp @@ -131,7 +131,6 @@ void (communicator::barrier)() const BOOST_MPI_CHECK_RESULT(MPI_Barrier, (MPI_Comm(*this))); } - communicator::operator MPI_Comm() const { if (comm_ptr) return *comm_ptr; @@ -325,4 +324,14 @@ bool operator==(const communicator& comm1, const communicator& comm2) return result == MPI_IDENT; } +// Non blocking common +#if BOOST_MPI_VERSION >= 3 +request communicator::ibarrier() const +{ + request::trivial_handler* handler = new request::trivial_handler; + BOOST_MPI_CHECK_RESULT(MPI_Ibarrier, (*this, &handler->m_request)); + return request(handler); +} +#endif + } } // end namespace boost::mpi diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index ac9ac253..31883867 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -49,7 +49,9 @@ test-suite mpi [ mpi-test groups_test ] # tests that require -std=c++11 [ mpi-test sendrecv_vector : : : 2 ] - # Intel MPI 2018 and older are axtected to fail: + # Intel MPI 2018 and older are expected to fail: [ mpi-test non_blocking_any_source : : : 2 17 ] + # Non Blockin common (MPI 3 only) + [ mpi-test ibarrier_test : : : 1 3 ] ; } diff --git a/test/ibarrier_test.cpp b/test/ibarrier_test.cpp new file mode 100644 index 00000000..ac7a1923 --- /dev/null +++ b/test/ibarrier_test.cpp @@ -0,0 +1,42 @@ +// Copyright Alain Miniussi 2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// A test of the non blocking barrier operation. + +#include +#include + + +#define BOOST_TEST_MODULE mpi_ibarrier +#include + +namespace mpi = boost::mpi; + +BOOST_AUTO_TEST_CASE(ibarrier_check) +{ + mpi::environment env; + mpi::communicator world; + + std::ostringstream buf; + int rk = world.rank(); + buf << "rk" << rk << ": calling ibarrier.\n"; + std::cout << buf.str(); + mpi::request r = world.ibarrier(); + if (rk == 0) { + while (!r.test()) { + buf << "rk" << rk << ": not completed yet.\n"; + std::cout << buf.str(); + } + buf << "rk" << rk << ": completed.\n"; + std::cout << buf.str(); + } else { + buf << "rk" << rk << ": waiting..."; + std::cout << buf.str() << std::flush; + r.wait(); + buf << "rk" << rk << ": done.\n"; + std::cout << buf.str(); + } + BOOST_TEST(true); +} From 36140307e8eb41d66e6231b0440c4a5caa022c39 Mon Sep 17 00:00:00 2001 From: Alain O Miniussi Date: Mon, 28 Oct 2019 19:15:22 +0100 Subject: [PATCH 4/5] Add a convenience trivial request handler factory method. --- include/boost/mpi/detail/request_handlers.hpp | 7 +++++++ include/boost/mpi/request.hpp | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/include/boost/mpi/detail/request_handlers.hpp b/include/boost/mpi/detail/request_handlers.hpp index 2f14a24f..49be3c66 100644 --- a/include/boost/mpi/detail/request_handlers.hpp +++ b/include/boost/mpi/detail/request_handlers.hpp @@ -530,6 +530,13 @@ class request::dynamic_handler : public request::handler { MPI_Request m_requests[2]; }; +inline +request request::make_trivial(MPI_Request const& r) { + trivial_handler *handler = new trivial_handler; + handler->m_request = r; + return request(handler); +} + template request request::make_serialized(communicator const& comm, int source, int tag, T& value) { #if defined(BOOST_MPI_USE_IMPROBE) diff --git a/include/boost/mpi/request.hpp b/include/boost/mpi/request.hpp index 548bead0..504bc3a5 100644 --- a/include/boost/mpi/request.hpp +++ b/include/boost/mpi/request.hpp @@ -38,6 +38,10 @@ class BOOST_MPI_DECL request */ request(); + /** + * Just make a request from a C API request. + */ + static request make_trivial(MPI_Request const& r); /** * Send a known number of primitive objects in one MPI request. */ From a7379ac5688503764eb2532f290d132b4964d087 Mon Sep 17 00:00:00 2001 From: Alain O Miniussi Date: Mon, 28 Oct 2019 19:25:02 +0100 Subject: [PATCH 5/5] When building a trivial request handler for C API interaction, export the nested C request address. --- include/boost/mpi/detail/request_handlers.hpp | 7 ------- include/boost/mpi/request.hpp | 5 +++-- src/request.cpp | 7 +++++++ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/boost/mpi/detail/request_handlers.hpp b/include/boost/mpi/detail/request_handlers.hpp index 49be3c66..2f14a24f 100644 --- a/include/boost/mpi/detail/request_handlers.hpp +++ b/include/boost/mpi/detail/request_handlers.hpp @@ -530,13 +530,6 @@ class request::dynamic_handler : public request::handler { MPI_Request m_requests[2]; }; -inline -request request::make_trivial(MPI_Request const& r) { - trivial_handler *handler = new trivial_handler; - handler->m_request = r; - return request(handler); -} - template request request::make_serialized(communicator const& comm, int source, int tag, T& value) { #if defined(BOOST_MPI_USE_IMPROBE) diff --git a/include/boost/mpi/request.hpp b/include/boost/mpi/request.hpp index 504bc3a5..6818b613 100644 --- a/include/boost/mpi/request.hpp +++ b/include/boost/mpi/request.hpp @@ -39,9 +39,10 @@ class BOOST_MPI_DECL request request(); /** - * Just make a request from a C API request. + * Just make a request from a C API request and provide its address + * for future assignement. */ - static request make_trivial(MPI_Request const& r); + static request make_trivial(MPI_Request*& r); /** * Send a known number of primitive objects in one MPI request. */ diff --git a/src/request.cpp b/src/request.cpp index 3ba5695a..b78951f8 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -26,6 +26,13 @@ request::preserve(boost::shared_ptr d) { } request request::make_dynamic() { return request(new dynamic_handler()); } +request request::make_trivial(MPI_Request*& r) { + trivial_handler *handler = new trivial_handler; + r = &(handler->m_request); + return request(handler); +} + + request request::make_bottom_send(communicator const& comm, int dest, int tag, MPI_Datatype tp) { trivial_handler* handler = new trivial_handler;