-
Notifications
You must be signed in to change notification settings - Fork 147
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
use Base.Fix1
instead of closures in ForwardDiffStaticArraysExt.jl
#735
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #735 +/- ##
==========================================
- Coverage 89.57% 86.14% -3.44%
==========================================
Files 11 10 -1
Lines 969 895 -74
==========================================
- Hits 868 771 -97
- Misses 101 124 +23 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well spotted, this seems fine.
I think the closure gets typeof(T) == DataType
, MWE is:
julia> let T = Float32
@code_warntype map(x -> convert(T, x), 1:3)
end
MethodInstance for map(::var"#27#28"{DataType}, ::UnitRange{Int64})
from map(f, A::AbstractArray) @ Base abstractarray.jl:3371
Arguments
#self#::Core.Const(map)
f::var"#27#28"{DataType}
A::UnitRange{Int64}
Body::Vector
1 ─ %1 = Base.collect_similar::Core.Const(Base.collect_similar)
│ %2 = Base.Generator(f, A)::Base.Generator{UnitRange{Int64}, var"#27#28"{DataType}}
│ %3 = (%1)(A, %2)::Vector
└── return %3
julia> VERSION
v"1.11.3"
It's fixed on master:
julia> let T = Float32
@code_warntype map(x -> convert(T, x), 1:3)
end
MethodInstance for map(::var"#8#9"{Type{Float32}}, ::UnitRange{Int64})
from map(f, A::AbstractArray) @ Base abstractarray.jl:3411
Arguments
#self#::Core.Const(map)
f::var"#8#9"{Type{Float32}}
A::UnitRange{Int64}
Body::Vector{Float32}
1 ─ %1 = Base.collect_similar::Core.Const(Base.collect_similar)
│ %2 = Base.Generator::Core.Const(Base.Generator)
│ %3 = (%2)(f, A)::Base.Generator{UnitRange{Int64}, var"#8#9"{Type{Float32}}}
│ %4 = (%1)(A, %3)::Vector{Float32}
└── return %4
julia> VERSION
v"1.12.0-DEV.1731"
julia> @code_warntype withjacobian(SVector(1.0, 2.0)) # from above
MethodInstance for withjacobian(::SVector{2, Float64})
from withjacobian(x::SVector) @ Main REPL[9]:1
Arguments
#self#::Core.Const(Main.withjacobian)
x::SVector{2, Float64}
Locals
res::DiffResults.ImmutableDiffResult{1, SVector{2, Float64}, Tuple{SMatrix{2, 2, Float64, 4}}}
Body::Tuple{SVector{2, Float64}, SMatrix{2, 2, Float64, 4}}
(@v1.12) pkg> st ForwardDiff
Status `~/.julia/environments/v1.12/Project.toml`
[f6369f11] ForwardDiff v0.10.38
Added checks that the MWEs from this PR and from #639 infer. |
Constant propagation of the tag
T
into the closured -> value(T,d)
seems to fail inForwardDiff.vector_mode_jacobian!(::ImmutableDiffResult, ...)
ForwardDiff.jl/ext/ForwardDiffStaticArraysExt.jl
Lines 102 to 108 in 7d63748
so I replaced the closure with
Base.Fix1
. I preemptively replaced two other closures as well.On the one hand, this is probably a compiler regression (though I'm not sure when; this bug occurs on both 1.9 and 1.11) that should be fixed elsewhere. But on the other hand,
StaticArrays
puts a lot of pressure on the compiler and closures are well-known to be finicky with respect to type inference, so IMO getting rid of the closures is worth the slight loss of readability.MWE
Without this PR:
With this PR:
Version info: