I’m testing ways to get the gradient of a function which at its core is a numerical loop. I’m trying to use ForwardDiff currently to see if it’s any faster than Zygote reverse diff. I can’t get ForwardDiff to perform AD on this MWE; could someone help me figure out what’s wrong with my implementation?
function ForDiffSL(x)
U = U1*x
L = 1
k = 0.25
dr = r[2] - r[1]
len = size(r)[1]-1
ur = zeros(len)
ui = zeros(len)
a = r[end-2]
ur[2] = 1e-2
ui[1] = 1e-3
ui[2] = 1e-2
for i in 3:len
uval = (L*(L+1)*ur[i-1]+ui[i-1]*k)*U[i]
ur[i] = uval/ur[i-1]
ui[i] = uval/ui[i-1]
end
SL = ur[len] * ui[len]
return SL
end
global r = Vector(LinRange(0, 20, 20000))
global U1 = rand(size(r,1), 2)
x = rand(2,2)
dSL_fd = ForwardDiff.gradient(ForDiffSL, x)
I get the following error message when running this code:
ERROR: LoadError: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(ForDiffSL), Float64}, Float64, 4})
Closest candidates are:
(::Type{T})(::Real, ::RoundingMode) where T<:AbstractFloat
@ Base rounding.jl:207
(::Type{T})(::T) where T<:Number
@ Core boot.jl:792
(::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
@ Base char.jl:50
...
Stacktrace:
[1] convert(#unused#::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(ForDiffSL), Float64}, Float64, 4})
@ Base ./number.jl:7
[2] setindex!(A::Vector{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(ForDiffSL), Float64}, Float64, 4}, i1::Int64)
@ Base ./array.jl:969
[3] ForDiffSL(x::Matrix{ForwardDiff.Dual{ForwardDiff.Tag{typeof(ForDiffSL), Float64}, Float64, 4}})
@ Main ~/nuclear-diffprog/MWEs/mwe_coreloop.jl:49
[4] vector_mode_dual_eval!
@ ~/.julia/packages/ForwardDiff/onEFt/src/apiutils.jl:24 [inlined]
[5] vector_mode_gradient(f::typeof(ForDiffSL), x::Matrix{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(ForDiffSL), Float64}, Float64, 4, Matrix{ForwardDiff.Dual{ForwardDiff.Tag{typeof(ForDiffSL), Float64}, Float64, 4}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/onEFt/src/gradient.jl:91
[6] gradient
@ ~/.julia/packages/ForwardDiff/onEFt/src/gradient.jl:20 [inlined]
[7] gradient(f::typeof(ForDiffSL), x::Matrix{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(ForDiffSL), Float64}, Float64, 4, Matrix{ForwardDiff.Dual{ForwardDiff.Tag{typeof(ForDiffSL), Float64}, Float64, 4}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/onEFt/src/gradient.jl:17
[8] gradient(f::typeof(ForDiffSL), x::Matrix{Float64})
@ ForwardDiff ~/.julia/packages/ForwardDiff/onEFt/src/gradient.jl:17
[9] macro expansion
@ ~/nuclear-diffprog/MWEs/mwe_coreloop.jl:81 [inlined]
[10] top-level scope
@ ./timing.jl:273
[11] include(fname::String)
@ Base.MainInclude ./client.jl:478
[12] top-level scope
@ REPL[1]:1
in expression starting at mwe_coreloop.jl:80