如何将Python与使用MPI的C程序接口

如何将Python与使用MPI的C程序接口,mpi,Mpi,目前我有一个Python程序(串行),它通过subprocess.run调用C可执行文件(通过MPI并行)。然而,这是一个非常笨拙的实现,因为这意味着我必须使用文件系统将一些非常大的数组从Python来回传递给C程序。我希望能够直接将数组从Python传递到C和C。我认为ctypes是我应该使用的。据我所知,我将从我的C代码中创建一个dll而不是一个可执行文件,以便能够将其与Python一起使用 但是,要使用MPI,您需要使用mpirun/mpiexec启动程序。如果我只是使用dll中的C函数,

目前我有一个Python程序(串行),它通过subprocess.run调用C可执行文件(通过MPI并行)。然而,这是一个非常笨拙的实现,因为这意味着我必须使用文件系统将一些非常大的数组从Python来回传递给C程序。我希望能够直接将数组从Python传递到C和C。我认为ctypes是我应该使用的。据我所知,我将从我的C代码中创建一个dll而不是一个可执行文件,以便能够将其与Python一起使用

但是,要使用MPI,您需要使用
mpirun
/
mpiexec
启动程序。如果我只是使用dll中的C函数,这是不可能的,对吗

对于从dll调用的函数,是否有一种好方法可以启用MPI?我发现的两种可能性是

  • 使用mpi4py并行启动python程序,然后将MPI_COMM_WORLD传递给C函数(根据本文)

  • 不使用
    mpirun
    在函数内部以某种方式初始化和生成进程。我不确定这是否可行


如果您同意通过c程序秩0传递所有内容,那么一种可能性是使用
subprocess.Popen()
stdin=subprocess.PIPE
以及python端的
communicate()
函数和c端的
fread()

这显然是脆弱的,但却把一切都留在了记忆中。另外,如果您的数据量很大(您说是这样),您可能需要将数据以块的形式写入子进程。另一种选择是使用
exe.stdin.write(x)
而不是
exe.communicate(x)

我创建了一个小示例程序

c代码(名为child的程序):

python代码(名为driver.py):

结果:

> python ./driver.py
rank 0 of 4 received 3.141592
rank 1 of 4 received 3.141592
rank 2 of 4 received 3.141592
rank 3 of 4 received 3.141592
rank 0 of 4 received 101.100000
rank 2 of 4 received 101.100000
rank 3 of 4 received 101.100000
rank 1 of 4 received 101.100000

我尝试通过mpi4py使用
MPI\u Comm\u connect()
MPI\u Comm\u accept()
,但我似乎无法在python端实现这一点。

因为大部分时间都花在被多次调用的
C
子例程中,并且您正在资源管理器中运行,我建议采取以下办法:

通过以下命令立即启动所有MPI任务(假设已分配
n+1
插槽

mpirun -np 1 python wrapper.py : -np <n> a.out
mpirun-np 1 python wrapper.py:-np a.out
您可能希望从
MPI\u Comm\u split()
开始,以便仅为
n
C
程序执行的任务生成通信器。 然后,您将定义一个“协议”,以便python包装器可以将参数传递给
C
任务,并等待结果,或者将
C
程序引导到
MPI\u Finalize()


<>你不妨考虑使用一个互通器(第一组是Python,第二组是<代码> C < /代码>)但这真的取决于你。Intercommunicator语义可能被视为非直观的,因此,如果你想朝这个方向发展,请确保你了解它是如何工作的。

你想在同一个节点上运行MPI程序吗?还是在多个节点上运行MPI程序?python只执行一次MPI程序?还是多次?MPI程序的相对持续时间是多少MPI程序与python one的比较?@GillesGouaillardet MPI程序在多个节点上运行,通常为3-10个节点,每个节点有16个处理器。python多次调用MPI程序,通常在运行期间调用10000多次(这是一个MCMC进程)。在MPI C程序中花费的时间比python包装器多得多。谢谢!您是否使用资源管理器(例如slurm、PBS、LSF或其他)?您使用的是哪一个MPI库(例如Open MPI、mpich或其衍生物)?@GillesGouaillardet我使用slurm和mpich 3.2。谢谢!
> python ./driver.py
rank 0 of 4 received 3.141592
rank 1 of 4 received 3.141592
rank 2 of 4 received 3.141592
rank 3 of 4 received 3.141592
rank 0 of 4 received 101.100000
rank 2 of 4 received 101.100000
rank 3 of 4 received 101.100000
rank 1 of 4 received 101.100000
mpirun -np 1 python wrapper.py : -np <n> a.out