我已经成功编写了用于使用Boost.python进行初始化和设置MPI环境的包装器,但是我不确定是否已正确初始化所有内容。我还没有遇到任何问题,但是我想看看我在做的事情是否某种程度上不正确,以后会引起问题,或者是否有更好的方法来解决。

我知道python确实有到MPI的绑定(bind)(通过mpi4py),但这不能满足我的需要。下面的简单示例可以用mpi4py代替,但实际上我不需要初始化普通的MPI环境:我需要初始化一个专用的MPI环境(MADNESS / TiledArray),没有我可以找到的python绑定(bind)。

我的文件结构如下:

interface.cxx:

#include <iostream>
#include <boost/python.hpp>
#include <mpi.h>

void initMPI(int argc, boost::python::list argv){
  char ** argv_ = new char *[argc];
  for(auto i = 0; i < argc; i++){
    std::string str = boost::python::extract<std::string>(argv[i]);
    auto len = str.length();
    argv_[i] = new char[len+1];
    strncpy(argv_[i],&str[0],len);
    argv_[i][len] = '\0'; // Termination character
  }
  MPI_Init(&argc,&argv_);
  for(auto i = 0; i < argc; i++){
    delete [] argv_[i];
  }
  delete [] argv_;
};

void finalizeMPI(){
  MPI_Finalize();
};

void hello(){
  int world_size, rank, name_len;
  std::string name;
  name.reserve(MPI_MAX_PROCESSOR_NAME);
  MPI_Comm_size(MPI_COMM_WORLD,&world_size);
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
  MPI_Get_processor_name(&name[0],&name_len);
printf("Hello world from processor %s, rank %d"
           " out of %d processors\n",
           name.c_str(), rank, world_size);
};

BOOST_PYTHON_MODULE(mpiinterface){
  boost::python::def("init", initMPI);
  boost::python::def("finalize", finalizeMPI);
  boost::python::def("hello",hello);
};

test.py:
import sys,os
sys.path.append('/home/dbwy/devel/tests/MPI/boost.python')
import mpiinterface

mpiinterface.init(len(sys.argv),sys.argv)
mpiinterface.hello();
mpiinterface.finalize();

编译后,它确实为我提供了正确的输出:
[dbwy@medusa boost.python]$ mpirun -np 4 python test.py
Hello world from processor medusa.chem.washington.edu, rank 0 out of 4 processors
Hello world from processor medusa.chem.washington.edu, rank 3 out of 4 processors
Hello world from processor medusa.chem.washington.edu, rank 1 out of 4 processors
Hello world from processor medusa.chem.washington.edu, rank 2 out of 4 processors

真的那么容易吗?还是我错过了以后会造成灾难性后果的大型物品?

最佳答案

由于当今几乎所有现有的MPI实现都符合1998年发布的MPI-2规范,因此完全不需要对参数列表进行整个处理。从MPI-2开始,可以通过调用MPI_Init(NULL, NULL)初始化MPI。

确实,使用MPI就像在应用程序的开头一次调用MPI_Init 和在退出之前一次调用MPI_Finalize 一样简单。如果您的程序是多线程的,则应将MPI_Init替换为 MPI_Init_thread ,并确保MPI库为所需的多线程级别提供支持。

关于python - 在boost.python中包装MPI,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34141178/

10-14 18:56
查看更多