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)
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 functionf, one obtains inHowever, for the mutating function, one gets
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.