0

これは私の最初の投稿です。よろしくお願いいたします。これは、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
4

1 に答える 1

0

@SteveBlackwell が指摘したように、myid代わりにmyrank. 使用する場合:

CALL MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr) 

代わりに、あなたはそこにいる途中です。ここでデッドロックが発生します。これは、両方のプロセッサが (おそらく) 持っているためですmyid = 0(注意、この動作はコンパイラに依存します。他のコンパイラはそれを奇妙な数値に設定する可能性があり、プログラムは動作しているように見えますが、メッセージは渡されません)。

2 番目の問題はstatus、実際の変数として暗黙的に宣言されていることですが、MPI は size の整数配列を期待していますMPI_STATUS_SIZE。これにより、あらゆる種類の影響が生じる可能性があります。MPI が書き込みを行うべきではないバッファーに書き込みを行っているため、segfault が発生したり、さらに悪いことに、奇妙なメモリ エラーが発生したりする可能性があります。(または、MPI_STATUS_IGNOREとにかくステータスで何もしていないので、使用できます)。

@HighPerformanceMark で指摘されているように、プログラム内のすべてを明示的に入力し、IMPLICIT NONEこれらのタイプの問題を回避するために使用することをお勧めします。言い換えれば、サブルーチン/モジュール/関数/メイン プログラムの宣言に IMPLICIT NONE がない場合は、十分な理由があるはずです。

于 2012-06-13T13:02:55.263 に答える