Fix misleading GPU probe diagnostics and add a GPU offload toggle (GPU.7, GPU.8) - #31
Merged
Merged
Conversation
GPU.7 — a gpu4pyscf install whose CUDA math libraries were missing failed with ImportError: Failure finding "libnvJitLink.so", and QuantUI reported it as "gpu4pyscf not installed", pointing the user back at an install step they had already completed. ModuleNotFoundError is a subclass of ImportError, so catching the latter conflated "absent" with "present but broken". The two are now caught separately, the real exception reaches the message, and both cases log. probe_gpu() returns (available, name, reason) and is the single source of truth — the CLI previously re-derived its own reason, which is how it came to contradict the dispatcher. GPU.8 — SCF is FP64 throughout and consumer GPUs gate double precision to ~1/32-1/64 of FP32, so offload there can be slower than a many-core CPU (measured: RTX 5060 Ti at 0.44x a 20-core CPU). Detected devices are now classified by name; consumer-class cards get an advisory in the Status tab and from `quantui gpu check`. Offload still auto-engages — we warn rather than override, since FP64 weakness is a tendency and a name-based auto-skip would silently overrule the user on hardware we guessed wrong about. A persistent Status-tab checkbox (compute.gpu_enabled, additive settings section) makes opting out one click; QUANTUI_DISABLE_GPU=1 still wins. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two fixes found by actually running the M-GPU validation recipe on a local CUDA
box (RTX 5060 Ti, CUDA 13.0) — the code has been GPU-code-complete but unvalidated
since session 54.
GPU.7 — a broken CUDA install was reported as "gpu4pyscf not installed"
gpu4pyscf-cuda13xdoes not declare the NVIDIA CUDA math libraries asdependencies, so a by-the-book install left
import gpu4pyscffailing withImportError: Failure finding "libnvJitLink.so". QuantUI reported that as:The package was installed. The message sent the user back to an install step
they had already completed, with the real cause discarded.
Cause:
ModuleNotFoundErroris a subclass ofImportError, soexcept ImportErrorcannot tell "the package is absent" from "the package ispresent but its import chain is broken". Both landed in the same branch — and that
branch logged nothing, so
quantui log tailcouldn't recover the cause either,despite the docstring promising it would.
Now:
ModuleNotFoundError→ "not installed", with the rightpip installhint.ImportError→ "installed but failed to import: {exc}", including themissing library name, plus a pointer that CUDA libraries are the usual cause.
probe_gpu() -> (available, name, reason)is now the single source of truth.The CLI previously re-implemented the probe to build its own reason string,
which is precisely how it drifted from what the dispatcher actually decided. The
Status badge reads the same triple.
is_gpu_available()keeps its exact 2-tuple contract; the cache moved onto theshared probe and
cache_clear/cache_infoare forwarded, so existing callersand tests are unaffected.
GPU.8 — warn when a detected GPU probably won't help
Quantum-chemistry SCF is FP64 throughout. Consumer and workstation GPUs gate
double precision to roughly 1/32–1/64 of their single-precision rate, so offload
on such a card can be slower than the CPU. Measured on this box (4096² DGEMM):
Real B3LYP single points bore that out — 0.44×–0.91× of CPU wall time across
benzene/def2-SVP, benzene/def2-TZVP and ibuprofen/def2-TZVP. Before this change,
any detected CUDA device was presented as unqualified good news.
is_low_fp64_device(name)classifies by device name against the knownstrong-FP64 datacenter families. Unknown names are classified low-FP64
deliberately: consumer hardware is the common student case, and a spurious
advisory costs far less than a silent halving of throughput.
quantui gpu check.tendency, not a guarantee, and a name-based auto-skip would silently overrule
the user on hardware the heuristic got wrong.
stored as
compute.gpu_enabled. Additive settings section, schema versionunchanged, unreadable settings never disable the GPU.
QUANTUI_DISABLE_GPU=1still wins over it, so scripted benchmarks areunaffected.
The toggle clears the detection cache on change — without that it would appear to
do nothing until restart, since the probe is cached for the process lifetime.
Testing
tests/test_gpu_diagnostics.py— 28 tests: the ImportError/ModuleNotFoundErrorsplit (including the exact
libnvJitLink.sofailure), logging, the preservedis_gpu_availablecontract and its cache-clear behavior, the settings gate, andFP64 classification across real device names. Platform-independent; no GPU, no CUDA.
test_reports_missing_gpu4pyscfasserted that a bareImportErrorproduced"gpu4pyscf not installed" — it had encoded the bug. It now uses
ModuleNotFoundError, and a new test locks the broken-chain case so theregression can't return.
test_happy_path_when_gpu_detectedwas patchingis_gpu_available; it now patchesprobe_gpu.setting off makes an actual B3LYP run return
gpu_used=False; toggling it backon restores
gpu_used=True.pre-commitclean at the pinnedversions.
Not in this PR
The M-GPU speedup exit criterion still needs an H200 — it cannot be met on a
consumer card for the FP64 reason above. Everything upstream of it (detection,
migration, numerical agreement to 8 dp,
gpu_used→perf_log→ dashboardpairing) is now validated locally, so that H200 session should be short.
🤖 Generated with Claude Code