如何通过cython将MPI通信器从python传递给C?

我试图通过cython将一个MPI_Comm通信器句柄作为参数包装一个C函数。 因此,我希望能够从python调用该函数,并将其传递给mpi4py.MPI.Comm对象。 我想知道的是,如何从mpi4py.MPI.Comm转换为MPI_Comm

为了演示,我使用了一个简单的“Hello World!” – 类型函数:

helloworld.h

 #ifndef HELLOWORLD #define HELLOWORLD #include  void sayhello(MPI_Comm comm); #endif 

helloworld.c

 #include  #include "helloworld.h" void sayhello(MPI_Comm comm){ int size, rank; MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank); printf("Hello, World! " "I am process %d of %d.\n", rank, size); } 

我现在想从python中调用这个函数,如下所示:

from_python.py

 import mpi4py import helloworld_wrap helloworld_wrap.py_sayhello(mpi4py.MPI.COMM_WORLD) 

意思是mpirun -np 4 python2 from_python.py应该给出类似的东西:

你好,世界! 我是4的过程0。
你好,世界! 我是第4步。
你好,世界! 我是4的过程2。
你好,世界! 我是第3步(共4步)。

但是如果我尝试通过cython实现这一点:

helloworld_wrap.pyx

 cimport mpi4py.MPI as MPI cimport mpi4py.libmpi as libmpi cdef extern from "helloworld.h": void sayhello(libmpi.MPI_Comm comm) def py_sayhello(MPI.Comm comm): sayhello(comm) 

和:

setup.py

 import os from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext mpi_compile_args = os.popen("mpicc --showme:compile").read().strip().split(' ') mpi_link_args = os.popen("mpicc --showme:link").read().strip().split(' ') ext_modules=[ Extension("helloworld_wrap", sources = ["helloworld_wrap.pyx", "helloworld.c"], language = 'c', extra_compile_args = mpi_compile_args, extra_link_args = mpi_link_args, ) ] setup( name = "helloworld_wrap", cmdclass = {"build_ext": build_ext}, ext_modules = ext_modules ) 

我收到以下错误消息:

helloworld_wrap.pyx:8:13:无法将Python对象转换为’MPI_Comm’

表示mpi4py.MPI.Comm无法转换为MPI_Comm 。 那么如何将mpi4py.MPI.Comm转换为MPI_Comm以使我的包装器工作?

转换相当简单,因为mpi4py.MPI.Comm内部存储MPI_Comm句柄作为成员ob_mpi 1 。 因此,如果更改helloworld_wrap.pyx的最后一行以传递comm.ob_mpi而不是comm ,则模块将按预期进行编译和工作:

helloworld_wrap.pyx

 cimport mpi4py.MPI as MPI cimport mpi4py.libmpi as libmpi cdef extern from "helloworld.h": void sayhello(libmpi.MPI_Comm comm) def py_sayhello(MPI.Comm comm): sayhello(comm.ob_mpi) 

令人惊讶的是,我没有找到任何相关的文档,但只是在研究mpi4py.MPI.Comm的来源时才意识到这mpi4py.MPI.Comm 。 我不确定,如果这是处理这个问题的预定方法,但我不能让它工作。


1事实上,大多数(如果不是所有) mpi4py.MPI中的对象都在mpi4py.MPI中对相应的MPI句柄进行建模,将相应的句柄作为成员ob_mpi