Skip to content

fix(desktop): re-detect GPU after CPU→NVIDIA build swap (#316) - #317

Merged
thcp merged 1 commit into
mainfrom
fix/win-cpu-only-reprobe
Jul 17, 2026
Merged

thcp merged 1 commit into
mainfrom
fix/win-cpu-only-reprobe

Conversation

@thcp

@thcp thcp commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Fixes #316.

Problem

A Windows user with an NVIDIA GPU who switches from the CPU portable build to the NVIDIA build — reusing the same %LOCALAPPDATA%\StemDeck data dir — stays pinned to CPU. The only recovery was manually deleting the data dir and relaunching.

Cause

The setup gate treats a persisted cpu-only-package device reason as permanently settled, so setup early-returns and skips ensure_torch_device — the very function whose clear_stale_cpu_marker + GPU re-probe (#247) heals this case. The cpu-only-package reason is only valid while the current install is still the CPU-only build; after an in-place swap to the NVIDIA build it is stale but never re-checked.

Fix

probe_runtime now runs the persisted reason through a new pure helper effective_device_reason(persisted, cpu_only_package): a cpu-only-package reason is dropped to None when the current install is not the cpu-only package. That marks the device unsettled, so the gate falls through and setup re-runs ensure_torch_device, which clears the stale marker, detects the GPU, and persists cuda/verified. Single heal — subsequent launches match. All other reasons pass through unchanged (reuses the existing #247 "unknown/unsettled reason self-heals" path).

Scope

  • Windows desktop: fixed.
  • macOS / Docker / self-hosted: unaffected (macOS mps reasons are already non-terminal; Docker has no persisted-device machinery and upgrades are clean image replacements).

Tests

Three unit tests for effective_device_reason (stale reason dropped on non-cpu-only package; kept on genuine cpu-only package; all other reasons + None pass through). Validated via WSL cargo test (3 passed) and cargo clippy --all-targets (no new warnings).

Follow-up (separate PR)

Make the Windows NVIDIA build install cu124 torch explicitly in make-portable.ps1 so GPU support is reproducible rather than an implicit property of the CI runner's PyPI resolution.

A persisted "cpu-only-package" torch device reason was treated as a
permanently settled decision by the setup gate, so replacing the CPU
portable build with the NVIDIA build in the same data dir left the user
pinned to CPU -- setup skipped ensure_torch_device (and its #247
clear_stale_cpu_marker + GPU re-probe) entirely.

Invalidate the stale reason at probe time when the current install is no
longer the cpu-only package, so the device reads as unsettled and setup
re-runs GPU detection. Reuses the existing #247 self-heal path.
@thcp
thcp merged commit 89367e5 into main Jul 17, 2026
8 checks passed
@thcp
thcp deleted the fix/win-cpu-only-reprobe branch July 17, 2026 23:59
thcp added a commit that referenced this pull request Jul 18, 2026
…318) (#320)

#318 force-installed the CUDA torch wheel into the NVIDIA package, which
pushed the release zip to 2456 MB -- over GitHub's 2 GiB release-asset cap
(2147483648 bytes) -- so the Windows NVIDIA asset upload failed on the
v0.8.0-alpha.12 release.

Bundling was the wrong approach: the desktop app already installs the CUDA
build on first run via ensure_torch_device (which picks the cuXXX index
matching the detected GPU's compute capability / driver). The NVIDIA
package is meant to ship base torch small (~419 MB zip) and pull CUDA on
first launch. #317 is the actual fix -- it makes that first-run install
trigger again after a CPU->NVIDIA build swap.

Restore the non-CpuOnly path to base torch and document why not to bundle,
so this isn't reintroduced.

Co-authored-by: Thales <>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows: GPU never re-detected after swapping CPU build for NVIDIA build in the same data dir

1 participant