如果使用不是直接从 MPI_COMM_WORLD 创建的组,则 Fortran MPI_COMM_CREATE_GROUP 中的段错误
Seg fault in fortran MPI_COMM_CREATE_GROUP if using a group not directly created from MPI_COMM_WORLD
我有一个分段错误,我无法用简单的代码真正理解它,只是:
- 调用 MPI_INIT
- 复制全局通信器,通过MPI_COMM_DUP
- 通过MPI_COMM_GROUP
创建一个包含全局通信器一半进程的组
- 最终来自该组的人通过 MPI_COMM_CREATE_GROUP
创建了一个新的通讯器
具体来说,我使用了最后一个调用,而不是仅使用 MPI_COMM_CREATE,因为它仅对 group 中包含的进程组进行集体调用,而 MPI_COMM_CREATE 对 COMM 中的每个进程进行集体调用。
代码如下
program mpi_comm_create_grp
use mpi
IMPLICIT NONE
INTEGER :: mpi_size, mpi_err_code
INTEGER :: my_comm_dup, mpi_new_comm, mpi_group_world, mpi_new_group
INTEGER :: rank_index
INTEGER, DIMENSION(:), ALLOCATABLE :: rank_vec
CALL mpi_init(mpi_err_code)
CALL mpi_comm_size(mpi_comm_world, mpi_size, mpi_err_code)
!! allocate and fill the vector for the new group
allocate(rank_vec(mpi_size/2))
rank_vec(:) = (/ (rank_index , rank_index=0, mpi_size/2) /)
!! create the group directly from the comm_world: this way works
! CALL mpi_comm_group(mpi_comm_world, mpi_group_world, mpi_err_code)
!! duplicating the comm_world creating the group form the dup: this ways fails
CALL mpi_comm_dup(mpi_comm_world, my_comm_dup, mpi_err_code)
!! creatig the group of all processes from the duplicated comm_world
CALL mpi_comm_group(my_comm_dup, mpi_group_world, mpi_err_code)
!! create a new group with just half of processes in comm_world
CALL mpi_group_incl(mpi_group_world, mpi_size/2, rank_vec,mpi_new_group, mpi_err_code)
!! create a new comm from the comm_world using the new group created
CALL mpi_comm_create_group(mpi_comm_world, mpi_new_group, 0, mpi_new_comm, mpi_err_code)
!! deallocate and finalize mpi
if(ALLOCATED(rank_vec)) DEALLOCATE(rank_vec)
CALL mpi_finalize(mpi_err_code)
end program !mpi_comm_create_grp
如果我不复制 COMM_WORLD,直接从全局通信器(注释行)创建组,一切正常。
我正在使用的并行调试器将段错误追溯到对 MPI_GROUP_TRANSLATE_RANKS 的调用,但据我所知,MPI_COMM_DUP 重复了 all被复制的通讯器属性,包含军衔编号
我使用的是 ifort 版本 18.0.5,但我也尝试过 17.0.4 和 19.0.2,但没有更好的结果。
事情有点棘手,至少对我来说是这样,但经过一些测试和帮助,找到了问题的根源。
代码中
CALL mpi_comm_create_group(mpi_comm_world, mpi_new_group, 0, mpi_new_comm, mpi_err_code)
为群组 mpi_new_group
创建一个新的通讯器,之前
创建。但是,用作第一个参数的 mpi_comm_world
与 mpi_new_group
不在同一上下文中,如 mpich reference:
中所述
MPI_COMM_DUP
will create a new communicator over the same group as
comm but with a new context
所以正确的调用是:
CALL mpi_comm_create_group(my_comm_copy, mpi_new_group, 0, mpi_new_comm, mpi_err_code)
即,将 mpi_comm_world
替换为 my_comm_copy
,即创建 mpi_group_world
的那个。
我仍然不确定为什么它与 OpenMPI 一起工作,但它通常更宽容
诸如此类。
喜欢我写给 openmpi 用户列表的评论中的建议,他们回复了
That is perfectly valid. The MPI processes that make up the group are all part of comm world. I would file a bug with Intel MPI.
所以我尝试 post 在英特尔论坛上 question。
这是他们在最新版本的库 19.3 中解决的一个错误。
我有一个分段错误,我无法用简单的代码真正理解它,只是:
- 调用 MPI_INIT
- 复制全局通信器,通过MPI_COMM_DUP
- 通过MPI_COMM_GROUP 创建一个包含全局通信器一半进程的组
- 最终来自该组的人通过 MPI_COMM_CREATE_GROUP 创建了一个新的通讯器
具体来说,我使用了最后一个调用,而不是仅使用 MPI_COMM_CREATE,因为它仅对 group 中包含的进程组进行集体调用,而 MPI_COMM_CREATE 对 COMM 中的每个进程进行集体调用。 代码如下
program mpi_comm_create_grp
use mpi
IMPLICIT NONE
INTEGER :: mpi_size, mpi_err_code
INTEGER :: my_comm_dup, mpi_new_comm, mpi_group_world, mpi_new_group
INTEGER :: rank_index
INTEGER, DIMENSION(:), ALLOCATABLE :: rank_vec
CALL mpi_init(mpi_err_code)
CALL mpi_comm_size(mpi_comm_world, mpi_size, mpi_err_code)
!! allocate and fill the vector for the new group
allocate(rank_vec(mpi_size/2))
rank_vec(:) = (/ (rank_index , rank_index=0, mpi_size/2) /)
!! create the group directly from the comm_world: this way works
! CALL mpi_comm_group(mpi_comm_world, mpi_group_world, mpi_err_code)
!! duplicating the comm_world creating the group form the dup: this ways fails
CALL mpi_comm_dup(mpi_comm_world, my_comm_dup, mpi_err_code)
!! creatig the group of all processes from the duplicated comm_world
CALL mpi_comm_group(my_comm_dup, mpi_group_world, mpi_err_code)
!! create a new group with just half of processes in comm_world
CALL mpi_group_incl(mpi_group_world, mpi_size/2, rank_vec,mpi_new_group, mpi_err_code)
!! create a new comm from the comm_world using the new group created
CALL mpi_comm_create_group(mpi_comm_world, mpi_new_group, 0, mpi_new_comm, mpi_err_code)
!! deallocate and finalize mpi
if(ALLOCATED(rank_vec)) DEALLOCATE(rank_vec)
CALL mpi_finalize(mpi_err_code)
end program !mpi_comm_create_grp
如果我不复制 COMM_WORLD,直接从全局通信器(注释行)创建组,一切正常。
我正在使用的并行调试器将段错误追溯到对 MPI_GROUP_TRANSLATE_RANKS 的调用,但据我所知,MPI_COMM_DUP 重复了 all被复制的通讯器属性,包含军衔编号
我使用的是 ifort 版本 18.0.5,但我也尝试过 17.0.4 和 19.0.2,但没有更好的结果。
事情有点棘手,至少对我来说是这样,但经过一些测试和帮助,找到了问题的根源。
代码中
CALL mpi_comm_create_group(mpi_comm_world, mpi_new_group, 0, mpi_new_comm, mpi_err_code)
为群组 mpi_new_group
创建一个新的通讯器,之前
创建。但是,用作第一个参数的 mpi_comm_world
与 mpi_new_group
不在同一上下文中,如 mpich reference:
MPI_COMM_DUP
will create a new communicator over the same group as comm but with a new context
所以正确的调用是:
CALL mpi_comm_create_group(my_comm_copy, mpi_new_group, 0, mpi_new_comm, mpi_err_code)
即,将 mpi_comm_world
替换为 my_comm_copy
,即创建 mpi_group_world
的那个。
我仍然不确定为什么它与 OpenMPI 一起工作,但它通常更宽容 诸如此类。
喜欢我写给 openmpi 用户列表的评论中的建议,他们回复了
That is perfectly valid. The MPI processes that make up the group are all part of comm world. I would file a bug with Intel MPI.
所以我尝试 post 在英特尔论坛上 question。 这是他们在最新版本的库 19.3 中解决的一个错误。