OpenFOAM Plugin for GPU (SpeedIT Classic) を使ってみる2010年12月23日 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
使用バージョンopenSUSE 11.3 x86_64, OpenFOAM 1.7.1, CUDA Toolkit 3.2, SpeedIT Classic 1.0, OpenFOAM Plugin 1.1。 グラフィックカードは NVIDIA GeForce GTX 470。 必要なものここ から以下を入手 (登録が必要)。
SpeedIT には "Classic" と "Extreme" があり、前者はオープンソース、後者は有料版である。Classic は単精度の CG 法のみ、Extreme は倍精度の BiCGStab 法が使える (らしい)。Plugin はどちらかの SpeedIT を使用して実装される。 あと、もちろん CUDA Toolkit をインストールしておく必要がある。 セットアップ単精度版 OpenFOAM のセットアップSpeedIT Classic では単精度版 PCG しか使えないので、まず単精度版の OpenFOAM を用意する必要がある。~/.bashrc で以下のように設定して OpenFOAM をコンパイルする。 WM_PRECISION_OPTION=SP . ~/OpenFOAM/OpenFOAM-1.7.1/etc/bashrc プラグインのコンパイルパッケージを展開。 $ unzip OpenFOAM_Plugin_1_1.zip $ cd OF\ 1.1 ソースは SpeedIT Extreme を使うように書かれているので修正する。 PCG_accel.C で speedit_ex.h をインクルードしているところを si_classic.h をインクルードするように書き換える。 #include "si_classic.h" //#inlucde "speedit_ex.h" PCG_accel.C で si_gscsrcg() を呼び出すところを sicl_gscsrcg() を呼び出すように修正。
/*solver_result = si_gscsrcg( n_rows,
...
&n_iter, &eps);*/
solver_result = sicl_gscsrcg( n_rows,
...
&n_iter, &eps);
GPU Computing SDK のパスを設定。 ~/.bashrc export SDK_INSTALL_PATH=~/NVIDIA_GPU_Computing_SDK ~/.bashrc を読み込む。 $ . ~/.bashrc コンパイル。 $ mkdir Make $ mv files options Make $ wmake libso SpeedIT Classic のセットアップパッケージを展開してコンパイル。 $ unzip SpeedIT_Classic.zip $ cd SpeedIT_Classic $ make ライブラリをコピー。 $ cp libSpeedIT_Classic.so $FOAM_USER_LIBBIN CUDA のライブラリもコピー。 $ cd /usr/local/cuda/lib64 $ cp libcublas.so $FOAM_USER_LIBBIN $ cp libcudart.so $FOAM_USER_LIBBIN 実行icoFoam でテスト。 $ cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity . $ cd cavity $ blockMesh system/controlDict に以下を追加。
libs
(
"libcudart.so"
"libcublas.so"
"libSpeedIT_Classic.so"
"libexternalsolv.so"
);
system/fvSolution を以下のように編集。
solvers
(
p
{
//solver PCG;
//preconditioner DIC;
solver PCG_accel;
preconditioner diagonal;
tolerance 1e-6;
relTol 0;
}
...
実行。 $ icoFoam 倍精度版の作成SpeedIT Classic & OpenFOAM Plugin を倍精度版に書き換えてみた。 si_classic.cu, si_classic.h の float を double に置換。また cublasSnrm2 を cublasDnrm2 に、cublasSdot を cublasDdot に、gsc を gdc に置換する。si_classic.h はプラグインのほうにコピーする。 Makefile の nvcc にオプション "-arch sm_13" を挿入。 libSpeedIT_Classic.so: si_classic.cu nvcc -arch sm_13 ... プラグインのほうは、PCG_accel.C の si_gdcsrcg を sicl_gdcsrcg に書き換える。 検証simpleFoam で計算時間の評価を行ってみたが、PCG_accel を使うと PCG のときよりも時間がかかる…。調べてみると、PCG_accel の反復計算回数がかなり大きくなっている。どうやら PCG_accel は preconditioner に diagonal を受け付けるようになっていながら、SpeedIT Classic のほうで前処理を行っていないようだ。 以下に simpleFoam での計算時間を示す。小さなモデル (Case 1, 12,000 セル)、大きいモデル (Case 2, 160,000 セル) それぞれについて PCG + DIC, 前処理なし PCG, PCG_accel の計算時間を比較した。単精度版と倍精度版との比較も行った。収束判定値 (SIMPLE の convergence) は 1e-3、ソルバーの maxIter は 1000 (デフォルト) とした。並列なしで計算した。 マシンスペック
単精度版Case 1
Case 2
倍精度版Case 1
Case 2
以上の結果からつぎのことがわかる。
おまけCase 2 (倍精度版)
Case 2 (4 パラレル, 倍精度版)
結論: GAMG + パラ。これ最強。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PENGUINITIS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||