wai-quantum 0.3.25: error correction at circuit level, sampled, modelled and decoded exactly #143
20 changed files with 3062 additions and 22 deletions
2
wai/wai-quantum-serve/Cargo.lock
generated
2
wai/wai-quantum-serve/Cargo.lock
generated
|
|
@ -589,7 +589,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wai-quantum"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
dependencies = [
|
||||
"blake3",
|
||||
"ed25519-dalek",
|
||||
|
|
|
|||
2
wai/wai-quantum/Cargo.lock
generated
2
wai/wai-quantum/Cargo.lock
generated
|
|
@ -415,7 +415,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|||
|
||||
[[package]]
|
||||
name = "wai-quantum"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
dependencies = [
|
||||
"blake3",
|
||||
"ed25519-dalek",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "wai-quantum"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
edition = "2024"
|
||||
rust-version = "1.97"
|
||||
license = "Apache-2.0"
|
||||
|
|
@ -53,6 +53,9 @@ quantum_bptn = ["quantum_spd"]
|
|||
quantum_resource = []
|
||||
# Signed, energy-accounted receipts for it, re-checkable bit for bit anywhere.
|
||||
quantum_resource_receipt = ["quantum_resource", "_signing"]
|
||||
# Noisy Clifford circuits at QEC scale: bit-packed Pauli-frame sampling, detector
|
||||
# error models by backward sensitivity, and exact minimum-weight matching.
|
||||
quantum_frame = []
|
||||
# Mixed states and the observables that distinguish quantum theory from a classical
|
||||
# account: density matrices, the partial trace, exact Pauli expectations, CHSH.
|
||||
quantum_info = ["quantum"]
|
||||
|
|
@ -92,13 +95,21 @@ quantum_phasor_meter = ["_signing"]
|
|||
|
||||
# Everything.
|
||||
full = [
|
||||
"quantum", "quantum_toolchain", "quantum_mps", "quantum_stabilizer", "quantum_pauli", "quantum_spd", "quantum_spd_receipt", "quantum_bptn", "quantum_resource", "quantum_resource_receipt", "quantum_qir", "quantum_info", "quantum_qudit", "quantum_comm", "quantum_source", "quantum_channel",
|
||||
"quantum", "quantum_toolchain", "quantum_mps", "quantum_stabilizer", "quantum_pauli", "quantum_spd", "quantum_spd_receipt", "quantum_bptn", "quantum_resource", "quantum_resource_receipt", "quantum_frame", "quantum_qir", "quantum_info", "quantum_qudit", "quantum_comm", "quantum_source", "quantum_channel",
|
||||
"quantum_receipt", "quantum_ops", "quantum_cal", "quantum_mitigate", "quantum_qec",
|
||||
"quantum_control", "quantum_noise", "quantum_compile", "quantum_atom", "quantum_qbom",
|
||||
"quantum_vml", "quantum_phasor", "quantum_qfhrr", "quantum_kernel", "quantum_qdata",
|
||||
"quantum_phasor_meter",
|
||||
]
|
||||
|
||||
[[example]]
|
||||
name = "qec_threshold"
|
||||
required-features = ["quantum_frame"]
|
||||
|
||||
[[example]]
|
||||
name = "qec_frame"
|
||||
required-features = ["quantum_frame"]
|
||||
|
||||
[[example]]
|
||||
name = "utility"
|
||||
required-features = ["quantum_spd"]
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ never creates information.
|
|||
| `quantum_cal`, `quantum_control`, `quantum_noise` | calibration, filter-function robust control, DD noise spectroscopy, Cycle-Benchmarking noise learning |
|
||||
| `quantum_mitigate` | zero-noise extrapolation, readout M3, classical shadows |
|
||||
| `quantum_qec` | CSS codes (distance verified by exhaustive search, not asserted) — **rotated surface** `[[d²,1,d]]`, toric, bivariate-bicycle, and the **`[[7,1,3]]` colour code**, whose self-duality buys a *transversal* logical Hadamard — one round, no ancillas, no surgery — verified on the simulator, with the surface code shown failing the same move — with **two decoders**: union-find (weighted matching, single-shot, space-time with faulty measurement, **and circuit-level with hook errors**; **imports and exports** Stim-syntax detector error models, so other tools' noise models decode here and ours decode there) and Relay-BP (for qLDPC) |
|
||||
| `quantum_frame` | **noisy Clifford circuits at QEC scale**: reads the ecosystem's circuit text; samples detection events by bit-packed Pauli-frame simulation (64 shots per word); derives the detector error model by backward sensitivity, refusing non-deterministic detectors; generates the rotated surface-code memory experiment byte for byte as the reference layout; and decodes by **exact minimum-weight perfect matching** (Edmonds' blossom on integer weights). Measures logical error rates and fits the code model resource estimates assume |
|
||||
| `quantum_compile` | Clifford routing + stabilizer-tableau equivalence proof |
|
||||
| `quantum_atom` | neutral-atom register preparation (Hungarian / LSAP) |
|
||||
| `quantum_qir` | **QIR export + ingest** — emit and parse QIR (the QIR Alliance's LLVM-based IR); emitted modules validated with `llvm-as`, and 9 of 10 catalog algorithms re-ingest to a bit-identical statevector |
|
||||
|
|
@ -148,6 +149,32 @@ search limits, to the bit). Re-running it anywhere must reproduce every figure,
|
|||
down to each factory round, and the bytes are the same natively and as a WASI
|
||||
component.
|
||||
|
||||
## Error correction at circuit level
|
||||
|
||||
An error-correction experiment is a noisy Clifford circuit, its detectors and
|
||||
its logical observable. `quantum_frame` samples it, derives its detector error
|
||||
model, and decodes it exactly:
|
||||
|
||||
```sh
|
||||
wai-quantum qec -d 5 --p 0.003 --shots 100000 # surface-code memory, per-round logical error
|
||||
wai-quantum qec --file circuit.txt --shots 100000 # any circuit in the ecosystem's text
|
||||
wai-quantum qec --dem -d 3 # its detector error model
|
||||
wai-quantum qec --fit # measure a and p* of P(d) = a·(p/p*)^((d+1)/2)
|
||||
```
|
||||
|
||||
The model is checked against an independent implementation:
|
||||
- the generated circuits are identical, byte for byte, across distances 2–15
|
||||
and 1–8 rounds;
|
||||
- the derived error models match mechanism for mechanism, to 10⁻¹² in
|
||||
probability, across surface codes in both bases (rotated and unrotated) and
|
||||
repetition codes;
|
||||
- decoded logical error rates agree point by point within sampling error.
|
||||
|
||||
`tests/frame_reference.rs` keeps two of those fixtures in the repository. The
|
||||
fitted code model comes out at `a ≈ 0.023`, `p* ≈ 0.0100`. That is a measured
|
||||
value for the constants a resource estimate (`quantum_resource`) otherwise takes
|
||||
on trust, and it can be fed straight into one.
|
||||
|
||||
## Determinism
|
||||
|
||||
Simulation is **byte-exact**: amplitudes are dyadic fixed-point, so a circuit
|
||||
|
|
|
|||
65
wai/wai-quantum/examples/qec_frame.rs
Normal file
65
wai/wai-quantum/examples/qec_frame.rs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
//! Noisy Clifford circuits from the command line.
|
||||
//!
|
||||
//! ```text
|
||||
//! cargo run --release --example qec_frame --features quantum_frame -- gen 5 5 0.001
|
||||
//! cargo run --release --example qec_frame --features quantum_frame -- dem circuit.txt
|
||||
//! cargo run --release --example qec_frame --features quantum_frame -- sample circuit.txt 100000 7
|
||||
//! cargo run --release --example qec_frame --features quantum_frame -- decode circuit.txt events.txt
|
||||
//! cargo run --release --example qec_frame --features quantum_frame -- rate circuit.txt 100000 7
|
||||
//! ```
|
||||
use wai_quantum::quantum_frame::{error_model, parse, sample, surface_code_memory};
|
||||
use wai_quantum::quantum_match::MatchingGraph;
|
||||
|
||||
fn main() {
|
||||
let a: Vec<String> = std::env::args().collect();
|
||||
let read = |p: &str| std::fs::read_to_string(p).expect("read circuit");
|
||||
match a.get(1).map(String::as_str) {
|
||||
Some("gen") => {
|
||||
let d: u32 = a[2].parse().unwrap();
|
||||
let r: u32 = a[3].parse().unwrap();
|
||||
let p: f64 = a[4].parse().unwrap();
|
||||
print!("{}", surface_code_memory(d, r, p));
|
||||
}
|
||||
Some("dem") => {
|
||||
let c = parse(&read(&a[2])).expect("parse");
|
||||
print!("{}", error_model(&c).expect("model").to_text());
|
||||
}
|
||||
Some("sample") => {
|
||||
let c = parse(&read(&a[2])).expect("parse");
|
||||
let shots: usize = a[3].parse().unwrap();
|
||||
let seed: u64 = a[4].parse().unwrap();
|
||||
let s = sample(&c, shots, seed);
|
||||
for d in 0..s.detectors {
|
||||
println!("D{d} {}", s.count(d));
|
||||
}
|
||||
let flips = (0..shots).filter(|&i| s.flips(i) & 1 == 1).count();
|
||||
println!("L0 {flips}");
|
||||
}
|
||||
// One line per shot of fired detector indices; prints one predicted
|
||||
// observable mask per line.
|
||||
Some("decode") => {
|
||||
let c = parse(&read(&a[2])).expect("parse");
|
||||
let g = MatchingGraph::from_model(&error_model(&c).expect("model")).expect("graphlike");
|
||||
let mut out = String::new();
|
||||
for line in read(&a[3]).lines() {
|
||||
let fired: Vec<u32> = line.split_whitespace().map(|t| t.parse().unwrap()).collect();
|
||||
out += &format!("{}\n", g.decode(&fired).expect("decode"));
|
||||
}
|
||||
print!("{out}");
|
||||
}
|
||||
// Sample and decode: logical failures out of shots, and the time spent.
|
||||
Some("rate") => {
|
||||
let c = parse(&read(&a[2])).expect("parse");
|
||||
let shots: usize = a[3].parse().unwrap();
|
||||
let seed: u64 = a[4].parse().unwrap();
|
||||
let g = MatchingGraph::from_model(&error_model(&c).expect("model")).expect("graphlike");
|
||||
let t0 = std::time::Instant::now();
|
||||
let s = sample(&c, shots, seed);
|
||||
let t1 = t0.elapsed();
|
||||
let f = g.failures(&s).expect("decode");
|
||||
let t2 = t0.elapsed() - t1;
|
||||
println!("{f} {shots} sample_s={:.3} decode_s={:.3}", t1.as_secs_f64(), t2.as_secs_f64());
|
||||
}
|
||||
_ => eprintln!("usage: qec_frame gen D ROUNDS P | dem FILE | sample FILE SHOTS SEED | decode FILE EVENTS | rate FILE SHOTS SEED"),
|
||||
}
|
||||
}
|
||||
26
wai/wai-quantum/examples/qec_threshold.rs
Normal file
26
wai/wai-quantum/examples/qec_threshold.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//! Measure the rotated surface code's logical error rate per round, and fit
|
||||
//! the code model `P(d) = a·(p/p*)^((d+1)/2)` that resource estimates assume.
|
||||
//!
|
||||
//! ```text
|
||||
//! cargo run --release --example qec_threshold --features quantum_frame -- [SHOTS] [SEED]
|
||||
//! ```
|
||||
use wai_quantum::quantum_match::{fit_code_model, memory_experiment};
|
||||
|
||||
fn main() {
|
||||
let a: Vec<String> = std::env::args().collect();
|
||||
let shots: usize = a.get(1).map_or(200_000, |s| s.parse().unwrap());
|
||||
let seed: u64 = a.get(2).map_or(1, |s| s.parse().unwrap());
|
||||
let mut pts = Vec::new();
|
||||
println!("{:>3} {:>7} {:>9} {:>9} {:>12}", "d", "p", "shots", "failures", "per round");
|
||||
for d in [3u32, 5, 7] {
|
||||
for p in [0.002, 0.003, 0.004, 0.005] {
|
||||
// Fewer shots where decoding costs more and failures are plentiful.
|
||||
let n = if d == 7 { shots / 4 } else { shots };
|
||||
let t = memory_experiment(d, d, p, n, seed).expect("decode");
|
||||
println!("{:>3} {:>7} {:>9} {:>9} {:>12.4e}", d, p, t.shots, t.failures, t.per_round());
|
||||
pts.push(t);
|
||||
}
|
||||
}
|
||||
let f = fit_code_model(&pts).expect("fit");
|
||||
println!("fit: a = {:.4}, p* = {:.5}", f.prefactor, f.threshold);
|
||||
}
|
||||
|
|
@ -27,7 +27,8 @@ mod linalg;
|
|||
feature = "quantum_vml",
|
||||
feature = "quantum_phasor",
|
||||
feature = "quantum_kernel",
|
||||
feature = "quantum_resource"
|
||||
feature = "quantum_resource",
|
||||
feature = "quantum_frame"
|
||||
))]
|
||||
mod repro;
|
||||
|
||||
|
|
@ -91,6 +92,12 @@ pub mod quantum_resource;
|
|||
#[cfg(feature = "quantum_resource_receipt")]
|
||||
pub mod quantum_resource_receipt;
|
||||
|
||||
#[cfg(feature = "quantum_frame")]
|
||||
pub mod quantum_frame;
|
||||
|
||||
#[cfg(feature = "quantum_frame")]
|
||||
pub mod quantum_match;
|
||||
|
||||
#[cfg(feature = "quantum_info")]
|
||||
pub mod quantum_info;
|
||||
|
||||
|
|
|
|||
1155
wai/wai-quantum/src/quantum_frame.rs
Normal file
1155
wai/wai-quantum/src/quantum_frame.rs
Normal file
File diff suppressed because it is too large
Load diff
1008
wai/wai-quantum/src/quantum_match.rs
Normal file
1008
wai/wai-quantum/src/quantum_match.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -30,28 +30,28 @@ pub use trig::sin_cos;
|
|||
// Natural logarithm
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
const LN2_HI: f64 = 6.931_471_803_691_238_164_90e-1;
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
const LN2_LO: f64 = 1.908_214_929_270_587_700_02e-10;
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
const LG1: f64 = 6.666_666_666_666_735_130e-1;
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
const LG2: f64 = 3.999_999_999_940_941_908e-1;
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
const LG3: f64 = 2.857_142_874_366_239_149e-1;
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
const LG4: f64 = 2.222_219_843_214_978_396e-1;
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
const LG5: f64 = 1.818_357_216_161_805_012e-1;
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
const LG6: f64 = 1.531_383_769_920_937_332e-1;
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
const LG7: f64 = 1.479_819_860_511_658_591e-1;
|
||||
|
||||
/// The natural logarithm, within an ulp of the true value: `−∞` at zero, NaN
|
||||
/// below it.
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
pub fn ln(x: f64) -> f64 {
|
||||
let mut bits = x.to_bits();
|
||||
let mut hx = (bits >> 32) as u32;
|
||||
|
|
@ -91,6 +91,74 @@ pub fn ln(x: f64) -> f64 {
|
|||
s * (hfsq + r) + dk * LN2_LO - hfsq + f + dk * LN2_HI
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Exponential
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[cfg(feature = "quantum_frame")]
|
||||
const EXP_P: [f64; 5] = [
|
||||
1.666_666_666_666_660_190_37e-1,
|
||||
-2.777_777_777_701_559_338_42e-3,
|
||||
6.613_756_321_437_934_361_17e-5,
|
||||
-1.653_390_220_546_525_153_90e-6,
|
||||
4.138_136_797_057_238_460_39e-8,
|
||||
];
|
||||
|
||||
/// `eˣ`, bit-identical on every IEEE-754 platform: fdlibm's algorithm
|
||||
/// (reduction by `ln 2` in two parts, a rational approximation on
|
||||
/// `[−ln2/2, ln2/2]`), using only `+ − × ÷`. Within an ulp of the true value.
|
||||
#[cfg(feature = "quantum_frame")]
|
||||
pub fn exp(x: f64) -> f64 {
|
||||
const LN2_HI_E: f64 = 6.931_471_803_691_238_164_90e-1;
|
||||
const LN2_LO_E: f64 = 1.908_214_929_270_587_700_02e-10;
|
||||
const INV_LN2: f64 = 1.442_695_040_888_963_387_00;
|
||||
if x.is_nan() {
|
||||
return x;
|
||||
}
|
||||
if x > 7.097_827_128_933_839_730_96e2 {
|
||||
return f64::INFINITY;
|
||||
}
|
||||
if x < -7.451_332_191_019_411_084_20e2 {
|
||||
return 0.0;
|
||||
}
|
||||
let ax = x.abs();
|
||||
let (hi, lo, k): (f64, f64, i32);
|
||||
if ax > 0.5 * core::f64::consts::LN_2 {
|
||||
let kk = if ax < 1.5 * core::f64::consts::LN_2 {
|
||||
if x < 0.0 { -1 } else { 1 }
|
||||
} else {
|
||||
(INV_LN2 * x + if x < 0.0 { -0.5 } else { 0.5 }) as i32
|
||||
};
|
||||
let t = f64::from(kk);
|
||||
hi = x - t * LN2_HI_E;
|
||||
lo = t * LN2_LO_E;
|
||||
k = kk;
|
||||
} else if ax < 3.725_290_298_461_914e-9 {
|
||||
// |x| < 2⁻²⁸: 1 + x to the last bit.
|
||||
return 1.0 + x;
|
||||
} else {
|
||||
hi = x;
|
||||
lo = 0.0;
|
||||
k = 0;
|
||||
}
|
||||
let r = hi - lo;
|
||||
let t = r * r;
|
||||
let c = r - t * (EXP_P[0] + t * (EXP_P[1] + t * (EXP_P[2] + t * (EXP_P[3] + t * EXP_P[4]))));
|
||||
if k == 0 {
|
||||
return 1.0 - ((r * c) / (c - 2.0) - r);
|
||||
}
|
||||
let y = 1.0 - ((lo - (r * c) / (2.0 - c)) - hi);
|
||||
// y · 2ᵏ, in two steps where 2ᵏ alone would leave the normal range.
|
||||
let pow2 = |e: i32| f64::from_bits(((e + 1023) as u64) << 52);
|
||||
if k > 1023 {
|
||||
y * pow2(1023) * pow2(k - 1023)
|
||||
} else if k < -1021 {
|
||||
y * pow2(k + 1000) * pow2(-1000)
|
||||
} else {
|
||||
y * pow2(k)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Arctangent
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -240,6 +308,27 @@ mod tests {
|
|||
#[allow(unused_imports)]
|
||||
use super::*;
|
||||
|
||||
#[cfg(feature = "quantum_frame")]
|
||||
#[test]
|
||||
fn exp_is_within_an_ulp_of_the_platform() {
|
||||
let mut s = 0x9e37_79b9_7f4a_7c15u64;
|
||||
for i in 0..400_000 {
|
||||
s ^= s << 13;
|
||||
s ^= s >> 7;
|
||||
s ^= s << 17;
|
||||
let u = (s >> 11) as f64 / (1u64 << 53) as f64;
|
||||
let span = [1e-10, 0.3, 0.7, 2.0, 20.0, 700.0, 740.0][i % 7];
|
||||
let x = (2.0 * u - 1.0) * span;
|
||||
assert!(ulps(exp(x), x.exp()) <= 1, "exp({x:e}) = {:e} vs {:e}", exp(x), x.exp());
|
||||
}
|
||||
assert_eq!(exp(0.0), 1.0);
|
||||
assert_eq!(exp(f64::INFINITY), f64::INFINITY);
|
||||
assert_eq!(exp(f64::NEG_INFINITY), 0.0);
|
||||
assert!(exp(f64::NAN).is_nan());
|
||||
assert_eq!(exp(800.0), f64::INFINITY);
|
||||
assert_eq!(exp(-800.0), 0.0);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn ulps(a: f64, b: f64) -> u64 {
|
||||
if a == b {
|
||||
|
|
@ -262,7 +351,7 @@ mod tests {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource"))]
|
||||
#[cfg(any(feature = "quantum_vml", feature = "quantum_kernel", feature = "quantum_resource", feature = "quantum_frame"))]
|
||||
#[test]
|
||||
fn ln_is_within_an_ulp_of_the_platform() {
|
||||
for x in inputs().filter(|&x| x > 0.0) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
feature = "quantum_pauli",
|
||||
feature = "quantum_spd",
|
||||
feature = "quantum_bptn",
|
||||
feature = "quantum_resource"
|
||||
feature = "quantum_resource",
|
||||
feature = "quantum_frame"
|
||||
))]
|
||||
|
||||
use wai_quantum::*;
|
||||
|
|
@ -147,3 +148,27 @@ fn resource_estimates() {
|
|||
assert_eq!(digest(&v), 0xce9d_43b2_d498_f379);
|
||||
}
|
||||
|
||||
/// Detection counts of a sampled surface-code run, the failures its decoding
|
||||
/// leaves, and the code model fitted from a small grid: the sampler's random
|
||||
/// stream, its logarithm-driven skips, the matching and the fit's `exp`.
|
||||
#[test]
|
||||
fn frame_sampling_and_matching() {
|
||||
use quantum_frame::{parse, sample, surface_code_memory};
|
||||
use quantum_match::{fit_code_model, memory_experiment};
|
||||
let c = parse(&surface_code_memory(3, 3, 0.01)).unwrap();
|
||||
let s = sample(&c, 10_000, 5);
|
||||
let mut v: Vec<f64> = (0..s.detectors).map(|d| s.count(d) as f64).collect();
|
||||
let mut pts = Vec::new();
|
||||
for d in [3, 5] {
|
||||
for p in [0.004, 0.008] {
|
||||
let t = memory_experiment(d, d, p, 4_000, 9).unwrap();
|
||||
v.push(t.failures as f64);
|
||||
v.push(t.per_round());
|
||||
pts.push(t);
|
||||
}
|
||||
}
|
||||
let f = fit_code_model(&pts).unwrap();
|
||||
v.extend([f.prefactor, f.threshold]);
|
||||
assert_eq!(digest(&v), 0xcbb3_99f9_6d5c_e8f0);
|
||||
}
|
||||
|
||||
|
|
|
|||
89
wai/wai-quantum/tests/data/memory_x_d3.circuit
Normal file
89
wai/wai-quantum/tests/data/memory_x_d3.circuit
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
QUBIT_COORDS(1, 1) 1
|
||||
QUBIT_COORDS(2, 0) 2
|
||||
QUBIT_COORDS(3, 1) 3
|
||||
QUBIT_COORDS(5, 1) 5
|
||||
QUBIT_COORDS(1, 3) 8
|
||||
QUBIT_COORDS(2, 2) 9
|
||||
QUBIT_COORDS(3, 3) 10
|
||||
QUBIT_COORDS(4, 2) 11
|
||||
QUBIT_COORDS(5, 3) 12
|
||||
QUBIT_COORDS(6, 2) 13
|
||||
QUBIT_COORDS(0, 4) 14
|
||||
QUBIT_COORDS(1, 5) 15
|
||||
QUBIT_COORDS(2, 4) 16
|
||||
QUBIT_COORDS(3, 5) 17
|
||||
QUBIT_COORDS(4, 4) 18
|
||||
QUBIT_COORDS(5, 5) 19
|
||||
QUBIT_COORDS(4, 6) 25
|
||||
RX 1 3 5 8 10 12 15 17 19
|
||||
Z_ERROR(0.002) 1 3 5 8 10 12 15 17 19
|
||||
R 2 9 11 13 14 16 18 25
|
||||
X_ERROR(0.002) 2 9 11 13 14 16 18 25
|
||||
TICK
|
||||
DEPOLARIZE1(0.002) 1 3 5 8 10 12 15 17 19
|
||||
H 2 11 16 25
|
||||
DEPOLARIZE1(0.002) 2 11 16 25
|
||||
TICK
|
||||
CX 2 3 16 17 11 12 15 14 10 9 19 18
|
||||
DEPOLARIZE2(0.002) 2 3 16 17 11 12 15 14 10 9 19 18
|
||||
TICK
|
||||
CX 2 1 16 15 11 10 8 14 3 9 12 18
|
||||
DEPOLARIZE2(0.002) 2 1 16 15 11 10 8 14 3 9 12 18
|
||||
TICK
|
||||
CX 16 10 11 5 25 19 8 9 17 18 12 13
|
||||
DEPOLARIZE2(0.002) 16 10 11 5 25 19 8 9 17 18 12 13
|
||||
TICK
|
||||
CX 16 8 11 3 25 17 1 9 10 18 5 13
|
||||
DEPOLARIZE2(0.002) 16 8 11 3 25 17 1 9 10 18 5 13
|
||||
TICK
|
||||
H 2 11 16 25
|
||||
DEPOLARIZE1(0.002) 2 11 16 25
|
||||
TICK
|
||||
X_ERROR(0.002) 2 9 11 13 14 16 18 25
|
||||
MR 2 9 11 13 14 16 18 25
|
||||
X_ERROR(0.002) 2 9 11 13 14 16 18 25
|
||||
DETECTOR(2, 0, 0) rec[-8]
|
||||
DETECTOR(2, 4, 0) rec[-3]
|
||||
DETECTOR(4, 2, 0) rec[-6]
|
||||
DETECTOR(4, 6, 0) rec[-1]
|
||||
REPEAT 2 {
|
||||
TICK
|
||||
DEPOLARIZE1(0.002) 1 3 5 8 10 12 15 17 19
|
||||
H 2 11 16 25
|
||||
DEPOLARIZE1(0.002) 2 11 16 25
|
||||
TICK
|
||||
CX 2 3 16 17 11 12 15 14 10 9 19 18
|
||||
DEPOLARIZE2(0.002) 2 3 16 17 11 12 15 14 10 9 19 18
|
||||
TICK
|
||||
CX 2 1 16 15 11 10 8 14 3 9 12 18
|
||||
DEPOLARIZE2(0.002) 2 1 16 15 11 10 8 14 3 9 12 18
|
||||
TICK
|
||||
CX 16 10 11 5 25 19 8 9 17 18 12 13
|
||||
DEPOLARIZE2(0.002) 16 10 11 5 25 19 8 9 17 18 12 13
|
||||
TICK
|
||||
CX 16 8 11 3 25 17 1 9 10 18 5 13
|
||||
DEPOLARIZE2(0.002) 16 8 11 3 25 17 1 9 10 18 5 13
|
||||
TICK
|
||||
H 2 11 16 25
|
||||
DEPOLARIZE1(0.002) 2 11 16 25
|
||||
TICK
|
||||
X_ERROR(0.002) 2 9 11 13 14 16 18 25
|
||||
MR 2 9 11 13 14 16 18 25
|
||||
X_ERROR(0.002) 2 9 11 13 14 16 18 25
|
||||
SHIFT_COORDS(0, 0, 1)
|
||||
DETECTOR(2, 0, 0) rec[-8] rec[-16]
|
||||
DETECTOR(2, 2, 0) rec[-7] rec[-15]
|
||||
DETECTOR(4, 2, 0) rec[-6] rec[-14]
|
||||
DETECTOR(6, 2, 0) rec[-5] rec[-13]
|
||||
DETECTOR(0, 4, 0) rec[-4] rec[-12]
|
||||
DETECTOR(2, 4, 0) rec[-3] rec[-11]
|
||||
DETECTOR(4, 4, 0) rec[-2] rec[-10]
|
||||
DETECTOR(4, 6, 0) rec[-1] rec[-9]
|
||||
}
|
||||
Z_ERROR(0.002) 1 3 5 8 10 12 15 17 19
|
||||
MX 1 3 5 8 10 12 15 17 19
|
||||
DETECTOR(2, 0, 1) rec[-8] rec[-9] rec[-17]
|
||||
DETECTOR(2, 4, 1) rec[-2] rec[-3] rec[-5] rec[-6] rec[-12]
|
||||
DETECTOR(4, 2, 1) rec[-4] rec[-5] rec[-7] rec[-8] rec[-15]
|
||||
DETECTOR(4, 6, 1) rec[-1] rec[-2] rec[-10]
|
||||
OBSERVABLE_INCLUDE(0) rec[-3] rec[-6] rec[-9]
|
||||
221
wai/wai-quantum/tests/data/memory_x_d3.dem
Normal file
221
wai/wai-quantum/tests/data/memory_x_d3.dem
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
error(0.003858066319639164) D0 D2
|
||||
error(0.007686363287824861) D0 D4
|
||||
error(0.003858066319639164) D0 L0
|
||||
error(0.004387566933333155) D1 D2
|
||||
error(0.001066666666666516) D1 D2 D5
|
||||
error(0.003858066319639164) D1 D3
|
||||
error(0.000400266975246834) D1 D4
|
||||
error(0.000400266975246834) D1 D4 D5
|
||||
error(0.0001334579439585259) D1 D4 D5 D8
|
||||
error(0.0001334579439585259) D1 D4 D8
|
||||
error(0.000400266975246834) D1 D5 D6
|
||||
error(0.0001334579439585259) D1 D5 D6 D8
|
||||
error(0.000400266975246834) D1 D5 D8 D9
|
||||
error(0.000400266975246834) D1 D5 D8 L0
|
||||
error(0.0001334579439585259) D1 D5 D9
|
||||
error(0.0001334579439585259) D1 D5 L0
|
||||
error(0.000400266975246834) D1 D6
|
||||
error(0.0001334579439585259) D1 D6 D8
|
||||
error(0.000400266975246834) D1 D8 D9
|
||||
error(0.001466079739032824) D1 D8 L0
|
||||
error(0.007817769619301565) D1 D9
|
||||
error(0.008343044294438688) D1 L0
|
||||
error(0.00821142736622363) D10
|
||||
error(0.001200017820547319) D10 D11
|
||||
error(0.0001334579439585259) D10 D11 D14
|
||||
error(0.0002668802658714406) D10 D11 D14 D18
|
||||
error(0.000400266975246834) D10 D11 D17
|
||||
error(0.0001334579439585259) D10 D11 D17 D18
|
||||
error(0.000400266975246834) D10 D11 D18
|
||||
error(0.0008002135231907215) D10 D13
|
||||
error(0.000400266975246834) D10 D13 D14 D17
|
||||
error(0.0001334579439585259) D10 D14 D16 D17
|
||||
error(0.0001334579439585259) D10 D14 D17
|
||||
error(0.000400266975246834) D10 D14 D17 D18
|
||||
error(0.0001334579439585259) D10 D14 D18
|
||||
error(0.0002668802658714406) D10 D16
|
||||
error(0.0001334579439585259) D10 D16 D17 L0
|
||||
error(0.0001334579439585259) D10 D17 L0
|
||||
error(0.004785824618421568) D10 D18
|
||||
error(0.001599324140787608) D11
|
||||
error(0.0002668802658714406) D11 D14
|
||||
error(0.0001334579439585259) D11 D14 D18
|
||||
error(0.0006669335944047278) D11 D17
|
||||
error(0.000400266975246834) D11 D17 D18
|
||||
error(0.000533618081590258) D11 D18
|
||||
error(0.000533618081590258) D11 D18 D19
|
||||
error(0.007160387030215617) D11 D19
|
||||
error(0.001200017820547319) D12 D13 D14
|
||||
error(0.0001334579439585259) D12 D13 D16 L0
|
||||
error(0.000533618081590258) D12 D13 D20
|
||||
error(0.001200017820547319) D12 D13 L0
|
||||
error(0.001200017820547319) D12 D14
|
||||
error(0.007160387030215617) D12 D20
|
||||
error(0.001599324140787608) D12 L0
|
||||
error(0.008211427366223628) D13
|
||||
error(0.0001334579439585259) D13 D14
|
||||
error(0.0001334579439585259) D13 D14 D16 D17
|
||||
error(0.000533618081590258) D13 D14 D17
|
||||
error(0.001200017820547319) D13 D14 D17 D18
|
||||
error(0.000533618081590258) D13 D14 D20
|
||||
error(0.001466257564268764) D13 D16
|
||||
error(0.001200017820547319) D13 D16 D17 L0
|
||||
error(0.000533618081590258) D13 D17 D20
|
||||
error(0.000533618081590258) D13 D17 L0
|
||||
error(0.001200017820547319) D13 D18
|
||||
error(0.001066666666666516) D13 D20 L0
|
||||
error(0.002928215306047978) D14
|
||||
error(0.001200017820547319) D14 D15
|
||||
error(0.0001334579439585259) D14 D15 D17
|
||||
error(0.0001334579439585259) D14 D15 D17 D18
|
||||
error(0.001200017820547319) D14 D15 D18
|
||||
error(0.000400266975246834) D14 D15 D18 D22
|
||||
error(0.000400266975246834) D14 D15 D22
|
||||
error(0.001865350750555233) D14 D17
|
||||
error(0.000533618081590258) D14 D17 D18
|
||||
error(0.0001334579439585259) D14 D18 D22
|
||||
error(0.001066666666666516) D14 D20
|
||||
error(0.007817769619301565) D14 D22
|
||||
error(0.006501598321819228) D15
|
||||
error(0.0001334579439585259) D15 D17 D18 D22
|
||||
error(0.0001334579439585259) D15 D17 D22
|
||||
error(0.001466257564268764) D15 D18
|
||||
error(0.0001334579439585259) D15 D18 D19
|
||||
error(0.0001334579439585259) D15 D18 D19 D22
|
||||
error(0.000400266975246834) D15 D18 D22
|
||||
error(0.0001334579439585259) D15 D19
|
||||
error(0.0001334579439585259) D15 D19 D22
|
||||
error(0.001466079739032824) D15 D22
|
||||
error(0.005842457790162801) D16
|
||||
error(0.001599324140787608) D16 D17 L0
|
||||
error(0.001200017820547319) D17 D18 D19
|
||||
error(0.0008002135231907215) D17 D18 D21
|
||||
error(0.000400266975246834) D17 D18 D22
|
||||
error(0.0002668802658714406) D17 D18 L0
|
||||
error(0.001200017820547319) D17 D19
|
||||
error(0.000533618081590258) D17 D20
|
||||
error(0.007949140876340624) D17 D21
|
||||
error(0.000400266975246834) D17 D22
|
||||
error(0.003591243050134198) D17 L0
|
||||
error(0.008867408007091262) D18
|
||||
error(0.001599324140787608) D18 D19
|
||||
error(0.000533618081590258) D18 D19 D21
|
||||
error(0.000400266975246834) D18 D19 D22
|
||||
error(0.001066666666666516) D18 D21 D22
|
||||
error(0.0002668802658714406) D18 D21 L0
|
||||
error(0.0001334579439585259) D18 D22
|
||||
error(0.00213123536581817) D19
|
||||
error(0.001066666666666516) D19 D21
|
||||
error(0.000400266975246834) D19 D22
|
||||
error(0.007686363287824861) D19 D23
|
||||
error(0.007423445364098325) D2
|
||||
error(0.001066666666666516) D2 D4
|
||||
error(0.000533618081590258) D2 D4 D5
|
||||
error(0.0002668802658714406) D2 D5
|
||||
error(0.0008002135231907215) D2 D5 D6
|
||||
error(0.007949140876340624) D2 D6
|
||||
error(0.002531483609263898) D20 D22
|
||||
error(0.003062399999999851) D20 L0
|
||||
error(0.003062399999999851) D21 D22
|
||||
error(0.002531483609263898) D21 D23
|
||||
error(0.004785824618421568) D21 L0
|
||||
error(0.005710347764487468) D22
|
||||
error(0.002531483609263898) D23
|
||||
error(0.004387566933333155) D3
|
||||
error(0.001066666666666516) D3 D10
|
||||
error(0.000533618081590258) D3 D10 D11
|
||||
error(0.007160387030215617) D3 D11
|
||||
error(0.000533618081590258) D3 D6
|
||||
error(0.000533618081590258) D3 D6 D10
|
||||
error(0.001066666666666516) D3 D9
|
||||
error(0.000533618081590258) D3 D9 D10
|
||||
error(0.007160387030215617) D4 D12
|
||||
error(0.000533618081590258) D4 D5 D12
|
||||
error(0.001200017820547319) D4 D5 D6
|
||||
error(0.0001334579439585259) D4 D5 D8 L0
|
||||
error(0.001599324140787608) D4 D5 L0
|
||||
error(0.001200017820547319) D4 D6
|
||||
error(0.0001334579439585259) D4 D8 L0
|
||||
error(0.00213123536581817) D4 L0
|
||||
error(0.008867408007091262) D5
|
||||
error(0.001200017820547319) D5 D10
|
||||
error(0.000400266975246834) D5 D12 D13 L0
|
||||
error(0.0001334579439585259) D5 D12 D16 L0
|
||||
error(0.000533618081590258) D5 D12 L0
|
||||
error(0.004785824618421568) D5 D13
|
||||
error(0.000400266975246834) D5 D16
|
||||
error(0.0002668802658714406) D5 D6
|
||||
error(0.000400266975246834) D5 D6 D12
|
||||
error(0.0001334579439585259) D5 D6 D12 D13
|
||||
error(0.0001334579439585259) D5 D6 D8 D9
|
||||
error(0.000533618081590258) D5 D6 D9
|
||||
error(0.001200017820547319) D5 D6 D9 D10
|
||||
error(0.000400266975246834) D5 D6 D9 D13
|
||||
error(0.001466257564268764) D5 D8
|
||||
error(0.001200017820547319) D5 D8 D9 L0
|
||||
error(0.0001334579439585259) D5 D9 D12
|
||||
error(0.0002668802658714406) D5 D9 D12 D13
|
||||
error(0.0001334579439585259) D5 D9 D12 D16
|
||||
error(0.0001334579439585259) D5 D9 D13 L0
|
||||
error(0.000400266975246834) D5 D9 D16 L0
|
||||
error(0.0035912430501342) D6
|
||||
error(0.000533618081590258) D6 D10
|
||||
error(0.0001334579439585259) D6 D10 D13 D14
|
||||
error(0.0006669335944047278) D6 D12
|
||||
error(0.000400266975246834) D6 D12 D13
|
||||
error(0.0001334579439585259) D6 D13
|
||||
error(0.000400266975246834) D6 D13 D14
|
||||
error(0.007423445364098326) D6 D14
|
||||
error(0.001599324140787608) D6 D7
|
||||
error(0.001200017820547319) D6 D7 D10
|
||||
error(0.000400266975246834) D6 D7 D10 D14
|
||||
error(0.0001334579439585259) D6 D7 D13
|
||||
error(0.0002668802658714406) D6 D7 D13 D14
|
||||
error(0.0001334579439585259) D6 D7 D14
|
||||
error(0.0001334579439585259) D6 D7 D9 D10
|
||||
error(0.0001334579439585259) D6 D7 D9 D13
|
||||
error(0.0001334579439585259) D6 D8 D9
|
||||
error(0.001865350750555233) D6 D9
|
||||
error(0.000533618081590258) D6 D9 D10
|
||||
error(0.000400266975246834) D6 D9 D10 D13
|
||||
error(0.0001334579439585259) D6 D9 D13
|
||||
error(0.005842457790162799) D7
|
||||
error(0.001466257564268764) D7 D10
|
||||
error(0.0001334579439585259) D7 D10 D11
|
||||
error(0.0001334579439585259) D7 D10 D11 D14
|
||||
error(0.000400266975246834) D7 D10 D14
|
||||
error(0.0001334579439585259) D7 D11 D14 D18
|
||||
error(0.0001334579439585259) D7 D11 D18
|
||||
error(0.0002668802658714406) D7 D13
|
||||
error(0.0001334579439585259) D7 D13 D14
|
||||
error(0.000400266975246834) D7 D14
|
||||
error(0.000533618081590258) D7 D14 D15
|
||||
error(0.000400266975246834) D7 D14 D18
|
||||
error(0.004521357674826842) D7 D15
|
||||
error(0.000400266975246834) D7 D18
|
||||
error(0.0001334579439585259) D7 D9 D10 D14
|
||||
error(0.0001334579439585259) D7 D9 D13 D14
|
||||
error(0.006501598321819227) D8
|
||||
error(0.004521357674826842) D8 D16
|
||||
error(0.000533618081590258) D8 D9 D16 L0
|
||||
error(0.001200017820547319) D8 D9 L0
|
||||
error(0.001200017820547319) D9 D10 D11
|
||||
error(0.0002668802658714406) D9 D10 D13 D14
|
||||
error(0.0001334579439585259) D9 D10 D13 D17
|
||||
error(0.0001334579439585259) D9 D10 D14 D16
|
||||
error(0.0002668802658714406) D9 D10 D16 D17
|
||||
error(0.0001334579439585259) D9 D10 D16 L0
|
||||
error(0.000400266975246834) D9 D10 D17
|
||||
error(0.0001334579439585259) D9 D10 L0
|
||||
error(0.001200017820547319) D9 D11
|
||||
error(0.0002668802658714406) D9 D12
|
||||
error(0.0001334579439585259) D9 D12 D13
|
||||
error(0.0001334579439585259) D9 D12 D13 D16
|
||||
error(0.0001334579439585259) D9 D13 D14 D16
|
||||
error(0.000400266975246834) D9 D13 D16 D17
|
||||
error(0.000400266975246834) D9 D13 D16 L0
|
||||
error(0.0002668802658714406) D9 D14
|
||||
error(0.0001334579439585259) D9 D16 D17
|
||||
error(0.000400266975246834) D9 D16 L0
|
||||
error(0.007423445364098326) D9 D17
|
||||
error(0.002928215306047977) D9 L0
|
||||
153
wai/wai-quantum/tests/data/memory_z_d5.circuit
Normal file
153
wai/wai-quantum/tests/data/memory_z_d5.circuit
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
QUBIT_COORDS(1, 1) 1
|
||||
QUBIT_COORDS(2, 0) 2
|
||||
QUBIT_COORDS(3, 1) 3
|
||||
QUBIT_COORDS(5, 1) 5
|
||||
QUBIT_COORDS(6, 0) 6
|
||||
QUBIT_COORDS(7, 1) 7
|
||||
QUBIT_COORDS(9, 1) 9
|
||||
QUBIT_COORDS(1, 3) 12
|
||||
QUBIT_COORDS(2, 2) 13
|
||||
QUBIT_COORDS(3, 3) 14
|
||||
QUBIT_COORDS(4, 2) 15
|
||||
QUBIT_COORDS(5, 3) 16
|
||||
QUBIT_COORDS(6, 2) 17
|
||||
QUBIT_COORDS(7, 3) 18
|
||||
QUBIT_COORDS(8, 2) 19
|
||||
QUBIT_COORDS(9, 3) 20
|
||||
QUBIT_COORDS(10, 2) 21
|
||||
QUBIT_COORDS(0, 4) 22
|
||||
QUBIT_COORDS(1, 5) 23
|
||||
QUBIT_COORDS(2, 4) 24
|
||||
QUBIT_COORDS(3, 5) 25
|
||||
QUBIT_COORDS(4, 4) 26
|
||||
QUBIT_COORDS(5, 5) 27
|
||||
QUBIT_COORDS(6, 4) 28
|
||||
QUBIT_COORDS(7, 5) 29
|
||||
QUBIT_COORDS(8, 4) 30
|
||||
QUBIT_COORDS(9, 5) 31
|
||||
QUBIT_COORDS(1, 7) 34
|
||||
QUBIT_COORDS(2, 6) 35
|
||||
QUBIT_COORDS(3, 7) 36
|
||||
QUBIT_COORDS(4, 6) 37
|
||||
QUBIT_COORDS(5, 7) 38
|
||||
QUBIT_COORDS(6, 6) 39
|
||||
QUBIT_COORDS(7, 7) 40
|
||||
QUBIT_COORDS(8, 6) 41
|
||||
QUBIT_COORDS(9, 7) 42
|
||||
QUBIT_COORDS(10, 6) 43
|
||||
QUBIT_COORDS(0, 8) 44
|
||||
QUBIT_COORDS(1, 9) 45
|
||||
QUBIT_COORDS(2, 8) 46
|
||||
QUBIT_COORDS(3, 9) 47
|
||||
QUBIT_COORDS(4, 8) 48
|
||||
QUBIT_COORDS(5, 9) 49
|
||||
QUBIT_COORDS(6, 8) 50
|
||||
QUBIT_COORDS(7, 9) 51
|
||||
QUBIT_COORDS(8, 8) 52
|
||||
QUBIT_COORDS(9, 9) 53
|
||||
QUBIT_COORDS(4, 10) 59
|
||||
QUBIT_COORDS(8, 10) 63
|
||||
R 1 3 5 7 9 12 14 16 18 20 23 25 27 29 31 34 36 38 40 42 45 47 49 51 53
|
||||
X_ERROR(0.001) 1 3 5 7 9 12 14 16 18 20 23 25 27 29 31 34 36 38 40 42 45 47 49 51 53
|
||||
R 2 6 13 15 17 19 21 22 24 26 28 30 35 37 39 41 43 44 46 48 50 52 59 63
|
||||
X_ERROR(0.001) 2 6 13 15 17 19 21 22 24 26 28 30 35 37 39 41 43 44 46 48 50 52 59 63
|
||||
TICK
|
||||
DEPOLARIZE1(0.001) 1 3 5 7 9 12 14 16 18 20 23 25 27 29 31 34 36 38 40 42 45 47 49 51 53
|
||||
H 2 6 15 19 24 28 37 41 46 50 59 63
|
||||
DEPOLARIZE1(0.001) 2 6 15 19 24 28 37 41 46 50 59 63
|
||||
TICK
|
||||
CX 2 3 24 25 46 47 15 16 37 38 6 7 28 29 50 51 19 20 41 42 23 22 45 44 14 13 36 35 27 26 49 48 18 17 40 39 31 30 53 52
|
||||
DEPOLARIZE2(0.001) 2 3 24 25 46 47 15 16 37 38 6 7 28 29 50 51 19 20 41 42 23 22 45 44 14 13 36 35 27 26 49 48 18 17 40 39 31 30 53 52
|
||||
TICK
|
||||
CX 2 1 24 23 46 45 15 14 37 36 6 5 28 27 50 49 19 18 41 40 12 22 34 44 3 13 25 35 16 26 38 48 7 17 29 39 20 30 42 52
|
||||
DEPOLARIZE2(0.001) 2 1 24 23 46 45 15 14 37 36 6 5 28 27 50 49 19 18 41 40 12 22 34 44 3 13 25 35 16 26 38 48 7 17 29 39 20 30 42 52
|
||||
TICK
|
||||
CX 24 14 46 36 15 5 37 27 59 49 28 18 50 40 19 9 41 31 63 53 12 13 34 35 25 26 47 48 16 17 38 39 29 30 51 52 20 21 42 43
|
||||
DEPOLARIZE2(0.001) 24 14 46 36 15 5 37 27 59 49 28 18 50 40 19 9 41 31 63 53 12 13 34 35 25 26 47 48 16 17 38 39 29 30 51 52 20 21 42 43
|
||||
TICK
|
||||
CX 24 12 46 34 15 3 37 25 59 47 28 16 50 38 19 7 41 29 63 51 1 13 23 35 14 26 36 48 5 17 27 39 18 30 40 52 9 21 31 43
|
||||
DEPOLARIZE2(0.001) 24 12 46 34 15 3 37 25 59 47 28 16 50 38 19 7 41 29 63 51 1 13 23 35 14 26 36 48 5 17 27 39 18 30 40 52 9 21 31 43
|
||||
TICK
|
||||
H 2 6 15 19 24 28 37 41 46 50 59 63
|
||||
DEPOLARIZE1(0.001) 2 6 15 19 24 28 37 41 46 50 59 63
|
||||
TICK
|
||||
X_ERROR(0.001) 2 6 13 15 17 19 21 22 24 26 28 30 35 37 39 41 43 44 46 48 50 52 59 63
|
||||
MR 2 6 13 15 17 19 21 22 24 26 28 30 35 37 39 41 43 44 46 48 50 52 59 63
|
||||
X_ERROR(0.001) 2 6 13 15 17 19 21 22 24 26 28 30 35 37 39 41 43 44 46 48 50 52 59 63
|
||||
DETECTOR(0, 4, 0) rec[-17]
|
||||
DETECTOR(0, 8, 0) rec[-7]
|
||||
DETECTOR(2, 2, 0) rec[-22]
|
||||
DETECTOR(2, 6, 0) rec[-12]
|
||||
DETECTOR(4, 4, 0) rec[-15]
|
||||
DETECTOR(4, 8, 0) rec[-5]
|
||||
DETECTOR(6, 2, 0) rec[-20]
|
||||
DETECTOR(6, 6, 0) rec[-10]
|
||||
DETECTOR(8, 4, 0) rec[-13]
|
||||
DETECTOR(8, 8, 0) rec[-3]
|
||||
DETECTOR(10, 2, 0) rec[-18]
|
||||
DETECTOR(10, 6, 0) rec[-8]
|
||||
REPEAT 3 {
|
||||
TICK
|
||||
DEPOLARIZE1(0.001) 1 3 5 7 9 12 14 16 18 20 23 25 27 29 31 34 36 38 40 42 45 47 49 51 53
|
||||
H 2 6 15 19 24 28 37 41 46 50 59 63
|
||||
DEPOLARIZE1(0.001) 2 6 15 19 24 28 37 41 46 50 59 63
|
||||
TICK
|
||||
CX 2 3 24 25 46 47 15 16 37 38 6 7 28 29 50 51 19 20 41 42 23 22 45 44 14 13 36 35 27 26 49 48 18 17 40 39 31 30 53 52
|
||||
DEPOLARIZE2(0.001) 2 3 24 25 46 47 15 16 37 38 6 7 28 29 50 51 19 20 41 42 23 22 45 44 14 13 36 35 27 26 49 48 18 17 40 39 31 30 53 52
|
||||
TICK
|
||||
CX 2 1 24 23 46 45 15 14 37 36 6 5 28 27 50 49 19 18 41 40 12 22 34 44 3 13 25 35 16 26 38 48 7 17 29 39 20 30 42 52
|
||||
DEPOLARIZE2(0.001) 2 1 24 23 46 45 15 14 37 36 6 5 28 27 50 49 19 18 41 40 12 22 34 44 3 13 25 35 16 26 38 48 7 17 29 39 20 30 42 52
|
||||
TICK
|
||||
CX 24 14 46 36 15 5 37 27 59 49 28 18 50 40 19 9 41 31 63 53 12 13 34 35 25 26 47 48 16 17 38 39 29 30 51 52 20 21 42 43
|
||||
DEPOLARIZE2(0.001) 24 14 46 36 15 5 37 27 59 49 28 18 50 40 19 9 41 31 63 53 12 13 34 35 25 26 47 48 16 17 38 39 29 30 51 52 20 21 42 43
|
||||
TICK
|
||||
CX 24 12 46 34 15 3 37 25 59 47 28 16 50 38 19 7 41 29 63 51 1 13 23 35 14 26 36 48 5 17 27 39 18 30 40 52 9 21 31 43
|
||||
DEPOLARIZE2(0.001) 24 12 46 34 15 3 37 25 59 47 28 16 50 38 19 7 41 29 63 51 1 13 23 35 14 26 36 48 5 17 27 39 18 30 40 52 9 21 31 43
|
||||
TICK
|
||||
H 2 6 15 19 24 28 37 41 46 50 59 63
|
||||
DEPOLARIZE1(0.001) 2 6 15 19 24 28 37 41 46 50 59 63
|
||||
TICK
|
||||
X_ERROR(0.001) 2 6 13 15 17 19 21 22 24 26 28 30 35 37 39 41 43 44 46 48 50 52 59 63
|
||||
MR 2 6 13 15 17 19 21 22 24 26 28 30 35 37 39 41 43 44 46 48 50 52 59 63
|
||||
X_ERROR(0.001) 2 6 13 15 17 19 21 22 24 26 28 30 35 37 39 41 43 44 46 48 50 52 59 63
|
||||
SHIFT_COORDS(0, 0, 1)
|
||||
DETECTOR(2, 0, 0) rec[-24] rec[-48]
|
||||
DETECTOR(6, 0, 0) rec[-23] rec[-47]
|
||||
DETECTOR(2, 2, 0) rec[-22] rec[-46]
|
||||
DETECTOR(4, 2, 0) rec[-21] rec[-45]
|
||||
DETECTOR(6, 2, 0) rec[-20] rec[-44]
|
||||
DETECTOR(8, 2, 0) rec[-19] rec[-43]
|
||||
DETECTOR(10, 2, 0) rec[-18] rec[-42]
|
||||
DETECTOR(0, 4, 0) rec[-17] rec[-41]
|
||||
DETECTOR(2, 4, 0) rec[-16] rec[-40]
|
||||
DETECTOR(4, 4, 0) rec[-15] rec[-39]
|
||||
DETECTOR(6, 4, 0) rec[-14] rec[-38]
|
||||
DETECTOR(8, 4, 0) rec[-13] rec[-37]
|
||||
DETECTOR(2, 6, 0) rec[-12] rec[-36]
|
||||
DETECTOR(4, 6, 0) rec[-11] rec[-35]
|
||||
DETECTOR(6, 6, 0) rec[-10] rec[-34]
|
||||
DETECTOR(8, 6, 0) rec[-9] rec[-33]
|
||||
DETECTOR(10, 6, 0) rec[-8] rec[-32]
|
||||
DETECTOR(0, 8, 0) rec[-7] rec[-31]
|
||||
DETECTOR(2, 8, 0) rec[-6] rec[-30]
|
||||
DETECTOR(4, 8, 0) rec[-5] rec[-29]
|
||||
DETECTOR(6, 8, 0) rec[-4] rec[-28]
|
||||
DETECTOR(8, 8, 0) rec[-3] rec[-27]
|
||||
DETECTOR(4, 10, 0) rec[-2] rec[-26]
|
||||
DETECTOR(8, 10, 0) rec[-1] rec[-25]
|
||||
}
|
||||
X_ERROR(0.001) 1 3 5 7 9 12 14 16 18 20 23 25 27 29 31 34 36 38 40 42 45 47 49 51 53
|
||||
M 1 3 5 7 9 12 14 16 18 20 23 25 27 29 31 34 36 38 40 42 45 47 49 51 53
|
||||
DETECTOR(0, 4, 1) rec[-15] rec[-20] rec[-42]
|
||||
DETECTOR(0, 8, 1) rec[-5] rec[-10] rec[-32]
|
||||
DETECTOR(2, 2, 1) rec[-19] rec[-20] rec[-24] rec[-25] rec[-47]
|
||||
DETECTOR(2, 6, 1) rec[-9] rec[-10] rec[-14] rec[-15] rec[-37]
|
||||
DETECTOR(4, 4, 1) rec[-13] rec[-14] rec[-18] rec[-19] rec[-40]
|
||||
DETECTOR(4, 8, 1) rec[-3] rec[-4] rec[-8] rec[-9] rec[-30]
|
||||
DETECTOR(6, 2, 1) rec[-17] rec[-18] rec[-22] rec[-23] rec[-45]
|
||||
DETECTOR(6, 6, 1) rec[-7] rec[-8] rec[-12] rec[-13] rec[-35]
|
||||
DETECTOR(8, 4, 1) rec[-11] rec[-12] rec[-16] rec[-17] rec[-38]
|
||||
DETECTOR(8, 8, 1) rec[-1] rec[-2] rec[-6] rec[-7] rec[-28]
|
||||
DETECTOR(10, 2, 1) rec[-16] rec[-21] rec[-43]
|
||||
DETECTOR(10, 6, 1) rec[-6] rec[-11] rec[-33]
|
||||
OBSERVABLE_INCLUDE(0) rec[-21] rec[-22] rec[-23] rec[-24] rec[-25]
|
||||
46
wai/wai-quantum/tests/frame_reference.rs
Normal file
46
wai/wai-quantum/tests/frame_reference.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//! Cross-tool fixtures for noisy Clifford circuits.
|
||||
//!
|
||||
//! `data/memory_z_d5.circuit` and `data/memory_x_d3.circuit` were written by
|
||||
//! an independent circuit generator. `data/memory_x_d3.dem` is that tool's
|
||||
//! detector error model of the second circuit, flattened, with identical
|
||||
//! mechanisms XOR-combined. Matching them checks three things against an
|
||||
//! implementation that shares no code with this one:
|
||||
//! - the generator, byte for byte;
|
||||
//! - the parser, including the X-basis resets and measurements our generator
|
||||
//! never emits;
|
||||
//! - the backward-sensitivity model, mechanism for mechanism.
|
||||
#![cfg(feature = "quantum_frame")]
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use wai_quantum::quantum_frame::{error_model, parse, surface_code_memory};
|
||||
|
||||
#[test]
|
||||
fn the_generator_matches_the_reference_text() {
|
||||
let want = include_str!("data/memory_z_d5.circuit");
|
||||
assert_eq!(surface_code_memory(5, 4, 0.001), want);
|
||||
}
|
||||
|
||||
/// `"D0 D4 L0"` → probability.
|
||||
fn model_map(text: &str) -> BTreeMap<String, f64> {
|
||||
text.lines()
|
||||
.filter_map(|l| {
|
||||
let rest = l.trim().strip_prefix("error(")?;
|
||||
let (p, syms) = rest.split_once(')')?;
|
||||
let mut s: Vec<&str> = syms.split_whitespace().collect();
|
||||
s.sort_by_key(|t| (t.as_bytes()[0], t[1..].parse::<u32>().unwrap()));
|
||||
Some((s.join(" "), p.parse().unwrap()))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_model_matches_the_reference_model() {
|
||||
let c = parse(include_str!("data/memory_x_d3.circuit")).unwrap();
|
||||
let ours = model_map(&error_model(&c).unwrap().to_text());
|
||||
let theirs = model_map(include_str!("data/memory_x_d3.dem"));
|
||||
assert_eq!(ours.len(), theirs.len());
|
||||
for (k, p) in &theirs {
|
||||
let q = ours.get(k).unwrap_or_else(|| panic!("missing mechanism {k}"));
|
||||
assert!((q / p - 1.0).abs() < 1e-9, "{k}: {q} vs {p}");
|
||||
}
|
||||
}
|
||||
2
wai/wai-rs/Cargo.lock
generated
2
wai/wai-rs/Cargo.lock
generated
|
|
@ -3900,7 +3900,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wai-quantum"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
dependencies = [
|
||||
"blake3",
|
||||
"ed25519-dalek",
|
||||
|
|
|
|||
|
|
@ -348,6 +348,9 @@ quantum_bptn = ["quantum_spd", "wai-quantum/quantum_bptn"]
|
|||
# and its signed receipts.
|
||||
quantum_resource = ["dep:wai-quantum", "wai-quantum/quantum_resource"]
|
||||
quantum_resource_receipt = ["quantum_resource", "wai-quantum/quantum_resource_receipt"]
|
||||
# Noisy Clifford circuits at QEC scale: frame sampling, detector error models,
|
||||
# exact matching, measured code models.
|
||||
quantum_frame = ["dep:wai-quantum", "wai-quantum/quantum_frame"]
|
||||
quantum_qir = ["quantum_toolchain", "wai-quantum/quantum_qir"]
|
||||
# Variational quantum machine learning (extensions/quantum-sim § VML,
|
||||
# `wai.quantum.vml`): the interference-based ML the thermodynamic-computing pivot
|
||||
|
|
@ -476,6 +479,7 @@ required-features = [
|
|||
"quantum_spd_receipt",
|
||||
"quantum_bptn",
|
||||
"quantum_resource_receipt",
|
||||
"quantum_frame",
|
||||
]
|
||||
|
||||
[[bin]]
|
||||
|
|
|
|||
|
|
@ -47,6 +47,16 @@
|
|||
//! wai-quantum estimate factoring --qubit ns-e4 --receipt | wai-quantum verify
|
||||
//! ```
|
||||
//!
|
||||
//! Error correction itself, at circuit level: sample a noisy Clifford circuit,
|
||||
//! derive its detector error model, decode it exactly, and measure the code
|
||||
//! model that estimates otherwise take on trust:
|
||||
//!
|
||||
//! ```text
|
||||
//! wai-quantum qec -d 5 --p 0.003 --shots 100000
|
||||
//! wai-quantum qec --file circuit.txt
|
||||
//! wai-quantum qec --fit # then: estimate --prefactor A --threshold P
|
||||
//! ```
|
||||
//!
|
||||
//! The `channel` command prints the Holevo bound before and after, which can only
|
||||
//! fall: noise never creates information. Two results there are easy to miss —
|
||||
//! fully damping `|1⟩` yields a *pure* output that still carries nothing (both
|
||||
|
|
@ -145,7 +155,12 @@ fn usage() -> ! {
|
|||
wai-quantum estimate [factoring|chemistry] [--qubit NAME|all] [--code surface|surface-meas|floquet]\n \
|
||||
[--budget E] [--slowdown N] [--frontier] [--json] [--receipt]\n \
|
||||
wai-quantum estimate --qubits N [--ccz N] [--t N] [--rotations N] [--depth N] [--measurements N] ...\n \
|
||||
Qubits: us-e3, us-e4, ns-e3, ns-e4, meas-e4, meas-e6.\n\n\
|
||||
Qubits: us-e3, us-e4, ns-e3, ns-e4, meas-e4, meas-e6. A measured code: --prefactor A --threshold P.\n\n\
|
||||
ERROR CORRECTION AT CIRCUIT LEVEL:\n \
|
||||
wai-quantum qec [-d D] [--rounds R] [--p P] [--shots N] [--seed S] [--json]\n \
|
||||
wai-quantum qec --file CIRCUIT [--shots N] (the ecosystem's circuit text)\n \
|
||||
wai-quantum qec [--circuit | --dem] [-d D | --file CIRCUIT]\n \
|
||||
wai-quantum qec --fit [--shots N] (measure a and p* of the code model)\n\n\
|
||||
Channels: identity, bitflip, dephasing, depolarizing, damping.\n\
|
||||
Run `wai-quantum list` for the algorithm catalog."
|
||||
);
|
||||
|
|
@ -560,6 +575,20 @@ fn main() {
|
|||
"floquet" => QecModel::floquet(),
|
||||
other => die(&format!("unknown code '{other}' (surface, surface-meas, floquet)")),
|
||||
});
|
||||
// A code model with given constants, e.g. as `qec --fit` measured them.
|
||||
let a = opt(args, "--prefactor", "").map(|v| v.parse::<f64>().unwrap_or_else(|_| die("bad --prefactor")));
|
||||
let t = opt(args, "--threshold", "").map(|v| v.parse::<f64>().unwrap_or_else(|_| die("bad --threshold")));
|
||||
let code = if a.is_some() || t.is_some() {
|
||||
let base = code.unwrap_or_else(QecModel::surface_gate);
|
||||
Some(QecModel {
|
||||
name: format!("{} (given)", base.name),
|
||||
prefactor: a.unwrap_or(base.prefactor),
|
||||
threshold: t.unwrap_or(base.threshold),
|
||||
..base
|
||||
})
|
||||
} else {
|
||||
code
|
||||
};
|
||||
let which = opt(args, "--qubit", "").unwrap_or_else(|| {
|
||||
if flag(args, "--receipt") || flag(args, "--frontier") { "ns-e4".into() } else { "all".into() }
|
||||
});
|
||||
|
|
@ -631,13 +660,13 @@ fn main() {
|
|||
let isa = qr::layout(&counts, budget);
|
||||
println!("program {} tiles, {} logical steps, {} T states (budget {budget})", isa.tiles, isa.min_steps, isa.t_states);
|
||||
println!(
|
||||
"{:<12} {:<13} {:>3} {:>9} {:>8} {:>14} {}",
|
||||
"{:<12} {:<22} {:>3} {:>9} {:>8} {:>14} {}",
|
||||
"qubit", "code", "d", "factories", "share", "physical", "runtime"
|
||||
);
|
||||
for (q, e) in &estimates {
|
||||
match e {
|
||||
Ok(e) => println!(
|
||||
"{:<12} {:<13} {:>3} {:>9} {:>7.1}% {:>14} {}",
|
||||
"{:<12} {:<22} {:>3} {:>9} {:>7.1}% {:>14} {}",
|
||||
e.qubit,
|
||||
e.code,
|
||||
e.distance,
|
||||
|
|
@ -651,6 +680,85 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
// Error correction at circuit level: sample a noisy Clifford circuit,
|
||||
// derive its detector error model, decode it exactly.
|
||||
"qec" => {
|
||||
use wai::quantum_frame::{error_model, parse, sample, surface_code_memory};
|
||||
use wai::quantum_match::{fit_code_model, memory_experiment, MatchingGraph};
|
||||
let shots: usize = num(args, "--shots", "", 100_000);
|
||||
let seed: u64 = num(args, "--seed", "", 1);
|
||||
let json = flag(args, "--json");
|
||||
if flag(args, "--fit") {
|
||||
// The surface code's logical error per round on a grid, and
|
||||
// the code model a resource estimate would otherwise assume.
|
||||
let mut pts = Vec::new();
|
||||
if !json {
|
||||
println!("{:>3} {:>7} {:>9} {:>9} {:>11}", "d", "p", "shots", "failures", "per round");
|
||||
}
|
||||
for d in [3u32, 5, 7] {
|
||||
for p in [0.002, 0.003, 0.004, 0.005] {
|
||||
let n = if d == 7 { shots / 4 } else { shots };
|
||||
let t = memory_experiment(d, d, p, n, seed).unwrap_or_else(|e| die(&format!("{e:?}")));
|
||||
if !json {
|
||||
println!("{:>3} {:>7} {:>9} {:>9} {:>11.3e}", d, p, t.shots, t.failures, t.per_round());
|
||||
}
|
||||
pts.push(t);
|
||||
}
|
||||
}
|
||||
let f = fit_code_model(&pts).unwrap_or_else(|| die("too few failures to fit; raise --shots"));
|
||||
if json {
|
||||
println!("{{\"prefactor\":{},\"threshold\":{}}}", f.prefactor, f.threshold);
|
||||
} else {
|
||||
println!("fit P(d) = a·(p/p*)^((d+1)/2) per round, a = {:.4}, p* = {:.5}", f.prefactor, f.threshold);
|
||||
println!("estimate wai-quantum estimate factoring --prefactor {:.4} --threshold {:.5}", f.prefactor, f.threshold);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let d: u32 = num(args, "--distance", "-d", 3);
|
||||
let rounds: u32 = num(args, "--rounds", "", d);
|
||||
let p: f64 = num(args, "--p", "", 0.001);
|
||||
let text = match opt(args, "--file", "") {
|
||||
Some(path) => std::fs::read_to_string(&path).unwrap_or_else(|e| die(&format!("{path}: {e}"))),
|
||||
None => {
|
||||
if d < 2 || rounds < 1 || !(0.0..=0.5).contains(&p) {
|
||||
die("need -d ≥ 2, --rounds ≥ 1 and 0 ≤ --p ≤ 0.5");
|
||||
}
|
||||
surface_code_memory(d, rounds, p)
|
||||
}
|
||||
};
|
||||
if flag(args, "--circuit") {
|
||||
print!("{text}");
|
||||
return;
|
||||
}
|
||||
let c = parse(&text).unwrap_or_else(|e| die(&format!("circuit: {e}")));
|
||||
let model = error_model(&c).unwrap_or_else(|e| die(&format!("model: {e}")));
|
||||
if flag(args, "--dem") {
|
||||
print!("{}", model.to_text());
|
||||
return;
|
||||
}
|
||||
let g = MatchingGraph::from_model(&model).unwrap_or_else(|e| die(&format!("matching graph: {e:?}")));
|
||||
let s = sample(&c, shots, seed);
|
||||
let failures = g.failures(&s).unwrap_or_else(|e| die(&format!("decode: {e:?}")));
|
||||
let rate = failures as f64 / shots as f64;
|
||||
if json {
|
||||
println!(
|
||||
"{{\"detectors\":{},\"failures\":{failures},\"mechanisms\":{},\"observables\":{},\"qubits\":{},\"seed\":{seed},\"shots\":{shots}}}",
|
||||
model.detectors,
|
||||
model.mechanisms.len(),
|
||||
model.observables,
|
||||
c.qubits
|
||||
);
|
||||
} else {
|
||||
println!("circuit {} qubits, {} detectors, {} observables", c.qubits, model.detectors, model.observables);
|
||||
println!("model {} error mechanisms", model.mechanisms.len());
|
||||
println!("failures {failures} of {shots} shots ({rate:.3e} per shot)");
|
||||
if opt(args, "--file", "").is_none() {
|
||||
let per_round = wai::quantum_match::MemoryPoint { distance: d, rounds, p, shots: shots as u64, failures }.per_round();
|
||||
println!("per round {per_round:.3e} (d = {d}, {rounds} rounds, p = {p})");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"entropy" => {
|
||||
let c = circuit_from(args, algo);
|
||||
let sv = c.simulate().unwrap_or_else(|e| die(&format!("simulate: {e:?}")));
|
||||
|
|
|
|||
|
|
@ -618,6 +618,12 @@ pub use wai_quantum::quantum_resource;
|
|||
|
||||
#[cfg(feature = "quantum_resource_receipt")]
|
||||
pub use wai_quantum::quantum_resource_receipt;
|
||||
|
||||
#[cfg(feature = "quantum_frame")]
|
||||
pub use wai_quantum::quantum_frame;
|
||||
|
||||
#[cfg(feature = "quantum_frame")]
|
||||
pub use wai_quantum::quantum_match;
|
||||
#[cfg(feature = "quantum_qir")]
|
||||
pub use wai_quantum::quantum_qir;
|
||||
|
||||
|
|
|
|||
2
wai/wai-web/Cargo.lock
generated
2
wai/wai-web/Cargo.lock
generated
|
|
@ -734,7 +734,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wai-quantum"
|
||||
version = "0.3.24"
|
||||
version = "0.3.25"
|
||||
dependencies = [
|
||||
"blake3",
|
||||
"ed25519-dalek",
|
||||
|
|
|
|||
Loading…
Reference in a new issue