3

我想通过例如(串行)python 脚本以某种方式触发MPI 程序(用 C++ 编写)的某些功能的执行。这个 python 脚本应该在开头启动 mpi 程序,例如,

subprocess.call(['mpirun','-np', '4', 'mpibinary', 'args' ])

我需要多次调用这个 MPI 程序的一个函数,并且我想避免为不同的输入重新启动程序,因为我必须重新初始化我的所有数据结构,这很昂贵。因此,我想到了在 MPI 程序空闲时外部触发一个函数。我认为这可以通过文件 IO 来完成,即 MPI 程序的根级别在 while(1) 循环中监视某个文件,一旦其内容发生变化,它就会解析新内容并通知其他级别并调用函数. 我的问题有更优雅的解决方案吗?

最好的解决方案是拥有一个包装 C++ MPI 程序的重要功能的 python 类,以便我可以从 python 调用它们

mpiprogram.superfunction(a,b)
4

1 回答 1

5

也许最优雅的解决方案是让 Python 代码成为 MPI 应用程序的一部分。然后它将能够直接将数据(通过 MPI 消息)发送到 MPI 应用程序的其余部分,因为它将是 MPI 应用程序的一部分。这里有两种不同的方法:

1) 将 Python 二进制文件作为 0 级插入 MPI 作业。为了将其排除在集体操作的参与mpibinary之外,您必须制作一个排除 0 级的子通信器,并将其用于所有进一步的集体通信mpibinary。第一步是简单的部分。在 Open MPI 中,您将执行以下操作:

mpirun --hostfile hosts -np 1 pythonbinary args : -np 32 mpibinary args

这称为 MPMD(多程序多数据)启动,它将启动其中的一个副本,pythonbinary该副本将成为 0 级,32 个副本mpibinary将成为 1 级、2 级,......直到 32 级(总共 33 个进程) . 其他 MPI 实现也为 MPMD 启动提供了非常相似的机制。然后,您将使用MPI_Comm_split()它来创建一个不包含 Python 程序的新通信器。拆分通信器是一项集体操作。这就是为什么您必须在 Python 代码和 C++ 应用程序中都调用它的原因。MPI_Comm_split()取一个“颜色”和一个键,根据颜色的不同将通信器拆分为多个子通信器。然后根据键值对具有相同颜色的进程进行排序。您很可能希望这样称呼它:

在 Python 中:

python_comm = mpi.mpi_comm_split(mpi.MPI_COMM_WORLD, 0, 0)

在 C++ 中:

int rank;
MPI_Comm c_comm;

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_split(MPI_COMM_WORLD, 1, rank, &c_comm);

通过使用rankas key one 可以保证 in 中的进程顺序与c_comm拆分之前的顺序相同,即 rank 1 fromMPI_COMM_WORLD将变为 rank 0 in c_comm, rank 2 将变为 rank 1 等。

从现在开始,C++ 应用程序可以c_comm像往常一样用来执行集体操作。为了在 Python 和 C++ 代码之间进行通信,您仍然必须使用MPI_COMM_WORLDPython 代码在其中的排名仍然为 0。

2) 使用 MPI-2 过程管理工具。首先,您将运行一个仅包含 Python 二进制文件的 MPI 作业:

mpirun --hostfile hosts -np 1 pythonbinary args

然后 Python 二进制文件将直接使用MPI_Comm_spawn()所需数量的新进程生成另一个 MPI 二进制文件。新生成的进程将拥有自己的进程MPI_COMM_WORLD,您无需使用MPI_Comm_split(). 此外,spawn 操作将建立一个互通器,允许 Python 代码将消息发送到 MPI 应用程序的其他部分。


在这两种情况下,该hosts文件都将包含可以执行 MPI 二进制文件的所有执行主机的定义。您还需要使用可用的 Python MPI 绑定之一。

请注意,您只需将一些 MPI 调用添加到您的 Python 脚本中,例如 ,MPI_Init和相关的/ 。你不需要让它平行。MPI 用途广泛,不仅允许您将它用于并行工作共享,还可以用作通用消息传递框架。但请注意,Python 绑定应使用与程序其余部分相同的 MPI 库。MPI_FinalizeMPI_Comm_splitMPI_SendMPI_Recv

另一种解决方案是使用一些消息队列库或文件池(这实际上是一个粗略的 MQ 实现)。

于 2012-05-15T11:01:49.887 回答