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.F90
  • hecmw_solver_las_22.F90
  • hecmw_solver_las_33.F90
  • hecmw_solver_las_44.F90
  • hecmw_solver_las_66.F90
  • hecmw_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)
Edited by Kanato Kono

Merge request reports

Loading
Loading