From 04f76ca18ef87b20ad47335ae09c859edfabdf66 Mon Sep 17 00:00:00 2001 From: KristofferC Date: Tue, 13 Dec 2022 16:55:24 +0100 Subject: [PATCH 1/5] make StaticArrays dependency into an extension --- Project.toml | 9 ++- ext/StaticArraysExt.jl | 135 +++++++++++++++++++++++++++++++++++++++++ src/ForwardDiff.jl | 7 ++- src/apiutils.jl | 13 ---- src/dual.jl | 13 ---- src/gradient.jl | 27 --------- src/hessian.jl | 25 -------- src/jacobian.jl | 44 -------------- 8 files changed, 148 insertions(+), 125 deletions(-) create mode 100644 ext/StaticArraysExt.jl diff --git a/Project.toml b/Project.toml index a75b616d..cd6430a8 100644 --- a/Project.toml +++ b/Project.toml @@ -15,6 +15,12 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +[weakdeps] +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[extensions] +StaticArraysExt = "StaticArrays" + [compat] Calculus = "0.5" CommonSubexpressions = "0.3" @@ -33,7 +39,8 @@ Calculus = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" DiffTests = "de460e47-3fe3-5279-bb4a-814414816d5d" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Calculus", "DiffTests", "SparseArrays", "Test", "InteractiveUtils"] +test = ["Calculus", "DiffTests", "SparseArrays", "StaticArrays", "Test", "InteractiveUtils"] diff --git a/ext/StaticArraysExt.jl b/ext/StaticArraysExt.jl new file mode 100644 index 00000000..9f627539 --- /dev/null +++ b/ext/StaticArraysExt.jl @@ -0,0 +1,135 @@ +module StaticArraysExt + +using ForwardDiff, StaticArrays, LinearAlgebra, DiffResults +using ForwardDiff: Dual, partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk, + gradient, hessian, jacobian, gradient!, hessian!, jacobian!, + extract_gradient!, extract_jacobian!, extract_value!, + vector_mode_jacobian, vector_mode_jacobian!, valtype, value, _lyap_div! +using DiffResults: DiffResult, ImmutableDiffResult, MutableDiffResult + +@generated function dualize(::Type{T}, x::StaticArray) where T + N = length(x) + dx = Expr(:tuple, [:(Dual{T}(x[$i], chunk, Val{$i}())) for i in 1:N]...) + V = StaticArrays.similar_type(x, Dual{T,eltype(x),N}) + return quote + chunk = Chunk{$N}() + $(Expr(:meta, :inline)) + return $V($(dx)) + end +end + +@inline static_dual_eval(::Type{T}, f, x::StaticArray) where T = f(dualize(T, x)) + +function LinearAlgebra.eigvals(A::Symmetric{<:Dual{Tg,T,N}, <:StaticArrays.StaticMatrix}) where {Tg,T<:Real,N} + λ,Q = eigen(Symmetric(value.(parent(A)))) + parts = ntuple(j -> diag(Q' * getindex.(partials.(A), j) * Q), N) + Dual{Tg}.(λ, tuple.(parts...)) +end + +function LinearAlgebra.eigen(A::Symmetric{<:Dual{Tg,T,N}, <:StaticArrays.StaticMatrix}) where {Tg,T<:Real,N} + λ = eigvals(A) + _,Q = eigen(Symmetric(value.(parent(A)))) + parts = ntuple(j -> Q*_lyap_div!(Q' * getindex.(partials.(A), j) * Q - Diagonal(getindex.(partials.(λ), j)), value.(λ)), N) + Eigen(λ,Dual{Tg}.(Q, tuple.(parts...))) +end + +# Gradient +@inline ForwardDiff.gradient(f, x::StaticArray) = ForwardDiff.vector_mode_gradient(f, x) +@inline ForwardDiff.gradient(f, x::StaticArray, cfg::GradientConfig) = gradient(f, x) +@inline ForwardDiff.gradient(f, x::StaticArray, cfg::GradientConfig, ::Val) = gradient(f, x) + +@inline ForwardDiff.gradient!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray) = ForwardDiff.vector_mode_gradient!(result, f, x) +@inline ForwardDiff.gradient!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray, cfg::GradientConfig) = gradient!(result, f, x) +@inline ForwardDiff.gradient!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray, cfg::GradientConfig, ::Val) = gradient!(result, f, x) + +@generated function extract_gradient(::Type{T}, y::Real, x::S) where {T,S<:StaticArray} + result = Expr(:tuple, [:(partials(T, y, $i)) for i in 1:length(x)]...) + return quote + $(Expr(:meta, :inline)) + V = StaticArrays.similar_type(S, valtype($y)) + return V($result) + end +end + +@inline function ForwardDiff.vector_mode_gradient(f, x::StaticArray) + T = typeof(Tag(f, eltype(x))) + return extract_gradient(T, static_dual_eval(T, f, x), x) +end + +@inline function ForwardDiff.vector_mode_gradient!(result, f, x::StaticArray) + T = typeof(Tag(f, eltype(x))) + return extract_gradient!(T, result, static_dual_eval(T, f, x)) +end + +# Jacobian +@inline ForwardDiff.jacobian(f, x::StaticArray) = vector_mode_jacobian(f, x) +@inline ForwardDiff.jacobian(f, x::StaticArray, cfg::JacobianConfig) = jacobian(f, x) +@inline ForwardDiff.jacobian(f, x::StaticArray, cfg::JacobianConfig, ::Val) = jacobian(f, x) + +@inline ForwardDiff.jacobian!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray) = vector_mode_jacobian!(result, f, x) +@inline ForwardDiff.jacobian!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray, cfg::JacobianConfig) = jacobian!(result, f, x) +@inline ForwardDiff.jacobian!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray, cfg::JacobianConfig, ::Val) = jacobian!(result, f, x) + +@generated function extract_jacobian(::Type{T}, ydual::StaticArray, x::S) where {T,S<:StaticArray} + M, N = length(ydual), length(x) + result = Expr(:tuple, [:(partials(T, ydual[$i], $j)) for i in 1:M, j in 1:N]...) + return quote + $(Expr(:meta, :inline)) + V = StaticArrays.similar_type(S, valtype(eltype($ydual)), Size($M, $N)) + return V($result) + end +end + +@inline function ForwardDiff.vector_mode_jacobian(f, x::StaticArray) + T = typeof(Tag(f, eltype(x))) + return extract_jacobian(T, static_dual_eval(T, f, x), x) +end + +function extract_jacobian(::Type{T}, ydual::AbstractArray, x::StaticArray) where T + result = similar(ydual, valtype(eltype(ydual)), length(ydual), length(x)) + return extract_jacobian!(T, result, ydual, length(x)) +end + +@inline function ForwardDiff.vector_mode_jacobian!(result, f, x::StaticArray) + T = typeof(Tag(f, eltype(x))) + ydual = static_dual_eval(T, f, x) + result = extract_jacobian!(T, result, ydual, length(x)) + result = extract_value!(T, result, ydual) + return result +end + +@inline function ForwardDiff.vector_mode_jacobian!(result::ImmutableDiffResult, f, x::StaticArray) + T = typeof(Tag(f, eltype(x))) + ydual = static_dual_eval(T, f, x) + result = DiffResults.jacobian!(result, extract_jacobian(T, ydual, x)) + result = DiffResults.value!(d -> value(T,d), result, ydual) + return result +end + +# Hessian +ForwardDiff.hessian(f, x::StaticArray) = jacobian(y -> gradient(f, y), x) +ForwardDiff.hessian(f, x::StaticArray, cfg::HessianConfig) = hessian(f, x) +ForwardDiff.hessian(f, x::StaticArray, cfg::HessianConfig, ::Val) = hessian(f, x) + +ForwardDiff.hessian!(result::AbstractArray, f, x::StaticArray) = jacobian!(result, y -> gradient(f, y), x) + +ForwardDiff.hessian!(result::MutableDiffResult, f, x::StaticArray) = hessian!(result, f, x, HessianConfig(f, result, x)) + +ForwardDiff.hessian!(result::ImmutableDiffResult, f, x::StaticArray, cfg::HessianConfig) = hessian!(result, f, x) +ForwardDiff.hessian!(result::ImmutableDiffResult, f, x::StaticArray, cfg::HessianConfig, ::Val) = hessian!(result, f, x) + +function ForwardDiff.hessian!(result::ImmutableDiffResult, f, x::StaticArray) + T = typeof(Tag(f, eltype(x))) + d1 = dualize(T, x) + d2 = dualize(T, d1) + fd2 = f(d2) + val = value(T,value(T,fd2)) + grad = extract_gradient(T,value(T,fd2), x) + hess = extract_jacobian(T,partials(T,fd2), x) + result = DiffResults.hessian!(result, hess) + result = DiffResults.gradient!(result, grad) + result = DiffResults.value!(result, val) + return result +end + +end diff --git a/src/ForwardDiff.jl b/src/ForwardDiff.jl index 1eb755ac..da1ba70f 100644 --- a/src/ForwardDiff.jl +++ b/src/ForwardDiff.jl @@ -1,8 +1,7 @@ module ForwardDiff using DiffRules, DiffResults -using DiffResults: DiffResult, MutableDiffResult, ImmutableDiffResult -using StaticArrays +using DiffResults: DiffResult, MutableDiffResult using Preferences using Random using LinearAlgebra @@ -23,6 +22,10 @@ include("gradient.jl") include("jacobian.jl") include("hessian.jl") +if !isdefined(Base, :get_extension) + include("../ext/StaticArraysExt.jl") +end + export DiffResults end # module diff --git a/src/apiutils.jl b/src/apiutils.jl index 971c368c..5a2a1df9 100644 --- a/src/apiutils.jl +++ b/src/apiutils.jl @@ -18,19 +18,6 @@ end # vector mode function evaluation # ################################### -@generated function dualize(::Type{T}, x::StaticArray) where T - N = length(x) - dx = Expr(:tuple, [:(Dual{T}(x[$i], chunk, Val{$i}())) for i in 1:N]...) - V = StaticArrays.similar_type(x, Dual{T,eltype(x),N}) - return quote - chunk = Chunk{$N}() - $(Expr(:meta, :inline)) - return $V($(dx)) - end -end - -@inline static_dual_eval(::Type{T}, f, x::StaticArray) where T = f(dualize(T, x)) - function vector_mode_dual_eval!(f::F, cfg::Union{JacobianConfig,GradientConfig}, x) where {F} xdual = cfg.duals seed!(xdual, x, cfg.seeds) diff --git a/src/dual.jl b/src/dual.jl index 4315e322..3a5f5244 100644 --- a/src/dual.jl +++ b/src/dual.jl @@ -726,12 +726,6 @@ function LinearAlgebra.eigvals(A::Symmetric{<:Dual{Tg,T,N}}) where {Tg,T<:Real,N Dual{Tg}.(λ, tuple.(parts...)) end -function LinearAlgebra.eigvals(A::Symmetric{<:Dual{Tg,T,N}, <:StaticArrays.StaticMatrix}) where {Tg,T<:Real,N} - λ,Q = eigen(Symmetric(value.(parent(A)))) - parts = ntuple(j -> diag(Q' * getindex.(partials.(A), j) * Q), N) - Dual{Tg}.(λ, tuple.(parts...)) -end - function LinearAlgebra.eigvals(A::Hermitian{<:Complex{<:Dual{Tg,T,N}}}) where {Tg,T<:Real,N} λ,Q = eigen(Hermitian(value.(real.(parent(A))) .+ im .* value.(imag.(parent(A))))) parts = ntuple(j -> diag(real.(Q' * (getindex.(partials.(real.(A)) .+ im .* partials.(imag.(A)), j)) * Q)), N) @@ -761,13 +755,6 @@ function LinearAlgebra.eigen(A::Symmetric{<:Dual{Tg,T,N}}) where {Tg,T<:Real,N} Eigen(λ,Dual{Tg}.(Q, tuple.(parts...))) end -function LinearAlgebra.eigen(A::Symmetric{<:Dual{Tg,T,N}, <:StaticArrays.StaticMatrix}) where {Tg,T<:Real,N} - λ = eigvals(A) - _,Q = eigen(Symmetric(value.(parent(A)))) - parts = ntuple(j -> Q*_lyap_div!(Q' * getindex.(partials.(A), j) * Q - Diagonal(getindex.(partials.(λ), j)), value.(λ)), N) - Eigen(λ,Dual{Tg}.(Q, tuple.(parts...))) -end - function LinearAlgebra.eigen(A::SymTridiagonal{<:Dual{Tg,T,N}}) where {Tg,T<:Real,N} λ = eigvals(A) _,Q = eigen(SymTridiagonal(value.(parent(A)))) diff --git a/src/gradient.jl b/src/gradient.jl index f9711984..6d4cc791 100644 --- a/src/gradient.jl +++ b/src/gradient.jl @@ -43,29 +43,12 @@ function gradient!(result::Union{AbstractArray,DiffResult}, f::F, x::AbstractArr return result end -@inline gradient(f::F, x::StaticArray) where F = vector_mode_gradient(f, x) -@inline gradient(f::F, x::StaticArray, cfg::GradientConfig) where F = gradient(f, x) -@inline gradient(f::F, x::StaticArray, cfg::GradientConfig, ::Val) where F = gradient(f, x) - -@inline gradient!(result::Union{AbstractArray,DiffResult}, f::F, x::StaticArray) where F = vector_mode_gradient!(result, f, x) -@inline gradient!(result::Union{AbstractArray,DiffResult}, f::F, x::StaticArray, cfg::GradientConfig) where F = gradient!(result, f, x) -@inline gradient!(result::Union{AbstractArray,DiffResult}, f::F, x::StaticArray, cfg::GradientConfig, ::Val) where F = gradient!(result, f, x) - gradient(f, x::Real) = throw(DimensionMismatch("gradient(f, x) expects that x is an array. Perhaps you meant derivative(f, x)?")) ##################### # result extraction # ##################### -@generated function extract_gradient(::Type{T}, y::Real, x::S) where {T,S<:StaticArray} - result = Expr(:tuple, [:(partials(T, y, $i)) for i in 1:length(x)]...) - return quote - $(Expr(:meta, :inline)) - V = StaticArrays.similar_type(S, valtype($y)) - return V($result) - end -end - function extract_gradient!(::Type{T}, result::DiffResult, y::Real) where {T} result = DiffResults.value!(result, y) grad = DiffResults.gradient(result) @@ -117,16 +100,6 @@ function vector_mode_gradient!(result, f::F, x, cfg::GradientConfig{T}) where {T return result end -@inline function vector_mode_gradient(f, x::StaticArray) - T = typeof(Tag(f, eltype(x))) - return extract_gradient(T, static_dual_eval(T, f, x), x) -end - -@inline function vector_mode_gradient!(result, f, x::StaticArray) - T = typeof(Tag(f, eltype(x))) - return extract_gradient!(T, result, static_dual_eval(T, f, x)) -end - ############## # chunk mode # ############## diff --git a/src/hessian.jl b/src/hessian.jl index a4cb6fe9..9c755c9a 100644 --- a/src/hessian.jl +++ b/src/hessian.jl @@ -69,28 +69,3 @@ function hessian!(result::DiffResult, f::F, x::AbstractArray, cfg::HessianConfig jacobian!(DiffResults.hessian(result), ∇f!, DiffResults.gradient(result), x, cfg.jacobian_config, Val{false}()) return ∇f!.result end - -hessian(f::F, x::StaticArray) where F = jacobian(y -> gradient(f, y), x) -hessian(f::F, x::StaticArray, cfg::HessianConfig) where F = hessian(f, x) -hessian(f::F, x::StaticArray, cfg::HessianConfig, ::Val) where F = hessian(f, x) - -hessian!(result::AbstractArray, f::F, x::StaticArray) where F = jacobian!(result, y -> gradient(f, y), x) - -hessian!(result::MutableDiffResult, f::F, x::StaticArray) where F = hessian!(result, f, x, HessianConfig(f, result, x)) - -hessian!(result::ImmutableDiffResult, f::F, x::StaticArray, cfg::HessianConfig) where F = hessian!(result, f, x) -hessian!(result::ImmutableDiffResult, f::F, x::StaticArray, cfg::HessianConfig, ::Val) where F = hessian!(result, f, x) - -function hessian!(result::ImmutableDiffResult, f::F, x::StaticArray) where F - T = typeof(Tag(f, eltype(x))) - d1 = dualize(T, x) - d2 = dualize(T, d1) - fd2 = f(d2) - val = value(T,value(T,fd2)) - grad = extract_gradient(T,value(T,fd2), x) - hess = extract_jacobian(T,partials(T,fd2), x) - result = DiffResults.hessian!(result, hess) - result = DiffResults.gradient!(result, grad) - result = DiffResults.value!(result, val) - return result -end diff --git a/src/jacobian.jl b/src/jacobian.jl index 743aeb45..e7ca96f5 100644 --- a/src/jacobian.jl +++ b/src/jacobian.jl @@ -86,35 +86,12 @@ function jacobian!(result::Union{AbstractArray,DiffResult}, f!::F, y::AbstractAr return result end -@inline jacobian(f::F, x::StaticArray) where F = vector_mode_jacobian(f, x) -@inline jacobian(f::F, x::StaticArray, cfg::JacobianConfig) where F = jacobian(f, x) -@inline jacobian(f::F, x::StaticArray, cfg::JacobianConfig, ::Val) where F = jacobian(f, x) - -@inline jacobian!(result::Union{AbstractArray,DiffResult}, f::F, x::StaticArray) where F = vector_mode_jacobian!(result, f, x) -@inline jacobian!(result::Union{AbstractArray,DiffResult}, f::F, x::StaticArray, cfg::JacobianConfig) where F = jacobian!(result, f, x) -@inline jacobian!(result::Union{AbstractArray,DiffResult}, f::F, x::StaticArray, cfg::JacobianConfig, ::Val) where F = jacobian!(result, f, x) - jacobian(f, x::Real) = throw(DimensionMismatch("jacobian(f, x) expects that x is an array. Perhaps you meant derivative(f, x)?")) ##################### # result extraction # ##################### -@generated function extract_jacobian(::Type{T}, ydual::StaticArray, x::S) where {T,S<:StaticArray} - M, N = length(ydual), length(x) - result = Expr(:tuple, [:(partials(T, ydual[$i], $j)) for i in 1:M, j in 1:N]...) - return quote - $(Expr(:meta, :inline)) - V = StaticArrays.similar_type(S, valtype(eltype($ydual)), Size($M, $N)) - return V($result) - end -end - -function extract_jacobian(::Type{T}, ydual::AbstractArray, x::StaticArray) where T - result = similar(ydual, valtype(eltype(ydual)), length(ydual), length(x)) - return extract_jacobian!(T, result, ydual, length(x)) -end - function extract_jacobian!(::Type{T}, result::AbstractArray, ydual::AbstractArray, n) where {T} out_reshaped = reshape(result, length(ydual), n) ydual_reshaped = vec(ydual) @@ -184,27 +161,6 @@ function vector_mode_jacobian!(result, f!::F, y, x, cfg::JacobianConfig{T}) wher return result end -@inline function vector_mode_jacobian(f, x::StaticArray) - T = typeof(Tag(f, eltype(x))) - return extract_jacobian(T, static_dual_eval(T, f, x), x) -end - -@inline function vector_mode_jacobian!(result, f, x::StaticArray) - T = typeof(Tag(f, eltype(x))) - ydual = static_dual_eval(T, f, x) - result = extract_jacobian!(T, result, ydual, length(x)) - result = extract_value!(T, result, ydual) - return result -end - -@inline function vector_mode_jacobian!(result::ImmutableDiffResult, f, x::StaticArray) - T = typeof(Tag(f, eltype(x))) - ydual = static_dual_eval(T, f, x) - result = DiffResults.jacobian!(result, extract_jacobian(T, ydual, x)) - result = DiffResults.value!(d -> value(T,d), result, ydual) - return result -end - const JACOBIAN_ERROR = DimensionMismatch("jacobian(f, x) expects that f(x) is an array. Perhaps you meant gradient(f, x)?") # chunk mode # From 0632329fc20cc405700e7f11ef79c7c7c758b666 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 19 Feb 2023 15:59:59 -0500 Subject: [PATCH 2/5] update extension naming --- Project.toml | 2 +- ext/{StaticArraysExt.jl => ForwardDiffStaticArraysExt.jl} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename ext/{StaticArraysExt.jl => ForwardDiffStaticArraysExt.jl} (99%) diff --git a/Project.toml b/Project.toml index cd6430a8..1f12c7ba 100644 --- a/Project.toml +++ b/Project.toml @@ -19,7 +19,7 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [extensions] -StaticArraysExt = "StaticArrays" +ForwardDiffStaticArraysExt = "StaticArrays" [compat] Calculus = "0.5" diff --git a/ext/StaticArraysExt.jl b/ext/ForwardDiffStaticArraysExt.jl similarity index 99% rename from ext/StaticArraysExt.jl rename to ext/ForwardDiffStaticArraysExt.jl index 9f627539..8c341c16 100644 --- a/ext/StaticArraysExt.jl +++ b/ext/ForwardDiffStaticArraysExt.jl @@ -1,4 +1,4 @@ -module StaticArraysExt +module ForwardDiffStaticArraysExt using ForwardDiff, StaticArrays, LinearAlgebra, DiffResults using ForwardDiff: Dual, partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk, From 77d9ac234b8ffd82364b7cc7ea34da39e2357622 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 19 Feb 2023 16:13:39 -0500 Subject: [PATCH 3/5] Make the two extension PRs "exactly" the same --- ext/ForwardDiffStaticArraysExt.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/ForwardDiffStaticArraysExt.jl b/ext/ForwardDiffStaticArraysExt.jl index 8c341c16..7d2a77b7 100644 --- a/ext/ForwardDiffStaticArraysExt.jl +++ b/ext/ForwardDiffStaticArraysExt.jl @@ -4,6 +4,7 @@ using ForwardDiff, StaticArrays, LinearAlgebra, DiffResults using ForwardDiff: Dual, partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk, gradient, hessian, jacobian, gradient!, hessian!, jacobian!, extract_gradient!, extract_jacobian!, extract_value!, + vector_mode_gradient, vector_mode_gradient!, vector_mode_jacobian, vector_mode_jacobian!, valtype, value, _lyap_div! using DiffResults: DiffResult, ImmutableDiffResult, MutableDiffResult @@ -34,11 +35,11 @@ function LinearAlgebra.eigen(A::Symmetric{<:Dual{Tg,T,N}, <:StaticArrays.StaticM end # Gradient -@inline ForwardDiff.gradient(f, x::StaticArray) = ForwardDiff.vector_mode_gradient(f, x) +@inline ForwardDiff.gradient(f, x::StaticArray) = vector_mode_gradient(f, x) @inline ForwardDiff.gradient(f, x::StaticArray, cfg::GradientConfig) = gradient(f, x) @inline ForwardDiff.gradient(f, x::StaticArray, cfg::GradientConfig, ::Val) = gradient(f, x) -@inline ForwardDiff.gradient!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray) = ForwardDiff.vector_mode_gradient!(result, f, x) +@inline ForwardDiff.gradient!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray) = vector_mode_gradient!(result, f, x) @inline ForwardDiff.gradient!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray, cfg::GradientConfig) = gradient!(result, f, x) @inline ForwardDiff.gradient!(result::Union{AbstractArray,DiffResult}, f, x::StaticArray, cfg::GradientConfig, ::Val) = gradient!(result, f, x) From 7cd21b95a42d38ce135d68729858bd78b152bb8b Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 19 Feb 2023 16:23:14 -0500 Subject: [PATCH 4/5] Fix extension naming --- src/ForwardDiff.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ForwardDiff.jl b/src/ForwardDiff.jl index da1ba70f..fdfcd560 100644 --- a/src/ForwardDiff.jl +++ b/src/ForwardDiff.jl @@ -23,7 +23,7 @@ include("jacobian.jl") include("hessian.jl") if !isdefined(Base, :get_extension) - include("../ext/StaticArraysExt.jl") + include("../ext/ForwardDiffStaticArraysExt.jl") end export DiffResults From df7e6e06de99bbd52c44be1318a8669a8421eeb7 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 19 Feb 2023 17:23:53 -0500 Subject: [PATCH 5/5] Only import ForwardDiff and StaticArrays --- ext/ForwardDiffStaticArraysExt.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/ForwardDiffStaticArraysExt.jl b/ext/ForwardDiffStaticArraysExt.jl index 7d2a77b7..52914cd6 100644 --- a/ext/ForwardDiffStaticArraysExt.jl +++ b/ext/ForwardDiffStaticArraysExt.jl @@ -1,6 +1,8 @@ module ForwardDiffStaticArraysExt -using ForwardDiff, StaticArrays, LinearAlgebra, DiffResults +using ForwardDiff, StaticArrays +using ForwardDiff.LinearAlgebra +using ForwardDiff.DiffResults using ForwardDiff: Dual, partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk, gradient, hessian, jacobian, gradient!, hessian!, jacobian!, extract_gradient!, extract_jacobian!, extract_value!,