3

我将 OpenMPI 与 C 绑定一起使用。在我的代码中,有一定数量的进程。如果执行 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

3 回答 3

5

除了以下内容外,我没有太多要添加到高性能标记已经编写的内容。您实际上可以调用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 的进程生成功能,但这会使代码更加复杂,因为您必须处理相互通信器。

于 2012-12-08T12:05:52.797 回答
4

这可能是一个扩展评论而不是答案,但在 Hristo Iliev 出现之前,这可能会有所帮助......

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

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

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

于 2012-12-08T11:11:58.867 回答
0

简单地

杀死 mpiexec.exe

在 Windows 上,所有连接的进程(mpiexec.exe、PMI proxy.exe、IMB MPI1.exe)将被终止。

于 2021-06-25T08:00:23.310 回答