MPI_Comm_spawn_multiple子进程数异常问题求解
问题原因
你遇到的MPI_Comm_size返回值为2的情况是MPI标准定义的默认行为,并非nprocs参数配置错误:
nprocs数组的作用是指定每个待启动命令对应的进程副本数,你将两个元素都设为1,实际确实只启动了2个独立进程,没有额外多启动进程。- 但
MPI_Comm_spawn_multiple单次调用启动的所有子进程,默认会共享同一个子进程侧的MPI_COMM_WORLD通信域,这个通信域的大小是本次调用所有nprocs值的总和,也就是1+1=2,因此每个子进程查询MPI_COMM_WORLD大小时都会得到2,两个子进程会被默认放在同一个全局通信域中。
解决方案
由于你的子进程内置求解器必须运行在单进程MPI_COMM_WORLD环境下,无法修改子进程代码适配通信域拆分,最稳妥、跨MPI实现兼容性最强的方案是放弃单次调用MPI_Comm_spawn_multiple启动两个子进程,改为分两次调用MPI_Comm_spawn分别启动每个子进程,参考代码如下:
MPI_Comm child_comms[2]; // 启动第一个子进程,仅启动1个副本 MPI_Comm_spawn(commands[0], MPI_ARGV_NULL, 1, infos[0], 0, MPI_COMM_SELF, &child_comms[0], errcodes); // 启动第二个子进程,仅启动1个副本 MPI_Comm_spawn(commands[1], MPI_ARGV_NULL, 1, infos[1], 0, MPI_COMM_SELF, &child_comms[1], errcodes);
这种方式下,每次spawn启动的单个子进程会拥有独立的MPI_COMM_WORLD,通信域大小为1,完全满足单进程运行要求。如果后续需要父进程和两个子进程通信,分别使用两个返回的子 intercomm 操作即可。
如果你必须使用MPI_Comm_spawn_multiple单次调用启动,需要根据你使用的MPI发行版配置对应的Info键,告知MPI运行时不要为所有子进程合并全局通信域:
- 对于OpenMPI,给每个infos条目设置键值对:
MPI_Info_set(infos[ic], "ompi_spawn_separate_worlds", "true"); - 对于MPICH及其衍生实现(Intel MPI、MVAPICH等),给每个infos条目设置键值对:
MPI_Info_set(infos[ic], "mpi_split_world_by_command", "true");
注意:上述Info键属于MPI实现的自定义扩展,不同版本支持度存在差异,优先选择两次调用MPI_Comm_spawn的标准方案。
内容的提问来源于stack exchange,提问作者analoy
相关产品推荐
相关产品推荐

