-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
value_and_jacobian inference problem with AutoForwardDiff #632
Comments
Unfortunately, it is a well-known limitation of ForwardDiff itself: the dynamic choice of chunk size leads to type instability. You don't actually need DI to see this: julia> using Test; import ForwardDiff
julia> @inferred ForwardDiff.jacobian(identity, [1.0])
ERROR: return type Matrix{Float64} does not match inferred return type Union{Matrix{Any}, Matrix{Float64}, Matrix{E} where E<:(ForwardDiff.Dual{ForwardDiff.Tag{typeof(identity), Float64}, Float64})} However, DI offers you two workarounds. You can either pick a backend with a fixed chunk size (ensuring that it is always smaller than the input dimension): julia> import DifferentiationInterface as DI
julia> @inferred DI.jacobian(identity, DI.AutoForwardDiff(; chunksize=1), [1.0])
1×1 Matrix{Float64}:
1.0 Or you can keep the adaptive backend but use the preparation mechanism. In the case of ForwardDiff, DI's preparation includes chunk size selection. It is type-unstable but you only need to do it once: julia> prep = DI.prepare_jacobian(identity, DI.AutoForwardDiff(), [0.0]);
julia> @inferred DI.jacobian(identity, prep, DI.AutoForwardDiff(), [0.0])
1×1 Matrix{Float64}:
1.0 Does that solve your problem? |
Using the preparation mechanism just shifts the type instability elsewhere.
|
That is true, but the important thing is that you can shift it outside of the hot loop. If you compute 1000 Jacobians of the same function on inputs of the same type and size, you only need to prepare once.
That is also true but the whole point of fixing the chunk size is to guarantee type stability of Jacobian config creation. If you keep the step where you threshold the chunk size using the input size, you still have a type-unstable mechanism.
That's a change which would need to be done in ForwardDiff itself. There have been discussions around it, but until the type-unstable chunk size selection is removed, DI can't really be smarter than ForwardDiff in this regard. |
Thanks for the explanation, closing this. |
MWE:
I included an
SVector
for comparison. Looking into this, I think the type unstable part is the tagging.The text was updated successfully, but these errors were encountered: