我有以下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
答案 0 :(得分: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)
如果您选择在创建组后立即检查组中的排名,请确保只有属于该组的进程才会调用。但这不是一个好主意,因为你可能不会保存new_group。