有时,计算任务不需要所有排名。我正在尝试根据需要定制通信器,但MPI似乎在减少的通信器构建后停止(等级= 8)。 MPI调试说PMPI_Comm_rank中的致命错误:无效的通信器'。我的基本代码是:
PROGRAM mpi_comm_create
USE MPI
IMPLICIT NONE
INTEGER comm,i,ierr,group,rank,rank1,root,size,size1,redcomm,redgroup
INTEGER,ALLOCATABLE::ranks(:)
comm=MPI_COMM_WORLD
!---------------------------------------------------------------------------
CALL MPI_init(ierr)
CALL MPI_comm_size(comm,size,ierr)
CALL MPI_comm_rank(comm,rank,ierr)
CALL MPI_comm_group(comm,group,ierr)
!--------------------------------------------------------------------------
size1=size-2
ALLOCATE(ranks(size1))
ranks(1:size1)=[0:size1-1]
!---------------------------------------------------------------------------
!Define new group redgroup and communicator redcomm with size1 processes
CALL MPI_group_incl(group,size1,ranks,redgroup,ierr)
CALL MPI_comm_create(comm,redgroup,redcomm,ierr)
CALL MPI_comm_rank(redcomm,rank1,ierr)
!---------------------------------------------------------------------------
!Use redcomm in a REDUCE operation
!---------------------------------------------------------------------------
CALL MPI_group_free(redgroup,ierr)
CALL MPI_comm_free(redcomm,ierr)
!---------------------------------------------------------------------------
CALL MPI_FINALIZE(ierr)
DEALLOCATE(ranks)
STOP; END
答案 0 :(得分:0)
首先使用MPI_COMM_SPLIT - 如回复您基本相同的早期问题所示,它更容易。
其次,错误是因为所有进程都在对mpi_comm_rank进行第二次调用,但并非所有进程都在该调用中指定的通信器中。
答案 1 :(得分:0)
崩溃的根本原因是MPI_Comm_rank()
上的rank [size1:size-1] invoke MPI_COMM_NULL
,这是不允许的,因为MPI_COMM_NULL
不是有效的沟通者。为了摆脱崩溃,您可以替换
CALL MPI_comm_rank(redcomm,rank1,ierr)
与
IF (MPI_COMM_NULL.ne.redcomm) CALL MPI_comm_rank(redcomm,rank1,ierr)
从效果的角度来看(这是您的问题的真正含义),我认为MPI_Comm_create()
和MPI_Comm_split()
之间没有任何显着差异。
从语义的角度来看,MPI_Comm_split()
和MPI_Comm_create()
都是集体操作,必须通过MPI_COMM_WORLD
的所有 MPI任务调用它们。如果MPI任务[size1:size-1]不能/不应该参与redcomm
的创建,那么你可以使用MPI_Comm_create_group()
,这只应该由MPI任务调用[0:size1-1 ]
如果所有任务都可以参与redcomm
的创建,那么我建议您坚持MPI_Comm_split()
以保持代码更简单。如果您不需要MPI任务[size1:size-1]成为有效沟通者redcomm
的一部分,那么我还建议您对这些任务使用color=MPI_UNDEFINED
,因此redcomm
将{ {1}}而不是有效的沟通者。但请记住MPI_COMM_NULL
不是有效的沟通者,因此您的代码不可以调用MPI_COMM_NULL
,MPI_Comm_rank()
,MPI_Comm_size()
和其他子程序就可以了。