Repository navigation
feat(rust): sparsity, coloured Jacobians, compiled models and the C ABI - #5957
Open
BradyPlanden wants to merge 1 commit into
Open
BradyPlanden wants to merge 1 commit into
BradyPlanden wants to merge 1 commit into
Conversation
This was referenced Oct 22, 2026
This was referenced Oct 22, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## stack/01-rust-core-graph #5957 +/- ##
============================================================
- Coverage 98.24% 98.23% -0.01%
============================================================
Files 350 350
Lines 36104 36104
============================================================
- Hits 35469 35468 -1
- Misses 635 636 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
4 tasks done
BradyPlanden
force-pushed
the
stack/02-rust-core-model-ffi
branch
from
October 28, 2026 09:55
6a8acfa to
a32f8b6
Compare
BradyPlanden
force-pushed
the
stack/02-rust-core-model-ffi
branch
2 times, most recently
from
October 28, 2026 15:28
94290b8 to
b3e6fed
Compare
Sparsity, colouring, constant entries, reverse-mode dense rows, observables, CompiledModel, snapshots and the C ABI. The pybammsolvers consumer headers land inert so the ABI drift test can read them.
BradyPlanden
force-pushed
the
stack/02-rust-core-model-ffi
branch
from
October 29, 2026 08:01
b3e6fed to
5f19006
Compare
BradyPlanden
marked this pull request as ready for review
October 29, 2026 08:55
Contributor
|
| Project | PyBaMM |
| Branch | stack/02-rust-core-model-ffi |
| Testbed | bare-metal |
🐰 View full continuous benchmarking report in Bencher
⚠️ WARNING: Truncated view!The full continuous benchmarking report exceeds the maximum length allowed on this platform.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Builds the model layer of
pybamm-coreon the compiler from #5956. ACompiledModelholds a DAEM y' = f(t, y; p)with its Jacobian, sensitivities, output variables and events, and a C ABI lets pybammsolvers' IDAKLU evaluate it. Nothing in Python changes.detect_sparsity_per_outputreads each output's Jacobian pattern from the graph without evaluating it. The pattern is conservative: an entry it leaves out is zero for everyy.classify_constant_entriesproves independent of(t, y, y', p)are written from a table instead of swept. On the pinned fixtures, SPM has 116 such entries and needs 0 colours, the SPMe 116 and 3, and the DFN 2316 and 9.LanePlansweeps the colours 8 or 4 lanes at a time, from a cost model fitted on an Apple M4, within a 32 MiB scratch budget.AdjointTape). That split is kept only when it lowers the colour count.CompiledModel,WorkspaceandModelEvaluator:CompiledModelis built once, fromCompiledModelOptions { sensitivities, algebraic }. Once its output variables and events are set, it is shared read-only.Workspace.ModelEvaluatorpairs anArc<CompiledModel>with oneWorkspace, and it is what the C ABI receives asuser_data.simplify, as a fold that shifts a value by one ulp stalls IDA's Newton iteration.dg/dp + dg/dy·S.DagSnapshot, behind theserializefeature, is the bincode form of a graph. The benches and the golden and bit-exactness tests read it.ffi.rs):extern "C"entry points. The count queries return a count or a negative status; every other entry point returnsSUCCESS(0) or a negative status:ERROR_NULL_POINTER,ERROR_PANIC,ERROR_INVALID_PARAM,ERROR_INVALID_OUTPUT,ERROR_NO_SENS,ERROR_NO_OUTPUTS,ERROR_NO_ALGorERROR_NO_EVENTS.user_dataand every required buffer for null, and catches a panic, rebuilding the workspace after one.pybamm_rust_n_algebraicandpybamm_rust_alg_jac_nnz.pybamm_rust_abi_version()returnsRUST_ABI_VERSION, which is 1.pybamm_rust_ffi.hresolves the symbols at runtime:dlsym(RTLD_DEFAULT), orGetProcAddressover the loaded modules on Windows. It checks the version first, and throws on any failed status.RustFunctions.hppadapts a model to IDAKLU'sExpressioninterface. Its algebraic and Newton adapters checkn_alg,n_rhs + n_algand the Jacobian pattern and nnz against those queries, and throwstd::invalid_argumentbefore Rust writes through a buffer.test_ffi_abi_contractparsesffi.rsand both headers, and checks that:EXPECTED_ABI_HASHpins the exported signatures, so a change to them fails until the hash is updated. The version numbers are only checked against each other.rust_testsCI job also runs when onlypackages/pybammsolverschanges, since the test reads its headers.test_primitives_match_libm(feat(rust): expression graph, typed IR, evaluator and forward-mode AD #5956) gains reverse mode: the adjoint partials takelibm's values too.Known limits:
SensParamVector.df/dpis assembled from a dense pattern.ERROR_PANIC.RTLD_GLOBALfor the symbols to resolve, whichpybamm.rustdoes in feat(rust)!: ship pybamm.rust in the pybamm wheel #5958.Review on #5732
CompiledModelholds no scratch. Each caller'sWorkspaceis separate, andModelEvaluatorpairs the two. The bindings' pools in feat(rust)!: ship pybamm.rust in the pybamm wheel #5958 and feat(rust): solve rust models with IDAKLUSolver #5962 follow the same split.Type of change
New feature, under
## FeaturesinCHANGELOG.md.Key checklist
pre-commit run, includingcargo fmtandcargo clippy--all-features, 1 ignored: the golden-fixture regenerator)cargo +1.89 check --locked --all-targets --all-featuresuser_dataand each null buffer, a panic, null inputs, negative indices and overflowing counts, and the count queries, the algebraic block's included;t,yand inputs;libm's values;Rust execution engine stack: proposal #5667, showcase #5732
Each PR is one commit on the one above it.
Function.create_copykeeps the function's classRegPowerand uniform-grid interpolant lookups matchevaluatepybamm-core: expression graph, typed IR, interpreters, forward-mode ADpybamm-core:CompiledModel, coloured Jacobians, the C ABI ← this PRpybamm.rustbindings, built into thepybammwheelSymbol.to_rustconvert_to_format = "rust"forScipySolver,AlgebraicSolverand EISpybammsolvers: IDAKLU over the C ABIIDAKLUSolveron rust modelspybamm-core: diffsol DAE solverpybamm.DiffsolSolver"rust"as the defaultconvert_to_format