2012-12-08 42 views
2

我正在使用OpenMPI和C绑定。在我的代码中,需要一些进程。如果MPI执行时会打开比所需更多的进程,我希望终止或终止额外的进程。我怎样才能做到这一点?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). 

回答

4

除了以下内容,我没有什么可以添加到High Performance 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,扭矩,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的过程中产卵的特点,但是这会使代码更复杂,因为你不得不处理对讲机。

+0

感谢您和惠普商标的有用评论。我最终只是允许额外的进程完成并从主返回。这样可以释放桌面上的资源,但当然,这并不是它在“真实”环境中执行操作的好指标。我将提交我的工作(在我使用的IBM Bladecenter上使用LSF)并查看会发生什么。然而,你的高度务实的方法可能只是票据,尤其是因为在我的情况下,我总是事先知道有多少个进程产生,只有我将运行代码。 – synaptik

3

这或许是一个扩展的意见,而不是一个答案,但直到里斯托·利维走来这可能帮助...

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

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

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

+0

我感到受宠若惊:) –

+0

谢谢惠普马克。我前天刚开始学习MPI,听到很明显有很多经验的人很棒。 – synaptik