Skip to content

fix: remove invalidating ::Any methods#346

Open
AayushSabharwal wants to merge 2 commits intoJuliaAlgebra:mainfrom
AayushSabharwal:as/improve-invalidations
Open

fix: remove invalidating ::Any methods#346
AayushSabharwal wants to merge 2 commits intoJuliaAlgebra:mainfrom
AayushSabharwal:as/improve-invalidations

Conversation

@AayushSabharwal
Copy link
Copy Markdown
Contributor

@AayushSabharwal AayushSabharwal commented Sep 20, 2025

I also removed the ::Nothing method since it was invalidating, and if I understand correctly it was necessary due to the ::Any methods.

Base.isequal(α, q::RationalPoly) = isequal(α * q.den, q.num)
Base.isequal(q::RationalPoly, α) = isequal(α, q)
Base.isequal(α::Union{Number,MA.AbstractMutable,AbstractArray}, q::RationalPoly) = isequal(α * q.den, q.num)
Base.isequal(q::RationalPoly, α::Union{Number,MA.AbstractMutable,AbstractArray}) = isequal(α, q)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define this Union as a const const _Constant

@AayushSabharwal AayushSabharwal force-pushed the as/improve-invalidations branch 2 times, most recently from 9738765 to ed52a33 Compare September 20, 2025 20:55
@blegat
Copy link
Copy Markdown
Member

blegat commented Sep 22, 2025

Is the support of AbstractArray also causing invalidations ?

@AayushSabharwal
Copy link
Copy Markdown
Contributor Author

AayushSabharwal commented Sep 22, 2025

No, that part is fine. The only other invalidations from this dependency tree are

inserting *(z::MutableArithmetics.Zero, ::Any) @ MutableArithmetics ~/.julia/packages/MutableArithmetics/PcwmY/src/rewrite.jl:61 invalidated:
   mt_backedges: 1: signature Tuple{typeof(*), Any, String} triggered MethodInstance for Base.Precompilation._precompilepkgs(::Vector{String}, ::Bool, ::Bool, ::Bool, ::Bool, ::Bool, ::Vector{Pair{Cmd, Base.CacheFlags}}, ::IOContext{IO}, ::Bool, ::Bool) (0 children)

inserting +(x, ::MutableArithmetics.Zero) @ MutableArithmetics ~/.julia/packages/MutableArithmetics/PcwmY/src/rewrite.jl:65 invalidated:
   mt_backedges: 1: signature Tuple{typeof(+), Ptr{UInt16}, Any} triggered MethodInstance for Base._copyfrompacked!(::Ptr, ::Ptr{UInt16}) (1 children)
                 2: signature Tuple{typeof(+), Ptr{Tuple{UInt8, UInt8}}, Any} triggered MethodInstance for Base._copyfrompacked!(::Ptr, ::Ptr{Tuple{UInt8, UInt8}}) (1 children)

inserting step(r::MutableArithmetics.MutatingStepRange) @ MutableArithmetics ~/.julia/packages/MutableArithmetics/PcwmY/src/implementations/MutatingStepRange.jl:25 invalidated:
   mt_backedges: 1: signature Tuple{typeof(step), OrdinalRange{Int64, Int64}} triggered MethodInstance for Base.IteratorsMD.__inc(::Tuple{Int64, Int64, Vararg{Int64}}, ::Tuple{OrdinalRange{Int64, Int64}, OrdinalRange{Int64, Int64}, Vararg{OrdinalRange{Int64, Int64}}}) (0 children)
                 2: signature Tuple{typeof(step), OrdinalRange{Int64, Int64}} triggered MethodInstance for (::Base.IteratorsMD.var"#23#25")(::OrdinalRange{Int64, Int64}) (3 children)
                 3: signature Tuple{typeof(step), OrdinalRange{Int64, Int64}} triggered MethodInstance for Base.IteratorsMD.__inc(::Tuple{Int64}, ::Tuple{OrdinalRange{Int64, Int64}}) (5 children)

@oameye
Copy link
Copy Markdown

oameye commented Mar 27, 2026

Can we merge this?

I ran into the same invalidation problem. Here's some concrete data from a @snoop_invalidations analysis on Julia 1.12:

MultivariatePolynomials causes 1,551 method invalidations
The top offenders are exactly the methods this PR fixes:

Method Invalidations
+(x, ::MutableArithmetics.Zero) 446
==(p::AbstractPolynomialLike, α) 411
isequal(q::RationalPoly, α) 394
==(x::AbstractPolynomialLike, α::Nothing) 329
isequal(α, q::RationalPoly) 267
==(α, q::RationalPoly) 97

This PR's approach of using _Constant = Union{Number, MA.AbstractMutable, AbstractArray} matches @blegat's suggestion in #290 and looks correct to me. The removal of the ::Nothing methods also makes sense since they were only disambiguation guards for the ::Any signatures.

@blegat
Copy link
Copy Markdown
Member

blegat commented Mar 29, 2026

As this is a breaking change, I plan to incorporate it into the next breaking release. The plan is as follows:

I did two bad design decisions in MultivariatePolynomials:

  1. Overloading Base methods for interacting with Any, this is what this PR is fixing
  2. When two polynomials have a different set of variables, instead of first promoting them to the same set of variables and then running a simple code that is specialized to polynomials with the same variables, I wrote complicated implementations for all operations that work with polynomials with a different set of variables. That makes the code complicated for no clear performance gain.
  3. Make DynamicPolynomials and TypedPolynomials implement their own different polynomial implementation (which was kind of necessary due to 2).

When writing StarAlgebras with @kalmarek , we learned from these mistakes and didn't repoduce them. I released StarAlgebras 2 days ago so I can now use it as backend for MultivariatePolynomials and that will automatically solve this issue. DynamicPolynomials and TypedPolynomials will now just define monomials and StarAlgebras will handle the rest. A prototype of how to use StarAlgebras to define monomials is already in MultivariateBases, I'll just replace the current polynomial implementation here by that.

@oameye
Copy link
Copy Markdown

oameye commented Mar 29, 2026

That sounds great! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants