[MPS] `torch.func.jacrev` INTERNAL ASSERT on empty input tensors
- Dominant language
- Python
- Stars
- 103k
- Forks
- 29.5k
- PR merge metrics
- PR metrics pending
Description
### 🐛 Describe the bug
# [MPS] `torch.func.jacrev` INTERNAL ASSERT on empty input tensors
## Description
`torch.func.jacrev(torch.relu)` on MPS raises an internal `RuntimeError: [srcBuf length] > 0 INTERNAL ASSERT FAILED ... Placeholder tensor is empty!` when the input has a size-0 dimension (e.g. shape `(0, 4)`). The same call succeeds on CPU and returns an empty Jacobian of shape `(0, 4, 0, 4)`.
## API under test
`torch.func.jacrev(func)(primals)` — reverse-mode Jacobian of `func` at `primals`.
## Broken convention
Empty tensors (any size-0 dimension) are valid PyTorch inputs. For `jacrev`, an empty primal should yield an empty Jacobian with the product of input/output shapes — not an internal assert.
- Valid: empty float tensors on CPU (`float16` / `float32`); non-empty tensors on MPS
- Crash trigger: empty input on MPS (reproduced with `float16` and `float32`)
MPS does not handle the empty-buffer path in `OperationUtils.mm` and asserts instead of producing an empty result or a clean validation error.
## To Reproduce
```python
import torch
x = torch.empty(0, 4, dtype=torch.float16, device="mps")
torch.func.jacrev(torch.relu)(x)
```
## Actual behavior
```
RuntimeError: [srcBuf length] > 0 INTERNAL ASSERT FAILED at ".../aten/src/ATen/native/mps/OperationUtils.mm":566, please report a bug to PyTorch. Placeholder tensor is empty!
```
## Expected behavior
Return an empty Jacobian matching CPU, e.g. shape `(0, 4, 0, 4)` for input `(0, 4)`, or raise a clear user-facing error. Do not hit an internal assert that asks the user to report a bug.
## Environment
- PyTorch version: 2.8.0
- OS: macOS 26.5 arm64
- Device: Apple Silicon (MPS)
### Versions
```
PyTorch version: 2.12.0
Is debug build: False
CUDA used to build PyTorch: None
ROCM used to build PyTorch: N/A
OS: macOS 26.5 (arm64)
GCC version: Could not collect
Clang version: 21.0.0 (clang-2100.1.1.101)
CMake version: version 4.3.4
Libc version: N/A
Python version: 3.14.5 (main, May 10 2026, 19:20:57) [Clang 22.1.3 ] (64-bit runtime)
Python platform: macOS-26.5-arm64-arm-64bit-Mach-O
Is CUDA available: False
CUDA runtime version: No CUDA
CUDA_MODULE_LOADING set to: N/A
GPU models and configuration: No CUDA
Nvidia driver version: No CUDA
cuDNN version: No CUDA
Is XPU available: False
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: True
Caching allocator config: N/A
CPU:
Apple M5
Versions of relevant libraries:
[pip3] numpy==2.4.6
[pip3] torch==2.12.0
[conda] Could not collect
```
cc @kulinseth @malfet @DenisVieriu97 @jhavukainen @aditvenk @Isalia20 @Chillee @samdow @kshitij12345
Contributor guide
Research direction
Reproduce torch.func.jacrev(torch.relu) with an empty MPS tensor, then inspect the empty-buffer path in aten/src/ATen/native/mps/OperationUtils.mm around line 566. Compare the result with CPU for the (0, 4) input and add regression coverage for the expected empty Jacobian or a clear user-facing error, without triggering the internal assert.
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
- Clearly specified
- Newbie friendliness
- 58/100