如果使用的不是直接从MPI_COMM_WORLD创建的组,则fortran MPI_COMM_CREATE_GROUP中的段错误

时间:2019-03-19 22:52:11

标签: fortran mpi intel-fortran intel-mpi

我遇到了一个细分错误,我无法用一个简单的代码真正地理解它,即:

  • 呼叫MPI_INIT
  • 通过MPI_COMM_DUP复制全局通信器
  • 通过MPI_COMM_GROUP创建一个具有全球通信器一半流程的组
  • 最后从该组中通过MPI_COMM_CREATE_GROUP创建一个新的通信器

具体地说,我使用了最后一个调用,而不是仅使用MPI_COMM_CREATE,因为它仅是组中包含的一组进程的集合,而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,而是直接从全局通信器(注释行)创建组,则一切正常。

我正在使用的并行调试器将seg错误追溯到对MPI_GROUP_TRANSLATE_RANKS的调用,但是据我所知,MPI_COMM_DUP复制了 all 的复制的通信器的属性,其中包括了编号

我使用的是ifort版本18.0.5,但我也尝试使用17.0.4和19.0.2,但没有更好的结果。

2 个答案:

答案 0 :(得分:0)

至少对我来说,这有点棘手,但是经过一些测试和帮助,才发现问题的根源。

在代码中

CALL mpi_comm_create_group(mpi_comm_world, mpi_new_group, 0, mpi_new_comm, mpi_err_code)

以前为mpi_new_group组创建了一个新的传播者 创建。但是,用作第一个参数的mpi_comm_worldmpi_new_group的上下文不同,如mpich reference中所述:

  

MPI_COMM_DUP将在与该组相同的组上创建一个新的通信器。   交流但具有新的上下文

因此正确的呼叫应为:

CALL mpi_comm_create_group(my_comm_copy, mpi_new_group, 0, mpi_new_comm, mpi_err_code)

即,将mpi_comm_world的{​​{1}}替换为my_comm_copy

我仍然不确定为什么它可以与OpenMPI一起使用,但是通常更宽容 这类事情。

答案 1 :(得分:0)

就像我在写给openmpi用户列表的评论中建议的那样,他们回答了

  

那是完全正确的。组成该组的MPI流程都是comm世界的一部分。我会向英特尔MPI提交错误。

因此,我尝试在英特尔论坛上发布question。 他们在libray的最新版本19.3中解决了这个错误。