fix(metric): honor torch.device context manager when setting default device - #3448
Merged
bhimrazy merged 5 commits intoAug 20, 2026
Merged
Conversation
…t device
`Metric.__init__` gated the use of `torch.get_default_device()` on torch >= 2.3.
However, until torch 2.8 that function only reflected `set_default_device()` and
ignored an active `with torch.device(...)` context manager, so metrics created
inside such a block were assigned the CPU instead of the context device.
torch 2.8 (pytorch/pytorch v2.8.0) added the `DeviceContext` lookup to
`get_default_device`, so gate on 2.8 and keep the `torch.empty(0).device` probe
for older versions, which does respect the context manager.
Verified on torch 2.6.0: inside `with torch.device("meta")`,
`get_default_device()` returns cpu while `torch.empty(0).device` returns meta.
Adds a CPU-runnable regression test using the meta device; the existing coverage
for this path was GPU-only.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3448 +/- ##
======================================
- Coverage 37% 36% -0%
======================================
Files 349 349
Lines 19901 19910 +9
======================================
+ Hits 7264 7265 +1
- Misses 12637 12645 +8 🚀 New features to boost your workflow:
|
Force the pre-2.8 `torch.empty(0).device` fallback via monkeypatch so that branch stays covered on torch >= 2.8, where CI would otherwise never execute it, and assert the state tensor lands on the context device too.
torch.device context manager when setting default devicetorch.device context manager when setting default device
bhimrazy
added a commit
to bhimrazy/torchmetrics
that referenced
this pull request
Aug 20, 2026
justusschock
approved these changes
Aug 20, 2026
k223kim
approved these changes
Aug 20, 2026
4 tasks
bhimrazy
added a commit
that referenced
this pull request
Aug 31, 2026
….6 (#3449) * fix(metric): honor `torch.device` context manager when setting default device `Metric.__init__` gated the use of `torch.get_default_device()` on torch >= 2.3. However, until torch 2.8 that function only reflected `set_default_device()` and ignored an active `with torch.device(...)` context manager, so metrics created inside such a block were assigned the CPU instead of the context device. torch 2.8 (pytorch/pytorch v2.8.0) added the `DeviceContext` lookup to `get_default_device`, so gate on 2.8 and keep the `torch.empty(0).device` probe for older versions, which does respect the context manager. Verified on torch 2.6.0: inside `with torch.device("meta")`, `get_default_device()` returns cpu while `torch.empty(0).device` returns meta. Adds a CPU-runnable regression test using the meta device; the existing coverage for this path was GPU-only. * docs: add CHANGELOG entry for #3448 * ci: drop PyTorch 2.0-2.5 and raise minimum to 2.6 Drops the end-of-life PyTorch minors and raises the floor to 2.6, keeping the latest five supported minors (2.6-2.10), matching what Lightning did in #21851. - CPU matrix: drop the 2.0-2.5 rows and retarget the oldest/macOS/Windows entries to 2.6.0 (23 -> 17 jobs). - Docker: drop the 2.0.1-2.5.1 CUDA images (14 -> 8 builds); 2.6.0/cu12.4.1 is the new oldest. Dockerfile ARG defaults follow it. - GPU lanes: move the oldest image to torch 2.6 (cu12.4.1 for unittests, pytorch/pytorch:2.6.0-cuda12.4 for integrations). - Requirements: torch >=2.6.0, torchaudio >=2.6.0, torchvision >=0.21.0. - pytorch-lightning floor 1.9.0 -> 2.5.1, the first release CI-tested against torch 2.6. The GPU lanes previously hardcoded `TORCH_VER == "2.0"` to decide whether to apply the oldest requirements. That silently goes stale whenever the floor moves on the CPU side, so derive it from requirements/base.txt instead and fail fast if an image is below the declared floor. * docs: add CHANGELOG entry for #3449 * ci(gpu): read torch floor before requirements are rewritten and mirror PL cuda images * docs: refresh dockers README build example to a supported image combo * chore: drop the metric default-device fix, tracked in #3448 * ci: update Docker image to use torch 2.10 and CUDA 12.8.1 * ci: allow pip in PEP 668 pytorch images and raise onnxruntime floor for py3.11 * ci: raise scikit-image and mecab-ko floors to versions with cp311 wheels * refactor(ci): tidy torch-floor guard and trim its comments - state the version check in positive polarity instead of relying on bool -> exit-code coercion, so it reads the same way as the error below it - shorten the guard comments to the one-liner style used in these files, and note the adjust-torch-versions ordering in both workflows, not just one - drop a redundant `pip install -q packaging`, already installed at the top - keep the _integrate.txt note about our own floor rather than upstream's test matrix, which we cannot verify here
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.
What does this PR do?
Fixes
Metriclanding on CPU instead of the context device when constructed inside awith torch.device(...)block on torch 2.3–2.7.Metric.__init__gated its default-device lookup on torch >= 2.3:torch.get_default_device()above,torch.empty(0).devicebelow. Butget_default_device()only started consulting the activeDeviceContext— what thetorch.devicecontext manager pushes — in torch 2.8 (pytorch/pytorch#148621, fixing pytorch/pytorch#148874). Before that it read only the global slotset_default_device()populates, so on 2.3–2.7 the newer branch is strictly worse than the fallback it replaced. Moving the gate to 2.8 respects both the context manager andset_default_deviceon every supported version.Verified on torch 2.6.0 inside
with torch.device("meta"):get_default_device()→cpu,torch.empty(0).device→meta. The metric's state still lands on the context device, so the bug leavesmetric.devicedisagreeing with its own state — the mismatch #3316 set out to fix.Existing coverage for this path is GPU-only and passes today only because the GPU workflow runs the torch 2.0 and 2.8 images. Added a CPU-runnable regression test on the
metadevice that exercises both sides of the version gate.Prerequisite for #3449.