BLACSAnyCommunicator - t-sakashita/rokko GitHub Wiki

ScaLAPACKの固有値ソルバにおいて任意のコミュニケータをとれるようにする方法

文書: www.netlib.org/blacs/mpiblacs_issues.ps

Rokkoラッパーでの実装

  • 使用する:sys2blacs_handle_free_blacs_system_handle_(Fortran式の名前)
  • 使用しない:Csys2blacs_handleCfree_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のgridmapping_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は、メインプログラムの中でユーザが排除するしかなさそうだ。