Hoping someone who understands autodiff better than I do can help me figure out what’s going on here. I’ve got a function that calls ldl
from LDLFactorizations.jl, and then does further calculations on a field of the LDLFactorization
object that’s returned. Taking the gradient of this function works with ForwardDiff and ReverseDiff, but errors for Zygote. MWE below:
using LinearAlgebra, LDLFactorizations
using ForwardDiff, ReverseDiff, Zygote
function foo(x)
A = diagm(0 => x)
F = ldl(A)
return sum(F.D)
end
x = [1.0, 2.0, 3.0]
ForwardDiff.gradient(foo, x) # works
ReverseDiff.gradient(foo, x) # works
Zygote.gradient(foo, x) # errors
The error seems to say there’s no field D
(there is) and that the object is a NamedTuple
(it isn’t):
ERROR: type NamedTuple has no field D
Stacktrace:
[1] (::Zygote.var"#back#158"{:D,Zygote.Context,LDLFactorizations.LDLFactorization{Float64,Int64,Int64,Int64},Diagonal{Float64,Array{Float64,1}}})(::FillArrays.Fill{Float64,2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}) at /home/sam/.julia/packages/Zygote/c0awc/src/lib/lib.jl:220
[2] (::Zygote.var"#1704#back#159"{Zygote.var"#back#158"{:D,Zygote.Context,LDLFactorizations.LDLFactorization{Float64,Int64,Int64,Int64},Diagonal{Float64,Array{Float64,1}}}})(::FillArrays.Fill{Float64,2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}) at /home/sam/.julia/packages/ZygoteRules/6nssF/src/adjoint.jl:49
[3] foo at ./untitled-42379960c5e23fc7ce2e780a42d5b5f9:7 [inlined]
[4] (::typeof(∂(foo)))(::Float64) at /home/sam/.julia/packages/Zygote/c0awc/src/compiler/interface2.jl:0
[5] (::Zygote.var"#41#42"{typeof(∂(foo))})(::Float64) at /home/sam/.julia/packages/Zygote/c0awc/src/compiler/interface.jl:45
[6] gradient(::Function, ::Array{Float64,1}) at /home/sam/.julia/packages/Zygote/c0awc/src/compiler/interface.jl:54
[7] top-level scope at none:1
This isn’t super critical, since I can use one of the other autodiff libraries, but it did make me curious what’s going on. Thanks in advance if anyone has insights!