I have a function where both a matrix g as well as a vector q depend on some vector input p. On the way I need to solve for g^{-1} q. I want to use DifferentiationInterface
+AutoForwardDiff
to take derivatives of this function and also avoid any allocations on the way. The dimension of p and q won’t be ever be bigger than 10 or so. Consider e.g. the following MWE
(ignore the specific computations, just wanted to have a nontrivial example)
using LinearAlgebra, DifferentiationInterface, StaticArrays
import ForwardDiff
function want_to_diff!(q::MVector{n, T}, p::StaticVector{n,T}, g_buffer::MMatrix{n,n,T}) where {n<:Any, T<:Real}
fill!(g_buffer, zero(T))
for i in 1:n
g_buffer[i, i] = p[i]
g_buffer[i, 1] = p[i]
g_buffer[1, i] = p[i]
end
ldiv!(q, g_buffer, p)
return nothing
end
g_buffer = zero(MMatrix{3,3,Float32})
p = @MVector [1f0, 2f0, 3f0]
q = MVector{3, Float32}(undef)
jac = MMatrix{3,3,Float32}(undef)
jacobian!(want_to_diff!, q, jac, AutoForwardDiff(), p, Cache(g_buffer))
This raises no method matching ldiv!(::MMatrix{3, 3, ForwardDiff.Dual{…}, 9}, ::MVector{3, ForwardDiff.Dual{…}})
.
I attempted manually specifying the factorization object by using FastLapackInterface
’s BunchKaufmanWs
, but even when manuallly trying to define DifferentiationInterface
’s recursive_similar
for these workspaces I got similar errors. If I understand Solve linear system repeatedly without allocation - #4 by PeterSimon correctly, then this is expected since FastLapackInterface
does not apparently work with FastForward
.
If a non-allocating inv!
function existed, I would gladly use it, even though factorization would of course be preferable. But since I deal with low-dimensional vectors and matrices, I assume this wouldn’t be much of a problem.
Do I need to use PreallocationTools
or something like that? Or is there a better way to accomplish these kind of calculations without allocations and in DifferentiationInterface
-friendly manner? Am I just missing something small to get ldiv!
to works here?
Edit: This does not seem to be specific to ForwardDiff
. I get the same error using AutoEnzyme(; mode=Enzyme.Forward)
.