open-standards/wai/wai-quantum/examples/fabric_state.rs
Transaction Science c5ddab49bc
Some checks failed
WAI examples / WAI examples · does this change touch them (push) Successful in 15s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 13s
WAI operation catalogue / does this change touch it (push) Successful in 18s
wai-audit collector and player integration / does this change touch it (push) Successful in 13s
wai-quantum clippy / does this change touch it (push) Successful in 19s
wai-quantum editors / does this change touch it (push) Successful in 32s
wai-quantum landscape stage 0, the sampler against the exact law / does this change touch it (push) Successful in 27s
wai-quantum energy-landscape jobs / does this change touch it (push) Successful in 23s
wai-quantum landscape energy to solution / does this change touch it (push) Successful in 35s
wai-quantum docs, course and locales / does this change touch it (push) Successful in 1m21s
wai-quantum command line / does this change touch it (push) Successful in 1m35s
wai-quantum qudit jobs / does this change touch it (push) Successful in 34s
wai-quantum error correction and mitigation / does this change touch it (push) Successful in 43s
wai-quantum contract / does this change touch it (push) Successful in 1m29s
wai-quantum for Python / does this change touch it (push) Successful in 40s
wai-quantum pulse and dynamics / does this change touch it (push) Successful in 42s
wai-quantum landscape stage 0, the sampler against the exact law / the small tier, to the byte · linux (push) Successful in 54s
wai-quantum verdicts and repairs / does this change touch it (push) Successful in 31s
wai-quantum views in agent hosts / does this change touch it (push) Successful in 30s
wai-quantum on Windows / does this change touch it (push) Successful in 26s
wai-quantum studio and desktop / does this change touch it (push) Successful in 31s
wai-quantum resource estimation / does this change touch it (push) Successful in 2m59s
wai-quantum service / does this change touch it (push) Successful in 1m37s
wai-quantum variational and algorithm library / does this change touch it (push) Successful in 1m35s
wai-quantum-landscape-fpga reference design / does this change touch it (push) Successful in 2m50s
wai-quantum other formats / does this change touch it (push) Successful in 2m52s
wai-quantum extension points / does this change touch it (push) Successful in 1m40s
wai-quantum for JavaScript / does this change touch it (push) Successful in 2m51s
wai-sink-android native sink library / does this change touch it (push) Successful in 25s
wai-quantum OpenQASM reader / does this change touch it (push) Successful in 2m36s
wai-quantum wasmQ / does this change touch it (push) Successful in 21s
wai-sink-swift native sink package / does this change touch it (push) Successful in 40s
WAI Studio / does this change touch it (push) Successful in 39s
wai-quantum service / service energy · linux packages (push) Failing after 15s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 4m20s
wai-quantum contract / the policy is linked, and the deprecations page reads (push) Successful in 21s
wai-audit collector and player integration / collector · linux (push) Successful in 5m7s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (push) Successful in 27s
wai-quantum clippy / clippy, warnings denied, every feature set · linux (push) Successful in 6m37s
wai-quantum editors / editors · linux (push) Successful in 7m0s
wai-quantum docs, course and locales / the course and the command line's languages · linux (push) Successful in 4m16s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs under wasm32-wasip2 (wasmtime) (push) Successful in 2m22s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 9m46s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs · linux, release (push) Successful in 4m12s
wai-quantum landscape energy to solution / the small tier, to the byte · linux (push) Successful in 3m38s
wai-quantum energy-landscape jobs / native against WebAssembly, over many seeds (push) Successful in 10m23s
wai-quantum qudit jobs / the module and the conformance set under wasm32-wasip2 (wasmtime) (push) Successful in 2m26s
wai-quantum verdicts and repairs / verdicts, repairs and the intent set · linux (push) Successful in 2m57s
wai-quantum verdicts and repairs / the intent set and the verdict under wasm32-wasip2 (wasmtime) (push) Successful in 3m22s
wai-quantum error correction and mitigation / codes, decoders, texts and mitigation · linux, release (push) Successful in 8m51s
wai-quantum qudit jobs / the module, the job, the conformance set, the referee and the verb · linux (push) Successful in 5m30s
wai-quantum contract / schemas and the committed tool lists · linux (push) Successful in 11m13s
wai-quantum for Python / python · linux (push) Successful in 5m14s
wai-quantum contract / API compatibility · linux (push) Successful in 12m4s
WAI operation catalogue / the catalogue and every door · linux (push) Successful in 17m36s
wai-quantum views in agent hosts / views · the page and its engine (push) Successful in 6m6s
wai-quantum other formats / readers, writers and the set · linux (push) Successful in 4m45s
wai-quantum other formats / the set under wasm32-wasip2 (wasmtime) (push) Successful in 3m57s
wai-quantum extension points / the registry under wasm32-wasip2 (wasmtime) (push) Successful in 3m27s
wai-quantum OpenQASM reader / corpus under wasm32-wasip2 (wasmtime) (push) Successful in 1m12s
wai-quantum views in agent hosts / views · a scripted host (push) Successful in 8m23s
wai-quantum for JavaScript / javascript · linux (push) Successful in 5m26s
wai-quantum studio and desktop / studio · browser (push) Successful in 8m37s
wai-quantum energy-landscape jobs / reader, kernels, answers and the stated result · linux, release (push) Successful in 20m1s
wai-quantum wasmQ / the reference modules rebuild to their modules of record · linux (push) Successful in 45s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 1m35s
wai-quantum energy-landscape jobs / the module under wasm32-wasip2 (wasmtime) (push) Successful in 21m30s
wai-quantum OpenQASM reader / reader and corpus · linux (push) Successful in 4m55s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 10m12s
wai-quantum extension points / the registry and the example · linux (push) Successful in 8m3s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux, release (push) Successful in 3m0s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · linux (push) Successful in 4m21s
wai-quantum wasmQ / interpreter and vectors under wasm32-wasip2 (wasmtime) (push) Successful in 4m26s
WAI examples / WAI examples · portable · linux (push) Successful in 25m1s
wai-quantum service / service · linux (push) Successful in 12m21s
wai-quantum resource estimation / estimation and calibration · linux, release (push) Successful in 13m33s
wai-quantum command line / command line · linux (push) Successful in 32m48s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (push) Successful in 36m49s
WAI Studio / Studio in WebKit · linux (push) Successful in 21m57s
wai-quantum-landscape-fpga reference design / the member against the model of the logic, and the logic against the model · linux, release (push) Successful in 35m22s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 2m12s
wai-quantum editors / editors · macos (push) Successful in 1m48s
wai-quantum landscape stage 0, the sampler against the exact law / the small tier, to the byte · macos (push) Successful in 21s
wai-quantum command line / command line · macos (push) Successful in 2m51s
wai-quantum pulse and dynamics / the same bits · macos (push) Successful in 2m11s
wai-quantum landscape energy to solution / the small tier, to the byte · macos (push) Successful in 1m54s
wai-quantum energy-landscape jobs / the same bits · macos (push) Successful in 7m36s
wai-quantum qudit jobs / the same bits · macos (push) Successful in 2m3s
wai-quantum for Python / python · macos (push) Successful in 3m55s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (push) Successful in 18m52s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 4m51s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · macos (push) Successful in 4m51s
wai-quantum service / service · macos (push) Successful in 7m39s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Successful in 10m11s
wai-quantum pulse and dynamics / the same bits · linux-arm64 (push) Successful in 2m50s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 9m15s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 9m23s
WAI examples / WAI examples · android-app · linux-arm64 (push) Successful in 12m1s
wai-quantum-landscape-fpga reference design / the board's code on the board's processor's architecture · linux-arm64, release (push) Successful in 1m47s
wai-quantum extension points / the registry and the example · linux-arm64 (push) Successful in 6m16s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux-arm64, release (push) Successful in 4m16s
wai-quantum energy-landscape jobs / the same bits · linux-arm64 (push) Successful in 19m51s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 6m47s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Failing after 36m24s
wai-quantum on Windows / engine · windows (push) Has been cancelled
wai-quantum on Windows / command line · windows (push) Has been cancelled
wai-quantum on Windows / job service · windows (push) Has been cancelled
wai-quantum on Windows / python · windows (push) Has been cancelled
wai-quantum studio and desktop / desktop app · windows (push) Has been cancelled
WAI Quantum cross-simulator: the engine's other methods against exact references, the integer reference to 22 qubits, GPU members, nightly
The corpus held the engine's state-vector, tableau, MPS, tensor-network,
density-matrix and error-correction methods to exact references; now it
holds the rest it can, each to an exact reference and to the accuracy the
method states:

- Pauli propagation against the integer state's <P>, within its stated
  truncation bound at every rung of its ladder plus a derived rounding (the
  bound must be 0 at threshold 0); the stabilizer-rank sum exactly (rounding
  of its one evaluation) and sampled (its stated bound failing over ten
  seeds no more often than a binomial count at its stated confidence
  allows); the cut-rank sum's amplitudes and counts.
- A new integer density matrix (exact.Density): trajectories and Pauli
  frames within Hoeffding's bound on their samples, the density matrix
  within its rounding, counts too, under depolarizing, dephasing, amplitude
  damping and readout noise; mitigation by zne (each scale against the
  folded program's exact value, the extrapolation against the same
  extrapolation of exact values), vd (purity exactly, ratio within shots)
  and readout inversion.
- Pulses against the Rabi formula within the run's stated bound; exact
  matching against the least-weight correction found by exhaustion
  (tools/decoding.py), union-find against its own single-edge claim.
- The integer state reference past 14 qubits: whole states at 16, 18, 20
  and 22 qubits in the full tier, the referee to 20.
- A gpu tier: wai-quantum's new example fabric_state runs the bit-exact
  op-log on every GPU member a build finds; each must give the CPU's
  integers bit for bit, and the single-precision methods on Metal are held
  to the integer state. Members a host lacks are recorded with why.
- Thirteen new injected faults, each caught by its own check alone, and a
  self-test that ran no fault now fails.
- A nightly workflow: the full tier on Linux bounded in time and memory
  (per-job guard, reproduce.sh --memory-gb), and the gpu tier on the macOS
  host and the Linux host with an integrated GPU.
- A single-precision engine past its derived bound at 20 qubits is listed
  as a known disagreement with a reproducer.

The engine's driver gains a decode job kind.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-11 18:52:55 -05:00

133 lines
6.3 KiB
Rust

//! The fabric's GPU members on one circuit, for the cross-simulator corpus
//! (`wai/quantum-cross-simulator/`, its `gpu` tier).
//!
//! ```text
//! fabric_state PROGRAM.qasm OUT_PREFIX # one JSON line on standard output
//! ```
//!
//! The program is read as the bit-exact method reads it (its op-log, its
//! gateset) and run on the CPU reference and on every member this build finds:
//! the WebGPU member on each adapter of the platform's GPU interfaces
//! (`quantum_fabric_webgpu`), the Metal member on each device
//! (`quantum_fabric_metal`), the CUDA member on each device
//! (`quantum_fabric_cuda`). Each state that comes back is written to
//! `OUT_PREFIX.<key>` as little-endian `i64` pairs at scale `2^30`, qubit 0 the
//! lowest bit of the index, beside its hash. A device found and not placed, a
//! member's refusal of the circuit, and a family this build leaves out are
//! listed with why, so the harness can say what could not run.
use serde_json::{Value, json};
use std::io::Write as _;
use wai_quantum::quantum::StateVector;
fn hex(b: &[u8]) -> String {
b.iter().map(|x| format!("{x:02x}")).collect()
}
fn write_state(path: &str, sv: &StateVector) -> Result<(), String> {
let f = std::fs::File::create(path).map_err(|e| format!("{path}: {e}"))?;
let mut w = std::io::BufWriter::with_capacity(1 << 20, f);
for a in &sv.amps {
w.write_all(&a.re.to_le_bytes()).map_err(|e| e.to_string())?;
w.write_all(&a.im.to_le_bytes()).map_err(|e| e.to_string())?;
}
w.flush().map_err(|e| e.to_string())
}
/// One member's run: its state written beside its hash, or its refusal.
fn ran(family: &str, key: &str, implementation: &str, max_qubits: u32, n: u32, run: impl FnOnce() -> Result<StateVector, String>, prefix: &str) -> Value {
let mut v = json!({ "family": family, "key": key, "implementation": implementation, "max_qubits": max_qubits });
if n > max_qubits {
v["refused"] = json!(format!("{n} qubits; this member holds at most {max_qubits}"));
return v;
}
let t = std::time::Instant::now();
match run() {
Ok(sv) => {
let path = format!("{prefix}.{key}");
match write_state(&path, &sv) {
Ok(()) => {
v["seconds"] = json!(t.elapsed().as_secs_f64());
v["state_out"] = json!(path);
v["state_hash"] = json!(hex(&sv.statevector_hash()));
}
Err(e) => v["refused"] = json!(e),
}
}
Err(e) => v["refused"] = json!(e),
}
v
}
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() != 3 {
eprintln!("usage: fabric_state PROGRAM.qasm OUT_PREFIX");
std::process::exit(2);
}
let (src_path, prefix) = (&args[1], &args[2]);
let answer = (|| -> Result<Value, String> {
let src = std::fs::read_to_string(src_path).map_err(|e| format!("{src_path}: {e}"))?;
let program = wai_quantum::qasm::read(&src).map_err(|d| d.to_string())?.program;
let (c, _) = program.dyadic_with_report()?;
let n = program.n_qubits;
let mut members: Vec<Value> = Vec::new();
let mut absent: Vec<Value> = Vec::new();
members.push(ran("cpu", "cpu", "reference", 64, n, || c.simulate().map_err(|e| e.to_string()), prefix));
#[cfg(feature = "quantum_fabric_webgpu")]
{
use wai_quantum::quantum_fabric_webgpu::blocking;
match blocking::discover() {
Ok(d) => {
for m in &d.found {
members.push(ran("webgpu", m.key(), m.implementation(), u32::from(m.max_qubits()), n, || blocking::simulate_from(m, &c, 0).map_err(|e| e.to_string()), prefix));
}
for r in &d.refused {
absent.push(json!({ "family": "webgpu", "key": r.key, "device": r.adapter, "why": r.error.to_string() }));
}
if d.found.is_empty() && d.refused.is_empty() {
absent.push(json!({ "family": "webgpu", "why": "the platform's GPU interfaces list no adapter" }));
}
}
Err(e) => absent.push(json!({ "family": "webgpu", "why": e.to_string() })),
}
}
#[cfg(not(feature = "quantum_fabric_webgpu"))]
absent.push(json!({ "family": "webgpu", "why": "this build leaves the WebGPU member out (feature quantum_fabric_webgpu)" }));
#[cfg(feature = "quantum_fabric_metal")]
{
let d = wai_quantum::quantum_fabric_metal::discover();
for m in &d.found {
members.push(ran("metal", m.key(), m.implementation(), u32::from(m.max_qubits()), n, || m.simulate(&c).map_err(|e| e.to_string()), prefix));
}
for r in &d.refused {
absent.push(json!({ "family": "metal", "key": r.key, "device": r.device, "why": r.error.to_string() }));
}
if let Some(why) = &d.unavailable {
absent.push(json!({ "family": "metal", "why": why }));
}
}
#[cfg(not(feature = "quantum_fabric_metal"))]
absent.push(json!({ "family": "metal", "why": "this build leaves the Metal member out (feature quantum_fabric_metal)" }));
#[cfg(feature = "quantum_fabric_cuda")]
{
let d = wai_quantum::quantum_fabric_cuda::discover();
for m in &d.found {
members.push(ran("cuda", m.key(), m.implementation(), u32::from(m.max_qubits()), n, || m.simulate(&c).map_err(|e| e.to_string()), prefix));
}
for r in &d.refused {
absent.push(json!({ "family": "cuda", "key": r.key, "device": r.device, "why": r.error.to_string() }));
}
if let Some(why) = &d.unavailable {
absent.push(json!({ "family": "cuda", "why": why }));
}
}
#[cfg(not(feature = "quantum_fabric_cuda"))]
absent.push(json!({ "family": "cuda", "why": "this build leaves the CUDA member out (feature quantum_fabric_cuda)" }));
Ok(json!({ "n": n, "n_ops": c.ops.len(), "members": members, "absent": absent }))
})();
match answer {
Ok(v) => println!("{}", json!({ "ok": true, "answer": v })),
Err(e) => println!("{}", json!({ "ok": false, "refused": e })),
}
}