使用含重复秩[0,0]创建MPI_Group/MPI_Comm的行为探究
使用含重复秩的数组创建MPI_Group/MPI_Comm的标准行为
问题背景
我想明确MPI标准规定下,使用包含重复秩(如两次0)的数组创建MPI_Group/MPI_Comm时的行为,当前使用OpenMPI 4.1.0。测试中遇到了错误和程序挂起的情况,且未在MPI标准文档中找到相关描述。
测试代码
#include <iostream> #include <mpi.h> int main (int argc, char ** argv) { MPI_Init(&argc, &argv); int idProc, nbProc; MPI_Comm_rank(MPI_COMM_WORLD,&idProc); MPI_Comm_size(MPI_COMM_WORLD,&nbProc); if (idProc == 0 || idProc == 1){ MPI_Group worldGroup; MPI_Comm_group(MPI_COMM_WORLD, &worldGroup); int* ranks = new int[2]; ranks[0] = 0; ranks[1] = 0; MPI_Group intrfGroup; MPI_Group_incl(worldGroup, 2, ranks, &intrfGroup); MPI_Comm mpiComm; std::cout << "MPI_Comm_create_group before ! By proc " << idProc << std::endl; MPI_Comm_create_group(MPI_COMM_WORLD, intrfGroup, 0, &mpiComm); std::cout << "MPI_Comm_create_group after ! By proc " << idProc << std::endl; int result; MPI_Comm_compare(mpiComm, MPI_COMM_WORLD, &result); if (result == MPI_IDENT) { std::cout << "mpiComm is MPI_COMM_WORLD." << std::endl; } else { std::cout << "mpiComm is not MPI_COMM_WORLD." << std::endl; } } MPI_Finalize(); }
运行结果
情况1:进程0和1执行相关逻辑
[ACH@is227051 bin]$ mpiexec -n 4 Allreduce MPI_Comm_create_group before ! By proc 1 MPI_Comm_create_group after ! By proc 1 MPI_Comm_create_group before ! By proc 0 [is227051:03157] *** An error occurred in MPI_Comm_compare [is227051:03157] *** reported by process [3464888321,1] [is227051:03157] *** on communicator MPI_COMM_WORLD [is227051:03157] *** MPI_ERR_COMM: invalid communicator [is227051:03157] *** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort, [is227051:03157] *** and potentially your MPI job)
情况2:仅进程0执行相关逻辑
[ACH@is227051 bin]$ mpiexec -n 4 Allreduce MPI_Comm_create_group before ! By proc 0
程序挂起无后续输出。
标准行为与问题分析
MPI标准规定:
MPI标准明确要求,调用MPI_Group_incl时传入的秩数组必须包含无重复的、属于原组的有效秩。重复秩属于非法输入,会触发未定义行为——标准不保证任何特定结果,具体表现依赖MPI实现。测试现象解释:
- 情况1的错误:OpenMPI 4.1.0中,传入重复秩创建组后,调用
MPI_Comm_create_group时,进程0未能成功创建有效的通信子(mpiComm未被正确初始化),后续MPI_Comm_compare使用无效通信子,触发MPI_ERR_COMM错误。 - 情况2的挂起:
MPI_Comm_create_group是集体操作,原通信子中的所有进程都必须调用该函数(不在新通信子中的进程可传入MPI_GROUP_EMPTY)。仅进程0调用时,其他进程会等待集体操作完成,导致程序挂起。
- 情况1的错误:OpenMPI 4.1.0中,传入重复秩创建组后,调用
正确做法:
确保传入MPI_Group_incl的秩数组无重复、且每个秩都是原组内的有效值。如果需要创建包含重复逻辑的通信子,应通过其他合法方式实现,避免依赖非标准的实现行为。
内容的提问来源于stack exchange,提问作者Thibault Cimic
相关产品推荐
相关产品推荐

