$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r82525 - in trunk/libs/mpi: doc src/python
From: troyer_at_[hidden]
Date: 2013-01-17 10:26:31
Author: troyer
Date: 2013-01-17 10:26:30 EST (Thu, 17 Jan 2013)
New Revision: 82525
URL: http://svn.boost.org/trac/boost/changeset/82525
Log:
Several minor bug fixes and updates
Text files modified: 
   trunk/libs/mpi/doc/mpi.qbk                   |    64 +++++++++++++++++++++++++++-----------  
   trunk/libs/mpi/src/python/py_environment.cpp |    66 ++++++--------------------------------- 
   2 files changed, 56 insertions(+), 74 deletions(-)
Modified: trunk/libs/mpi/doc/mpi.qbk
==============================================================================
--- trunk/libs/mpi/doc/mpi.qbk	(original)
+++ trunk/libs/mpi/doc/mpi.qbk	2013-01-17 10:26:30 EST (Thu, 17 Jan 2013)
@@ -110,7 +110,7 @@
   #include <mpi.h>
   #include <iostream>
 
-  int main(int argc, char* argv[])
+  int main()
   {
     MPI_Init(&argc, &argv);
 
@@ -304,9 +304,9 @@
   #include <iostream>
   namespace mpi = boost::mpi;
 
-  int main(int argc, char* argv[]) 
+  int main() 
   {
-    mpi::environment env(argc, argv);
+    mpi::environment env;
     mpi::communicator world;
     std::cout << "I am process " << world.rank() << " of " << world.size()
               << "." << std::endl;
@@ -332,6 +332,26 @@
 writing "I am a process" before another process has finished writing
 "of 7.".
 
+If you should still have an MPI library supporting only MPI 1.1 you 
+will need to pass the command line arguments to the environment
+constructor as shown in this example:
+
+  #include <boost/mpi/environment.hpp>
+  #include <boost/mpi/communicator.hpp>
+  #include <iostream>
+  namespace mpi = boost::mpi;
+
+  int main(int argc, char* argv[]) 
+  {
+    mpi::environment env(argc, argv);
+    mpi::communicator world;
+    std::cout << "I am process " << world.rank() << " of " << world.size()
+              << "." << std::endl;
+    return 0;
+  }
+
+
+
 [section:point_to_point Point-to-Point communication]
 
 As a message passing library, MPI's primary purpose is to routine
@@ -353,9 +373,9 @@
   #include <boost/serialization/string.hpp>
   namespace mpi = boost::mpi;
 
-  int main(int argc, char* argv[]) 
+  int main() 
   {
-    mpi::environment env(argc, argv);
+    mpi::environment env;
     mpi::communicator world;
 
     if (world.rank() == 0) {
@@ -425,9 +445,9 @@
   #include <boost/serialization/string.hpp>
   namespace mpi = boost::mpi;
 
-  int main(int argc, char* argv[]) 
+  int main() 
   {
-    mpi::environment env(argc, argv);
+    mpi::environment env;
     mpi::communicator world;
 
     if (world.rank() == 0) {
@@ -623,9 +643,9 @@
   #include <boost/serialization/string.hpp>
   namespace mpi = boost::mpi;
 
-  int main(int argc, char* argv[])
+  int main()
   {
-    mpi::environment env(argc, argv);
+    mpi::environment env;
     mpi::communicator world;
 
     std::string value;
@@ -671,9 +691,9 @@
   #include <cstdlib>
   namespace mpi = boost::mpi;
 
-  int main(int argc, char* argv[])
+  int main()
   {
-    mpi::environment env(argc, argv);
+    mpi::environment env;
     mpi::communicator world;
 
     std::srand(time(0) + world.rank());
@@ -732,9 +752,9 @@
   #include <cstdlib>
   namespace mpi = boost::mpi;
 
-  int main(int argc, char* argv[])
+  int main()
   {
-    mpi::environment env(argc, argv);
+    mpi::environment env;
     mpi::communicator world;
 
     std::srand(time(0) + world.rank());
@@ -765,9 +785,9 @@
   #include <boost/serialization/string.hpp>
   namespace mpi = boost::mpi;
 
-  int main(int argc, char* argv[])
+  int main()
   {
-    mpi::environment env(argc, argv);
+    mpi::environment env;
     mpi::communicator world;
 
     std::string names[10] = { "zero ", "one ", "two ", "three ", 
@@ -879,9 +899,9 @@
   void generate_data(mpi::communicator local, mpi::communicator world);
   void collect_data(mpi::communicator local, mpi::communicator world);
 
-  int main(int argc, char* argv[])
+  int main()
   {
-    mpi::environment env(argc, argv);
+    mpi::environment env;
     mpi::communicator world;
 
     bool is_generator = world.rank() < 2 * world.size() / 3;
@@ -1276,7 +1296,10 @@
   [[C Function/Constant] [Boost.MPI Equivalent]]
 
   [[[@http://www.mpi-forum.org/docs/mpi-11-html/node56.html#Node56
-`MPI_Address`]] [used automatically in Boost.MPI]]
+`MPI_Address`]] [used automatically in Boost.MPI for MPI version 1.x]]
+
+  [[[@http://www.mpi-forum.org/docs/mpi-20-html/node76.htm#Node76
+`MPI_Get_address`]] [used automatically in Boost.MPI for MPI version 2.0 and higher]]
 
   [[[@http://www.mpi-forum.org/docs/mpi-11-html/node58.html#Node58
 `MPI_Type_commit`]] [used automatically in Boost.MPI]]
@@ -1306,7 +1329,10 @@
 `MPI_Type_size`]] [used automatically in Boost.MPI]]
 
   [[[@http://www.mpi-forum.org/docs/mpi-11-html/node55.html#Node55
-`MPI_Type_struct`]] [user-defined classes and structs]]
+`MPI_Type_struct`]] [user-defined classes and structs with MPI 1.x]]
+
+  [[[@http://www.mpi-forum.org/docs/mpi-20-html/node76.htm#Node76
+`MPI_Type_create_struct`]] [user-defined classes and structs with MPI 2.0 and higher]]
 
   [[[@http://www.mpi-forum.org/docs/mpi-11-html/node57.html#Node57
 `MPI_Type_ub`]] [unsupported]]
Modified: trunk/libs/mpi/src/python/py_environment.cpp
==============================================================================
--- trunk/libs/mpi/src/python/py_environment.cpp	(original)
+++ trunk/libs/mpi/src/python/py_environment.cpp	2013-01-17 10:26:30 EST (Thu, 17 Jan 2013)
@@ -33,14 +33,22 @@
  * 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. 
+#if PY_MAJOR_VERSION >= 3
+  #ifdef BOOST_MPI_HAS_NOARG_INITIALIZATION
+    env = new environment(abort_on_exception);
+  #else
+    #error No argument initialization, supported from MPI 1.2 and up, is needed when using Boost.MPI with Python 3.x
+  #endif
+#else
+  
+  // 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)
@@ -53,64 +61,12 @@
 
   // If anything changed, convert C-style argc/argv into Python argv
   if (mpi_argv != my_argv)
-  {
-#if PY_MAJOR_VERSION >= 3
-
-    wchar_t **argv_copy = (wchar_t **)PyMem_Malloc(sizeof(wchar_t*)*mpi_argc);
-    /* We need a second copy, as Python might modify the first one. */
-    wchar_t **argv_copy2 = (wchar_t **)PyMem_Malloc(sizeof(wchar_t*)*mpi_argc);
-
-    if (!argv_copy || !argv_copy2) {
-      fprintf(stderr, "out of memory\n");
-      return false;
-    }
-
-    std::locale mylocale;
-    mbstate_t mystate;
-
-    const std::codecvt<char, wchar_t, mbstate_t>& myfacet =
-      std::use_facet<std::codecvt<char, wchar_t, mbstate_t> >(mylocale);
-
-    for (int i = 0; i < mpi_argc; i++) 
-    {
-      size_t length = strlen(mpi_argv[i]);
-
-      wchar_t *dest = (wchar_t *) PyMem_Malloc(sizeof(wchar_t) * (length + 1));
-
-      const char *from_next;
-      wchar_t *to_next;
-
-      std::codecvt<wchar_t,char,mbstate_t>::result myresult = 
-        myfacet.out(mystate,
-            mpi_argv[i], mpi_argv[i] + length + 1, from_next,
-            dest, dest+length+1, to_next);
-
-      if (myresult != std::codecvt<wchar_t,char,mbstate_t>::ok )
-      {
-        fprintf(stderr, "failure translating argv\n");
-        return 1;
-      }
-
-      argv_copy2[i] = argv_copy[i] = dest;
-      if (!argv_copy[i])
-          return false;
-    }
-
-    PySys_SetArgv(mpi_argc, argv_copy);
-
-    for (int i = 0; i < mpi_argc; i++) {
-        PyMem_Free(argv_copy2[i]);
-    }
-    PyMem_Free(argv_copy);
-    PyMem_Free(argv_copy2);
-#else
     PySys_SetArgv(mpi_argc, mpi_argv);
-#endif
-  }
 
   for (int arg = 0; arg < mpi_argc; ++arg)
     free(mpi_argv[arg]);
   delete [] mpi_argv;
+#endif
 
   return true;
 }