JuliaDiff / JuliaDiff/ReverseDiff.jl

Strange bug when deferring to ChainRules

Open
#236 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Julia
Stars
393
Forks
60
Avg merge
18h 24m
Merged PRs (30d)
8

Description

I unfortunately haven't been able to debug this properly yet, but I encountered a somewhat strange bug when using @grad_from_chainrules.

In https://github.com/TuringLang/Bijectors.jl/actions/runs/5781513384/job/15666726634#step:5:274 you can see

   BoundsError: attempt to access 4×4 Matrix{Float64} at index [0]
  Stacktrace:
    [1] getindex
      @ ./array.jl:805 [inlined]
    [2] getindex
      @ ./multidimensional.jl:643 [inlined]
    [3] special_reverse_exec!(instruction::ReverseDiff.SpecialInstruction{Tuple{typeof(getindex), Val{:generic}}, Tuple{ReverseDiff.TrackedArray{Float64, Float64, 2, Matrix{Float64}, Matrix{Float64}}, Tuple{Matrix{Bool}}}, ReverseDiff.TrackedArray{Float64, Float64, 1, Vector{Float64}, Vector{Float64}}, Nothing})
      @ ReverseDiff ~/.julia/packages/ReverseDiff/7pHoq/src/tracked.jl:372
    [4] reverse_exec!(instruction::ReverseDiff.SpecialInstruction{Tuple{typeof(getindex), Val{:generic}}, Tuple{ReverseDiff.TrackedArray{Float64, Float64, 2, Matrix{Float64}, Matrix{Float64}}, Tuple{Matrix{Bool}}}, ReverseDiff.TrackedArray{Float64, Float64, 1, Vector{Float64}, Vector{Float64}}, Nothing})
      @ ReverseDiff ~/.julia/packages/ReverseDiff/7pHoq/src/tape.jl:93
    [5] reverse_pass!(tape::Vector{ReverseDiff.AbstractInstruction})
      @ ReverseDiff ~/.julia/packages/ReverseDiff/7pHoq/src/tape.jl:87
    [6] reverse_pass!
      @ ~/.julia/packages/ReverseDiff/7pHoq/src/api/tape.jl:36 [inlined]
    [7] seeded_reverse_pass!(result::Vector{Float64}, output::ReverseDiff.TrackedReal{Float64, Float64, Nothing}, input::ReverseDiff.TrackedArray{Float64, Float64, 1, Vector{Float64}, Vector{Float64}}, tape::ReverseDiff.GradientTape{var"#31#33"{Bijectors.PDVecBijector, Int64}, ReverseDiff.TrackedArray{Float64, Float64, 1, Vector{Float64}, Vector{Float64}}, ReverseDiff.TrackedReal{Float64, Float64, Nothing}})
      @ ReverseDiff ~/.julia/packages/ReverseDiff/7pHoq/src/api/utils.jl:31
    [8] seeded_reverse_pass!(result::Vector{Float64}, t::ReverseDiff.GradientTape{var"#31#33"{Bijectors.PDVecBijector, Int64}, ReverseDiff.TrackedArray{Float64, Float64, 1, Vector{Float64}, Vector{Float64}}, ReverseDiff.TrackedReal{Float64, Float64, Nothing}})
      @ ReverseDiff ~/.julia/packages/ReverseDiff/7pHoq/src/api/tape.jl:47
    [9] gradient(f::Function, input::Vector{Float64}, cfg::ReverseDiff.GradientConfig{ReverseDiff.TrackedArray{Float64, Float64, 1, Vector{Float64}, Vector{Float64}}})
      @ ReverseDiff ~/.julia/packages/ReverseDiff/7pHoq/src/api/gradients.jl:24
   [10] gradient
      @ ~/.julia/packages/ReverseDiff/7pHoq/src/api/gradients.jl:22 [inlined]
   [11] test_ad(f::Function, x::Vector{Float64}, broken::Tuple{}; rtol::Float64, atol::Float64, use_forwarddiff_as_truth::Bool)
      @ Main ~/work/Bijectors.jl/Bijectors.jl/test/ad/utils.jl:33
   [12] macro expansion
      @ ~/work/Bijectors.jl/Bijectors.jl/test/ad/pd.jl:9 [inlined]
   [13] macro expansion
      @ /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/Test/src/Test.jl:1151 [inlined]
   [14] top-level scope
      @ ~/work/Bijectors.jl/Bijectors.jl/test/ad/pd.jl:2

If I then replace the offending rule with a "hard-coded" version using ChainRules, i.e. apply https://github.com/TuringLang/Bijectors.jl/pull/280/commits/29790dcd12e659d2f311b92b8f75a72e03802f5e, then the above error goes away 😕

I don't have time to dig into this right now, but figured I'd put it here for future reference.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with test/ad/pd.jl and test/ad/utils.jl, especially the @grad_from_chainrules path and the test_ad call shown in the report. Reproduce the ReverseDiff BoundsError, then compare it with the hard-coded ChainRules version from pull request 280's referenced commit. Done means identifying the cause and adding a regression test that passes without the error.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
backend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.