You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
gradient!, jacobian! and hessian! do not support an immutable DiffResult unless x is a StaticArray #849
The methods in src store derivatives by mutating the buffer they pull out of a DiffResult, so they cannot handle a result whose buffers are genuinely immutable. The StaticArrays extension does handle one, but its methods are only reached when x is itself a StaticArray.
using ForwardDiff, DiffResults, StaticArrays
x = [1.0, 2.0, 3.0]
sq(z) = z .^2# succeeds or fails depending only on the chunk sizefor c in (1, 2, 3)
cfg = ForwardDiff.GradientConfig(prod, x, ForwardDiff.Chunk{c}())
ForwardDiff.gradient!(DiffResults.GradientResult(@SVectorzeros(3)), prod, x, cfg)
end# chunk 1, 2: ERROR: setindex!(::SVector{3, Float64}, value, ::Int) is not defined.# chunk 3: ImmutableDiffResult(6.0, ([6.0, 3.0, 2.0],))
ForwardDiff.hessian!(DiffResults.HessianResult(@SVectorzeros(3)), prod, x)
# ERROR: setindex!(::SVector{3, Float64}, value, ::Int) is not defined.
ForwardDiff.jacobian!(DiffResults.JacobianResult(@SVector(zeros(3)), @SVector(zeros(3))), sq, x)
# ERROR: MethodError: no method matching extract_jacobian!(…, ::ImmutableDiffResult{…}, …)
All three work with x = SVector(1.0, 2.0, 3.0).
Cause
extract_gradient_chunk! (gradient.jl#L83-L86) and hessian!(::DiffResult, …) (hessian.jl#L69) write the extracted buffer via setindex!/broadcast, and extract_jacobian! (jacobian.jl#L104) only has AbstractArray and MutableDiffResult methods.
Vector-mode gradient! shows what the others need: extract_gradient!(::Type{T}, ::DiffResult, ::Dual) stores through DiffResults.gradient!, rebuilding the struct instead of writing the buffer.
Scope
Only about genuinely immutable buffers. A result holding MArray buffers hits some of the same errors, but that is DiffResults#25 — those are writable and should give a MutableDiffResult.
Independent of #696; reproduces before and after the re-aliasing fix there.
ForwardDiff master (v1.4.6), Julia 1.12.7, StaticArrays 1.9.22, DiffResults 1.1.0.
Activity