Resolve "NVIDIAコンパイラのビルドエラー"
Closes #755 (closed)
概要
openacc_gpu2 ブランチの master へのマージで導入された OpenACC GPU 実装について、
ビルドエラーと、ビルドは通るが計算が発散する根本的なバグを修正する。
修正内容
コミット 3e33dd2b: hecmw_mat_integrate 内の indexA 代入ミスを修正
hecmw_mat_integrate の !$acc parallel loop 内で、統合行列の行位置配列をhecMAT%indexA(i) ではなく未宣言の indexA(i) に代入していた。
これによりNVIDIAコンパイラでビルドエラーとなっていた。
コミット 5f281ca9: !$acc end parallel の欠落を修正
hecmw_mat_integrate の !$acc parallel loop に対応する !$acc end parallel 指示文が抜けていた。
コミット 0e8a4f29: GPU SpMV の indexA アクセスの1ずれを修正(計算発散の原因)
openacc_gpu ブランチでは indexA(0:NP) をローカル allocatable 変数として確保し、サブルーチンに渡していた。
Fortran の仕様により assumed-shape ダミー引数 (:) は下限が常に1にリベースされるため、
サブルーチン内では indexA(i) が呼び出し元の indexA(i-1) に対応し、jS = indexA(i)+1 が行 i の先頭を正しく指していた。
openacc_gpu2 でのリファクタリング後は hecMAT%indexA をポインタとして allocate(hecMAT%indexA(0:NP)) で確保し、
SpMV内でポインタ代入 indexA => hecMAT%indexA でアクセスするようになった。
ポインタ代入は下限0をそのまま引き継ぐため、indexA(i) は行 i の末尾位置を指す。
結果として jS = indexA(i)+1 / jE = indexA(i+1) は行 i ではなく行 i+1 の要素を参照してしまい、SpMVが完全に誤った値を計算して発散していた。
jS = indexA(i-1)+1 / jE = indexA(i) に修正することで、0ベースの indexA に対して行 i の正しい範囲を参照するようにした。
対象ファイル(全 NDOF バリアント):
hecmw_solver_las_11.F90hecmw_solver_las_22.F90hecmw_solver_las_33.F90hecmw_solver_las_44.F90hecmw_solver_las_66.F90hecmw_solver_las_nn.F90
変更ファイル
hecmw1/src/solver/matrix/hecmw_matrix_misc.F90(コミット1・2)hecmw1/src/solver/las/hecmw_solver_las_{11|22|33|44|66|nn}.F90(コミット3)