无法实现MPI_Intercomm_create

时间:2016-07-13 15:32:33

标签: parallel-processing fortran mpi fortran90 openmpi

我正在尝试在Fortran中实现一个MPI_intercomm在两个交互器之间,一个具有前2个进程,另一个具有其余的进程。 我需要在新创建的通信器之间执行send,recv操作。

代码:

program hello
include 'mpif.h'
integer tag,ierr,rank,numtasks,color,new_comm,inter1,inter2

tag = 22
call MPI_Init(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD,rank,ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,numtasks,ierr)

if (rank < 2) then
color = 0
else 
color = 1
end if

call MPI_COMM_SPLIT(MPI_COMM_WORLD,color,rank,new_comm,ierr)

if (color .eq. 0) then

call MPI_INTERCOMM_CREATE(new_comm,0,MPI_Comm_world,1,tag,inter1,ierr)

!local_comm,local leader,peer_comm,remote leader,tag,new,ierr

else if(color .eq. 1) then      
call   MPI_INTERCOMM_CREATE(new_comm,1,MPI_COMM_WORLD,0,tag,inter2,ierr)
end if

select case (color)
case (0)
call    MPI_COMM_FREE(inter1)       
case(1)
 call mpi_comm_free(inter2) 

end select

call MPI_finalize(ierr)
end

代码编译没有任何问题。但是在跑步时卡住了,有时会出现错误。

1 个答案:

答案 0 :(得分:3)

简短回答:问题来自remote_leader

的规范

答案很长: 我假设您的分裂逻辑是您想要的:处理颜色0中的0和1以及颜色1的世界其他地方,并且您将始终拥有3个以上的进程。 你必须选择:

  • 每种颜色的local_leader。这是每个组领导者的本地沟通者(在您的案例中为new_comm)中的排名。无头痛的方法是选择等级0的过程,因为这是本地通信器中的等级,所有过程都可以具有完全相同的值。所以我选择等级0。

  • 每种颜色的remote_leader;这必须是交流员另一端领导者的peer_comm(在您的情况下为MPI_Comm_world)中的排名。这意味着,颜色0的过程必须知道0中颜色1中的MPI_Comm_world对应的进程;和颜色处理1必须知道0中颜色0中的哪个处理MPI_Comm_world对应。根据您的分裂逻辑和选择本地领导者的逻辑,remote_leader必须为颜色0处理2,并为颜色0处理1

你应该很好地使用这些修改过的代码行:

if (color .eq. 0) then
    if(rank==0) print*, ' 0 here'
    call MPI_INTERCOMM_CREATE(new_comm,0,MPI_Comm_world,2,tag,inter1,ierr)

else if(color .eq. 1) then
    if(rank==2) print*, ' 2 here'
    call   MPI_INTERCOMM_CREATE(new_comm,0,MPI_COMM_WORLD,0,tag,inter2,ierr)
end if

与您的代码最重要的区别是,remote_leader对于颜色20。这是问题的根源。 次要的区别在于{1}}对于颜色1是local_leader。这与我选择0的逻辑相对应。这不是问题的根源,但是,如果您只有local_leader彩色1处理,那就可以了。

更新

感谢Hristo Iliev,我正在添加此更新。如果您的目标是将颜色1的流程1用作1,那么颜色local_leader的{​​{1}}应为remote_leader,代码将为:

0

请确保检查此选项的所有内容,因为我没有特别注意检查它。另外,请确保您总是拥有3彩色if (color .eq. 0) then if(rank==0) print*, ' 0 here' call MPI_INTERCOMM_CREATE(new_comm,0,MPI_Comm_world,3,tag,inter1,ierr) else if(color .eq. 1) then if(rank==2) print*, ' 2 here' call MPI_INTERCOMM_CREATE(new_comm,1,MPI_COMM_WORLD,0,tag,inter2,ierr) end if 进程。