Installation#

Base Install#

MADDENING requires Python 3.12+ and installs with CPU-based JAX by default. The floor is 3.12 rather than 3.11 because jax/jaxlib 0.11 requires 3.12 and there is no 0.12 series: 0.10 and 0.11 are the whole of the declared jax>=0.10,<0.13, and a 3.11 floor would make one of the two uninstallable.

pip install maddening

This gives you the full simulation engine (JAX + NumPy + lineax) running on CPU. All core features work: graph construction, compilation, stepping, coupling, adaptive timestepping, parameter sweeps, and checkpoint/restore.

That includes differentiating through a coupling group at its default settings. A coupling group defaults to solver="ift" with linear_solver="gmres", whose adjoint is solved with lineax; lineax is therefore a base dependency as of v0.4.0, not an extra. In v0.3.x it lived behind an ift extra and the default configuration raised ImportError on a base install. The ift extra still exists and is now empty, so pip install maddening[ift] keeps working — you no longer need it.

GPU Acceleration#

For GPU acceleration, add the hardware extra matching your CUDA version:

# CUDA 12 (most common)
pip install maddening[cuda12]

# TPU (Google Cloud)
pip install maddening[tpu]

You can combine hardware extras with any other extra:

pip install maddening[cuda12,viz]         # GPU + matplotlib plots
pip install maddening[cuda12,server]      # GPU + FastAPI server
pip install maddening[cuda12,runpod]      # GPU + RunPod cloud deploy

Note: The cuda12 extra upgrades the base JAX installation to the CUDA 12 variant. You must have CUDA 12 drivers installed on your system. Check with nvidia-smi.

Float32 matrix products on NVIDIA GPUs: JAX computes float32 matrix products (@, jnp.matmul, jnp.dot, jnp.einsum) at reduced precision by default on these cards. MADDENING traces every program it builds at full float32 precision instead: the compiled step, run_scan and its siblings, the adaptive steppers, a coupling group’s implicit-function gradient, a step under your own jax.jit or jax.grad and the sysid fits run under jax.default_matmul_precision(gm.matmul_precision), which is "highest" unless you set it, and sysid.fim and sysid.fim_core under their own matmul_precision=, also "highest" by default; up to 0.3.1 they took the default (MADD-ANO-291). Measured on an RTX A2000: an interface mapping applied to a 3-component field was off by 2.5e-4 relative to float64 at the default and by 6.5e-7 at highest. The lattice Boltzmann nodes (LBMNode, LBMPipeNode) also pin their own products (the momentum f @ E and the products e·u of their equilibrium) with precision=jax.lax.Precision.HIGHEST (MADD-ANO-290); on four RTX PRO 6000 Blackwell cards their sharded and unsharded gradients disagreed by 1.6e-3 relative at the default and by 2e-6 pinned, at no measured cost in speed. Vector dot products and matrix-vector products gave the same result at both settings. To trade that precision for tensor-core speed (an MLP or FNO surrogate node, for instance), set gm.matmul_precision = None (experimental): the graph then uses JAX’s own setting, and matmul_precision=None does the same for sysid.fim and sysid.fim_core. JAX_DEFAULT_MATMUL_PRECISION=highest (set before the first JAX call, or jax.config.update("jax_default_matmul_precision", "highest")) still matters for float32 matrix products of your own outside a graph: code around it, a surrogate’s training loop, the maddening.testing helpers that step a node on its own. On CPU the setting changes nothing, so a result checked on CPU says nothing about it.

Feature Extras#

Install only what you need. Each extra adds one capability:

Extra

What it adds

Install command

viz

Matplotlib 2D renderers

pip install maddening[viz]

terminal

Rich terminal renderer (works over SSH), and the box-and-arrow graph diagram (termaid)

pip install maddening[terminal]

network

ZeroMQ remote transport (a non-loopback bind encrypts with ZMQ CURVE and requires MADDENING_TRANSPORT_TOKEN, falling back to MADDENING_API_TOKEN)

pip install maddening[network]

api

FastAPI HTTP/WebSocket server (a non-loopback bind requires MADDENING_API_TOKEN; no TLS either way)

pip install maddening[api]

surrogates

Neural surrogate training (equinox + optax)

pip install maddening[surrogates]

viz3d

PyVista 3D server-side rendering

pip install maddening[viz3d]

gpu-viz

pygfx GPU-accelerated 3D viewer

pip install maddening[gpu-viz]

usd

OpenUSD graph serialization

pip install maddening[usd]

streaming

GStreamer WebRTC streaming (system packages first: Streaming prerequisites)

pip install maddening[streaming]

compression

zstandard for binary-encoder compression (v0.2 #6)

pip install maddening[compression]

verify

Hypothesis, for maddening.testing: verifying your own nodes (verify_node, the order and GCI studies; see Verification)

pip install maddening[verify]

Mix and match freely:

pip install maddening[viz,surrogates]           # plots + neural surrogates
pip install maddening[cuda12,api,network]       # GPU server with ZMQ

Streaming prerequisites#

WebRTC streaming runs on GStreamer, which pip cannot install: GStreamer and its plugins come from your system’s package manager. On Ubuntu 24.04 these are the packages the project’s streaming test image installs:

sudo apt install gir1.2-gstreamer-1.0 gir1.2-gst-plugins-base-1.0 gir1.2-gst-plugins-bad-1.0 \
    gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \
    gstreamer1.0-plugins-ugly gstreamer1.0-nice

The Python bindings, PyGObject, then come one of two ways:

  • From pip, as the streaming extra installs them. PyPI publishes PyGObject as source only, so pip compiles it, and the build needs the C headers: sudo apt install libcairo2-dev libgirepository-2.0-dev pkg-config python3-dev, then pip install maddening[streaming]. Without the headers the build stops with Dependency "cairo" not found.

  • From the system: sudo apt install python3-gi, then use the system Python 3.12, or a virtual environment created with --system-site-packages, and install MADDENING without the streaming extra. The project’s Docker images do this.

Until both GStreamer and PyGObject are present, constructing a SelkiesSession raises an ImportError that names them. all leaves streaming out for this reason (below).

Cloud Deployment#

Deploy simulations to cloud GPU providers via SkyPilot. Each provider has its own extra that bundles SkyPilot with the provider’s SDK:

Extra

Provider

Install command

runpod

RunPod

pip install maddening[runpod]

lambda

Lambda Labs

pip install maddening[lambda]

aws

Amazon Web Services

pip install maddening[aws]

gcp

Google Cloud Platform

pip install maddening[gcp]

cloud

All supported providers (RunPod + Lambda)

pip install maddening[cloud]

cloud-all

Every SkyPilot provider

pip install maddening[cloud-all]

After installing, set up your credentials file:

mkdir -p ~/.maddening
cp src/maddening/examples/cloud/config/cloud_credentials.example.yaml ~/.maddening/cloud_credentials.yaml
# Edit ~/.maddening/cloud_credentials.yaml and fill in your API key(s)
# ~/.maddening/cloud_credentials.yaml is the default path. For a different location, use:
# CloudLauncher(credentials_path='path/to/cloud_credentials.yaml')

The credentials file holds keys for all providers in one place:

runpod:
  api_key: "rp_xxxxxxxxxxxx"

lambda_labs:
  api_key: "llxxxxxxxxxxxxxxxxxx"

CloudLauncher reads only the block matching the provider: field in your job config. See src/maddening/examples/cloud/ for complete examples.

Task Bundles#

For common workflows, use a task bundle instead of listing individual extras:

Bundle

What it includes

Use case

server

FastAPI + uvicorn + websockets + ZMQ + rich + matplotlib

Running a simulation server (Docker image, GPU workstation)

client

ZMQ + rich

Thin client viewing a remote simulation

# Cloud GPU Docker image
pip install maddening[server,cuda12]

# Thin client on your laptop
pip install maddening[client,viz]

Everything#

pip install maddening[all]       # every feature extra but usd and streaming, + the RunPod and Lambda cloud providers
pip install maddening[all,usd]   # the same, with OpenUSD (usd-core)
pip install maddening[dev]       # all + verify + the test tools (still without usd and streaming)

all installs every package of the feature extras in the table above except two: usd-core, the one package of the usd extra (name usd beside it to get OpenUSD), and the streaming extra’s PyGObject, which needs system packages first (Streaming prerequisites). Everything all installs comes from wheels, so it needs no compiler. Before 0.4.1, all included PyGObject, and pip install maddening[all] failed without the C headers (MADD-ANO-296).

Development and tooling extras#

Extra

What it is for

dev

Working on MADDENING itself: all, verify, and everything the test suite imports (pytest, httpx, fsspec, FMPy, the build backend, pyright with a floor). Install it editable from a checkout: pip install -e ".[dev]". Before 0.4.1 it lacked hypothesis and two other test tools, so such a checkout could not collect the tests.

ci

What the CI jobs install: the test tools of dev with pyright pinned to the exact release the typing ceilings were measured with, and without the display packages.

sbom

cyclonedx-bom, to run cyclonedx-py by hand. scripts/generate_sbom.py does not need it: it installs its own copy in a separate environment.

Using uv#

All install commands work identically with uv:

uv pip install maddening[cuda12,runpod]
uv add maddening[server]

Verifying Your Installation#

import maddening
import jax

# Check JAX backend
print(f"JAX backend: {jax.devices()[0].platform}")  # 'cpu', 'gpu', or 'tpu'

# Check available features
try:
    from maddening.viz.backends import MatplotlibRenderer
    print("matplotlib: available")
except ImportError:
    print("matplotlib: not installed (pip install maddening[viz])")

try:
    from maddening.cloud import CloudLauncher
    print("cloud: available")
except ImportError:
    print("cloud: not installed (pip install maddening[runpod])")

Missing Dependency Errors#

MADDENING uses lazy imports — optional features only fail when you try to use them, not at import time. When a dependency is missing, you’ll see a clear error with the exact install command:

ImportError: 'SurrogateTrainer' requires equinox and/or optax.
Install with:  pip install maddening[surrogates]
ImportError: TerminalRenderer requires 'rich'.
Install with:  pip install maddening[terminal]

Follow the suggested command to install the missing extra.