OpenFOAM で CNC (GPU 用 CG ソルバー) を使う

2010年12月28日

はじめに

Inria が提供している Concurrent Number Cruncher という GPU 用 CG ソルバーが使えるライブラリがある。これを OpenFOAM で使ってみる。

グラフィックカードは NVIDIA GeForce GTX 470。

使用バージョン

openSUSE 11.3 x86_64, OpenFOAM 1.7.1, CUDA Toolkit 3.2, CNC 0.9。

ファイル

CNC 含む。CNC は ここ から入手した。

セットアップ

CUDA Toolkit と GPU Computing SDK はインストールしているものとする。

  1. パッケージを展開し、cnc-gpu-cuda-0.9-2/src/Makefile.so (単精度用) あるいは Makefile_dp.so (倍精度用) を環境に合わせて修正する。
  2. Allwmake を実行。
    $ ./Allwmake
    
    $FOAM_USER_LIBBIN ディレクトリにライブラリがインストールされる。
  3. CUDA Toolkit のライブラリ libcublas.so, libcudart.so を $FOAM_USER_LIBBIN にコピーする。
    $ 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"
    "libcnccuda.so"
    "libcnc.so"
);

system/fvSolution を以下のように編集。

solvers
(
    p
    {
        //solver          PCG;
        //preconditioner  DIC;
        solver          PCG_CNC;
        preconditioner  none;
        tolerance       1e-06;
        relTol          0;
    }
    ...

実行。

$ icoFoam

検証

SpeedIT Classic 検証結果 に今回の計算結果を追加してみよう。計算は倍精度、モデルは大きいモデル (160,000 セル, 以前の検証では Case 2) とする。本ソルバー (PCG_CNC) は OpenFOAM 側では "preconditioner none" としているが、CNC 側で Jacobi 前処理が行われる。

マシンスペック

CPUCore i7 870 (4 コア, 定格 2.93 GHz)
グラフィックカードNVIDIA GeForce GTX470 1280 MB

並列なし

SolverPreconditioner/SmootherStepClock Time
PCGDIC4754 s
PCGnone47119 s
PCG_acceldiagonal (none)4790 s
GAMGGaussSeidel4731 s
PCG_CNCJacobi4751 s

4 パラレル

SolverPreconditioner/SmootherStepClock Time
PCGDIC4726 s
PCGnone4753 s
GAMGGaussSeidel4715 s

やはり GAMG にはかなわない。