Try to improve type stability with Householder#184
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests.
... and 3 files with indirect coverage changes 🚀 New features to boost your workflow:
|
cb03fcf to
4535feb
Compare
4535feb to
6d6e3f1
Compare
src/algorithms.jl
Outdated
|
|
||
| # Utility generated function to canonicalize keys in type-stable way | ||
| @generated _sortkeys(nt::NamedTuple{K}) where {K} = | ||
| :(NamedTuple{$(Tuple(sort!(collect(K))))}(nt)) |
There was a problem hiding this comment.
Any reason for not doing
| :(NamedTuple{$(Tuple(sort!(collect(K))))}(nt)) | |
| :(NamedTuple{$(sort(K))}(nt)) |
There was a problem hiding this comment.
Also, don't know if this really requires a generated function:
julia> function _canonicalize_nt(x::NamedTuple{N}) where {N}
return NamedTuple{sort(N)}(x)
end
_canonicalize_nt (generic function with 1 method)
julia> _canonicalize_nt((; y=3, x=5))
(x = 5, y = 3)
julia> @code_warntype _canonicalize_nt((; y=3, x=5))
MethodInstance for _canonicalize_nt(::@NamedTuple{y::Int64, x::Int64})
from _canonicalize_nt(x::NamedTuple{N}) where N @ Main REPL[10]:1
Static Parameters
N = (:y, :x)
Arguments
#self#::Core.Const(Main._canonicalize_nt)
x::@NamedTuple{y::Int64, x::Int64}
Body::@NamedTuple{x::Int64, y::Int64}
1 ─ %1 = Main.NamedTuple::Core.Const(NamedTuple)
│ %2 = Main.sort::Core.Const(sort)
│ %3 = $(Expr(:static_parameter, 1))::Core.Const((:y, :x))
│ %4 = (%2)(%3)::Core.Const((:x, :y))
│ %5 = Core.apply_type(%1, %4)::Core.Const(NamedTuple{(:x, :y)})
│ %6 = (%5)(x)::@NamedTuple{x::Int64, y::Int64}
└── return %6
There was a problem hiding this comment.
I feel like I tried that but that didn't work, let me double check
There was a problem hiding this comment.
Can confirm this doesn't work on Julia 1.10 😉
|
I would like to see a final run with the non-generated function suggestion to canonicalize the |
|
@Jutho I think I have now more or less exhausted the ways of writing a generated function without using a generated function. The verdict is that on LTS |
|
Ok, I quickly checked on LTS. That is indeed annoying. The one solution you did not think of is using |
Here I standardized the
Householderkeyword arguments in an attempt to improve the type stability (again).Apparently this just isn't enough, so I gave up again and just put the
@assume_effectsinto place.In general, I think this really is what we want, and the main point is that this should really only go wrong if
default_algorithmisn't foldable, which is probably a fair thing to ask for.I am also quite unhappy about this solution, and am very open to alternative suggestions, but I spent way too long on this already and am running out of ideas.
To give some insight into what I found:
The main thing seems to be that there is a maximal depth that the compiler will
@inlineor const-prop. For example, with some tinkering I actually got it to the point whereselect_algorithm(right_orth!, A, alg)is type stable, butselect_algorithm(right_orth, A, alg)then wasn't, even though it is marked with inline annotations.From this I concluded there is a maximal depth of logic we can achieve, and since the "orthnull" already is using up quite a bit of that I can't seem to get past it without a major rewrite