Inline linear SCCs: 296×296 dense runtime solve for an ~18-unknown core; non-rank-tolerant; symbolic shrinkage intractable — solve sparse+rank-tolerant instead
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 静か
- 技術スタック
- julia
- 領域
- compilers, performance
調査の方向性
get_linear_scc_linsol から開始し、ArrayMaker リージョンが生成された疎性パターンをどのように公開しているか、また __reduce_linear_system! がランタイムの求解にどのように入力を渡しているかを調べます。シンボリックなゼロ除去の失敗については、別途 get_new_mm を確認します。生成されたシステムが、シンボリックな肥大化、dense-LU の特異性による失敗、または無言の Inf 結果なしに、疎でランク許容のランタイム求解を使用すれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
For multibody vehicle models, the inline-linear-SCC pass (DefaultReassembleAlgorithm(inline_linear_sccs = true)) emits a runtime dense A \ b over a system that is an order of magnitude larger than the mathematically-required core, and solves it with a non-rank-tolerant dense LU. Measured on a half-car suspension model (22 states after mtkcompile):
- The big algebraic SCC enters
get_linear_scc_linsolwith 396 rows. __reduce_linear_system!removes only 101 (the all-constant-coefficient rows) → a 296×296 dense runtime LU, evaluated every RHS call and during initialization reconstruction.- Of the 396 rows, 384 are matched (torn) and 378 of those have a constant pivot coefficient — i.e. the irreducible simultaneous core is only ~18–24 unknowns (consistent with the same model compiled with
inline_linear_sccs=false, which yields a 48-state DAE = 22 differential + 26 algebraic). - The emitted 296×296 pattern is 1.6% dense and, after a Dulmage–Mendelsohn analysis, ~93% block-triangular given the tearing order; only the small core is truly coupled.
The inflation mechanism: rows whose non-pivot coefficients are symbolic (every product-rule-differentiated definitional equation — rotation-matrix entries, contact-frame vectors, etc.) fail the all(isconst, coeffs) gate in __reduce_linear_system! and are kept inside the numeric solve, even though tearing already matched them with constant pivots.
Why the obvious fix doesn't work (tested)
Relaxing the gate to "pivot coefficient constant" (which is sufficient for a division-free elimination, and the alias/substitution machinery in __reduce_linear_system!/get_new_mm handles symbolic alias coefficients as-is) shrinks the system but explodes symbolically:
- First failure:
iszero(::Num)insideget_new_mm's duplicate-entry pruning goes throughfraction_iszero → expand, which is exponential for the deep product-of-sums coefficients →OutOfMemoryError. (Workaroundable with a cheap syntactic zero test — see suggestion below.) - With that bypassed,
mtkcompilesucceeds (~90 s) butODEProblemconstruction stalls indefinitely: the substituted core coefficients are enormous expression trees and codegen blows up.
So full symbolic elimination of the torn rows is intractable; the inflation is an inherent artifact of numeric tearing. Sequential runtime evaluation of the eliminated rows is also impossible (they depend on the core unknowns — circular).
Suggested fixes
- Solve the emitted system sparse and rank-tolerant at runtime. The pattern is already available (the
ArrayMakerregions); a sparse LU/QR with fill-reducing ordering automatically exploits the ~93% triangular structure, so the 296-system costs about as much as the 18-core. Crucially it should be rank-revealing (or regularized): these acceleration/reaction systems are legitimately rank-deficient whenever constraint reactions are statically indeterminate (vehicle with ≥2 rigid suspension mounts on one body) — the current dense\throwsSingularException(LU) and the DyadCompilerPasses LDIV rewrite produces silentInf(unpivoted QR). See JuliaComputing/DyadCompilerPasses.jl#40. - Independent robustness improvement: the duplicate-entry pruning in
get_new_mmshould use a cheap syntactic zero test (term construction already cancels syntactically identical terms; an entry that is mathematically zero but kept is harmless), e.g. an overridableprune_iszero(x) = iszero(x)specialized forNumto a syntactic check — exactiszero(::Num)can OOM via polynomial expansion. - Optionally expose the SCC composition (total/matched/const-pivot counts) as a debug aid — these numbers immediately reveal the inflation.
Context
Found while debugging SingularException(13) during initialization of suspension vehicle models (Multibody-style components). ModelingToolkit v11.26.8 (#master), ModelingToolkitTearing v1.14.1, StateSelection v1.9.3. Related: SciML/ModelingToolkit.jl#4237 (init reconstruction LU of indeterminate reactions), SciML/ModelingToolkit.jl#4607.
- 主要言語
- Julia
- スター
- 7
- フォーク
- 10
- 平均マージ
- 5日 11時間
- マージ済み PR(30日)
- 3
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
JuliaComputing/StateSelection.jl のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 30/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 38/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
JuliaComputing/StateSelection.jl#98 · コメント 2 件 ·
JuliaComputing/StateSelection.jl の issue をすべて見る
似ている issue
-
add-on doc enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
JuliaGraphics/ColorTypes.jl#344 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
R
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
eWaterCycle/remotebmi#58 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
`enzymexla.linalg.lu` lowering fails for a tall matrix: the permutation is built with the pivot typeオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
EnzymeAD/Enzyme-JAX#3286 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
SciML/LinearSolve.jl#1359 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信