| // (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 |