Expand description
§ferrotherm — thermodynamic sampling for Physical AI
The IPAI @ BMI equivalent of the thermodynamic-computing software stack, in pure Rust: sparse energy-based models, chromatic block-Gibbs sampling, and — first-class, not an appendix — the device energy ledger that prices every sample, read, and write in joules.
The physics is old and open: Ising (1925), Glauber dynamics (1963), Gibbs sampling (Geman & Geman 1984), graph-colored parallel sweeps (standard checkerboard decomposition). What a “thermodynamic sampling unit” accelerates is exactly this loop; what it charges for is I/O. Both belong in the open commons, runnable on every compute fabric — CPU today, WebGPU next, physics-native silicon when it exists to measure.
Design positions, each earned from a verified source:
- The ledger is first-class. Extropic’s Thermalizers appendix (arXiv:2608.01615, Table IV)
prices a Z1-class node at 7.09 fJ per Gibbs cycle, 1.692 pJ per read, 153.6 pJ per write —
a write costs ~21,700 samples. Any honest account of this hardware class is an I/O story,
so every
ferrothermsimulation carries aledger::Ledgerand reports what the device WOULD pay, crossings included. - Sparse and 2-colorable is the native shape. The published Z1 topology is a planar grid
with odd-Manhattan couplings (degree 16, longest edge sqrt(17)), which is bipartite: one
full sweep = two parallel half-sweeps.
device::z1_gridreproduces it. - Verification against exact physics before any claim. The sampler must reproduce the
exact Boltzmann distribution on enumerable systems and the Onsager magnetization on the 2D
lattice before it is used for anything else. See
examples/ring_tv.rs,examples/onsager.rs.
§Quickstart
use ferrotherm::{ising, gibbs::Sampler, ledger::{Ledger, Z1_SPICE}};
// a 16x16 Ising magnet below its critical temperature
let g = ising::lattice2d(16, 1.0);
let mut led = Ledger::default();
let mut smp = Sampler::new(&g, 0.6, 42);
smp.sweeps(500, Some(&mut led));
let m = (smp.s.iter().map(|&v| v as i64).sum::<i64>().abs() as f64) / g.n as f64;
assert!(m > 0.9, "ordered phase: |M| = {m}");
// What those sweeps WOULD cost on a Z1-class device. `joules` returns an Option because a
// device whose per-operation energy nobody has published has no answer here -- and borrowing
// another device's prices produces a figure indistinguishable from a measured one.
assert!(led.joules(&Z1_SPICE).unwrap() > 0.0);
assert_eq!(led.joules(&ferrotherm::ledger::Prices::UNSTATED), None);§What “deterministic by seed” does and does not promise
Measured across three machines – macOS/arm64 (Apple M5 Max), Linux/x86_64 (AMD EPYC 9R14) and Linux/aarch64 (Graviton3), all on rustc 1.97.1 – running the identical program:
| macOS arm64 | Linux x86_64 | Linux aarch64 | |
|---|---|---|---|
compiled .ftp program | identical | identical | identical |
| CSR neighbour order | identical | identical | identical |
| sampled state | identical | identical | identical |
exp() and the sigmoid | identical | identical | identical |
| energy computed from that state | ..a7b3 | ..a7b2 | ..a7b2 |
The answer is bit-reproducible. The state a seed produces is the same on every platform tested, which is what the promise is for: a run can be repeated and a result checked.
A derived float may differ by one ULP across operating systems. The two Linux boxes agree
with each other across DIFFERENT architectures, and macOS disagrees with Linux on the SAME
architecture – so it is not architecture. It is not libm either: exp and the sigmoid were
measured bit-identical on both. It is floating-point contraction, w * s_i * s_j accumulating
through an fma on one target and a separate multiply and add on another, which round
differently. Same values, same order, one bit apart.
So: compare states, hashes and programs with ==; compare energies with a tolerance. A test
asserting bit-equality of a derived float across platforms asserts something this crate does not
promise and could only deliver by disabling contraction everywhere, which costs more than the
property is worth.
Scope note: binary (pbit) nodes with pairwise couplings are the sampling core. Categorical
and continuous nodes arrive through the program layer (program) and the thermodynamic
linear-algebra module (tla); the compiler (compile) targets device topologies.
Modules§
- adaptive
- Ladders that fix themselves — adaptive parallel tempering over beta, and over (beta, coupling).
- bls
- Breakout local search — the algorithm that holds the max-cut record on most of G-set.
- bound
- Lower bounds on the ground energy — how far from optimal a sampler’s answer might be.
- branch
- Branch and bound: the only thing here that returns a proof.
- categorical
- Categorical variables as a workload: does the encoding choice actually pay?
- certify
- Proof that a sampler did what it claimed.
- compile
- Variational compilation — fit a target conditional kernel P(y|x) with the conditional of a DEVICE-NATIVE Boltzmann machine: couplings restricted to the hardware graph’s actual edges, inputs clamped, hidden spins marginalized.
- conform
- A conformance suite any fabric can run.
- dense
- The
[n, k]interaction layout the CPU, GPU and hardware emitters share. - device
- Device topologies. The published Z1-class fabric is a planar grid with four coupling displacement rules — (1,0), (2,1), (2,3), (4,1), each applied in 4 rotations — giving interior degree 16 and longest edge sqrt(17) grid units. Every displacement has ODD Manhattan length, so the graph is bipartite under checkerboard parity: chromatic Gibbs needs exactly two half-sweeps per full sweep. (Topology per arXiv:2608.01615; exact die dimensions unpublished — the builder is parametric, and published totals like “269,568 pbits” are the vendor’s figures for silicon nobody outside has measured.)
- dtm
- Denoising Thermodynamic Models — the flagship architecture of the thermodynamic-computing program (Jelincic et al., arXiv:2510.23972 / npj Unconventional Computing 2026): a chain of shallow Boltzmann machines, each denoising one step of a closed-form forward noising process. Capacity comes from the CHAIN, not any single EBM — each conditional stays easy to sample, which is the same capacity-through-factorization law our chain benches measured.
- duty
- What a machine costs when it is mostly WAITING.
- ebm
- Fitting an energy-based model to data — contrastive divergence, and the exact likelihood to judge it by.
- embed
- Minor embedding: put a program on a machine whose graph is not the program’s graph.
- encode
- How a discrete variable is spelled in spins.
- exact
- Exact answers on sparse graphs, well past where enumeration stops.
- fabric
- What a fabric can do, declared — and checked before a program reaches it.
- factor
- Factors, and the mistakes a factor must not be able to express.
- ffi
- C ABI for WebAssembly and host-language bindings.
- ftp
- The
.ftpprogram format. - gibbs
- Chromatic block-Gibbs sampling.
- graph
- Sparse pairwise energy-based model over binary spins, with graph coloring for parallel Gibbs.
- gset
- G-set: the standard max-cut benchmark, and the sign convention that decides everything.
- hdl
- The hardware backend: lower a sampling graph to a fixed-point p-bit fabric and emit
synthesizable Verilog for it — the same design for every deployment target in
crate::targets, from an Alchitry board to an Alveo card to an AWS F2 instance. - het
- Heterogeneous factor-graph Gibbs — the general engine the spin sampler is a special case of.
- hfs
- Hamze–de Freitas–Selby: solve a low-treewidth block exactly, over and over.
- host
- What the machine was doing while the clock ran.
- hubo
- Higher-order models, solved without reducing them to pairwise.
- icm
- Isoenergetic cluster moves, and parallel tempering built on them.
- ising
- Ising-model constructions and the exact results the sampler must reproduce before it is trusted with anything else: exact Boltzmann enumeration for small systems, and Onsager’s spontaneous magnetization for the 2D nearest-neighbor lattice (Onsager 1944 / Yang 1952): M(beta) = (1 - sinh(2 beta J)^-4)^(1/8) for beta > beta_c = ln(1+sqrt(2))/2 ~ 0.4407, M = 0 above.
- kernel
- The update. One implementation, every caller.
- ledger
- The device energy ledger — first-class, because on this hardware class the story IS the I/O.
- linalg
- Minimal dense linear algebra used by the compiler and the thermodynamic linear-algebra modules: a cyclic Jacobi eigensolver for symmetric matrices. std-only, deterministic.
- lp
- Read a problem written in LP format.
- lrw
- Lattice Random Walk SDE discretisation — the published algorithm behind Normal Computing’s CN101 “stochastic sampling with lattice random walk” (arXiv:2508.20883).
- matching
- Minimum-weight perfect matching on a general graph — Edmonds’ blossom algorithm.
- model
- Writing a model in the problem’s own words.
- mppi
- Sampling-based control: choosing an action by weighting sampled futures.
- ommx
- Export a ferrotherm program as an OMMX instance.
- oracle
- Things that find ground states, including one that must never work.
- planar
- Planar embedding — the rotation system every surface algorithm is written against.
- planarcut
- Exact max-cut on a planar graph, in polynomial time.
- planted
- Instances whose ground state is known because it was put there.
- popanneal
- Population annealing: a sequential Monte Carlo annealer that reports how much to believe it.
- program
- Stochastic differentiable programs — the program layer over the sampler.
- reduce
- Higher-order reduction: run a k-body model on pairwise hardware.
- rng
- Deterministic, seedable RNG (PCG-XSH-RR 64/32). std-only, wasm-clean, no external deps. Determinism is a feature: every published number must be reproducible from its seed.
- sbm
- Simulated bifurcation — the Toshiba Ising-machine algorithm line (Goto et al.; ballistic bSB and discrete dSB per the 2021 Science Advances formulation), as portable deterministic Rust.
- schedule
- What changes while a program runs.
- sdp
- A certified SDP lower bound on the ground energy, in std-only Rust.
- sqa
- Simulated quantum annealing: path-integral Monte Carlo on the transverse-field Ising model.
- tabu
- Tabu search — the baseline every new max-cut heuristic is measured against.
- targets
- FPGA deployment-target database for the ferrotherm VM — from edge parts a classroom owns to
the cloud instances a lab rents. Every number is labelled:
[DS]datasheet fact,[EST]engineering estimate,[SWEEP]verified market/status research (Aug 2026). The capacity model (p-bits per LUT budget, flips/s at a colored-update clock) is an ESTIMATE until the calibration-anchor pass lands; the published-machine anchors below bound it from above. - tempering
- Optimization-grade sampling: simulated annealing and parallel tempering.
- tla
- Thermodynamic linear algebra — the continuous (pmode) side of the field.
- wgsl
- The sweep, emitted as a WebGPU compute shader.
- wire
- The protobuf wire format, written against the specification rather than against examples.