Skip to content

Reduce load-time invalidations from untyped operator methods#77

Open
DavidSagan wants to merge 1 commit into
mainfrom
reduce-invalidations
Open

Reduce load-time invalidations from untyped operator methods#77
DavidSagan wants to merge 1 commit into
mainfrom
reduce-invalidations

Conversation

@DavidSagan

Copy link
Copy Markdown
Member

Reduce load-time invalidations from untyped operator methods

Part of the invalidation-reduction work tracked in bmad-sim/SciBmad.jl#77.

Problem

Several operators were defined with an untyped first (or second) argument, which makes them f(::Any, …) methods. Inserting such methods at package load time invalidates large amounts of already-compiled generic code that calls the same functions:

  • map.jl: *(m2, m1::$t) = ∘(m2, m1)*(::Any, ::DAMap) / *(::Any, ::TPSAMap)
  • map.jl: ∘(m2, m1::$t)∘(::Any, ::DAMap) / ∘(::Any, ::TPSAMap)
  • utils.jl: the SymplecticS + - * / operators → *(::Any, ::SymplecticS), *(::SymplecticS, ::Any), etc.

Fix

Constrain the arguments to the types actually accepted (no behavior change for valid inputs):

  • *(m2, m1::TaylorMap) is split into
    • *(m2::$t, m1::$t) — map ∘ map composition, and
    • *(m2::Union{Number,AbstractArray}, m1::$t) — TPS scalar/vector-function composition.
  • ∘(m2, m1::$t) gains the same m2::Union{Number,AbstractArray} constraint (its body already requires eltype(m2) to be a TPS type).
  • The SymplecticS operators constrain the matrix argument to AbstractVecOrMat (they already index it with size(M, …)).

DAMap/TPSAMap are <: TaylorMap (not <: Number/AbstractArray), so the split methods are unambiguous.

Measurement

Using SnoopCompile's @snoop_invalidations using SciBmad (Julia 1.11.7):

NonlinearNormalForm invalidation children
before 197
after 56

The 141 removed are exactly the untyped * and SymplecticS roots (*(m2, m1::DAMap) = 41, *(m2, m1::TPSAMap) = 41, *(M, S::SymplecticS) = 41, *(S::SymplecticS, M) = 16, +(M, S::SymplecticS) = 2). No new roots are introduced. The residual 56 are the concrete-argument map-composition methods, which are structural.

Tests

Pkg.test("NonlinearNormalForm") passes, including the "Composition and inversion" (14/14) and "Comparison with FPP" (19/19) suites that directly exercise the changed operators.

🤖 Generated with Claude Code

The out-of-place `*` for TaylorMaps and the `SymplecticS` `+/-/*//`
operators were defined with an untyped first (or second) argument, e.g.
`*(m2, m1::DAMap)` and `*(M, S::SymplecticS)`. Inserting these
`f(::Any, ...)` methods at load time invalidates large amounts of
precompiled generic code that calls the same functions.

Constrain the arguments to the types actually accepted:
- `*(m2, m1::TaylorMap)` is split into `*(m2::TaylorMap, m1::TaylorMap)`
  (map composition) and `*(m2::Union{Number,AbstractArray}, m1::TaylorMap)`
  (TPS scalar/vector function composition).
- `∘(m2, m1::TaylorMap)` gains the same `Union{Number,AbstractArray}`
  constraint on `m2`.
- The `SymplecticS` operators constrain the matrix argument to
  `AbstractVecOrMat` (they already index it via `size(M, .)`).

Measured with SnoopCompile on `using SciBmad`: NonlinearNormalForm's
invalidation children drop from 197 to 56 (the removed 141 were exactly
the untyped `*`/`SymplecticS` roots). No behavior change for valid
inputs; full test suite passes.

Refs bmad-sim/SciBmad.jl#77

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant