Skip to content

fix: structural cheap_iszero hook in CLIL dropzeros! (OOM on symbolic values after #97)#99

Open
baggepinnen wants to merge 2 commits into
mainfrom
fbc/cheap-iszero-dropzeros
Open

fix: structural cheap_iszero hook in CLIL dropzeros! (OOM on symbolic values after #97)#99
baggepinnen wants to merge 2 commits into
mainfrom
fbc/cheap-iszero-dropzeros

Conversation

@baggepinnen

Copy link
Copy Markdown

Follow-up to #97, implementing the fix proposed in this comment.

Problem

dropzeros!(::SparseMatrixCLIL) (added in #97) calls Base.iszero on the stored values. In get_new_mm the value type is Num, and iszero(::Num) is a semantic zero test (fraction_iszeroexpand) that can be arbitrarily expensive. On MultibodyComponents.examples.suspension.HalfCar the process is OOM-killed inside dropzeros! at ~row 40 of a 295-row Num-valued mm (instrumented run; the pre-#97 commit completes fine).

Fix

Explicit stored zeros (as produced by sparsevec duplicate-index summation or alias cancellation) are always structural zeros, so a structural check suffices:

  • StateSelection.CLIL.cheap_iszero(x) = iszero(x) — hook used by dropzeros!(::SparseMatrixCLIL) instead of Base.iszero,
  • ModelingToolkitTearing overloads it for Num/SymbolicT via SU._iszero (structural Const(0) check, no expansion).

Numeric value types are unaffected (the default is Base.iszero).

Validation

  • New regression test: a value type whose Base.iszero throws (standing in for "arbitrarily expensive") must still round-trip through dropzeros! correctly via the hook.
  • The equivalent patch was validated on the HalfCar model: compiles without OOM, with behavior otherwise identical to pre-fix edge case in inline linear solve #97 (same emitted inline-linsolve blocks; details in the #97 comment).

🤖 Generated with Claude Code

… values)

dropzeros!(::SparseMatrixCLIL) (added in #97) called Base.iszero on the stored
values. For symbolic value types (Num) that is a semantic, expansion-based
zero test that OOMs on large coefficient expressions. Explicit stored zeros
are always structural, so a structural check suffices: add a cheap_iszero
hook (default Base.iszero) and overload it for Num/SymbolicT in
ModelingToolkitTearing via SU._iszero.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@KristofferC

Copy link
Copy Markdown
Contributor

Please cherry pick b281896 onto this branch

@baggepinnen

Copy link
Copy Markdown
Author

Done — branch fast-forwarded to b281896 (its parent was the branch head, so this preserves your original commit/SHA rather than a re-applied copy). fbc/cheap-iszero-dropzeros tip is now b281896.

@AayushSabharwal

Copy link
Copy Markdown
Member

Should be rendered unnecessary by JuliaSymbolics/Symbolics.jl#1893

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