Fortran 为什么这个MPI_SENDRECV是死锁?
这是我的第一篇文章。提前感谢您的帮助。这是用于测试MPI_SENDRECV的非常短的代码,我不理解。但这是僵局谁能告诉我为什么Fortran 为什么这个MPI_SENDRECV是死锁?,fortran,mpi,Fortran,Mpi,这是我的第一篇文章。提前感谢您的帮助。这是用于测试MPI_SENDRECV的非常短的代码,我不理解。但这是僵局谁能告诉我为什么 PROGRAM sendrecv INCLUDE "mpif.h" INTEGER ibuf(20) CALL MPI_INIT(ierr) CALL MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr) CALL MPI_COMM_RANK(MPI_COMM_WORLD, myrank, ierr) a=1
PROGRAM sendrecv
INCLUDE "mpif.h"
INTEGER ibuf(20)
CALL MPI_INIT(ierr)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, myrank, ierr)
a=1
b=2
if (myid == 0) then
call mpi_sendrecv(a,1,mpi_real,1,0,
. b,1,mpi_real,1,0,
. MPI_COMM_WORLD, status,ierr)
elseif (myid == 1) then
call mpi_sendrecv(b,1,mpi_real,0,0,
. a,1,mpi_real,0,0,
. MPI_COMM_WORLD,status,ierr)
end if
if (myid.eq.0) then
write(*,*) a
endif
if (myid.eq.1) then
write(*,*) b
endif
CALL MPI_FINALIZE(ierr)
END
正如@SteveBlackwell所指出的,您使用的是
myid
而不是myrank
。如果您使用:
CALL MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
相反,你会走到一半。这里出现死锁是因为两个处理器(可能)都具有myid=0
(注意,此行为依赖于编译器——其他编译器可能会将其设置为某个奇怪的数字,并且您的程序看起来可以工作,但不会传递任何消息)
第二个问题是,status
隐式声明为实变量,但MPI需要一个大小为MPI\u status\u size
的整数数组。这可能会产生各种各样的影响——您可能会遇到segfault,或者更糟的是,一些奇怪的内存错误,因为MPI正在写入不应该写入的缓冲区。(或者,您可以使用MPI\u STATUS\u IGNORE
,因为您没有对状态执行任何操作)
正如@HighPerformanceMark所指出的,最好的做法是显式键入程序中的所有内容,并使用
IMPLICIT NONE
来避免这些类型的问题。换句话说,如果您的子例程/模块/函数/主程序在声明中没有隐式的NONE,您应该有一个很好的理由。一:您使用myrank
,但稍后检查myid
。第二:是《国家公共广播公司法》>2吗?@SteveBlackwell——关于myrank
/myid
的好观点。这就是为什么implict none
很有用的原因。为什么nproc>2
很重要?也许我只是没有看到……在Fortran程序中,总是编写隐式无
@Steve Blackwell是的,非常感谢。最好是完全删除myid
并坚持使用myrank
,或者删除myrank
并使用myid
。同一事物有两个名称只会让人困惑,正如问题所指出的那样。@HighPerformanceMark--当然。我只是在解释什么是错的。无论如何,我已经添加了一行,说明用户应该将它们更改为使用相同的名称。很好的评论。我修改了代码,现在它可以工作了,谢谢同志们,我不相信我自己在发布问题后能很快得到帮助,我真的很感动,我在编程方面很差劲。谢谢你的时间!