HPCメモ

HPC(High Performance Computing)に関連したりしなかったりすることのメモ書き

MPI_Finalize()後の世界

ほとんどの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しても良いって話じゃないのは当然ですね。

というわけで、今日からは再び安心してメインルーチンにおまじないとして書いておこう。

*1:某気象系コードで、ひととおり初期化してからMPI_Initを呼ぶプログラムを見たことがありますが、別にその位置で呼ぶ必然性があったわけではなさそう。

*2:強いて理由を挙げるなら、MPI_Init()に引数を渡すのがめんd(マテ

*3:でも、その代わりに返り値を受け取る引数(ierr)が必要になる罠

*4:Version 3.0だと8章MPI Environment Managementの8.7 Startupのあたり、p361