-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong results for forward-mode exp!
half of the time
#715
Comments
This only appears to be a problem for the non-symmetric version of using LinearAlgebra, ForwardDiff, ForwardDiffChainRules, FiniteDifferences
@ForwardDiff_frule LinearAlgebra.exp!(x1::AbstractMatrix{<:ForwardDiff.Dual})
function test_exp(x)
X = copy(reshape(x, 4, 4))
X2 = LinearAlgebra.exp!(X)
sum(X2)
end
for i = 1:20
X = randn(4,4)
X = X'X
x = vec(X)
g1 = ForwardDiff.gradient(test_exp, x)
g2 = FiniteDifferences.grad(central_fdm(5, 1), test_exp, x)[1]
@show norm(g1-g2)
end I've also tested the reverse rule using Zygote and there is no problem in reverse |
@sethaxen do you think you might have time to look into this? |
Yes, I can look into this. @baggepinnen I'm not familiar with ForwardDiffChainRules. Can you provide an MWE that exhibits the observed failure using just ChainRules? Using our own testing machinery, I am unable to observe any failures on 1000x the number of random matrices: julia> using ChainRules, ChainRulesTestUtils, LinearAlgebra, Random, Test
julia> Random.seed!(42);
julia> @testset "exp!" begin
Xs = (randn(4, 4) for _ in 1:20_000)
@testset for X in Xs
test_frule(LinearAlgebra.exp!, X)
end
end;
Test Summary: | Pass Total Time
exp! | 80000 80000 13.2s Btw, in a fresh environment, your example errors on my machine in the for loop with: ERROR: MethodError: no method matching iterate(::Nothing)
Closest candidates are:
iterate(::Union{LinRange, StepRangeLen})
@ Base range.jl:880
iterate(::Union{LinRange, StepRangeLen}, ::Integer)
@ Base range.jl:880
iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, Base.ValueIterator{<:Dict}}
@ Base dict.jl:698
...
Stacktrace:
[1] indexed_iterate(I::Nothing, i::Int64)
@ Base ./tuple.jl:91
[2] exp!(x1::Matrix{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_exp), Float64}, Float64, 8}})
@ Main ~/.julia/packages/ForwardDiffChainRules/2Xt9G/src/ForwardDiffChainRules.jl:81
[3] test_exp(x::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_exp), Float64}, Float64, 8}})
@ Main ./REPL[4]:3
[4] chunk_mode_gradient(f::typeof(test_exp), x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(test_exp), Float64}, Float64, 8, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_exp), Float64}, Float64, 8}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/vXysl/src/gradient.jl:123
[5] gradient(f::Function, x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(test_exp), Float64}, Float64, 8, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_exp), Float64}, Float64, 8}}}, ::Val{true})
@ ForwardDiff ~/.julia/packages/ForwardDiff/vXysl/src/gradient.jl:21
[6] gradient(f::Function, x::Vector{Float64}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{typeof(test_exp), Float64}, Float64, 8, Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(test_exp), Float64}, Float64, 8}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/vXysl/src/gradient.jl:17
[7] gradient(f::Function, x::Vector{Float64})
@ ForwardDiff ~/.julia/packages/ForwardDiff/vXysl/src/gradient.jl:17
[8] top-level scope
@ ./REPL[5]:4 |
I think the problem is related to how ForwardDiffChainRules deals with (doesn't deal with) the fact that |
Sounds right. This line calls |
If I repeatedly run the example below, I get the wrong result for the gradient through
exp!
about half of the time.Also reported in ThummeTo/ForwardDiffChainRules.jl#14
The text was updated successfully, but these errors were encountered: