--- orphan: false --- # What's new in v0.3.0 ```{versionadded} v0.3.0 ``` v0.3.0 is the M2 "redesigns" milestone (STACK_V1 §3). Its theme is *finish the deferred-but-necessary redesigns before feature work freezes any interface*. Three groups of work landed: 1. **New substrates** for the FMI 3.0 export path, sharded sparse iterative solvers, graph-partitioned sharding, and the domain-neutral USD live-stage writer. Each surfaces a contract that downstream code (MIME's FVM, MICROROBOTICA's renderer, any FMU consumer) will read against at 1.0.0. 2. **The `@stability` audit** — first wave of tagged public surfaces plus a generated docs page. The audit *begins* in v0.3.0; it finalises at M4 (v0.9.0). 3. **Compat hygiene** — every "removed in v0.3" promise from v0.2.x release notes / docstrings is honoured in one pass, closing the deprecation tail. The CHANGELOG entry (`[0.3.0]` in [`CHANGELOG.md`](https://github.com/Microrobotics-Simulation-Framework/MADDENING/blob/main/CHANGELOG.md)) has the itemised diff. This page is the narrative summary. ```{warning} **v0.3.0 is a minor release with intentional breaking changes.** Every breakage was pre-announced in v0.2.x release notes, docstrings, or `CHANGELOG.md`. See the "[Breaking changes & migration paths](#breaking-changes-migration-paths)" section below — every removal has a structured {class}`~maddening.warnings.MigrationError` whose `replacement` / `migration_guide` fields tell you exactly where to look. ``` ## Highlights ### FMI 3.0 substrate — `maddening.fmi` MADDENING graphs can now be exported as FMI 3.0 functional mock-up units (FMUs), with `fmi3GetDirectionalDerivative` routed through `jax.jvp` / `jax.vjp` to preserve the differentiable-simulation advantage in the co-simulation ecosystem. v0.3.0 ships the *substrate*: * {func}`~maddening.fmi.model_description.build_model_description` reads a compiled {class}`~maddening.core.graph_manager.GraphManager`'s external-input edges, per-node state fields, and the `@stability` registry to emit `modelDescription.xml`. Conservative by default: only surfaces tagged `@stability(STABLE)` enter the FMU surface unless the caller opts in via `include_evolving=True`. * {func}`~maddening.fmi.directional_derivatives.get_directional_derivative` wraps `jax.jvp` (`FORWARD`) and `jax.vjp` (`REVERSE`). This is the load-bearing FMI-3-over-2 decision: FMI 2.0 had no equivalent. * {func}`~maddening.fmi.fmu_state.serialize_fmu_state` / {func}`~maddening.fmi.fmu_state.deserialize_fmu_state` round-trip graph state through a schema-token-validated {class}`~maddening.fmi.fmu_state.FMUState` handle, mirroring `fmi3GetFMUState` / `fmi3SetFMUState`. * {class}`~maddening.fmi.sidecar.FmuSidecar` is a Python reference implementation of the ZMQ sidecar protocol the FMU's C wrapper (v0.4.0 / MIME v0.5.0 deliverable) will marshal into. The named-experiment FMU wrappers (`mime-fmi`) ship on the MIME side in v0.5.0 / STACK_V1 M3. ### Sharded sparse iterative solver — `sharded_cg` / `sharded_gmres` {func}`~maddening.cloud.multigpu.iterative_solver.sharded_cg` and {func}`~maddening.cloud.multigpu.iterative_solver.sharded_gmres` wrap user-supplied sharded matvec callables. Lineax-backed by default (reusing the IFT branch's {class}`lineax.FunctionLinearOperator` path) with a hand-rolled `lax.while_loop` PCG / `lax.fori_loop` restarted GMRES fallback — both `@stability(STABLE)` because MIME's v0.5.0 FVM PISO pressure correction reads against this signature. ### Unstructured (graph-partitioned) sharding — `ShardedUnstructuredNode` Sibling of v0.2.1's `ShardedStencilNode`: ```text ShardedNode (Protocol) ├── ShardedPointwiseNode (no halo, no spatial topology) v0.2.0 ├── ShardedStencilNode (Cartesian, axis-aligned halos) v0.2.1 └── ShardedUnstructuredNode (graph-partition, sparse halos) v0.3.0 ``` The plan deliberately ships both as first-class citizens — see {doc}`/developer_guide/sharding_topology` for the choice criteria. v0.3.0 ships the *contract* (constructor signature, `update_padded` plumbing, output classification, partition-assignment handoff), the toy 16-cell test, and a 1024-cell smoke; v0.4.0 will harden the implementation for real mesh sizes. By v0.4.0 (the hard downstream gate) MIME's FVM port must work against this surface without breaking changes — see the {class}`~maddening.cloud.multigpu.sharded_unstructured.ShardedUnstructuredNode` docstring's "v0.4.0 commitment" section. The new `StaticArray(replication="partition")` variant pairs an array with a `partition_assignment` (1-D `int32`, one entry per global cell, value = device index). See {doc}`/developer_guide/static_array_migration` for the full contract. ### USD live-stage — pulled out of MIME, now generic {class}`~maddening.usd.live_stage.LiveStage` is the domain-neutral core of what was MIME's `viz/stage_bridge.py`. Non-MIME consumers (the bouncing-ball quickstart, future non-microrobotics frameworks) can now render to MICROROBOTICA without depending on MIME. The MIME-specific bits (robot/field/flow-cross-section registrations) stay in MIME's viz layer. A new non-MIME demo (`maddening.examples.advanced.live_stage_bouncing_ball_demo`) exports a time-sampled `.usda` runnable in MICROROBOTICA. ### `@stability` audit — first wave v0.3.0 grows the `StabilityLevel` enum with `EVOLVING` and `INTERNAL`, then tags the first wave of public surfaces named in the v0.3.0 plan: `GraphManager`, `SimulationNode`, `EdgeSpec`, `StaticArray`, both Cartesian sharded wrappers, the new sharded solvers and unstructured node (`STABLE`); `BinaryStateEncoder` and `CloudProvider` (`EVOLVING`); surrogates trainer / node / dataset (`EXPERIMENTAL`). The audit is auto-rendered to {doc}`/developer_guide/stability_report` at docs-build time via `scripts/generate_stability_report.py`. At the time of v0.3.0 tagging the registry holds **29 surfaces** (13 stable, 7 evolving, 9 experimental). The audit *begins* in v0.3.0 and *finalises* at M4 (v0.9.0). ### IFT coupling-solver redesign merged The `perf/coupling-ift-gradient` branch's 9 commits land on `main`: {class}`~maddening.core.coupling.CouplingGroup` gains `solver: Literal["fori", "ift"]`, `acceleration` (`"none"`, `"aitken"`, `"fixed"`, `"iqn-ils"`, `"iqn-imvj"`), and `linear_solver: Literal["gmres", "bicgstab", "dense"]` Literal-typed fields, with `__post_init__` runtime validation and matrix-free lineax GMRES adjoint at the fixed point. See the CHANGELOG for the full sub-list. ## Breaking changes & migration paths Every breakage below was pre-announced in v0.2.x and emits a {class}`~maddening.warnings.MigrationError` at the moment of use, with structured `api_name` / `replacement` / `migration_guide` fields for auto-migration tooling. | Removal | Migration path | Guide | |---|---|---| | `SimulationNode.requires_halo` property + compat shim (was `FutureWarning` in v0.2) | Override `halo_width()` instead. | {doc}`/developer_guide/halo_width_migration` | | `ShardedNode` deprecated alias (was `DeprecationWarning` in v0.2.x) | Use `ShardedPointwiseNode` or `ShardedStencilNode` directly. | — | | Bare arrays in `static_data` (was `FutureWarning`-coerce in v0.2.1) | Wrap with `StaticArray(value=..., replication=...)`. | {doc}`/developer_guide/static_array_migration` | | `EdgeValidationWarning` / `ShapeMismatchWarning` / `DtypeMismatchWarning` aliases | Use `EdgeValidationError` / `ShapeMismatchError` / `DtypeMismatchError`. `UnitMismatchWarning` now roots at `UserWarning`. | {doc}`/developer_guide/edge_validation_migration` | | `maddening.surrogates.{checkpoint,trainer,callbacks,physics_losses}` top-level paths | Import from `maddening.surrogates.weights.checkpoint` and `maddening.surrogates.training.{trainer,callbacks,physics_losses}` (the `maddening.surrogates.SurrogateTrainer` etc. lazy re-exports are unchanged). | — | ## Dependencies * New: `httpx2>=2.0` pulled alongside `httpx` in the `[ci]` and `[dev]` extras. Starlette's testclient auto-detects httpx2 and uses it preferentially, closing the v0.2.1 `StarletteDeprecationWarning`-ignore loop. ## Verification evidence Full suite (slow + default lanes) green at v0.3.0 tagging: * Default lane: **1824 tests** passed, 3 skipped. * Slow lane: **1827 tests** passed (3 additional slow-marked cases for the 1024-cell unstructured smoke and a couple of perf-bench checks). A1 / A5 / A6 acceptance criteria from the v0.3.0 plan: * `sharded_cg` solves a 4-device sharded 1-D Laplacian Poisson bit-compat (`atol=1e-5`) with the unsharded reference. * `jax.jvp` through `sharded_cg` matches `jax.jvp` through the unsharded reference — the FMI 3 directional-derivative export path's regression guard. * The toy 16-cell unstructured node test (`bit-compat + psum + state strip + construction validation`) is green. * The 1024-cell intermediate-size smoke catches scaling bugs not visible at toy size. * The `_MockFVMFluidNode(ShardedUnstructuredNode)` contract- stress-test confirms the v0.4.0 commitment ("sharded FVM in MIME v0.5.0") is achievable against the v0.3.0 surface without breaking-change asks. ## What's NOT in v0.3.0 (and explicitly so) * The FMU C wrapper that calls into the ZMQ sidecar (v0.4.0 / MIME v0.5.0 deliverable). * `fmpy` round-trip CI test wiring (a release-prep follow-up). * Multi-clock per-effect FMU export (designed-in via FMI 3's clock concept, single-clock-only for v0.3.0). * Production-grade unstructured sharding at real mesh sizes (v0.4.0 hardening). * MIME's `FVMFluidNode` sharded port — MIME v0.5.0 against MADDENING v0.4.0. ## Upgrade checklist 1. Pin `maddening>=0.3.0,<0.4`. 2. Drop the `maddening<0.3` / `maddening~=0.2` pin if you have one. 3. Run your test suite. If anything raises {class}`~maddening.warnings.MigrationError`, the error's `replacement` field tells you the new API. 4. Drop any `pytest.warns(ShapeMismatchWarning)` / `pytest.warns( DtypeMismatchWarning)` calls — those classes are gone. Use `pytest.raises(ShapeMismatchError)` etc. instead, or `pytest.raises(ExceptionGroup)` with `.exceptions` iteration to catch the whole group. 5. If your CI installs `maddening[ci]` and you had a `StarletteDeprecationWarning` ignore filter, drop it — the warning is gone at source.