【问题标题】:MPI_BCAST() applied on only a fraction of the base groupMPI_BCAST() 仅应用于基组的一小部分
【发布时间】:2014-07-18 11:12:59
【问题描述】:

我将 8 个处理器分成两组,每组平均包含四个处理器。我要求每个子组的根使用子程序“MPI_BCAST”与他们的下属进行一些通信。

我遇到一个问题:要表示子组的根,我应该使用 MPI_COMM_WORLD 通信器与子组根对应的原始排名,还是用新通信器表示的新排名?

以下面的代码 sn-p 为例,我想要求 P:0 向它的下属 P:1、P:2 和 P:3 发送数据,同样我要求 P:4 发送出去其数据为 P:5, P:6, P:7。为了达到这个目标,我想知道是否应该将第 36 行中的第四个参数指定为 1,或者将它们分别指定为 0 和 4,条件是我指的是哪个子组的头部?

谢谢。 李

1  program main
2    include 'mpif.h'
3    integer :: ierr, irank, num_procs, base_group
4    integer :: nrow, ncol, irow, icol
5    integer :: dummy_group, dummy_comm, new_comm, new_rank
6    integer :: i, j, roster(4), data(4)
7    
8    call MPI_Init ( ierr )
9    call MPI_COMM_RANK( MPI_comm_world, irank, ierr )
10   call MPI_COMM_SIZE( MPI_comm_world, num_procs, ierr)
11   call MPI_COMM_GROUP( MPI_comm_world, base_group, ierr)
12   nrow = 4
13   ncol = 2
14   irow = mod( irank, nrow )  + 1
15   icol = irank/nrow + 1
16   
17   roster(1) = 0
18   do i = 2, nrow
19       roster(i) = roster(i-1) + 1        
20   enddo
21   
22   do i = 1, ncol
23    call MPI_GROUP_INCL( base_group, nrow, roster, dummy_group, ierr )
24    call MPI_COMM_CREATE( MPI_COMM_WORLD, dummy_group, dummy_comm, ierr ) 
25    if( icol == i ) new_comm = dummy_comm
26    forall( j=1:nrow ) roster(j) = roster(j) + nrow
27   enddo
28   
29   ! Here I want to initialize data for processors P:0 and P:4
30   if( irank == 0 ) data = 0
31   if( irank == 4 ) data = 4
32   
33   ! In the code below I want to require P:0 to send data to 
34   ! its subordinates P:1, P:2, and P:3. Similarly, I ask P:4 
35   ! to send out its data to P:5, P:6, P:7.
36   call MPI_BCAST( data, 4, MPI_INTEGER, 0, new_comm, ierr)
37   
38   call MPI_Finalize ( ierr ) 
39 end program

【问题讨论】:

    标签: parallel-processing fortran mpi fortran90


    【解决方案1】:

    MPI 中的所有等级类型参数(起点、目标等)必须在与通讯器参数给出的相同通讯器中的等级。实际上,这意味着在创建一个新的通信器之后,该通信器中的每个进程都必须调用 MPI_Comm_rank 和 MPI_Comm_size 来检索它的排名以及 通信器中的总大小(除非您可以推断出新的排名当然,在您的代码中通过其他方式和大小)。

    顺便说一句,由于您正在做的是将原始通信器拆分为两个不相交的通信器,我认为更简单的方法是使用 MPI_Comm_split 而不是像您所做的那样手动设置组。

    【讨论】:

    • 感谢您的回复。由于在我的实际程序中处理器的不均匀划分,我选择使用这种替代方法,而不是使用 MPI_Comm_split。经过反复试验,我终于得到了我想要的,将第 36 行的第四个参数设置为 0,这意味着并行协议自动将每个新子组根的等级指定为 0,而不是 1(这是一个错误)或 0和 4(与协议工作方式不一致的规范)。
    • 还可以使用不知名的MPI_Group_translate_ranks 将进程在原始组中的排名转换为它在新组中的排名。当一个人分裂通讯器并且不知道新的等级编号是什么时,例如如果所有等级都为拆分调用提供了相同的密钥。
    猜你喜欢
    • 2015-11-20
    • 2020-03-19
    • 1970-01-01
    • 2020-12-22
    • 2013-11-04
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 2016-04-27
    相关资源
    最近更新 更多