ForwardDiffChainRules.jl icon indicating copy to clipboard operation
ForwardDiffChainRules.jl copied to clipboard

Error message for missing chain rule

Open baggepinnen opened this issue 2 years ago • 2 comments

The following snippet appears to fail due to a missing frule for exp(::Matrix) (there's one for exp!(::Matrix) only)

using ForwardDiff
using ForwardDiffChainRules
@ForwardDiff_frule Base.exp(x1::AbstractMatrix{<:ForwardDiff.Dual})
foo(x) = sum(exp(reshape(x, 2, 2)))
v = randn(4)
ForwardDiff.gradient(foo, v)

The error message is rather cryptic and could maybe be improved :)

ERROR: MethodError: no method matching iterate(::Nothing)
Closest candidates are:
  iterate(::Union{LinRange, StepRangeLen}) at range.jl:872
  iterate(::Union{LinRange, StepRangeLen}, ::Integer) at range.jl:872
  iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, Base.ValueIterator{<:Dict}} at dict.jl:712
  ...
Stacktrace:
 [1] indexed_iterate(I::Nothing, i::Int64)
   @ Base ./tuple.jl:91
 [2] exp(x1::Matrix{ForwardDiff.Dual{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4}})
   @ Main ~/.julia/packages/ForwardDiffChainRules/s5si2/src/ForwardDiffChainRules.jl:62
 [3] foo(x::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4}})
   @ Main ~/Desktop/semi_tmp/diffexp.jl:2
 [4] vector_mode_dual_eval!(f::typeof(foo), cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4}}}, x::Vector{Float64})
   @ ForwardDiff ~/.julia/packages/ForwardDiff/QdStj/src/apiutils.jl:37
 [5] vector_mode_gradient(f::typeof(foo), x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4}}})
   @ ForwardDiff ~/.julia/packages/ForwardDiff/QdStj/src/gradient.jl:106
 [6] gradient(f::Function, x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4}}}, ::Val{true})
   @ ForwardDiff ~/.julia/packages/ForwardDiff/QdStj/src/gradient.jl:19
 [7] gradient(f::Function, x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(foo), Float64}, Float64, 4}}}) (repeats 2 times)
   @ ForwardDiff ~/.julia/packages/ForwardDiff/QdStj/src/gradient.jl:17
 [8] top-level scope
   @ ~/Desktop/semi_tmp/diffexp.jl:4

cc: @mohamed82008

baggepinnen avatar Feb 08 '23 13:02 baggepinnen

someone can open a PR to check if the output of frule is nothing, before unpacking it

https://github.com/ThummeTo/ForwardDiffChainRules.jl/blob/master/src/ForwardDiffChainRules.jl#L62

mohdibntarek avatar Feb 08 '23 13:02 mohdibntarek

if it is nothing, throw an informative error saying that no frule is defined for f

mohdibntarek avatar Feb 08 '23 13:02 mohdibntarek