Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Polynomials.jl: `Base.promote(p::P, q::Q)` in `@poly_register` invalidates ~20,600 method instances on load

Aperta Adatta ai principianti
#641 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
62/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Ambito
performance

Direzione di ricerca

Leggi src/abstract-polynomial.jl intorno alla riga 277 ed esamina l’espansione di @poly_register e i metodi promote_rule esistenti. Riproduci l’invalidazione con il comando fornito SnoopCompileCore.@snoop_invalidations in una sessione con un pacchetto di grandi dimensioni caricato, quindi rimuovi il metodo ridondante Base.promote e confronta il comportamento. Il lavoro è terminato quando la promozione continua a funzionare per i tipi di polinomi registrati e il caricamento non causa più le invalidazioni segnalate.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Target: https://github.com/JuliaMath/Polynomials.jl (observed on v4.1.3; the line is still present on master as of 2026-10-19).

What happens

src/abstract-polynomial.jl:277 (inside macro poly_register):

Base.promote(p::P, q::Q) where {B, X, T, P <:$poly{B,T,X}, Q <: $poly{B,T,X}} = p,q

The macro is expanded for six container types (MutableDensePolynomial, MutableDenseViewPolynomial, MutableDenseLaurentPolynomial, ImmutableDensePolynomial, MutableSparsePolynomial, MutableSparseVectorPolynomial), so loading Polynomials adds six 2-argument methods to Base.promote.

Base.promote with two arguments has only two methods in Base (promote(x, y) and promote(x::T, y::T, zs::T...)). Under the default max_methods = 3, every call promote(a, b) that inference sees with non-concrete argument types therefore gets a precise edge to those two methods. The first new 2-arg promote method intersects Tuple{typeof(promote), Any, Any} and invalidates all of those callers and, transitively, everything inferred on top of them.

Measured in a Julia 1.13.2 session whose sysimage contains ModelingToolkit 11.45 / Symbolics 7.45 / SciMLBase 3.57, using SnoopCompileCore.@snoop_invalidations:

20637  promote(p::P, q::Q) where {B, X, T, P<:MutableSparsePolynomial{B,T,X}, Q<:MutableSparsePolynomial{B,T,X}} @ Polynomials src/abstract-polynomial.jl:277
   90  adjoint(A::VecOrMat{<:AbstractPolynomial}) @ Polynomials src/common.jl:546
   81  collect(::Type{T}, p::MutableSparseVectorPolynomial) where T @ Polynomials src/polynomial-container-types/mutable-sparse-vector-polynomial.jl:91
   15  Symbol(::Polynomials.Var{T}) where T @ Polynomials src/abstract.jl:11

Polynomials accounts for 20,823 of the 30,680 invalidated method instances in that session (68%). Whichever of the six promote methods is inserted first takes the whole count; the other five find nothing left to invalidate. Recompiling the invalidated ModelingToolkit mtkcompile pipeline afterwards costs ~35 s of wall time on the first model compile in that process.

Why the method is unnecessary

P <: poly{B,T,X} and Q <: poly{B,T,X} with poly a concrete 3-parameter struct forces P === Q === poly{B,T,X}. Base already has promote(x::T, y::T, zs::T...) where {T} = (x, y, zs...), which returns (p, q) for that case and is more specific than the generic promote(x, y). The Polynomials method is a behavioural no-op.

Proposed fix

Delete the Base.promote line from @poly_register (keep the two promote_rule methods, which are not on an invalidation-prone function). A one-line change, no observable behaviour change.

Smaller follow-ups from the same measurement:

  • LinearAlgebra.adjoint(A::VecOrMat{<:AbstractPolynomial}) (90): consider adjoint(A::Vector{<:AbstractPolynomial}) / adjoint(A::Matrix{<:AbstractPolynomial}) as two methods, or drop it.
  • Base.collect(::Type{T}, p::MutableSparseVectorPolynomial) (81): collect(::Type, ::Any) call sites carry edges; a non-Base name (coeffs) avoids it.

How to reproduce

using SnoopCompileCore
invs = @snoop_invalidations using Polynomials
using SnoopCompile; trees = invalidation_trees(invs); trees[end]

in a session where ModelingToolkit (or any large package that calls promote generically) is already loaded.

🤖 Posted for @pankgeorg by an AI agent — harness: Claude Code 2.1.304 · model: claude-fable-5-1
Session: local Claude Code session 4d6ce0ef-76db-4236-95e4-ec740bb4651c

Lingua principale
Julia
Stelle
321
Fork
81
Merge medio
10h 1m
PR unite (30g)
5

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di JuliaMath/Polynomials.jl

Tutte le issue di JuliaMath/Polynomials.jl

Issue simili

Altre issue su Julia

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.