SCALAPACK を多用する並列プログラムを作成したいと考えています。SCALAPACK の基礎は BLACS であり、BLACS 自体はプロセス間通信を MPI に依存しています。
定義された数のプロセス (マシン上のコアの数など) でプログラムを開始し、これらのプロセスを計算に使用する方法をアルゴリズムに決定させたいと考えています。
テストケースとして、10 個のプロセスを使用したいと考えました。これらのプロセスのうち 9 つをグリッド ( BLACS_GRIDINIT
) に配置し、10 番目のプロセスは他のプロセスが終了するまで待機する必要があります。
残念ながら、最後のプロセスが BLACS から MPI コンテキストに入らないため、OpenMPI はクラッシュします。
質問:必要以上のプロセスで BLACS を使用する正しい方法は何ですか?
MPI_INIT
additionalとMPI_FINALIZE
呼び出しを使っていくつかの実験を行いましたが、どれも成功しませんでした。
インテル® MKL のサンプル・コード (少し短縮) から始めました。
PROGRAM HELLO
* -- BLACS example code --
* Written by Clint Whaley 7/26/94
* Performs a simple check-in type hello world
* ..
* .. External Functions ..
INTEGER BLACS_PNUM
EXTERNAL BLACS_PNUM
* ..
* .. Variable Declaration ..
INTEGER CONTXT, IAM, NPROCS, NPROW, NPCOL, MYPROW, MYPCOL
INTEGER ICALLER, I, J, HISROW, HISCOL
* Determine my process number and the number of processes in
* machine
CALL BLACS_PINFO(IAM, NPROCS)
* Set up process grid that is as close to square as possible
NPROW = INT( SQRT( REAL(NPROCS) ) )
NPCOL = NPROCS / NPROW
* Get default system context, and define grid
CALL BLACS_GET(0, 0, CONTXT)
CALL BLACS_GRIDINIT(CONTXT, 'Row', NPROW, NPCOL)
CALL BLACS_GRIDINFO(CONTXT, NPROW, NPCOL, MYPROW, MYPCOL)
* If I'm not in grid, go to end of program
IF ( (MYPROW.GE.NPROW) .OR. (MYPCOL.GE.NPCOL) ) GOTO 30
* Get my process ID from my grid coordinates
ICALLER = BLACS_PNUM(CONTXT, MYPROW, MYPCOL)
* If I am process {0,0}, receive check-in messages from
* all nodes
IF ( (MYPROW.EQ.0) .AND. (MYPCOL.EQ.0) ) THEN
WRITE(*,*) ' '
DO 20 I = 0, NPROW-1
DO 10 J = 0, NPCOL-1
IF ( (I.NE.0) .OR. (J.NE.0) ) THEN
CALL IGERV2D(CONTXT, 1, 1, ICALLER, 1, I, J)
END IF
* Make sure ICALLER is where we think in process grid
CALL BLACS_PCOORD(CONTXT, ICALLER, HISROW, HISCOL)
IF ( (HISROW.NE.I) .OR. (HISCOL.NE.J) ) THEN
WRITE(*,*) 'Grid error! Halting . . .'
STOP
END IF
WRITE(*, 3000) I, J, ICALLER
10 CONTINUE
20 CONTINUE
WRITE(*,*) ' '
WRITE(*,*) 'All processes checked in. Run finished.'
* All processes but {0,0} send process ID as a check-in
ELSE
CALL IGESD2D(CONTXT, 1, 1, ICALLER, 1, 0, 0)
END IF
30 CONTINUE
CALL BLACS_EXIT(0)
1000 FORMAT('How many processes in machine?')
2000 FORMAT(I)
3000 FORMAT('Process {',i2,',',i2,'} (node number =',I,
$ ') has checked in.')
STOP
END
更新:のソース コードを調べて、BLACS
そこで何が起こっているのかを確認しました。
これが以前に発生しなかった場合、呼び出しBLACS_PINFO
は MPI コンテキストを で初期化します。MPI_INIT
これは、この時点ですべてが期待どおりに機能することを意味します。
最後に、 への呼び出しはBLACS_EXIT(0)
からすべてのリソースを解放する必要がBLACS
あり、引数が0
の場合は も呼び出す必要がありますMPI_FINALIZE
。残念ながら、これは期待どおりに機能せず、最後のプロセスは を呼び出しませんMPI_FINALIZE
。
回避策として、必要に応じて質問MPI_FINALIZED
して電話することができますMPI_FINALIZE
。
更新 2:以前の試みは と で行われIntel Studio 2013.0.079
ましOpenMPI 1.6.2
たSUSE Linux Enterprise Server 11
。
ctheo の回答を読んだ後、Ubuntu 12.04
( gfortran 4.6.3, OpenMPI 1.4.3, BLACS 1.1
) で指定されたツールを使用してこの例をコンパイルしようとしましたが、成功しました。
私の結論は、Intel の実装にはバグがあるように見えるということです。の最新のサービス リリースで、そう遠くない将来にこの例を再試行しますがIntel Studio
、変更は期待できません。
ただし、他の(そしておそらくより良い)ソリューションをいただければ幸いです。