
On Thu, 2006-12-14 at 10:34 +0000, Bo Peng wrote:
Dear boost users,
I am using Boost.MPI for a python module so there is no argc, argv that can be provided to
boost::parallel::mpi::environment(int & argc, char ** & argv)
Because an environment object has to exist during the life time of the module, I have to define a global variable in an awkward way:
int fake_argc = 0; char * fake_argv = ""; char ** ptr_argv = &fake_argv; boost::parallel::mpi::environment env(fake_argc, ptr_argv);
Can a default constructor be provided?
Unfortunately, the default constructor could only be provided if the underlying MPI implementation is MPI-2 complaint, since MPI-1 allows MPI implementations to require that the "argc" and "argv" pointers passed to MPI_Init be the "real" argc and argv. I don't know what MPI implementations take advantage of this latitude. Boost.MPI's own Python module jumps through some hoops to be MPI-1 compliant in this regard. We basically extract the Python "sys.argv" like this: object sys = object(handle<>(PyImport_ImportModule("sys"))); mpi_init(extract<list>(sys.attr("argv")), true); Then, we convert that into C-style argc/argv to initialize Boost.MPI's "environment" variable. If MPI_Init does anything to that argc/argv, we write the results back into Python's sys.argv. This routine (from libs/parallel/src/mpi/python/py_environment.cpp) does the trick: 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; } It's messy, but as far as I know that's the only way to do it for MPI-1. I'll be happy to provide the default constructor, but it will only be available when we can be sure that it can be implemented correctly, either because we've checked out a particular MPI implementation (e.g., LAM-MPI does not need the real argc/argv) or it claims to be MPI-2 compliant. I'll add a new macro "BOOST_MPI_HAS_DEFAULT_ENVIRONMENT" that is used to indicate that the default constructor exists. Cheers, Doug