-
Notifications
You must be signed in to change notification settings - Fork 8
Description
At the moment, if derivatives wrt several inputs are needed, our recommendation is to use ComponentArrays.jl to concatenate them into a single vector. However, this is not very handy and can lead to performance issues: the naive keyword-based constructor for ComponentVector is type-unstable:
julia> using ComponentArrays, Test
julia> @inferred ComponentVector(a=1, b=[2, 3])
ERROR: return type ComponentVector{Int64, Vector{Int64}, Tuple{Axis{(a = 1, b = 2:3)}}} does not match inferred return type Any
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
julia> f() = ComponentVector(a=1, b=[2, 3])
f (generic function with 1 method)
julia> @inferred f()
ERROR: return type ComponentVector{Int64, Vector{Int64}, Tuple{Axis{(a = 1, b = 2:3)}}} does not match inferred return type Any
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35In fact, achieving type-stable construction would require knowing the array sizes statically (SciML/ComponentArrays.jl#126 (comment)), which is impossible in many cases.
An alternative would be to accept an arbitrary number of input arrays on our end. After brief experimentation, I fear this would introduce new sources of type instability as we loop through the args and splat them, storing results in vectors or tuples.
My proposal is to manually add support for two arguments. It will lead to code duplication but ensure type stability, and should cover a lot of use cases. Most notably, it will be necessary to implement implicit linear solvers, and thus enable second-order differentiation out of the box (#26).