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

问题描述 投票:1回答:2

我有一个我在一个简单的代码中无法理解的分段错误,它只是:

  • 调用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复制了复制的通信器的所有属性,包括了排序编号。

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

fortran mpi intel-fortran intel-mpi
2个回答
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将创建一个与comm相同的组的新通信器,但具有新的上下文

所以正确的电话会是:

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

即,取代mpi_comm_worldmy_comm_copy,这是mpi_group_world创建的那个。

我仍然不确定它为什么使用OpenMPI,但它通常对这类事情更加宽容。


0
投票

就像我写给openmpi用户列表的评论中提到的那样,他们回复了

这完全有效。组成该组的MPI流程都是通信世界的一部分。我会向英特尔MPI提交一个错误。

所以我尝试在英特尔论坛上发布question。这是他们在libray的最后一个版本中解决的一个错误,19.3。

© www.soinside.com 2019 - 2024. All rights reserved.