BLACSAnyCommunicator - t-sakashita/rokko GitHub Wiki
ScaLAPACKの固有値ソルバにおいて任意のコミュニケータをとれるようにする方法
文書: www.netlib.org/blacs/mpiblacs_issues.ps
Rokkoラッパーでの実装
- 使用する:
sys2blacs_handle_
、free_blacs_system_handle_
(Fortran式の名前) - 使用しない:
Csys2blacs_handle
、Cfree_blacs_system_handle
上記を使用する理由
- Rokkoで使用するルーチンを、LAPACK、ScaLAPACKと同様に、BLACSともFortran版に統一した。
- BLACSのCblacsは、別途ライブラリのリンクが必要であるかもしれないから、使わない。
- Fortran式の名前の関数にLAPACKEライクなラッパーを書いた。
netlib版の実装
- 上記4つの関数は全て、C関数。Fortranラッパーではない。
sys2blacs_handle_
では、BI_TransUserComm
関数が呼び出される。(実際にScaLAPACKのソースコードにprintf文を挿入してみる事により確認した。)- Fortran版コミュニケータは、
MPI_Fint
ではなく、じかにint
型で扱われている。MPI実装によってはエラーとならないか? Csys2blacs_handle
では、MPIコミュニケータを直接扱っている。(こちらの方が安全)
上記の問題点
- netlib版と同様に、大抵のBLACSの実装にはC言語が用いられていると思われる。つまり、むしろCblacsこそがオリジナルのBLACSであり、Fortran版はそのラッパーのはず。
- Cblacs(C言語)、Fortran版BLACS、LAPACKEライクなRokkoラッパー(C言語)、C++(Rokko)という冗長な構造となっている。
ソルバライブラリとの整合性
部分MPIコミュニケータでソルバを呼び出すときに、その中にMPI_NULL_COMM
があるとフリーズする。
対策
- ScaLAPACK、ELPA:
MPI_COMM_NULL
の場合、if文で処理を分けることで、ScaLAPACKルーチンを呼び出すインターフェース関数に参加させない。 - PMRRR(Elemental):処理を分けても原因不明のフリーズ
- EigenExaでは、部分コミュニケータを使用する場合も、
MPI_COMM_WORLD
全体でEigenExaを呼び出す必要がある。
RokkoとEigenExaでは、方法が異なる。そのため、RokkoからEigenExaを部分コミュニケータで使用しようとすると、blacs_gridmap
で以下のエラーが起きる。
BLACS ERROR 'Illegal grid (0 x 0), #procs=5'
from {-1,-1}, pnum=4, Contxt=-1, on line -1 of file 'BLACS_GRIDINIT/BLACS_GRIDMAP'.
このエラーは、BLACSでは(0,0)サイズのグリッドを使用できないため。
EigenExa向けの対策の検討
-
MPI_COMM_NULL
には、その意味から、(0,0)サイズのグリッドを割り当てるのが合理的である。 Rokkoでは、(0,0)サイズとしている。そのため、グリッドの問題が起きる。 -
エラーを回避するための対策としてサイズを仮に(1,1)としてみると、
sys2blacs_handle
でエラーとなる。このエラーは、MPI_Group_incl
に無効な1x1=1個のプロセス番号が渡されるため。 -
(0,0)サイズのグリッドに対して、Rokkoの
grid
やmapping_bc
でも、各種のサイズ計算の際にゼロ割の例外が起こる:
mapping_bc<matrix_col_major> default_mapping(int dim, grid const& g) const {
// Determine mb, nb, lld, larray
int mb, nb;
if (g.get_nprow() != 0) mb = dim / g.get_nprow();
else mb = 1;
if (g.get_npcol() != 0) nb = dim / g.get_npcol();
else mb = 1;
if (mb == 0) mb = 1;
if (nb == 0) nb = 1;
// Note: it should be that mb = nb in pdsyev.
int b = std::min(mb, nb);
return mapping_bc<matrix_col_major>(dim, b, g);
}
ソルバに依存しないRokkoインターフェースの仕様
rokko::gridのみ、MPI_COMM_NULLでもエラーとならないようにした。 以下の値が設定される。
- nprocs=0, nprow=0, npcol=0
- myrank=-1、myrow=-1, mycol=-1
不要と判明した知識
NOTINCONTEXT
blacs_gridmap
は、MPI_COMM_NULL
の場合、NOTINCONTEXT
という定整数を設定する。- これは、他のScaLAPACKのルーチンでは一切チェックされないので無意味。ScaLAPACKの各ルーチンにおいて、プロセスが
NOTINCONTEXT
である場合、はじいている訳ではない。MPI_COMM_NULL
は、メインプログラムの中でユーザが排除するしかなさそうだ。