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 戦略:
|
GPU で走るもの |
|---|---|
|
従来型 4 中心 J/K を GPU で |
|
密度フィッティング(RI)J/K、デバイス常駐 factor + cuBLAS |
|
セミダイレクト RI-JK(毎サイクル 3 中心を GPU で再計算) |
|
ホスト常駐 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-JK(
ri-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
確実に NVIDIA GPU があるマシンで
qc.GPU_ENABLEDがFalseです。考えられる理由を 2 つ挙げなさい。小さな分子と大きな GPU があり、
4c-cudaが CPU より遅いです。バグですか。説明しなさい。GPU 加速の RI-MP2 相関エネルギーが必要です。qc-rs は今日何を対応し、実務的な選択肢は何ですか。
解答 練習 19
(a) qc-rs が
cuda機能なしでビルドされた(既定ビルドに GPU 経路はない)、または (b)cudaはあるが 実行時に GPU が可視でない(ドライバ/libcudart/CUDA_VISIBLE_DEVICESの問題)。--features …,cudaで 再ビルドし実行時 GPU を確認。バグではありません。 小さな分子では GPU へのデータ転送コストが throughput の利点を上回ります;GPU は 大きな系で勝ちます。小さなジョブには CPU を使います。
GPU RI-JK(
ri-cuda)は動きますが、GPU RI-MP2 は未実装です。SCF は好みで GPU で走らせてよいですが、MP2 相関は CPU(lct(method="mp2"))で計算します。それが対応された経路です。
これで 3 つの並列レベルすべてに出会いました。最終章は、それらすべてに触れる 1 つの軸 — ERI / J-K 戦略 — でそれらを結びつけます。