Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran MPI中的多个通讯器_Fortran_Mpi_Fluid Dynamics - Fatal编程技术网

Fortran MPI中的多个通讯器

Fortran MPI中的多个通讯器,fortran,mpi,fluid-dynamics,Fortran,Mpi,Fluid Dynamics,这个问题的背景是一些计算领域,如计算流体力学(CFD)。在某些关键区域,我们通常需要更精细的网格/栅格,而背景网格可能更粗糙。例如,用于跟踪冲击波的自适应细化网格和气象学中的嵌套域 使用笛卡尔拓扑,区域分解如下图所示。在这种情况下,使用4*2=8个处理器。单个数字表示处理器的秩,(x,y)表示其拓扑坐标。 假设网格在等级为2、3、4、5(中间)的区域中细化,在这种情况下,局部细化比率定义为R=D_粗略/D_精细=2。由于网格已细化,因此时间推进也应细化。这需要在细化区域中计算时间步长t,t+1

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

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

假设网格在等级为2、3、4、5(中间)的区域中细化,在这种情况下,局部细化比率定义为R=D_粗略/D_精细=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.
 ...
当我运行程序时,问题来自“****获取本地通信器的排名”步骤。我的想法是建立两个通讯器:全局通讯器和本地通讯器,本地通讯器嵌入到全局通讯器中。然后分别在全局和局部通讯器中建立相应的拓扑关系。如果我的概念是错误的或某些语法是错误的,我不知道。如果你能给我一些建议,我将非常感谢

错误消息是

*** 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\u Cart\u create
返回的
local\u comm
值将为
MPI\u comm\u NULL
。在空通信器上调用
MPI\u Comm\u 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

您在
ierr
中获得了操作的状态,您是否尝试在每次操作后和每个列组上检查这些状态,以验证到目前为止所有操作都确实有效?我以前总是使用粗糙的背景网格设置(只有一个全局通信器),这没有问题。当我测试2个通讯器案例时,如果我对来自!****的所有内容进行注释,则程序运行良好步骤(本地通信器的mpi_comm_rank)和错误消息如上所示。我还添加了一个命令来测试调用mpi_comm_rank步骤后ierr是否等于0,但该命令未执行,程序在调用mpi_comm_rank步骤中中止,并出现错误。为什么创建
local_comm
两次?(例如,首先使用
mpi\u comm\u create()
,然后使用
mpi\u cart\u create()
)@GillesGouaillardet mpi\u comm\u create()创建一个只有4个列组的较小的通信器。中间区域应该进行一些独立的计算,因此它需要与相邻处理器进行通信,并且笛卡尔拓扑是由本地的mpi_cart_creat()构建的communicator@GillesGouaillardet事实上,我发现了问题所在。我创建了两次本地通信。在
mpi\u cart\u create()
步骤中,我应该使用
local\u comm
作为旧的通信器来创建新的笛卡尔通信器。谢谢,谢谢。实际上,该步骤使本地组的本地通信器为
local\u COMM
提供4个
MPI\u NULL
值。如果我直接做
!为本地通信器创建拓扑调用mpi\U cart\U create(本地通信,2,[2,2],.false.,.false.],.true.&本地通信,ierr)
此操作无法执行。因此,我使用
if(local\u comm/=mpi\u comm\u null)
条件在
mpi\u cart\u create()之前进行
local\u cart\u comm
。当然,我也犯了我在第一段中描述的同样错误:)