-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
lazier, less-jazzy linalg internals #24969
Conversation
(CI appears happy apart from the global method ambiguity check and stdlib/suitesparse, which I had forgotten.) |
Fixed the one non-ambiguity CI failure. Satisfying the ambiguity check... julia> length(Test.detect_ambiguities(Core, Base; imported=true, recursive=true, ambiguous_bottom=false))
387 ... might take a few days. |
Unsurprisingly, the vast majority of the ambiguities come from transferring the broad fallbacks for (*(A::AbstractArray{T,2} where T, adjB::Base.LinAlg.Adjoint{#s336,#s335} where #s335<:(Union{Hermitian{T,S}, Hermitian{Complex{T},S}, Symmetric{T,S}} where S where T<:Real) where #s336) in Base.LinAlg at linalg/symmetric.jl:332, *(adjA::Base.LinAlg.Adjoint{#s336,#s335} where #s335<:Base.LinAlg.AbstractTriangular where #s336, B::AbstractArray{T,2} where T) in Base.LinAlg at linalg/triangular.jl:1700) requiring resolution signature Tuple{typeof(*),Base.LinAlg.Adjoint{#s336,#s335} where #s335<:Base.LinAlg.AbstractTriangular where #s336,Base.LinAlg.Adjoint{#s336,#s335} where #s335<:(Union{Hermitian{T,S}, Hermitian{Complex{T},S}, Symmetric{T,S}} where S where T<:Real) where #s336} But the resolution signatures for the 300+ ambiguities with that commit get a bit abstract, e.g. ambiguous pair (*(a::Adjoint, b::Adjoint) in Base.LinAlg at linalg/adjtrans.jl:105, *(adjA::Adjoint{#s336,#s335} where #s335<:Base.LinAlg.AbstractTriangular where #s336, B::AbstractArray{T,2} where T) in Base.LinAlg at linalg/triangular.jl:1700) requiring resolution signature Tuple{typeof(*),Adjoint{#s336,#s335} where #s335<:Base.LinAlg.AbstractTriangular where #s336,Adjoint} I begin to lean towards simply not transferring those (overly broad?) fallbacks. Thoughts? Thanks! |
Update, and a fundamental design point (opt-in versus opt-out laziness): Transferring the broad fallbacks for So instead I added the shims for those broad fallbacks, e.g. What are the implications of not transferring those fallbacks? Formerly, due to those broad fallbacks, most This pull request presently makes lazy Given those upsides and the problems associated with transferring the broad fallbacks, I presently lean heavily towards not transferring the broad fallbacks and making laziness opt-in. By default I will follow that approach in this and subsequent PRs and flip the opt-in switch at some point in that process. Best! |
…h de-jazzed passthroughs.
… with de-jazzed passthroughs.
…l with de-jazzed passthroughs.
… with de-jazzed passthroughs.
…an.jl with de-jazzed passthroughs.
…l with de-jazzed passthroughs.
…ion.jl with de-jazzed passthroughs.
….jl with de-jazzed passthroughs.
…th de-jazzed passthroughs.
…h de-jazzed passthroughs.
…jl with de-jazzed passthroughs.
… de-jazzed passthroughs.
… de-jazzed passthroughs.
… de-jazzed passthroughs.
…with de-jazzed passthroughs.
….jl with de-jazzed passthroughs.
…with de-jazzed passthroughs.
…or.jl with de-jazzed passthroughs.
…jl with de-jazzed passthroughs.
…with de-jazzed passthroughs.
….jl as *, /, \, mul!, ldiv!, or rdiv!.
…r.jl as *, /, \, mul!, ldiv!, or rdiv!.
…l as *, /, \, mul!, ldiv!, or rdiv!.
…aling.jl as *, /, \, mul!, ldiv!, or rdiv!.
…\, mul!, ldiv!, or rdiv!.
… as *, /, \, mul!, ldiv!, or rdiv!.
…tor.jl as *, /, \, mul!, ldiv!, or rdiv!.
…Solvers as *, /, \, mul!, ldiv!, or rdiv!.
… *, /, \, mul!, ldiv!, or rdiv!.
This pull request now replaces/rewrites all
|
end | ||
end | ||
|
||
@pure function checkeltype(::Type{Transform}, ::Type{ResultEltype}, ::Type{ParentEltype}) where {Transform, ResultEltype, ParentEltype} |
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.
Why does this need to be @pure
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.
This definition was preexisting for RowVector
s :).
end | ||
end | ||
|
||
@pure function checkeltype(::Type{Transform}, ::Type{ResultEltype}, ::Type{ParentEltype}) where {Transform, ResultEltype, ParentEltype} |
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.
This is very strongly not a pure
function and terrible things will happen.
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.
As above, this definition was preexisting for RowVector
s :).
Thanks this is great. However, I thought this PR would come together with the parser changes that no longer parse julia> struct MyType{T<:Number}
a::T
end
julia> Base.:*(x::MyType,y::MyType) = MyType(x.a*y.a)
julia> Base.adjoint(x::MyType) = x
julia> x=MyType(3)
MyType{Int64}(3)
julia> x'*x
ERROR: MethodError: no method matching *(::Base.LinAlg.Adjoint{Any,MyType{Int64}}, ::MyType{Int64})
Closest candidates are:
*(::Any, ::Any, ::Any, ::Any...) at operators.jl:469
*(::AbstractArray, ::Number) at arraymath.jl:55
*(::AbstractArray{T,2} where T, ::Base.LinAlg.Transpose{#s344,#s343} where #s343<:RowVector where #s344) at linalg/rowvector.jl:221
...
Stacktrace:
[1] Ac_mul_B(::MyType{Int64}, ::MyType{Int64}) at ./deprecated.jl:2968
[2] top-level scope Could we please have Or is that what #25083 is about? |
Ok thanks. I don't see the parser changes there either yet, but I guess those are to come then? Thanks again for all the work! |
Please see the OP for a task list. Best! |
This pull request completes the first two major blocks of work towards JuliaLang/LinearAlgebra.jl#57. Specifically,
The first commit introduces
Adjoint
andTranspose
types, basic functionality for those types, and an extensive test suite for that functionality.The remaining twenty-one commits then strip all
A[ct]_(mul|ldiv|rdiv)_B[ct][!]
definitions fromBase
. More precisely, these commits transform each such definition to a corresponding*
//
/\
/mul!
/ldiv!
/rdiv!
definition overAdjoint
/Transpose
, and then place the original signature inbase/deprecated.jl
as a shim that calls the transformed definition.(In a vain attempt to minimize erosion of my sanity in this process, I made the preceding transformations in the most safe and mechanically simple manner I could: Each method like
A_ldiv_Bc!(A::TypeA, B::TypeB) = $METHBODY
tranforms in place toldiv!(A::TypeA, adjB::Adjoint{<:Any,<:TypeB}) = (B = adjB.parent; $METHBODY)
with shimA_ldiv_Bc!(A::TypeA, B::TypeB) = ldiv!(A, Adjoint(B))
placed in base/deprecated.jl. I also de-meta-fied definitions where that made life simpler.)All intermediate commits pass the linear algebra and sparse test suites locally.
Collapsing all e.g.
A[ct]_mul_B[ct]
methods into a single e.g.*
function yields the mother of all ambiguity resolution nightmares.So while I fixed all ambiguities necessary to get each commit to pass tests, I expect CI's general method ambiguity filter to detonate on contact.Ambiguities resolved.(Updated.) Next steps, whether in this or subsequent pull requests:
Strip alldone hereA[ct]_(mul|ldiv|rdiv)_B[ct][!]
definitions fromstdlib/
.Strip all explicitdone hereA[ct]_(mul|ldiv|rdiv)_B[ct][!]
calls frombase/
.Strip all explicitdone hereA[ct]_(mul|ldiv|rdiv)_B[ct][!]
calls fromtest/
.Strip all explicitdone hereA[ct]_(mul|ldiv|rdiv)_B[ct][!]
calls fromstdlib/
.Transition linalg todone in transition linalg to Adjoint/Transpose externally #25083Adjoint
/Transpose
externally.Strip alldone in remove special lowering for and deprecate .' #25125.'
instances frombase/
.Strip alldone in remove special lowering for and deprecate .' #25125.'
instances fromtest/
.Strip alldone in remove special lowering for and deprecate .' #25125.'
instances fromstdlib/
.Remove specialdone in remove special lowering for and deprecate .' #25125A[t]_(mul|ldiv|rdiv)_B[t]
lowering.Deprecatedone in remove special lowering for and deprecate .' #25125.'
.Rewrite all semantically eagerdone in update context-independent and remove context-dependent lowering of ' #25148'
calls inbase/
.Rewrite all semantically eagerdone in update context-independent and remove context-dependent lowering of ' #25148'
calls intest/
.Rewrite all semantically eagerdone in update context-independent and remove context-dependent lowering of ' #25148'
calls instdlib/
.Changedone in update context-independent and remove context-dependent lowering of ' #25148'
lowering fromadjoint
toAdjoint
.Remove specialdone in update context-independent and remove context-dependent lowering of ' #25148A[c]_(mul|ldiv|rdiv)_B[c]
lowering.Deprecate all the things.done in sunset linalg jazz #25217Best!