Problem with ForwardDiff and pre-allocating vector

I’m attempting to use ForwardDiff in a function that involves several instances of pre-allocating vectors. I’ve boiled the function down to the cause of the bug

using ForwardDiff

function f(x) 
    tmp = zeros(2)

    for i in 1:2
        tmp[i] = x[i] * i
    end

    return tmp
end

ForwardDiff.jacobian(f, [4.7 5.7])

Any ideas on how I can fix this issue? In this case, rewriting the function as

function f(x) 
    tmp = [x[1] * 1 x[2] * 2]

    return tmp
end

fixes the problem, but in my use case, this solution isn’t feasible since the size of the output vector depends on other inputs.

function f(x::T) where T
  tmp = zeros(T, 2)
...

that way tmp has the same type as x.

1 Like

It’s not a bug. It’s because you need to have things typed to handle Dual numbers when x is Dual. If you want to pre-allocate, you need to pre-allocate for both the Dual and non-dual type, and use dispatch to choose the cache. You’ll likely need to disable tagging for that to work, or use a non-function-based tag.

Note that supposedly a Cassette.jl version of ForwardDiff.jl won’t have the Dual typing constraint, so that may make this easier when it comes out.

I think you need zeros(eltype(x), 2) since x itself is a Vector in the example.

2 Likes

You can also just do zeros(x).

You can also just do zeros(x).

Yes, in 0.6.1. It seems to be going away in 0.7, however. (Or did I get this wrong?)

Thanks for the responses everyone! I was able to get my problem working!