MPI的组没有正确分配处理器的等级

3
我有以下MPI/fortran代码,用于创建两个组,一个包含处理器总数的前2/3,另一个包含剩余的1/3。它可以编译通过,但是当我打印新的排名(在最近创建的组中)时,只有第二个组显示正确的排名,第一个组中的进程显示负数。
您对此问题有何评论? 谢谢。
program test

    implicit none
    include "mpif.h"
    integer, allocatable :: rs_use(:),ks_use(:)
    integer numnodes,myid,mpi_err
    integer ijk,new_group,old_group,num_used,used_id
    integer proc_rs,proc_ks
    integer RSPA_COMM_WORLD    !Real Space communicator
    integer KSPA_COMM_WORLD    !Recip. Space communicator

! initialize mpi
    call MPI_INIT( mpi_err )
    call MPI_COMM_SIZE( MPI_COMM_WORLD, numnodes, mpi_err )
    call MPI_Comm_rank(MPI_COMM_WORLD, myid, mpi_err)

    proc_rs = 2*numnodes/3            !Nr. of processors for Real Space
    proc_ks = numnodes - proc_rs      !Nr. of processors for Recip.  Space

    write(6,*) 'processors rs',proc_rs,'ks',proc_ks

! get our old group from MPI_COMM _WORLD
    call MPI_COMM_GROUP(MPI_COMM_WORLD,old_group,mpi_err)

! Real Space group  that will contain 2*N/3 processors
    allocate(rs_use(0:proc_rs-1))
    do ijk=0,proc_rs-1
        rs_use(ijk)=ijk
    enddo
    call MPI_GROUP_INCL(old_group,proc_rs,rs_use,new_group,mpi_err)
! create the new communicator
    call MPI_COMM_CREATE(MPI_COMM_WORLD,new_group,RSPA_COMM_WORLD, mpi_err)
! test to see if I am part of new_group.
    call MPI_GROUP_RANK(new_group,used_id, mpi_err)

! Recip.  Space group  that will contain N/3 processors
    allocate(ks_use(proc_rs:numnodes-1))
    do ijk=proc_rs,numnodes-1
        ks_use(ijk)=ijk
    enddo
    call MPI_GROUP_INCL(old_group,proc_ks,ks_use,new_group,mpi_err)
! create the new communicator
    call MPI_COMM_CREATE(MPI_COMM_WORLD,new_group,KSPA_COMM_WORLD, mpi_err)
! test to see if I am part of new_group.
    call MPI_GROUP_RANK(new_group,used_id, mpi_err)

    if(used_id==0) write(6,*) 'group ',used_id,myid


end program test

2
您没有测试任何MPI例程调用的成功与否,也没有测试“分配”语句的成功与否。为什么我不能得出结论,其中一个调用将悄无声息地失败? - High Performance Mark
嗨,我测试了allocate和MPI例程,感谢建议。然而,我仍然有问题,第一组的used_id打印出负数。 - armando
@innoSPG 给出了正确的答案,但我想再提供两个一般性的建议:(1) 在现代 Fortran 中,强烈建议使用 use mpi 而不是 include "mpif.h",让编译器在编译时为您找到整个类别的潜在问题。(2) 在这种情况下,您要将现有通信器分成两个不重叠的子集,使用 MPI_Comm_split 更容易。 - Jonathan Dursi
1个回答

2
问题在于只有属于该组的进程才在该组中拥有id。您需要做的是仅在进程所属的适当进程组中设置new_group,并在将每个进程包含在其新组之后检查新的id。例如,使用临时变量tmp_group调用MPI_COMM_CREATE,仅将其分配给组的进程。对于第一次调用MPI_COMM_CREATE,您可以这样做:
call MPI_GROUP_RANK(tmp_group,used_id, mpi_err)
if(myid<proc_rs) new_group = tmp_group

对于第二次调用MPI_COMM_CREATE,您需要这样做:
call MPI_GROUP_RANK(tmp_group,used_id, mpi_err)
if(myid>=proc_rs) new_group = tmp_group

在完成所有这些步骤之后,您可以检查所有项目的新排名:

call MPI_GROUP_RANK(new_group,used_id, mpi_err)

如果您选择在创建组后立即检查组中的排名,请确保只有属于该组的进程调用。但这不是一个好主意,因为您可能不会保存新建的组。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接