torch.sinc produces NaN in the second derivative at its removable singularity
- Dominant language
- Python
- Stars
- 103k
- Forks
- 29.5k
- PR merge metrics
- PR metrics pending
Description
### 🐛 Describe the bug
`torch.sinc` returns `nan` for a nested reverse-mode second derivative whose mathematically correct value is `35.56404073668897` in `float64`.
At `t = -0.5`, one argument is exactly zero: `2 * t + 1 = 0`. Normalized sinc extends analytically through zero, with `sinc''(0) = -pi**2 / 3`. Combining that with the other two finite arguments and the output weights gives `35.56404073668897`, which is finite and ordinary-sized. PyTorch returns `nan`. The forward value matches.
This issue reproduces on CPU, so CUDA availability does not affect the result.
```python
import torch
dtype = torch.float64
t = torch.tensor(-0.5, dtype=dtype, requires_grad=True)
y = torch.sinc(torch.stack((t, 2 * t + 1, -t / 2 + 2)))
out = 2 * y[0] - 3 * y[1] + 5 * y[2]
g, = torch.autograd.grad(out, t, create_graph=True)
actual, = torch.autograd.grad(g, t)
expected = torch.tensor(35.56404073668897, dtype=dtype)
print("actual:")
print(actual)
print("expected:")
print(expected)
```
### Actual vs expected result
```text
actual:
nan
expected:
35.56404073668897
```
The discrepancy occurs in the nested (second-order) backward pass. The forward value is about `-1.226584724066445` and matches the analytic sinc; the second derivative becomes `nan` at the removable singularity.
### Versions
```text
PyTorch version: 2.12.0+cu130
Is debug build: False
CUDA used to build PyTorch: 13.0
ROCM used to build PyTorch: N/A
OS: Ubuntu 24.04.3 LTS (x86_64)
Python version: 3.13.13 | packaged by Anaconda, Inc.
Python platform: Linux x86_64
Is CUDA available: False
GPU models:
GPU 0: NVIDIA RTX 6000 Ada Generation
GPU 1: NVIDIA RTX 6000 Ada Generation
Nvidia driver version: 570.211.01
CPU:
Model name: AMD Ryzen Threadripper PRO 7985WX 64-Cores
CPU(s): 128
Versions of relevant libraries:
[pip3] numpy==2.4.6
[pip3] torch==2.12.0
[pip3] triton==3.7.0
```
cc @albanD
Contributor guide
Research direction
Start by running the provided CPU reproducer with torch.sinc and nested torch.autograd.grad calls, then inspect the torch.sinc implementation and its existing tests. Trace the second-order backward path at the zero argument and add regression coverage showing that the result is finite and matches 35.56404073668897.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- machine-learning
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100