MPI杀死不需要的进程

syn*_*tik 3 c 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).
Run Code Online (Sandbox Code Playgroud)

Hri*_*iev 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
Run Code Online (Sandbox Code Playgroud)

此代码首先获取进程组,MPI_COMM_WORLD然后创建一个新组,从中排除所有进程process_limit.然后它从新进程组创建一个新的通信器.该MPI_COMM_CREATE操作将MPI_COMM_NULL在这些不属于新组的进程中返回,并且此事实用于终止此类进程.鉴于在此之后一些过程将"消失" MPI_COMM_WORLD,它不再可用于广播,障碍等集体操作,而newworld应该使用它们.

此外,正如马克指出的那样,在一些架构上,额外的进程实际上可能会在它们返回后仍然存在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);
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用MPI_Abort(MPI_COMM_WORLD, 0);而不是MPI_Finalize()惹恼用户:)

您还可以使用MPI的进程生成功能,但这会使代码更加复杂,因为您必须处理相互通信器.