ほとんどのMPIプログラムで、おまじないとしてmainルーチンの最初と最後に置かれてる*1MPI_Init()&MPI_Finalize()ですが、ふと思いたって、MPI_Finalize()の後でもう一回MPI_Init()してみたらどうなるのか試してみました。
テストコード
なんとなくF77で書いてみたけど、特に意味は無い*2*3
$ cat main.f program test implicit none include 'mpif.h' integer nproc, myrank integer recvbuff integer tag, ierr, SRC, DEST integer stat(MPI_STATUS_SIZE) tag=0 call MPI_Init(ierr) call MPI_Finalize(ierr) write(*,*) 'MPI_finalize() called' call MPI_Init(ierr) write(*,*) 'After 2nd MPI_Init()' write(*,*) 'ierr = ', ierr call MPI_Comm_size(nproc, MPI_COMM_WORLD) call MPI_Comm_rank(myrank, MPI_COMM_WORLD) write(*,*) 'nproc = ', nproc write(*,*) 'myrank = ', myrank DEST = mod((myrank + 1),nproc) SRC = (myrank - 1) if (SRC .lt. 0 ) SRC = SRC+nproc call MPI_Sendrecv(myrank, 1, MPI_INTEGER, DEST, tag, & recvbuff, 1, MPI_INTEGER, SRC, tag, & MPI_COMM_WORLD, stat, ierr ) write(*,*) 'recvbuff = ', recvbuff call MPI_Finalize(ierr) end program
で、実行結果はこちら
MPI_finalize() called
The MPI_Init() function was called after MPI_FINALIZE was invoked.
This is disallowed by the MPI standard.
Your MPI job will now abort.
[CentOS:5073] Local abort after MPI_FINALIZE completed successfully; not able to aggregate error messages, and not able to guarantee that all other processes were killed!
ふむ。
テストしてから調べるもんじゃないけど、規格書*4を読むときちんとFinalizeした後はInitも含めてMPIのルーチンを呼んじゃだめって書いてますね・・・
Once MPI_FINALIZE returns, no MPI routine (not even MPI_INIT) may be called, except
for MPI_GET_VERSION, MPI_GET_LIBRARY_VERSION, MPI_INITIALIZED,
MPI_FINALIZED, and any function with the pre
x MPI_T_
ま、MPI_INITIALIZEDとかMPI_FINALIZEDとかいう関数があるぐらいだから、Init/Finalizeが呼ばれたかどうかって状態は保持してるはずだし、そうするとFinalizeしたからもう一回Initしても良いって話じゃないのは当然ですね。
というわけで、今日からは再び安心してメインルーチンにおまじないとして書いておこう。