除了以下内容,我没有什么可以添加到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的过程中产卵的特点,但是这会使代码更复杂,因为你不得不处理对讲机。
感谢您和惠普商标的有用评论。我最终只是允许额外的进程完成并从主返回。这样可以释放桌面上的资源,但当然,这并不是它在“真实”环境中执行操作的好指标。我将提交我的工作(在我使用的IBM Bladecenter上使用LSF)并查看会发生什么。然而,你的高度务实的方法可能只是票据,尤其是因为在我的情况下,我总是事先知道有多少个进程产生,只有我将运行代码。 – synaptik