180 likes | 338 Views
HPC アプリケーション向け 計算網羅性 / 計算順序を テスト するツール. HPC Unit. 穂積 俊平 * 佐藤 芳樹 千葉 滋 東京大学大学院 情報理工学系研究科 創造情報学専攻. 計算の分割によるバグの混入. 計算の分割 1 つのループを複数のループに分割 キャッシュヒット率の改善 (e.g. 行列積におけるブロック化 ) 並列分散実行 (e.g. MPI) 計算のオフロード (e.g. GPGPU) バグの温床 分割の境界の計算間違い (e.g. 抜け , 重複 ) 分割による計算順序の変更 (e.g. 依存関係の破壊 ).
E N D
HPCアプリケーション向け計算網羅性 / 計算順序をテストするツール HPC Unit 穂積俊平* 佐藤芳樹 千葉滋 東京大学大学院情報理工学系研究科 創造情報学専攻
計算の分割によるバグの混入 • 計算の分割 • 1つのループを複数のループに分割 • キャッシュヒット率の改善 (e.g. 行列積におけるブロック化) • 並列分散実行 (e.g. MPI) • 計算のオフロード (e.g. GPGPU) • バグの温床 • 分割の境界の計算間違い (e.g. 抜け, 重複) • 分割による計算順序の変更 (e.g. 依存関係の破壊)
グラムシュミットの正規直交化法 @ RSDFT • RSDFT [岩田氏@東京大学] • 物理シミュレーションソフトウェア • 2011 ゴードン・ベル賞 • 計算の分割による実行性能の改善 • 行列積を利用したキャッシュヒット率の改善 • MPIを利用した並列分散実行
グラムシュミットの正規直交化法 • 線形独立なベクトルの組 (A) から正規直交系 (Q) を作るアルゴリズム • カーネル計算(中心となる計算) が • シミュレーション領域(パラメータi, j, kがつくり出す空間) を巡回 シミュレーション領域 プログラム k for (i=0; i<N; i++) { for (j=0; j<=i-1; j++) { ip=0; for (k=0; k<M; k++) ip+= Q[j][k] * A[i][k]; for (k=0; k<M; k++) Q[i][k] -= Q[j][k] * ip; } Q[i] /= |Q[i]|; } i カーネル計算 N:ベクトル数, M:ベクトルの長さ j
計算の分割 @グラムシュミットの正規直交化法 • 行列積を利用したキャッシュヒット率の改善 • i, j のループを分割, 計算の一部を行列積に委譲 • MPIによる並列分散実行 • k のループを分割, 各ノードに計算を割り当て ランク 2 ランク 1 ランク 0 シミュレーション領域 プログラム ループが分割される - 境界判定コードの増加 - カーネル計算がコード中に分散 k k k 行列積 行列ベクトル積 i j
計算の分割 @グラムシュミットの正規直交化法 • 行列積を利用したキャッシュヒット率の改善 • i, j のループを分割, 計算の一部を行列積に委譲 • MPIによる並列分散実行 • k のループを分割, 各ノードに計算を割り当て ランク 0 ランク 1 ランク 2 重複 シミュレーション領域 シミュレーション領域 プログラム ループが分割される - 境界判定コードの増加 - カーネル計算がコード中に分散 行列積 行列積 k 行列積 k k 行列積 依存関係 の破壊 抜け ・抜け / 重複 ・依存関係の破壊 i ・誤った計算結果 ・終了しない可能性 j 行列積
計算の分割の正しさをユニットテストする • HPCUnit:ユニットテストに必要な機能を提供 • パラメータの変化の追跡と記録 • 範囲, 順序, 文脈 (MPIのランク, 計算結果 etc.)の取得 • ユニットテストの間だけ追跡コードを埋め込める • HUList : 追跡結果を表すデータ構造 • パラメータの組をタプルの順序付き集合として表現 • 計算の抜けや重複を見つけやすい • 計算の依存関係を無視したパラメータ変化を見つけやすい • 正解集合を作るためのAPIも提供 注:現在は Java 向けに開発
HPCUnitのテスト方法 • パラメータの変化を追跡し, 正解領域と比較 対象アプリケーション テストコード CollectingLogs.aj GSTest.java OptimizedGS.java BLAS.java class OptimizedGS { void calc(..){ ... BLAS.gemv(..); ... BLAS.gemm(..); } } class BLAS { static void gemv(..){ ... kernel(i,j,k); } static void gemm(..){ ... kernel(i,j,k); }} ・カーネル計算の指定 ・追跡パラメータの指定 計算に抜けがない事を保証 ・追跡結果と正解集合 の比較 == ∪
HPCUnitができるテスト • 計算の抜け 計算の分割によって発生するバグを検出 / 特定 対象アプリケーション OptimizedGS.java BLAS.java class OptimizedGS { void calc(..){ ... BLAS.gemv(..); ... BLAS.gemm(..); } } == ∪ class BLAS { static void gemv(..){ ... kernel(i,j,k); } static void gemm(..){ ... kernel(i,j,k); }} • 計算の重複 {} == ∩ 計算に抜けがない事を保証 • 応用 • 依存関係の検査 • プログラムの局所性の評価 • 計算結果の突合 == ∪
MPIアプリケーションのテストも可能 • 追跡したMPIランクから各ノードのオフセット値を計算 • 分散メモリにより、各ノードの担当領域の始点は0 • HUListの map メソッドを利用 0 0 0 ランク 0 ランク 1 ランク 2 k 20 10 0 .map( (rank, i, j, k) -> (i, j, k + 10*rank) ) 注擬似コード
パラメータの変化の追跡 • アスペクトで追跡方法を記述 • 監視対象とするカーネル計算の指定 • 制御フローやクラスによってカーネル計算を絞り込める • 追跡するパラメータの指定 • 範囲, 順序, 文脈の取得 pointcutatGemvKernel(inti, int j, int k): args(i,j,k, ..) && within(BLAS) && cflow(call(void gemm(..))) && call(void kernel(int, int, int, ..)); before(inti, int j, int k) : atGemvKernel(inti, int j, int k) { GSTest.gemmArea.add(new HPCTuple3(i, j, k)); } BLAS.java class BLAS { static void gemv(..){ ... kernel(i,j,k); } static void gemm(..){ ... kernel(i,j,k); } } CollectingLogs.aj
HUList : 追跡結果を表すデータ構造 • パラメータの組の順序付き集合 • 正解集合と比較し, 抜けや重複を発見 • 様々な集合演算を提供 計算の抜け class GSTest { static HUListsimuArea, nullArea; static HUListgemvArea, gemmArea; void gsTest() { /* テストドライバ */ GS gs = new OptimizedGS(); gs.calc(arr, N, N-1, M); /* 不変条件式 */ simuArea.equals(gemvArea.union(gemmArea))); nullArea.equals(gemvArea.intersection(gemmArea)) }} ∪ == 計算の重複 ∩ {} == GSTest.java
正解集合の作成方法 • 典型的なシミュレーション領域を作るメソッドを利用 • 引数で領域サイズを指定 • e.g. 直線, 長方形, 直方体, 三角柱... • 最適化前のアプリケーションを追跡 • テスト対象アプリケーションと同様の方法で追跡
実験 • 目的 • HPCUnitによるオーバーヘッドの程度を知る • HPCUnitのオーバーヘッドの原因を探る • 内容 • マイクロベンチマーク • グラムシュミットの正規直交化法に適用 • 実験環境 • FUJITSU Supercomputer PRIMEHPC FX10 1 ノード • Linux ベースの専用 OS (カーネル 2.6.25.8) • SPARC64TM IXfx 1.848 GHz • Memory 32GB • OpenJDK Runtime Environment (IcedTea6 1.11.5) • 実行オプション デフォルト オーバーヘッドが 大きすぎると, 実データサイズの ユニットテストが できない
1.マイクロベンチマーク • 5つのプログラムの実行時間を測定 / 比較 • 配列の要素を添え字の2倍にするプログラムに対し • 4つの方法でパラメータの変化を追跡するコードを埋め込んだ • (配列の長さ = 10^7) タプルオブジェクトの生成コストが大きい アスペクトによるオーバーヘッドが見られる
2. グラムシュミットの正規直交化に適用 • 4つのプログラムの実行時間を測定 / 比較 • 3つの目的を達成するためにパラメータの変化を追跡 • カーネル計算追跡:計算の重複, 抜けをテスト • 行列読み込み追跡:プログラムの局所性を評価 • 行列書き込み追跡:計算結果の比較 N (ベクトル数, ベクトルの長さ) = 128 テストケース毎にオーバーヘッドが大きく異なる
関連研究 • ユニットテスト • e.g. JUnit[YoonsikCheon et al ECOOP’02] • HPCUnitは HPC に特化したテストフレームワーク • モデル検査 • e.g. SPIN, Java Path Finder [Klaus Havelund et al STTT’00] • HPCUnitのような HPC に特化したサポートが必要 • 追跡ベースの検査 • e.g. tracematch [Chris Allan et al OOPSLA’05] • 部分的な制御フローの検査が目的
まとめと今後の課題 • まとめ • HPC 向けユニットテストツールHPCUnitを提案 • パラメータの変化の追跡と記録 • 追跡結果を表すデータ構造 • HPCUnitのオーバーヘッドを計測 • 今後の課題 • オーバーヘッドの削減 • メモリ使用量の削減 • Domain Specific Language の設計