【问题标题】:Multiple communicators in MPIMPI 中的多个通信器
【发布时间】:2017-12-17 02:27:40
【问题描述】:

这个问题的背景是一些计算领域,例如计算流体动力学 (CFD)。我们经常在一些关键区域需要更精细的网格/网格,而背景网格可能更粗糙。例如,自适应细化网格可跟踪气象学中的冲击波和嵌套域。

使用笛卡尔拓扑,域分解如下图所示。在这种情况下,使用 4*2=8 个处理器。单个数字表示处理器的等级,(x,y) 表示其拓扑坐标。

假设网格在等级为 2、3、4、5(中间)的区域中进行了细化,在这种情况下,局部细化率定义为 R=D_coarse/D_fine=2。由于网格是细化的,所以时间推进也应该细化。这需要在细化区域中计算时间步长 t、t+1/2*dt、t+dt,而在全局区域中仅计算时间步长 t 和 t+dt。这需要一个较小的通信器,它只包括中间的秩以进行额外的计算。全局等级+坐标和对应的局部坐标(红色)示意图如下:

但是,我在执行此方案时遇到了一些错误,并且显示了 Fortran 中的 sn-p 代码(不完整):

integer :: global_comm, local_comm   ! global and local communicators
integer :: global_rank, local_rank   !
integer :: global_grp,  local_grp    ! global and local groups
integer :: ranks(4)                  ! ranks in the refined region
integer :: dim                       ! dimension
integer :: left(-2:2), right(-2:2)   ! ranks of neighbouring processors in 2 directions
ranks=[2,3,4,5]

!---- Make global communicator and their topological relationship
call mpi_init(ierr)
call mpi_cart_create(MPI_COMM_WORLD, 2, [4,2], [.false., .false.], .true., global_comm, ierr)
call mpi_comm_rank(global_comm, global_rank, ierr)
do dim=1, 2
    call mpi_cart_shift(global_comm, dim-1, 1, left(-dim), right(dim), ierr)
end do


!---- make local communicator and its topological relationship
! Here I use group and create communicator

! create global group
call mpi_comm_group(MPI_COMM_WORLD, global_grp, ierr)

! extract 4 ranks from global group to make a local group
call mpi_group_incl(global_grp, 4, ranks, local_grp, ierr)

! make new communicator based on local group
call mpi_comm_create(MPI_COMM_WORLD, local_grp, local_comm, ierr)

! make topology for local communicator
call mpi_cart_create(global_comm, 2, [2,2], [.false., .false.], .true., local_comm, ierr)

! **** get rank for local communicator
call mpi_comm_rank(local_comm, local_rank, ierr)

! Do the same thing to make topological relationship as before in local communicator.
 ...

当我运行程序时,问题来自“**** 获取本地通信器的排名”步骤。我的想法是构建两个通信器:全局和本地通信器,本地通信器嵌入到全局通信器中。然后分别在全局和局部通信器中创建它们对应的拓扑关系。如果我的概念错误或某些语法错误,我不会。如果您能给我一些建议,非常感谢。

错误信息是

*** An error occurred in MPI_Comm_rank
 *** reported by process [817692673,4]
 *** on communicator MPI_COMM_WORLD
 *** MPI_ERR_COMM: invalid communicator
 *** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,
 ***    and potentially your MPI job)

【问题讨论】:

  • 您在ierr 中获得了操作状态,您是否尝试在每次操作后和每个级别上检查这些以验证到目前为止的所有操作是否确实有效?
  • 我之前总是使用粗略的背景网格设置(只有一个全局通信器),这没问题。当我测试 2 个通信器案例时,如果我评论来自 ! 的所有内容,程序运行良好。 **** 步骤(本地通信器的 mpi_comm_rank)和错误消息如上所示。我还在调用 mpi_comm_rank 步骤后添加了一个命令来测试 ierr 是否等于 0,但此命令未执行,并且程序在调用 mpi_comm_rank 步骤中中止并出现错误。
  • 为什么要创建两次local_comm? (例如,首先使用mpi_comm_create(),然后使用mpi_cart_create()
  • @GillesGouaillardet mpi_comm_create() 是创建一个只有 4 个等级的较小的通信器。中间区域应该做一些独立的计算,所以它需要与相邻的处理器通信,并且通过本地通信器中的 mpi_cart_creat() 构建笛卡尔拓扑
  • @GillesGouaillardet 确实,我发现了问题所在。我创建了 local_comm 两次。在mpi_cart_create() 步骤中,我应该使用local_comm 作为旧通信器来创建新的笛卡尔通信器。谢谢

标签: fortran mpi fluid-dynamics


【解决方案1】:

您正在从包含八个等级的全局通信器组创建一个 2x2 笛卡尔拓扑。因此,在其中四个中,MPI_Cart_create 返回的local_comm 的值将是MPI_COMM_NULL。在 null 通信器上调用 MPI_Comm_rank 会导致错误。

如果我正确理解您的逻辑,您应该改为:

if (local_comm /= MPI_COMM_NULL) then
  ! make topology for local communicator
  call mpi_cart_create(local_comm, 2, [2,2], [.false., .false.], .true., &
                     local_cart_comm, ierr)

  ! **** get rank for local communicator
  call mpi_comm_rank(local_cart_comm, local_rank, ierr)

  ...
end if

【讨论】:

  • 谢谢。实际上,该步骤使本地组中的本地通信器为local_comm 提供4 个MPI_COMM_NULL 值。如果我直接做! make topology for local communicator call mpi_cart_create(local_comm, 2, [2,2], [.false., .false.], .true., & local_cart_comm, ierr)这个就不能执行了。所以我在mpi_cart_create() 之前使用if (local_comm /= mpi_comm_null) 条件来生成local_cart_comm
  • 当然,我犯了我在第一段中描述的同样的错误:)
猜你喜欢
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 2012-04-26
  • 2018-03-04
  • 1970-01-01
  • 2018-04-03
  • 2022-01-01
  • 2018-04-06
相关资源
最近更新 更多