Skip to content

ReverseDiff.value(output) depends on input of tape for mutating functions #143

Description

@frankschae

When using ReverseDiff to compute the gradients of an inplace function f!, we found that the output value of ReverseDiff depends on the input value of the tape (y*2 in the MWE). For the non-mutating input function f, one obtains in

(ReverseDiff.deriv(tu), ReverseDiff.deriv(tp), ReverseDiff.value(output)) = ([-8.0], [-16.0], [8.0])

However, for the mutating function, one gets

(ReverseDiff.deriv(tu), ReverseDiff.deriv(tp), ReverseDiff.value(output)) = ([-8.0], [-16.0], 16.0])

i.e., vec(du1) != ReverseDiff.value(output)) in the last line of the MWE.
This happens for both a compiled and a non-compiled tape.

using ReverseDiff
p2 = [2.0]

f!(du,u,p,t) = du.=p[1]*u

f(u,p,t) = p[1]*u

y = [4.0]
λ = -y
t = 1.0
tape = ReverseDiff.GradientTape((y*2, p2, [t])) do u,p,t 
  du1 = similar(u, size(u))
  f!(du1,u,p,first(t))
  return vec(du1)
end

config = ReverseDiff.compile(tape)

# tape = ReverseDiff.GradientTape((y*2, p2, [t])) do u,p,t
#   vec(f(u,p,first(t)))
# end

tu, tp, tt = ReverseDiff.input_hook(config)
output = ReverseDiff.output_hook(config)
ReverseDiff.unseed!(tu) # clear any "leftover" derivatives from previous calls
ReverseDiff.unseed!(tp)
ReverseDiff.value!(tu, y)
ReverseDiff.value!(tp, p2)
ReverseDiff.value!(tt, [t])
ReverseDiff.forward_pass!(config)
ReverseDiff.increment_deriv!(output, λ)
ReverseDiff.reverse_pass!(config)
@show ReverseDiff.deriv(tu), ReverseDiff.deriv(tp), ReverseDiff.value(output)
### ([-8.0], [-16.0], [16.0])
du1 = similar(y, size(y))
f!(du1,y,p2,first(t))
vec(du1) == vec(f(y,p2,first(t)))
vec(du1) == ReverseDiff.value(output)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions