summaryrefslogtreecommitdiff
path: root/libs/mpi/src/python/py_environment.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/mpi/src/python/py_environment.cpp')
-rw-r--r--libs/mpi/src/python/py_environment.cpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/libs/mpi/src/python/py_environment.cpp b/libs/mpi/src/python/py_environment.cpp
new file mode 100644
index 000000000..bcd95e4a8
--- /dev/null
+++ b/libs/mpi/src/python/py_environment.cpp
@@ -0,0 +1,111 @@
+// (C) Copyright 2006 Douglas Gregor <doug.gregor -at- gmail.com>
+
+// 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)
+
+// Authors: Douglas Gregor
+
+/** @file environment.cpp
+ *
+ * This file reflects the Boost.MPI "environment" class into Python
+ * methods at module level.
+ */
+#include <boost/python.hpp>
+#include <boost/mpi.hpp>
+
+using namespace boost::python;
+using namespace boost::mpi;
+
+namespace boost { namespace mpi { namespace python {
+
+extern const char* environment_init_docstring;
+extern const char* environment_finalize_docstring;
+extern const char* environment_abort_docstring;
+extern const char* environment_initialized_docstring;
+extern const char* environment_finalized_docstring;
+
+/**
+ * The environment used by the Boost.MPI Python module. This will be
+ * zero-initialized before it is used.
+ */
+static environment* env;
+
+bool mpi_init(list python_argv, bool abort_on_exception)
+{
+ // If MPI is already initialized, do nothing.
+ if (environment::initialized())
+ return false;
+
+ // Convert Python argv into C-style argc/argv.
+ int my_argc = extract<int>(python_argv.attr("__len__")());
+ char** my_argv = new char*[my_argc];
+ for (int arg = 0; arg < my_argc; ++arg)
+ my_argv[arg] = strdup(extract<const char*>(python_argv[arg]));
+
+ // Initialize MPI
+ int mpi_argc = my_argc;
+ char** mpi_argv = my_argv;
+ env = new environment(mpi_argc, mpi_argv, abort_on_exception);
+
+ // If anything changed, convert C-style argc/argv into Python argv
+ if (mpi_argv != my_argv)
+ PySys_SetArgv(mpi_argc, mpi_argv);
+
+ for (int arg = 0; arg < my_argc; ++arg)
+ free(my_argv[arg]);
+ delete [] my_argv;
+
+ return true;
+}
+
+void mpi_finalize()
+{
+ if (env) {
+ delete env;
+ env = 0;
+ }
+}
+
+void export_environment()
+{
+ using boost::python::arg;
+
+ def("init", mpi_init, (arg("argv"), arg("abort_on_exception") = true),
+ environment_init_docstring);
+ def("finalize", mpi_finalize, environment_finalize_docstring);
+
+ // Setup initialization and finalization code
+ if (!environment::initialized()) {
+ // MPI_Init from sys.argv
+ object sys = object(handle<>(PyImport_ImportModule("sys")));
+ mpi_init(extract<list>(sys.attr("argv")), true);
+
+ // Setup MPI_Finalize call when the program exits
+ object atexit = object(handle<>(PyImport_ImportModule("atexit")));
+ object finalize = scope().attr("finalize");
+ atexit.attr("register")(finalize);
+ }
+
+ def("abort", &environment::abort, arg("errcode"),
+ environment_abort_docstring);
+ def("initialized", &environment::initialized,
+ environment_initialized_docstring);
+ def("finalized", &environment::finalized,
+ environment_finalized_docstring);
+ scope().attr("max_tag") = environment::max_tag();
+ scope().attr("collectives_tag") = environment::collectives_tag();
+ scope().attr("processor_name") = environment::processor_name();
+
+ if (optional<int> host_rank = environment::host_rank())
+ scope().attr("host_rank") = *host_rank;
+ else
+ scope().attr("host_rank") = object();
+
+ if (optional<int> io_rank = environment::io_rank())
+ scope().attr("io_rank") = *io_rank;
+ else
+ scope().attr("io_rank") = object();
+}
+
+} } } // end namespace boost::mpi::python