What’s new in v0.3.0#

Added in version 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) 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” section below — every removal has a structured 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:

  • build_model_description() reads a compiled 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.

  • 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.

  • serialize_fmu_state() / deserialize_fmu_state() round-trip graph state through a schema-token-validated FMUState handle, mirroring fmi3GetFMUState / fmi3SetFMUState.

  • 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#

sharded_cg() and sharded_gmres() wrap user-supplied sharded matvec callables. Lineax-backed by default (reusing the IFT branch’s 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:

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 Sharding topology: structured vs unstructured 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 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 StaticArray migration guide (v0.2 → v0.3.0) for the full contract.

USD live-stage — pulled out of MIME, now generic#

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 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: 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 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.

halo_width migration guide (v0.2 → v0.3.0)

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=...).

StaticArray migration guide (v0.2 → v0.3.0)

EdgeValidationWarning / ShapeMismatchWarning / DtypeMismatchWarning aliases

Use EdgeValidationError / ShapeMismatchError / DtypeMismatchError. UnitMismatchWarning now roots at UserWarning.

Edge validation: migration guide (v0.2 → v0.3.0)

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 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.