CUDA による GPU 計算#

速さへの第 3 の道は GPU(グラフィックス処理装置)です。適した種類の仕事 — 巨大な配列に同じ演算を適用する — では、1 つの GPU が多数の CPU コアを凌げます。qc-rs は積分と Fock 構築に任意の NVIDIA-GPU 経路を持ちます。 本章は GPU とは何か、GPU 対応で qc-rs をどうビルドするか、そして今日何が GPU で走るかを説明します。

GPU とは、いつ効くか#

CPU は汎用で分岐の多い仕事に最適化された少数の強力なコアを持ちます。GPU は、同じ算術を多数のデータ要素に 一度に行う(大規模データ並列)ことに最適化された数千の小さなコアを持ちます。これは量子化学の最も密な内側 ループ — 二電子積分と J/K 構築の行列積 — にぴったりで、巨大な配列に同じ式を適用します。

CUDA は NVIDIA の GPU 向けプログラミング基盤で、qc-rs の GPU 経路はその上に(ベンダー提供の GPU 最適化積分 カーネルで)築かれています。GPU の throughput がデータをカードへ送るコストを上回る大きな系で最も効きます; 小さな分子はそのオーバーヘッドで、GPU の方が CPU より遅いこともあります。

cuda ビルド(オプトイン;既定 OFF)#

GPU 経路は既定で OFF — 通常の qc-rs ビルドは CUDA 依存を一切持たず、NVIDIA から何もリンクせず、 qc.GPU_ENABLED == False を報告します。ビルド時cuda 機能を加えてオプトインします(CUDA ツールキットと NVIDIA GPU が必要):

"${UV_PROJECT}/.venv/bin/maturin" develop --no-default-features \
  --features intel-mkl-system,xc-bundled,pcm,python-mpi-direct,hdf5,cuda

するとセンチネルが切り替わります:

import qc
qc.GPU_ENABLED       # cuda ビルド + 可視の GPU で True;それ以外で False

cuda ビルドで GPU 戦略を要求すると、qc-rs は静かに CPU で走る代わりに明確なメッセージで失敗します:

jk: eri="4c-cuda" requires qc-rs built with the `cuda` feature and a CUDA GPU; rebuild with …

警告

cuda ビルドは開発専用 / 再配置不可 CUDA 拡張はベンダー .so をビルドツリーへの rpath でリンクし、実行時に libcudart を必要とするので、 cargo clean・移動したインストール・コピーした wheel は壊れます。cuda ビルドはビルドしたマシンにローカルな ものと扱ってください。

GPU を使う:eri="4c-cuda" とその仲間#

GPU は積分戦略ints(eri=...)次章)で選ぶので、ワークフローの残りは変わりません:

import qc
m = qc.chk.new(atom="...", ao="cc-pvdz")
m = qc.ints(m, eri="4c-cuda").scf(ref="r").run()      # J/K を GPU で行う RHF
print(qc.GPU_ENABLED, m.scf.energy)

GPU 戦略:

eri=

GPU で走るもの

4c-cuda

従来型 4 中心 J/K を GPU で

ri-cuda

密度フィッティング(RI)J/K、デバイス常駐 factor + cuBLAS

ri-recomp-cuda

セミダイレクト RI-JK(毎サイクル 3 中心を GPU で再計算)

ri-ram-cuda

ホスト常駐 RI factor を GPU の cuBLAS J/K へストリーム

GPU SCF は GPU KS-DFT(交換相関構築がカードで走る、xc= つきの eri="4c-cuda")と GPU PCM 溶媒和も 無料で得ます(pcm={..., device="auto"} は SCF が既に GPU なら GPU を使う)。

今日動くもの — まだのもの#

GPU 経路はその中核について正確性が完全で、CPU/PySCF のエネルギーに一致します:

  • J/K — RHF / UHF / ROHF、spherical Cartesian、g 関数まで(l ≤ 4)、スクリーニングと範囲分離 ハイブリッドの長距離項つき。

  • KS-DFT XC — RKS / UKS / ROKS、LDA / GGA / meta-GGA とハイブリッド全般(libxc は CPU で走る)。

  • RI-JKri-cuda)— 密度フィッティング J/K、最適化済み(32 水のフラッグシップで参照 gpu4pyscf を上回る)、 範囲分離ハイブリッド含む。

  • PCM — GPU 反応場結合。

まだ GPU にないもの:RI-MP2(GPU RI 経路は J/K のみ)、低精度(fp32/混合)の高速経路、角運動量 ≥ 5 (h 関数)、KS-DFT 勾配。それらには CPU 経路を使います。GPU の作業は完全な性能チューニングというより正確性が 完全なので、万能アクセラレータではなく高速な J/K/XC エンジンと扱ってください。

総合例(概念 — cuda ビルド + GPU が必要)#

import qc
# cuda ビルドでないマシンでは、これは明確な ValueError を投げます(検証済み):
m = qc.chk.new(atom="O 0 0 0.117; H 0 0.757 -0.469; H 0 -0.757 -0.469",
               ao="cc-pvdz", unit="angstrom")
try:
    m.ints(eri="4c-cuda").scf(ref="r").run()
except ValueError as e:
    print("GPU not available:", str(e)[:60])   # ... requires the `cuda` feature and a CUDA GPU

練習 19

  1. 確実に NVIDIA GPU があるマシンで qc.GPU_ENABLEDFalse です。考えられる理由を 2 つ挙げなさい。

  2. 小さな分子と大きな GPU があり、4c-cuda が CPU より遅いです。バグですか。説明しなさい。

  3. GPU 加速の RI-MP2 相関エネルギーが必要です。qc-rs は今日何を対応し、実務的な選択肢は何ですか。

これで 3 つの並列レベルすべてに出会いました。最終章は、それらすべてに触れる 1 つの軸 — ERI / J-K 戦略 — でそれらを結びつけます。