[MPS] non_blocking MPS to CPU copy does not return pinned storage
- Dominant language
- Python
- Stars
- 103k
- Forks
- 29.5k
- PR merge metrics
- PR metrics pending
Description
### 🐛 Describe the bug
Copying an MPS tensor to CPU with non_blocking=True is expected to return pinned host memory, but is_pinned() reports False.
```python
import torch
t_acc = torch.randn(100).to("mps")
t_host = t_acc.to("cpu", non_blocking=True)
torch.accelerator.synchronize()
print(t_host.is_pinned()) # False, expected True
```
This is exactly what TestAcceleratorMPS::test_pin_memory_on_non_blocking_copy asserts. The test is currently skipped on MPS, and #193838 updated the skip message to point at this gap.
Pinned storage support for MPS landed in #181720 (pin_memory returns CPU-aliased storage backed by a unified MTLBuffer), so this looks like an integration gap rather than missing machinery: either the non-blocking device to CPU copy path does not allocate through the pinned allocator, or the returned storage is pinned in practice but the is_pinned() query does not recognize it.
Found while working on #167447.
### Versions
PyTorch version: 2.15.0a0+git0f3e7e2 (built from source, main at 0f3e7e2)
OS: macOS 26.6.1 (Tahoe), arm64
Chip: Apple M4, 24 GB unified memory
Python: 3.14.4
Xcode: 26.6 (17F113), Metal Toolchain 17F109
MPS available: True
cc @kulinseth @malfet @DenisVieriu97 @jhavukainen @aditvenk @Isalia20
Contributor guide
Research direction
Start with TestAcceleratorMPS::test_pin_memory_on_non_blocking_copy, which currently skips on MPS, and trace the MPS device-to-CPU non-blocking copy together with the pinned-memory query. Done means the test runs without the MPS skip and the copied tensor reports is_pinned() as True.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100