我将8个处理器分为两组,每组包含四个处理器。我要求每个子组的根使用子程序" MPI_BCAST与他们的下属进行一些通信。"
我遇到了一个问题:为了表明子组的根,我应该使用子组根与MPI_COMM_WORLD通信器对应的原始等级,还是使用新通信器代表的新等级?
以下面的代码片段为例,我想要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
答案 0 :(得分:5)
MPI中的所有排名类型参数(起源,目标等)必须与通信者参数给出的排名在同一个通信器中。在实践中,这意味着在创建新的通信器之后,该通信器中的每个进程必须调用MPI_Comm_rank和MPI_Comm_size来检索它的等级以及 通信器中的总大小(除非您可以推断出新的等级)当然,在你的代码中通过其他方式确定大小。
顺便说一句,正如你所做的那样是将原始的沟通者分成两个不相交的沟通者,我认为更简单的方法就是使用MPI_Comm_split,而不是像你一样手动设置组。