MPI 中的多个通信器
Multiple communicators in MPI
这个问题的背景是一些计算领域,例如计算流体动力学(CFD)。我们经常需要在一些关键区域更精细 mesh/grid 而背景网格可以更粗糙。例如自适应细化网格跟踪冲击波和气象学中的嵌套域。
使用笛卡尔拓扑,域分解如下图所示。在这种情况下,使用了 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 代码片段(不完整):
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.
...
当我 运行 程序时,问题来自“ **** 获取本地通信者的排名”这一步。我的想法是构建两个通信器:全局和本地通信器,本地通信器嵌入到全局通信器中。然后分别在global和local communicators中建立它们对应的拓扑关系。如果我的概念错误或某些语法错误,我不会。如果您能给我一些建议,非常感谢。
错误信息是
*** 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)
您正在从包含八个等级的全局通信器组创建 2x2 笛卡尔拓扑。因此,在其中四个中,MPI_Cart_create
返回的 local_comm
的值将是 MPI_COMM_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
这个问题的背景是一些计算领域,例如计算流体动力学(CFD)。我们经常需要在一些关键区域更精细 mesh/grid 而背景网格可以更粗糙。例如自适应细化网格跟踪冲击波和气象学中的嵌套域。
使用笛卡尔拓扑,域分解如下图所示。在这种情况下,使用了 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 代码片段(不完整):
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.
...
当我 运行 程序时,问题来自“ **** 获取本地通信者的排名”这一步。我的想法是构建两个通信器:全局和本地通信器,本地通信器嵌入到全局通信器中。然后分别在global和local communicators中建立它们对应的拓扑关系。如果我的概念错误或某些语法错误,我不会。如果您能给我一些建议,非常感谢。
错误信息是
*** 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)
您正在从包含八个等级的全局通信器组创建 2x2 笛卡尔拓扑。因此,在其中四个中,MPI_Cart_create
返回的 local_comm
的值将是 MPI_COMM_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