Description
When Zygote returns nothing as a gradient (indicating zero/no gradient), DI's Zygote extension fails with a MethodError: no method matching iterate(::Nothing) instead of converting it to zero.
MWE
using DifferentiationInterface
using Zygote: Zygote
# Native Zygote returns (nothing,)
Zygote.gradient(sign, 0.0) # (nothing,)
# DI fails
derivative(sign, AutoZygote(), 0.0) # MethodError
Stacktrace
ERROR: MethodError: no method matching iterate(::Nothing)
Stacktrace:
[1] first(itr::Nothing)
@ Base ./abstractarray.jl:472
[2] (::DifferentiationInterfaceZygoteExt.var"#2#3"...)(dy::Float64)
@ DifferentiationInterfaceZygoteExt .../DifferentiationInterfaceZygoteExt.jl:65
[3] map
@ ./tuple.jl:358 [inlined]
[4] value_and_pullback(...)
@ DifferentiationInterfaceZygoteExt .../DifferentiationInterfaceZygoteExt.jl:64
Expected Behavior
DI should convert nothing gradients to zero, returning 0.0 (like ForwardDiff does).
Actual Behavior
Throws MethodError: no method matching iterate(::Nothing).
Native Backend Comparison
# Native Zygote - returns nothing to indicate zero gradient
Zygote.gradient(sign, 0.0) # (nothing,)
Zygote.gradient(trunc, 1.5) # (nothing,)
# DI with ForwardDiff - correctly returns 0.0
derivative(sign, AutoForwardDiff(), 0.0) # 0.0
derivative(trunc, AutoForwardDiff(), 1.5) # 0.0
The native Zygote API returns nothing for some functions where the gradient is zero. DI's Zygote extension should handle this case.
Functions Affected
| Function |
Native Zygote |
DI AutoZygote |
DI ForwardDiff |
sign(0.0) |
(nothing,) |
MethodError |
0.0 |
trunc(1.5) |
(nothing,) |
MethodError |
0.0 |
floor(1.5) |
(0.0,) |
0.0 ✓ |
0.0 |
ceil(1.5) |
(0.0,) |
0.0 ✓ |
0.0 |
round(1.5) |
(0.0,) |
0.0 ✓ |
0.0 |
Environment
- Julia 1.12.6
- DifferentiationInterface v0.7.18
- Zygote v0.7.10
🤖 I am a robot. This is an experiment in agentic bug-catching under the supervision of @adrhill and @gdalle (#1008). Contents may be hallucinated.
Description
When Zygote returns
nothingas a gradient (indicating zero/no gradient), DI's Zygote extension fails with aMethodError: no method matching iterate(::Nothing)instead of converting it to zero.MWE
Stacktrace
Expected Behavior
DI should convert
nothinggradients to zero, returning0.0(like ForwardDiff does).Actual Behavior
Throws
MethodError: no method matching iterate(::Nothing).Native Backend Comparison
The native Zygote API returns
nothingfor some functions where the gradient is zero. DI's Zygote extension should handle this case.Functions Affected
sign(0.0)(nothing,)0.0trunc(1.5)(nothing,)0.0floor(1.5)(0.0,)0.0✓0.0ceil(1.5)(0.0,)0.0✓0.0round(1.5)(0.0,)0.0✓0.0Environment
🤖 I am a robot. This is an experiment in agentic bug-catching under the supervision of @adrhill and @gdalle (#1008). Contents may be hallucinated.