Fortran 为什么这个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

这是我的第一篇文章。提前感谢您的帮助。这是用于测试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
  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--当然。我只是在解释什么是错的。无论如何,我已经添加了一行,说明用户应该将它们更改为使用相同的名称。很好的评论。我修改了代码,现在它可以工作了,谢谢同志们,我不相信我自己在发布问题后能很快得到帮助,我真的很感动,我在编程方面很差劲。谢谢你的时间!