我正在使用带有C绑定的OpenMPI。在我的代码中,有一个必需的进程数。如果执行MPI使得打开的进程多于所需的进程,我希望终止或终止额外的进程。我怎么能这样做?
当我尝试以我能想到的几种方式时,我收到以下错误:
mpirun has exited due to process rank 3 with PID 24388 on
node pc15-373 exiting without calling "finalize". This may
have caused other processes in the application to be
terminated by signals sent by mpirun (as reported here).
答案 0 :(得分:5)
除了以下内容之外,我没有太多要补充高性能Mark已经写过的内容。你实际上可以调用MPI_FINALIZE
并退出过量的进程,但你必须意识到这将破坏世界通信器MPI_COMM_WORLD
上所有进一步的集体操作 - 其中大部分都不会完成(MPI_BARRIER
是肯定会挂起的那个)。为了防止这种情况,您可能希望首先创建一个排除所有不必要进程的新通信器:
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Obtain the group of processes in the world communicator
MPI_Group world_group;
MPI_Comm_group(MPI_COMM_WORLD, &world_group);
// Remove all unnecessary ranks
MPI_Group new_group;
int ranges[3] = { process_limit, size-1, 1 };
MPI_Group_range_excl(world_group, 1, ranges, &new_group);
// Create a new communicator
MPI_Comm newworld;
MPI_Comm_create(MPI_COMM_WORLD, new_group, &newworld);
if (newworld == MPI_COMM_NULL)
{
// Bye bye cruel world
MPI_Finalize();
exit(0);
}
// From now on use newworld instead of MPI_COMM_WORLD
此代码首先获取MPI_COMM_WORLD
中的进程组,然后创建一个新组,从process_limit
开始排除所有进程。然后它从新进程组创建一个新的通信器。 MPI_COMM_CREATE
操作将在这些不属于新组的进程中返回MPI_COMM_NULL
,并且此事实用于终止此类进程。鉴于在此之后某些进程会从MPI_COMM_WORLD
“消失”,它不再可用于广播,障碍等集体操作,而应使用newworld
。< / p>
另外,正如Mark指出的那样,在一些架构上,即使从main
返回后,额外的进程实际上也可能存在。例如,在Blue Gene或Cray或使用硬件分区管理MPI作业的任何其他系统上,在整个MPI作业完成之前,不会释放其他资源。如果程序在资源管理器(例如SGE,LSF,Torque,PBS,SLURM等)的控制下在集群或其他系统上运行,也会出现这种情况。
我对此类案件的惯常做法非常务实:
int size, rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (size != process_limit)
{
if (rank == 0)
printf("Please run this program with %d MPI processes\n", process_limit);
MPI_Finalize();
exit(1);
}
您也可以使用MPI_Abort(MPI_COMM_WORLD, 0);
代替MPI_Finalize()
来惹恼用户:)
您也可以使用MPI的过程产生功能,但这会使代码变得更加复杂,因为您必须处理相互通信器。
答案 1 :(得分:4)
这可能是一个延伸的评论而不是一个答案,但是直到Hristo Iliev出现这可能会有所帮助......
我不确定你能做你想做的事。我相信如果您尝试使用非MPI功能(例如Linux kill
)终止MPI进程,则MPI运行时将崩溃,因为其中一个进程已意外退出。您报告的错误消息往往支持我的想法。
您可以在不需要的进程上调用MPI_FINALIZE
,但请注意,MPI标准不要求底层操作系统进程(或线程或其他)实际停止。对MPI_FINALIZE
的调用完成了待处理的MPI操作,并阻止对该进程的(几乎所有)MPI函数的进一步调用。这可能不是你想要的。我想你可能会幸运kill
已经完成的过程,MPI运行时可能不会崩溃;这不是我曾尝试过的。
您可以采用不同的方法并使用MPI的功能生成新流程;在一个进程上启动程序,然后生成程序使用的数字,调用MPI_SPAWN_PROCESS
及其关系。除了MPI例程之外,您还需要调查产生如何与平台的流程管理进行交互。您可能会发现系统未配置为通过运行MPI作业来允许动态进程管理。
答案 2 :(得分:0)
简单
<块引用>杀死mpiexec.exe
在 Windows 上,所有连接的进程(mpiexec.exe、PMI proxy.exe、IMB MPI1.exe)都将被终止。