JuliaDiff / JuliaDiff/ReverseDiff.jl
@grad_from_chainrules macro fails when using multi-output functions
Nobody has claimed this yet.
- Dominant language
- Julia
- Stars
- 394
- Forks
- 60
- Avg merge
- 18h 24m
- Merged PRs (30d)
- 8
Description
Dear team,
first: Thanks for developing this nice package :-)
I think there is an error with the macro @grad_from_chainrules when using it on multi-output functions (for example a function that outputs a tuple of two vectors). Note, that gradient/jacobian determination is not part of the current Github-tests, only the rrules are evaluated directly, but no gradient/jacobian is built for testing ReverseDiff with the corresponding rrule. However this works fine for single-output functions together with ReverseDiff.gradient.
See the following MWE:
using ForwardDiff, Zygote, ReverseDiff, ChainRulesCore
# SINGLE OUTPUT FUNCTION
f(x) = sum(4x .+ 1)
function ChainRulesCore.rrule(::typeof(f), x)
r = f(x)
function back(d)
return ChainRulesCore.NoTangent(), fill(3, size(x))
end
return r, back
end
ReverseDiff.@grad_from_chainrules f(x::AbstractVector{<:ReverseDiff.TrackedReal})
seed = rand(3)
# Everything ok, ForwardDiff computes the correct derivatives (no frule defined),
# ReverseDiff and Zygote use the new rrule as to expect
ForwardDiff.gradient(f, seed)
Zygote.gradient(f, seed)[1]
ReverseDiff.gradient(f, seed)
# MULTI OUTPUT FUNCTION
f_multi(x, y) = (4x .+ 1, 3x .+ 1 .+ y)
function ChainRulesCore.rrule(::typeof(f_multi), x, y)
r = f_multi(x, y)
function back(d)
y1, y2 = d
return ChainRulesCore.NoTangent(), fill(2 , size(x)), fill(3 , size(y))
end
return r, back
end
ReverseDiff.@grad_from_chainrules f_multi(x::AbstractVector{<:ReverseDiff.TrackedReal}, y::AbstractVector{<:Real})
# ForwardDiff computes the correct derivatives (no frule defined),
# Zygote use the new rrule as to expect, ReverseDiff fails!
ForwardDiff.jacobian(x -> f_multi(x, ones(3))[1], seed)
Zygote.jacobian(x -> f_multi(x, ones(3))[1], seed)[1]
ReverseDiff.jacobian(x -> f_multi(x, ones(3))[1], seed) # this errors!
Tested in Julia 1.8.5, all used libraries up-to-date.
Thanks in advance & best regards!
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at ReverseDiff.@grad_from_chainrules and reproduce the supplied f_multi MWE, comparing its handling of tuple outputs with the single-output case. Add regression coverage for ReverseDiff.jacobian on the multi-output example and confirm it succeeds while the existing rrule tests remain passing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100