# Hessian-vector product in place with ReverseDiff

**URL:** <https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280>\
**Category:** General Usage\
**Tags:** differentiation\
**Created:** [April 9, 2020, 2:26pm UTC](https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280 "2020-04-09T14:26:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)\
**Post date:** [April 9, 2020, 2:26pm UTC](https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280/1 "2020-04-09T14:26:33Z")

</div>

I posted this question of the `autodiff` Slack channel but haven’t heard back.

I’m trying to compute Hessian-vector products in place with ReverseDiff. I tried the following

```julia
julia> function arglina(x)
         n = length(x)
         m = 2 * n
         return sum((x[i] - 2/m * sum(x[j] for j = 1:n) - 1)^2 for i = 1:n) + sum((-2/m * sum(x[j] for j = 1:n) - 1)^2 for i = n+1:m)
       end
arglina (generic function with 1 method)

julia> ∇f!(g, x) = ReverseDiff.gradient!(g, arglina, x);

julia> ∇²fv!(x, v, hv) = begin
           g = similar(x)
           ReverseDiff.gradient!(hv, x -> dot(∇f!(g, x), v), x)
       end
∇²fv! (generic function with 1 method)

julia> x = ones(5); v = copy(x); hv = similar(x);

julia> ∇²fv!(x, v, hv)
5-element Array{Float64,1}:
 0.0
 0.0
 0.0
 0.0
 0.0

```

Allocating new vectors for the result works:

```julia
julia> ∇f(x) = ReverseDiff.gradient(arglina, x);

julia> ∇²fv(x, v) = ReverseDiff.gradient(x -> dot(∇f(x), v), x);

julia> ∇²fv(x, v)
5-element Array{Float64,1}:
 2.0
 2.0
 2.0
 2.0
 2.0

```

Am I doing something wrong here? Or is this [Perturbation Confusion (Nested Differentiation Bug) · Issue #83 · JuliaDiff/ForwardDiff.jl · GitHub](https://github.com/JuliaDiff/ForwardDiff.jl/issues/83)?

Thanks!

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [April 9, 2020, 3:27pm UTC](https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280/2 "2020-04-09T15:27:30Z")

</div>

It seems `g` should be `similar` to the `x` in the `dot` not the `x` input to `∇²fv!`. Why the code above doesn’t error is probably a bug. You can open an issue.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [April 9, 2020, 3:29pm UTC](https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280/3 "2020-04-09T15:29:03Z")

</div>

In general, in-place mutation and autodiff don’t mix well together in reverse-mode AD packages in Julia.

---

<div class="post-metadata">

**Author:** ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)\
**Post date:** [April 9, 2020, 3:35pm UTC](https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280/4 "2020-04-09T15:35:37Z")

</div>

Thanks for the comments. There’s special provision for in-place gradient in ReverseDiff though.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [April 9, 2020, 3:39pm UTC](https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280/5 "2020-04-09T15:39:10Z")

</div>

Replacing `g = similar(x)` with `g = ReverseDiff.track.(zero(x))` works too.

---

<div class="post-metadata">

**Author:** ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)\
**Post date:** [April 9, 2020, 3:43pm UTC](https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280/6 "2020-04-09T15:43:35Z")

</div>

This works:

```julia
∇²fv!(x, v, hv) = ReverseDiff.gradient!(hv, x -> begin g = similar(x); dot(∇f!(g, x), v) end, x)

```

Is that what you meant?

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [April 9, 2020, 3:49pm UTC](https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280/7 "2020-04-09T15:49:33Z")

</div>

Yes! Sorry I wasn’t clear.

---

<div class="post-metadata">

**Author:** ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)\
**Post date:** [April 9, 2020, 3:56pm UTC](https://discourse.julialang.org/t/hessian-vector-product-in-place-with-reversediff/37280/8 "2020-04-09T15:56:28Z")

</div>

Many thanks! In fact, this appears to work as well:

```julia
∇²fv!(x, v, hv) = begin
  g = ReverseDiff.track.(zero(x))
  ReverseDiff.gradient!(hv, x -> dot(∇f!(g, x), v), x)
end

```
