MPI_BCAST() се прилага само върху част от основната група

Групирах 8 процесора в две групи, всяка от които съдържа по четири процесора. Моля корена на всяка подгрупа да осъществи някаква комуникация със своите подчинени, използвайки подпрограмата "MPI_BCAST."

Попаднах на въпрос: за да посоча корена на подгрупа, трябва ли да използвам оригиналния ранг, на който коренът на подгрупата съответства с комуникатора MPI_COMM_WORLD, или новия ранг, който представлява с новия комуникатор?

Вземете например кодовия фрагмент по-долу, искам да изискам P:0 да изпраща данни на своите подчинени P:1, P:2 и P:3 и по подобен начин моля P:4 да изпрати своите данни на P: 5, Р:6, Р: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

person Li-Pin Juan    schedule 29.05.2014    source източник


Отговори (1)


Всички аргументи от тип ранг (произход, цел и т.н.) в MPI трябва да бъдат класирани в същия комуникатор като този, даден от аргумента на комуникатора. На практика това означава, че след създаването на нов комуникатор, всеки процес в този комуникатор трябва да извика MPI_Comm_rank и MPI_Comm_size, за да извлече своя ранг и общия размер в този комуникатор (освен ако не можете да изведете новия ранг и размер чрез други средства във вашия код, разбира се).

Като настрана, тъй като това, което правите, е да разделите оригиналния комуникатор на два несвързани комуникатора, мисля, че по-лесният начин да постигнете това е да използвате MPI_Comm_split, вместо да настройвате групи ръчно, както сте направили.

person janneb    schedule 29.05.2014
comment
Благодаря за отговора. Вместо да използвам MPI_Comm_split, избрах да използвам този алтернативен подход поради неравномерното разделяне на процесорите в реалната ми програма. След проба и грешка най-накрая получих това, което исках, като зададох четвъртия аргумент в ред 36 на 0, което означава, че протоколът за паралелизъм автоматично определя ранга на всеки нов корен на подгрупа като 0, вместо 1 (което е грешка) или 0 и 4 (спецификация, която не е в съответствие с начина, по който работи протоколът). - person Li-Pin Juan; 29.05.2014
comment
Човек може също да използва неясния MPI_Group_translate_ranks, за да преведе ранга на процес в оригиналната група в ранга, който има в новата група. Полезно е, когато някой раздели комуникатора и няма представа какво е новото ранг номериране, напр. ако един и същ ключ е бил предоставен от всички рангове на разделното повикване. - person Hristo Iliev; 29.05.2014