Hi,
I am facing an unexpected autograd behavior when applying boolean conditions.
Below is a minimal example:
I evaluate the sinc function (equal to sin(x)/x for x!=0 and 1 otherwise), using ether the base definition of sinc or a Taylor series expansion close to 0 to avoid numerical issues.
import torch
for value in (0.0, 1e-7, 1e-3):
x = torch.as_tensor(value).requires_grad_(True)
# Base definition valid for x != 0
sinc_base = torch.sin(x)/x
# Taylor series expansion valid for x close to 0
sinc_taylor = 1.0 - x**2 / 6
# Switching between the two expressions depending on the value of x
condition = torch.abs(x) < 1e-6
sinc = torch.where(condition, sinc_taylor, sinc_base)
print(f"---- x={x.item()} ----")
print(f"sinc_base: {sinc_base.item()} -- grad: {torch.autograd.grad(sinc_base, x, retain_graph=True)[0].item()}")
print(f"sinc_taylor: {sinc_taylor.item()} -- grad: {torch.autograd.grad(sinc_taylor, x, retain_graph=True)[0].item()}")
print(f"condition:", condition.item())
print(f"sinc: {sinc.item()} -- grad: {torch.autograd.grad(sinc, x, retain_graph=True)[0].item()}")
# Output:
# ---- x=0.0 ----
# sinc_base: nan -- grad: nan
# sinc_taylor: 1.0 -- grad: -0.0
# condition: True
# sinc: 1.0 -- grad: nan
# ---- x=1.0000000116860974e-07 ----
# sinc_base: 1.0 -- grad: 0.0
# sinc_taylor: 1.0 -- grad: -3.33333360913457e-08
# condition: True
# sinc: 1.0 -- grad: -3.33333360913457e-08
# ---- x=0.0010000000474974513 ----
# sinc_base: 0.9999998807907104 -- grad: -0.0003662109375
# sinc_taylor: 0.9999998211860657 -- grad: -0.0003333333588670939
# condition: False
# sinc: 0.9999998807907104 -- grad: -0.0003662109375
The gradient of sinc should be finite everywhere. For x=0.0 however, the Taylor series sinc_taylor is used to estimate sinc, yet autograd does not return the gradient of sinc_taylor but NaN.
Do you think it is a bug, or do you have any workaround to suggest?