Hi,
I have a tentative patch that is supposed to provide binding to the MPI
thread API. What is the best way to have it reviewed ?
It might be a ticket buthttps://svn.boost.org/trac/boost/report/15the
referenced maintainer is Doug
(https://svn.boost.org/trac/boost/report/15)
and, probably since I have no userid in the tracker, I won't be able to
change it.
Just in case, there is a patch in attachment (against rev 81596 of
trunk).
Thanks
Alain
--
Alain Miniussi
Responsable Tech. Centre de Calcul Haute Performance
Obs. de la Côte d'Azur |Mont Gros: +33 4 92 00 30 09
BP 4229 |Sophia : +33 4 83 61 85 44
06304 Nice Cedex 4 |https://crimson.oca.eu
Index: boost/mpi/environment.hpp
===================================================================
--- boost/mpi/environment.hpp (revision 81596)
+++ boost/mpi/environment.hpp (working copy)
@@ -17,9 +17,42 @@
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <string>
+#include <iosfwd>
namespace boost { namespace mpi {
-
+namespace mt {
+/** @brief specify the supported threading level.
+ *
+ * Based on MPI 2 standard/8.7.3
+ */
+enum level {
+ /** Only one thread will execute.
+ */
+ SINGLE = MPI_THREAD_SINGLE,
+ /** Only main thread will do MPI calls.
+ *
+ * The process may be multi-threaded, but only the main
+ * thread will make MPI calls (all MPI calls are ``funneled''
+ * to the main thread).
+ */
+ FUNNELED = MPI_THREAD_FUNNELED,
+ /** Only one thread at the time do MPI calls.
+ *
+ * The process may be multi-threaded, and multiple
+ * threads may make MPI calls, but only one at a time:
+ * MPI calls are not made concurrently from two distinct
+ * threads (all MPI calls are ``serialized'').
+ */
+ SERIALIZED = MPI_THREAD_SERIALIZED,
+ /** Multiple thread may do MPI calls.
+ *
+ * Multiple threads may call MPI, with no restrictions.
+ */
+ MULTIPLE = MPI_THREAD_MULTIPLE
+};
+/** Formated output for threading level. */
+std::ostream& operator<<(std::ostream& out, level l);
+} // namespace mt
/** @brief Initialize, finalize, and query the MPI environment.
*
* The @c environment class is used to initialize, finalize, and
@@ -62,6 +95,22 @@
* program if it is destructed due to an uncaught exception.
*/
explicit environment(bool abort_on_exception = true);
+ /** Initialize the MPI environment.
+ *
+ * If the MPI environment has not already been initialized,
+ * initializes MPI with a call to @c MPI_Init_thread. Since this
+ * constructor does not take command-line arguments (@c argc and @c
+ * argv), it is only available when the underlying MPI
+ * implementation supports calling @c MPI_Init with @c NULL
+ * arguments, indicated by the macro @c
+ * BOOST_MPI_HAS_NOARG_INITIALIZATION.
+ *
+ * @param mt_level the required level of threading support.
+ *
+ * @param abort_on_exception When true, this object will abort the
+ * program if it is destructed due to an uncaught exception.
+ */
+ explicit environment(mt::level mt_level, bool abort_on_exception = true);
#endif
/** Initialize the MPI environment.
@@ -80,6 +129,25 @@
*/
environment(int& argc, char** &argv, bool abort_on_exception = true);
+ /** Initialize the MPI environment.
+ *
+ * If the MPI environment has not already been initialized,
+ * initializes MPI with a call to @c MPI_Init_thread.
+ *
+ * @param argc The number of arguments provided in @p argv, as
+ * passed into the program's @c main function.
+ *
+ * @param argv The array of argument strings passed to the program
+ * via @c main.
+ *
+ * @param mt_level the required level of threading support
+ *
+ * @param abort_on_exception When true, this object will abort the
+ * program if it is destructed due to an uncaught exception.
+ */
+ environment(int& argc, char** &argv, mt::level mt_level,
+ bool abort_on_exception = true);
+
/** Shuts down the MPI environment.
*
* If this @c environment object was used to initialize the MPI
@@ -185,13 +253,21 @@
*/
static std::string processor_name();
+ /** Query the current level of thread support.
+ */
+ static mt::level thread_level();
+
+ /** Are we in the main thread?
+ */
+ static bool main_thread();
+
private:
/// Whether this environment object called MPI_Init
bool i_initialized;
/// Whether we should abort if the destructor is
bool abort_on_exception;
-
+
/// The number of reserved tags.
static const int num_reserved_tags = 1;
};
Index: libs/mpi/src/environment.cpp
===================================================================
--- libs/mpi/src/environment.cpp (revision 81596)
+++ libs/mpi/src/environment.cpp (working copy)
@@ -11,8 +11,32 @@
#include <cassert>
#include <exception>
#include <stdexcept>
+#include <ostream>
namespace boost { namespace mpi {
+namespace mt {
+std::ostream& operator<<(std::ostream& out, level l)
+{
+ switch(l) {
+ case SINGLE:
+ out << "single";
+ break;
+ case FUNNELED:
+ out << "funneled";
+ break;
+ case SERIALIZED:
+ out << "serialized";
+ break;
+ case MULTIPLE:
+ out << "multiple";
+ break;
+ default:
+ out << "<level error>[" << int(l) << ']';
+ break;
+ }
+ return out;
+}
+} // namespace mt
#ifdef BOOST_MPI_HAS_NOARG_INITIALIZATION
environment::environment(bool abort_on_exception)
@@ -26,6 +50,21 @@
MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
}
+
+environment::environment(mt::level mt_level, bool abort_on_exception)
+ : i_initialized(false),
+ abort_on_exception(abort_on_exception)
+{
+ // It is not clear that we can pass null in MPI_Init_thread.
+ int dummy_thread_level = 0;
+ if (!initialized()) {
+ BOOST_MPI_CHECK_RESULT(MPI_Init_thread,
+ (0, 0, int(mt_level), &dummy_thread_level ));
+ i_initialized = true;
+ }
+
+ MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
+}
#endif
environment::environment(int& argc, char** &argv, bool abort_on_exception)
@@ -40,6 +79,22 @@
MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
}
+environment::environment(int& argc, char** &argv, mt::level mt_level,
+ bool abort_on_exception)
+ : i_initialized(false),
+ abort_on_exception(abort_on_exception)
+{
+ // It is not clear that we can pass null in MPI_Init_thread.
+ int dummy_thread_level = 0;
+ if (!initialized()) {
+ BOOST_MPI_CHECK_RESULT(MPI_Init_thread,
+ (&argc, &argv, int(mt_level), &dummy_thread_level));
+ i_initialized = true;
+ }
+
+ MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
+}
+
environment::~environment()
{
if (i_initialized) {
@@ -122,4 +177,20 @@
return std::string(name, len);
}
+mt::level environment::thread_level()
+{
+ int level;
+
+ BOOST_MPI_CHECK_RESULT(MPI_Query_thread, (&level));
+ return static_cast<mt::level>(level);
+}
+
+bool environment::main_thread()
+{
+ int isit;
+
+ BOOST_MPI_CHECK_RESULT(MPI_Is_thread_main, (&isit));
+ return bool(isit);
+}
+
} } // end namespace boost::mpi
Index: libs/mpi/test/mt_init_test.cpp
===================================================================
--- libs/mpi/test/mt_init_test.cpp (revision 0)
+++ libs/mpi/test/mt_init_test.cpp (revision 0)
@@ -0,0 +1,28 @@
+// Copyright (C) 2005-2006 Douglas Gregor <[email protected]>
+
+// Use, modification and distribution is subject to 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)
+
+// Test a few basic feature for multi-threading.
+// It is quite basic since the support is dependent
+// on the underlying implementation those threading
+// support is allowed to varry by the MPI standard.
+
+#include <boost/mpi/environment.hpp>
+#include <boost/test/minimal.hpp>
+
+using namespace boost::mpi;
+using namespace std;
+
+int test_main(int argc, char* argv[])
+{
+ // just test for one value, I could not find the doc in mpi.jam
+ // to pass params through argc/argv
+ mt::level mt_level = mt::MULTIPLE;
+ boost::mpi::environment env(argc, argv, mt_level);
+ mt::level provided = env.thread_level();
+ std::cout << "Asked:" << mt_level << ", provided: " << provided << '\n';
+ BOOST_CHECK((provided >= mt::SINGLE && provided <= mt::MULTIPLE));
+ return 0;
+}
Index: libs/mpi/test/mt_level_test.cpp
===================================================================
--- libs/mpi/test/mt_level_test.cpp (revision 0)
+++ libs/mpi/test/mt_level_test.cpp (revision 0)
@@ -0,0 +1,26 @@
+// Copyright (C) 2005-2006 Douglas Gregor <[email protected]>
+
+// Use, modification and distribution is subject to 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)
+
+// Test a few basic feature for multi-threading.
+// It is quite basic since the support is dependent
+// on the underlying implementation those threading
+// support is allowed to varry by the MPI standard.
+
+#include <boost/mpi/environment.hpp>
+#include <boost/test/minimal.hpp>
+
+using namespace boost::mpi;
+using namespace std;
+
+int test_main(int argc, char* argv[])
+{
+ using namespace boost::mpi::mt;
+ BOOST_CHECK((SINGLE < FUNNELED));
+ BOOST_CHECK((FUNNELED < SERIALIZED));
+ BOOST_CHECK((SERIALIZED < MULTIPLE));
+
+ return 0;
+}
Index: libs/mpi/test/Jamfile.v2
===================================================================
--- libs/mpi/test/Jamfile.v2 (revision 81596)
+++ libs/mpi/test/Jamfile.v2 (working copy)
@@ -23,6 +23,8 @@
[ mpi-test broadcast_test : : : 2 17 ]
[ mpi-test gather_test ]
[ mpi-test is_mpi_op_test : : : 1 ]
+ [ mpi-test mt_level_test : : : 1 4 ]
+ [ mpi-test mt_init_test : : : 1 4 ]
# Note: Microsoft MPI fails nonblocking_test on 1 processor
[ mpi-test nonblocking_test ]
[ mpi-test reduce_test ]
Index: tools/build/v2/tools/mpi.jam
===================================================================
--- tools/build/v2/tools/mpi.jam (revision 81596)
+++ tools/build/v2/tools/mpi.jam (working copy)
@@ -314,7 +314,7 @@
# Prepend COMPILER as the executable name, to match the format of
# other compilation commands.
- compile_flags = "COMPILER $(compile_flags)" ;
+ compile_flags = "COMPILER $(compile_flags) -DOMPI_SKIP_MPICXX " ;
link_flags = "COMPILER $(link_flags)" ;
}
# Look for LAM-MPI's -showme
_______________________________________________
Boost-mpi mailing list
[email protected]
http://lists.boost.org/mailman/listinfo.cgi/boost-mpi