異なるプロセッサ間でデータを共有するようにこのアルゴリズムをセットアップしましたが、これまでのところうまくいきましたが、もっと大きな問題を投げかけようとしていて、非常に奇妙な動作が見られます。MPI_Isend と MPI_Recv の間でデータが失われています。
以下にコードのスニペットを示します。基本的に3段階で構成されています。まず、プロセッサは、指定された配列内のすべての要素をループします。各要素は、メッシュ内のセルを表します。プロセッサは、要素が他のプロセッサで使用されているかどうかを確認します。はいの場合、セルの一意のグローバル ID をタグとして使用して、そのプロセスに非ブロック送信を行います。そうでない場合は、次の要素をチェックします。
次に、プロセッサは再びすべての要素をループし、今度はプロセッサがそのセルのデータを更新する必要があるかどうかを確認します。はいの場合、データは別のプロセスによってすでに送信されています。現在のプロセスは、データの所有者とそのセルの一意のグローバル ID を認識して、ブロッキング受信を行うだけです。
最後に、MPI_Waitall は、ノンブロッキング送信中に「req」配列に格納されたリクエスト コードに使用されます。
私が抱えている問題は、このプロセス全体が完了することです---コードにハングはありません。しかし、一部のセルが受信しているデータの一部は正しくありません。送信操作の前に各データを印刷して、送信されるすべてのデータが正しいことを確認します。配列のスライスを送受信していることに注意してください。各送信は 31 個の要素を渡します。配列を受け取ったプロセスから配列を出力すると、31 個の要素のうち 3 個がガベージです。他のすべての要素は正しいです。奇妙なことに、ガベージになるのは常に同じ 3 つの要素 (最初、2 番目、最後の要素) です。
これを説明するアルゴリズムで何かが大幅に間違っているわけではないことを除外したいと思います。それとも、私が取り組んでいるクラスターに関連しているのでしょうか? 前述したように、これは私が投げた他のすべてのモデルで機能し、最大 31 個のコアを使用しました。問題に 56 コアを投入しようとすると、この動作が発生します。何も問題がない場合、送信の特定の部分が宛先に届かない理由をテストする手段を提案できますか?
do i = 1, num_cells
! skip cells with data that isn't needed by other processors
if (.not.needed(i)) cycle
tag = gid(i) ! The unique ID of this cell in the entire system
ghoster = ghosts(i) ! The processor that needs data from this cell
call MPI_Isend(data(i,1:tot_levels),tot_levels,mpi_datatype,ghoster,tag,MPI_COMM,req(send),mpierr)
send = send + 1
end do
sends = send-1
do i = 1, num_cells
! skip cells that don't need a data update
if (.not.needed_here(i)) cycle
tag = gid(i)
owner = owner(i)
call MPI_Recv(data(i,1:tot_levels),tot_levels,mpi_datatype,owner,tag,MPI_COMM,MPI_STATUS_IGNORE,mpierr)
end do
call MPI_Waitall(sends,req,MPI_STATUSES_IGNORE,mpierr)