use std::hint::black_box;
use std::time::Duration;
use criterion::{BatchSize, Criterion, Throughput, criterion_group, criterion_main};
use ticit::{Pauli, PauliString, TableauSimulator};
#[path = "support/workload.rs"]
mod workload;
use workload::{
MixedShape, Rng, SEED, clifford_stream, magic_qubits_for, magic_state, mixed_verify,
};
const N: usize = 128;
const CLIFFORD_GATES: usize = 10_000;
fn bench_clifford_frame(c: &mut Criterion) {
let mut group = c.benchmark_group("clifford-frame");
group.sample_size(20);
group.measurement_time(Duration::from_secs(3));
group.throughput(Throughput::Elements(CLIFFORD_GATES as u64));
for n in [64usize, 128, 256, 512] {
group.bench_function(format!("n{n}"), |b| {
b.iter_batched(
|| (TableauSimulator::with_seed(n, SEED), Rng::new(SEED)),
|(mut sim, mut rng)| {
clifford_stream(&mut sim, &mut rng, n, CLIFFORD_GATES);
black_box(sim)
},
BatchSize::PerIteration,
);
});
}
group.finish();
}
fn bench_t_gate(c: &mut Criterion) {
let mut group = c.benchmark_group("t-gate");
group.sample_size(50);
group.measurement_time(Duration::from_secs(3));
for rank in [256usize, 1024, 4096] {
group.bench_function(format!("n{N}-rank{rank}"), |b| {
let magic = magic_qubits_for(rank);
let target = magic as usize;
let base = {
let mut sim = magic_state(N, magic, SEED);
sim.h(target);
sim
};
assert_eq!(base.rank(), rank, "ladder must land on the requested rank");
let mut probe = base.clone();
probe
.t(target)
.expect("T on a superposed qubit stays under the cap");
assert_eq!(
probe.rank(),
2 * rank,
"this must be the rank-doubling path"
);
b.iter_batched(
|| base.clone(),
|mut sim| {
sim.t(target).expect("T stays under the rank cap");
black_box(sim)
},
BatchSize::PerIteration,
);
});
}
group.finish();
}
fn bench_t_gate_diagonal(c: &mut Criterion) {
let mut group = c.benchmark_group("t-gate-diagonal");
group.sample_size(50);
group.measurement_time(Duration::from_secs(3));
let rank = 1024usize;
group.bench_function(format!("n{N}-rank{rank}"), |b| {
let magic = magic_qubits_for(rank);
let target = magic as usize;
let base = magic_state(N, magic, SEED);
assert_eq!(base.rank(), rank);
let mut probe = base.clone();
probe.t(target).expect("diagonal T stays under the cap");
assert_eq!(probe.rank(), rank, "diagonal T must not grow the map");
b.iter_batched(
|| base.clone(),
|mut sim| {
sim.t(target).expect("T stays under the rank cap");
black_box(sim)
},
BatchSize::PerIteration,
);
});
group.finish();
}
fn bench_measure_deterministic(c: &mut Criterion) {
let mut group = c.benchmark_group("measure-deterministic");
group.sample_size(50);
group.measurement_time(Duration::from_secs(3));
let rank = 1024usize;
group.bench_function(format!("n{N}-rank{rank}"), |b| {
let magic = magic_qubits_for(rank);
let target = magic as usize;
let base = magic_state(N, magic, SEED);
let outcome = base
.clone()
.measure(target)
.expect("Z on a product-state qubit is measurable");
assert!(outcome.deterministic, "setup must hit the a = 0 branch");
assert!(
(outcome.probability - 1.0).abs() < 1e-9,
"|0> yields +1 surely"
);
b.iter_batched(
|| base.clone(),
|mut sim| {
let result = sim
.measure(black_box(target))
.expect("measurement succeeds");
black_box((sim, result))
},
BatchSize::PerIteration,
);
});
group.finish();
}
fn bench_measure_random(c: &mut Criterion) {
let mut group = c.benchmark_group("measure-random");
group.sample_size(50);
group.measurement_time(Duration::from_secs(3));
let rank = 1024usize;
group.bench_function(format!("n{N}-rank{rank}"), |b| {
let magic = magic_qubits_for(rank);
let target = magic as usize;
let base = {
let mut sim = magic_state(N, magic, SEED);
sim.h(target);
sim
};
let outcome = base
.clone()
.measure(target)
.expect("Z on a |+> qubit is measurable");
assert!(!outcome.deterministic, "setup must hit the a != 0 branch");
assert!(
(outcome.probability - 0.5).abs() < 1e-9,
"Z on |+> is an even coin"
);
b.iter_batched(
|| base.clone(),
|mut sim| {
let result = sim
.measure(black_box(target))
.expect("measurement succeeds");
black_box((sim, result))
},
BatchSize::PerIteration,
);
});
group.finish();
}
fn bench_measure_random_lowrank(c: &mut Criterion) {
let mut group = c.benchmark_group("measure-random-lowrank");
group.sample_size(100);
group.measurement_time(Duration::from_secs(3));
for n in [128usize, 256] {
group.bench_function(format!("n{n}"), |b| {
let magic = 2u32;
let target = magic as usize;
let base = {
let mut sim = magic_state(n, magic, SEED);
sim.h(target);
sim
};
assert_eq!(base.rank(), 4, "the map must be small enough to ignore");
let outcome = base
.clone()
.measure(target)
.expect("Z on a |+> qubit is measurable");
assert!(!outcome.deterministic, "setup must hit the a != 0 branch");
b.iter_batched(
|| base.clone(),
|mut sim| {
let result = sim
.measure(black_box(target))
.expect("measurement succeeds");
black_box((sim, result))
},
BatchSize::PerIteration,
);
});
}
group.finish();
}
fn bench_expectation(c: &mut Criterion) {
let mut group = c.benchmark_group("expectation");
group.sample_size(50);
group.measurement_time(Duration::from_secs(3));
let rank = 4096usize;
let magic = magic_qubits_for(rank);
let superposed = magic as usize;
let idle = superposed + 1;
let sim = {
let mut sim = magic_state(N, magic, SEED);
sim.h(superposed);
sim
};
assert_eq!(sim.rank(), rank);
let diagonal = PauliString::single(N, idle, Pauli::Z);
let off_diagonal = PauliString::single(N, superposed, Pauli::Z);
assert!(
(sim.peek_observable_expectation(&diagonal)
.expect("in range")
- 1.0)
.abs()
< 1e-9,
"idle qubit is |0>"
);
assert!(
sim.peek_observable_expectation(&off_diagonal)
.expect("in range")
.abs()
< 1e-9,
"superposed qubit is |+>, reachable only via the coset-pairing path"
);
group.bench_function(format!("n{N}-rank{rank}/diagonal"), |b| {
b.iter(|| black_box(sim.peek_observable_expectation(black_box(&diagonal))));
});
group.bench_function(format!("n{N}-rank{rank}/off-diagonal"), |b| {
b.iter(|| black_box(sim.peek_observable_expectation(black_box(&off_diagonal))));
});
group.finish();
}
fn bench_ccz(c: &mut Criterion) {
let mut group = c.benchmark_group("ccz");
let n = 64usize;
group.bench_function(format!("n{n}"), |b| {
let base = {
let mut sim = TableauSimulator::with_seed(n, SEED);
for q in 0..3 {
sim.h(q);
}
sim
};
b.iter_batched(
|| base.clone(),
|mut sim| {
sim.ccz(0, 1, 2)
.expect("CCZ on three qubits stays under the cap");
black_box(sim)
},
BatchSize::PerIteration,
);
});
group.finish();
}
fn bench_mixed_verify(c: &mut Criterion) {
let mut group = c.benchmark_group("mixed-verify");
group.sample_size(10);
group.measurement_time(Duration::from_secs(10));
for n in [128usize, 256] {
group.bench_function(format!("n{n}"), |b| {
let shape = MixedShape::bench(n);
b.iter(|| black_box(mixed_verify(black_box(&shape), SEED)));
});
}
group.finish();
}
criterion_group!(
benches,
bench_clifford_frame,
bench_t_gate,
bench_t_gate_diagonal,
bench_measure_deterministic,
bench_measure_random,
bench_measure_random_lowrank,
bench_expectation,
bench_ccz,
bench_mixed_verify,
);
criterion_main!(benches);