Skip to content

Add inline_linear_systems diagnostic#111

Merged
AayushSabharwal merged 4 commits into
mainfrom
fbc/inline-linear-systems-diagnostic
Jun 18, 2026
Merged

Add inline_linear_systems diagnostic#111
AayushSabharwal merged 4 commits into
mainfrom
fbc/inline-linear-systems-diagnostic

Conversation

@baggepinnen

Copy link
Copy Markdown
Contributor

What

Adds inline_linear_systems, a diagnostic that reports the inline linear-solve blocks a compiled system re-solves on every evaluation.

When tearing solves a strongly-connected component of algebraic equations as one linear system, it emits — into equations(sys) / observed(sys) — a square system A x = b that the generated code re-solves at every call (A \ b, or inline_scc_ldiv for the rank-tolerant aggressive reduction). Each solution component appears as an assignment vᵢ ~ (A \ b)[i].

inline_linear_systems(sys) collects these and returns, for each, an InlineLinearSystem with:

  • operation\ or inline_scc_ldiv,
  • size — the dimension N of the N×N system,
  • variables — the N variables it solves for, in solution order,
  • expression — the retained A \ b term, so callers can inspect or numerically evaluate A (e.g. to check conditioning).

Why

It is a diagnostic for understanding a compiled model's per-step cost and structure: large blocks are the dominant linear-algebra work each evaluation, and a singularity-prone block can be traced to the physical quantities it determines. (It grew out of debugging the multibody car/rotorcraft models, where knowing which variables a deficient block solves for was the key to locating the model-level degeneracy.)

Notes

  • Block detection matches \ and inline_scc_ldiv by name, so it works whether or not the rank-tolerant op is present (stock systems emit plain \ blocks).
  • The walk over the right-hand-side DAG is memoized by object identity (the DAG is heavily shared).
  • exported for discoverability — happy to switch to @public/qualified-only if that better matches the package's conventions (it currently exports nothing).

Test

New testset inline_linear_systems diagnostic: a 3-variable algebraic SCC with state/time-dependent coefficients compiles to a single 3×3 inline \ solve; the diagnostic reports size 3 and the three solved variables, and an empty result for a system with no inline solves. Verified locally (9/9 pass).

🤖 Generated with Claude Code

Report the inline linear-solve blocks a compiled system re-solves on every
evaluation. When tearing solves a strongly-connected component of algebraic
equations as one linear system, it emits, into `equations`/`observed`, a
square system A x = b solved at every call (as `A \\ b`, or `inline_scc_ldiv`
for the rank-tolerant aggressive reduction), with each component appearing as
`vᵢ ~ (A \\ b)[i]`.

`inline_linear_systems(sys)` collects those blocks and reports, for each, its
size N and the N variables it solves for (returned as `InlineLinearSystem`s, with
the solve expression retained so callers can inspect/evaluate A). It is a
diagnostic for a model's per-step linear-algebra cost and for tracing a
singularity-prone block to the physical quantities it determines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AayushSabharwal

Copy link
Copy Markdown
Member

Looks great. However, instead of parsing equations what if the code that creates the linsolves in reassemble.jl builds a list of these InlineLinearSystem structs and puts them into the metadata of the simplified system? That way the diagnostic just has to check metadata.

Address PR review: instead of re-parsing equations/observed to rediscover
the inline `A \ b` blocks, have the reassemble pass build the
`InlineLinearSystem` structs as it emits each block and store them in the
simplified system metadata under `InlineLinearSystemsMetadata`.
`inline_linear_systems` now just reads the metadata.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@AayushSabharwal AayushSabharwal left a comment

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.

Some suggestions around type-stability and redundancy.

Comment thread lib/ModelingToolkitTearing/src/diagnostics.jl Outdated
Comment thread lib/ModelingToolkitTearing/src/diagnostics.jl Outdated
Comment thread lib/ModelingToolkitTearing/src/diagnostics.jl Outdated
Comment thread lib/ModelingToolkitTearing/src/reassemble.jl Outdated
Comment thread lib/ModelingToolkitTearing/src/reassemble.jl Outdated
Comment thread lib/ModelingToolkitTearing/src/diagnostics.jl Outdated
Comment thread lib/ModelingToolkitTearing/src/diagnostics.jl Outdated
Comment thread lib/ModelingToolkitTearing/src/diagnostics.jl Outdated
Comment thread lib/ModelingToolkitTearing/src/reassemble.jl Outdated
Comment thread lib/ModelingToolkitTearing/test/runtests.jl Outdated
Co-authored-by: Aayush Sabharwal <aayush.sabharwal@gmail.com>
@AayushSabharwal

Copy link
Copy Markdown
Member

Hopefully I did this right :D

Comment thread lib/ModelingToolkitTearing/test/runtests.jl Outdated
@AayushSabharwal AayushSabharwal merged commit 48ebcd8 into main Jun 18, 2026
8 of 9 checks passed
@AayushSabharwal AayushSabharwal deleted the fbc/inline-linear-systems-diagnostic branch June 18, 2026 09:59
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.

2 participants