MPI会杀死不需要的进程

我正在使用带有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). 

除了以下内容之外,我没有太多要补充高性能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

另外,正如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的进程生成function,但这会使代码更复杂,因为您必须处理内部通信器。

这可能是一个延伸的评论,而不是一个答案,但直到Hristo Iliev出现这可能有帮助……

我不确定你能做你想做的事。 我相信如果你试图使用非MPIfunction(例如Linux kill )杀死MPI进程,那么MPI运行时将崩溃,因为其中一个进程意外退出。 您报告的错误消息往往支持我的想法。

您可以在不需要的进程上调用MPI_FINALIZE ,但请注意,MPI标准不要求底层操作系统进程(或线程或其他)实际停止。 对MPI_FINALIZE的调用完成了挂起的MPI操作,并阻止进一步调用该进程上的(几乎所有)MPI函数。 这可能不是你想要的。 我想你可能会幸运地kill一个已经完成的进程,MPI运行时间可能不会崩溃; 这不是我曾经尝试过的。

您可以采用不同的方法并使用MPI的function来生成新的流程; 在一个进程上启动程序,然后生成程序使用的数字,调用MPI_SPAWN_PROCESS及其关系。 除了MPI例程之外,您还需要调查产生如何与平台的流程管理进行交互。 您可能会发现系统未配置为通过运行MPI作业来允许动态进程管理。