Hi all. I have the following MWE. I get a stackoverflow error when using a sparse matrix in a function that I am using ForwardDiff to find the gradient of. When using a dense matrix (i.e. change W1s
to W1d
in the anonymous function), there is no error.
It seems that using dual numbers in the sparse matrix is somehow causing an error. Does anyone have a suggestion on how to get the gradient of a function where I will need to use sparse arrays internally?
using LinearAlgebra, SparseArrays, ForwardDiff
W1s = sparse([1,2,3,5,5],[2,1,2,4,5],ones(Int,5))
W1d = Matrix(W1s)
ForwardDiff.gradient(x -> begin
W1a = LinearAlgebra.I(5) - W1s*prod(x)
ladetW1a = logabsdet(W1a)[1]
return ladetW1a
end, [0.1,0.2])
I pasted the error below (on Julia 1.9.4).
ERROR: StackOverflowError:
Stacktrace:
[1] SparseMatrixCSC{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}, Int64}(m::Int64, n::Int64, colptr::Vector{Int64}, rowval::Vector{Int64}, nzval::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}})
@ SparseArrays ~/.julia/juliaup/julia-1.9.4+0.x64.linux.gnu/share/julia/stdlib/v1.9/SparseArrays/src/sparsematrix.jl:26
[2] SparseMatrixCSC(m::Int64, n::Int64, colptr::Vector{Int64}, rowval::Vector{Int64}, nzval::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}})
@ SparseArrays ~/.julia/juliaup/julia-1.9.4+0.x64.linux.gnu/share/julia/stdlib/v1.9/SparseArrays/src/sparsematrix.jl:44
[3] float(S::SparseMatrixCSC{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}, Int64})
@ SparseArrays ~/.julia/juliaup/julia-1.9.4+0.x64.linux.gnu/share/julia/stdlib/v1.9/SparseArrays/src/sparsematrix.jl:935
[4] lu(A::SparseMatrixCSC{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}, Int64}; check::Bool) (repeats 21635 times)
@ SparseArrays.UMFPACK ~/.julia/juliaup/julia-1.9.4+0.x64.linux.gnu/share/julia/stdlib/v1.9/SparseArrays/src/solvers/umfpack.jl:398
[5] logabsdet(A::SparseMatrixCSC{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}, Int64})
@ LinearAlgebra ~/.julia/juliaup/julia-1.9.4+0.x64.linux.gnu/share/julia/stdlib/v1.9/LinearAlgebra/src/generic.jl:1663
[6] (::var"#7#8")(x::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}})
@ Main ./REPL[4]:4
[7] vector_mode_dual_eval!
@ ~/.julia/packages/ForwardDiff/PcZ48/src/apiutils.jl:24 [inlined]
[8] vector_mode_gradient(f::var"#7#8", x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:89
[9] gradient(f::Function, x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}}}, ::Val{true})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:19
[10] gradient(f::Function, x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#7#8", Float64}, Float64, 2}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:17
[11] gradient(f::Function, x::Vector{Float64})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:17
[12] top-level scope
@ REPL[4]:1