本当に奇妙なことをしているMPIと並列化しているFortranコードがいくつかあります。まず、ボス プロセスからすべてのワーカーにブロードキャストする変数 nstartg があります。
call mpi_bcast(nstartg,1,mpi_integer,0,mpi_comm_world,ierr)
nstartg
プログラム内で変数が再度変更されることはありません。後で、boss プロセスにeproc
配列の要素をedge
ワーカーに送信させます。
if (me==0) then
do n=1,ntasks-1
(determine the starting point estart and the number eproc
of values to send)
call mpi_send(edge(estart),eproc,mpi_integer,n,n,mpi_comm_world,ierr)
enddo
endif
me
ゼロ以外の場合、一致する receive ステートメントを使用します。(読みやすくするために他のコードを省略しています。scatterv を使用しないのには十分な理由があります。)
ここで奇妙なことが起こります: 変数は実際の値を保持する代わりに にnstartg
変更されます。n
たとえば、プロセス 1 では、mpi_recv の後、nstartg = 1
プロセス 2 では 2 に等しい、などです。さらに、上記のコードを次のように変更すると
call mpi_send(edge(estart),eproc,mpi_integer,n,n+1234567,mpi_comm_world,ierr)
それに応じてタグを mpi_recv への一致する呼び出しで変更し、プロセス 1 で nstartg = 1234568; プロセス 2 では、nstartg = 1234569 など。
一体何が起こっているのですか?変更したのは、mpi_send/recv がメッセージを識別するために使用しているタグだけです。メッセージが混同されないようにタグが一意である場合、これは何も変更しないはずですが、まったく無関係な変数を変更しています.
ボス プロセスでnstartg
は は変更されていないので、再度ブロードキャストすることで修正できますが、それでは根本的な解決にはなりません。最後に、電気フェンスを使用してこのコードをコンパイルして実行しても、バッファ オーバーフローは検出されず、-fbounds-check で何もスローされませんでした。