mod catalog;
mod optimization;
use crate::{
model::*,
simulation::{TraceLimits, simulate},
};
use burn::tensor::Device;
use burn_quantum::{
Angle, Circuit, Matrix, Operation, Register, Result, Rotation, Unitary, gate::Axis, photonic::*,
};
pub use catalog::{DemoConfig, Preview, build_configured, preview};
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum DemoKind {
Bell,
Ghz,
Interference,
Qutrit,
PhotonicRouting,
MixedRegister,
Teleportation,
Toffoli,
Qft,
DeutschJozsa,
Qpe,
Grover,
Qaoa,
BitFlip,
Optimization,
}
impl DemoKind {
pub fn all() -> &'static [Self] {
&[
Self::Bell,
Self::Ghz,
Self::Interference,
Self::Qutrit,
Self::PhotonicRouting,
Self::MixedRegister,
Self::Teleportation,
Self::Toffoli,
Self::Qft,
Self::DeutschJozsa,
Self::Qpe,
Self::Grover,
Self::Qaoa,
Self::BitFlip,
Self::Optimization,
]
}
pub fn id(self) -> &'static str {
match self {
Self::Bell => "bell",
Self::Ghz => "ghz",
Self::Interference => "interference",
Self::Qutrit => "qutrit",
Self::PhotonicRouting => "photonic",
Self::MixedRegister => "mixed",
Self::Teleportation => "teleportation",
Self::Toffoli => "toffoli",
Self::Qft => "qft",
Self::DeutschJozsa => "deutsch-jozsa",
Self::Qpe => "qpe",
Self::Grover => "grover",
Self::Qaoa => "qaoa",
Self::BitFlip => "bit-flip",
Self::Optimization => "optimization",
}
}
pub fn from_id(id: &str) -> Option<Self> {
Self::all().iter().copied().find(|kind| kind.id() == id)
}
pub fn title(self) -> &'static str {
match self {
Self::Bell => "Bell entanglement",
Self::Ghz => "GHZ correlations",
Self::Interference => "Phase interference",
Self::Qutrit => "Qutrit Fourier",
Self::PhotonicRouting => "Photonic routing",
Self::MixedRegister => "Qubits & qutrits",
Self::Teleportation => "Quantum teleportation",
Self::Toffoli => "Toffoli / controlled X",
Self::Qft => "Quantum Fourier transform",
Self::DeutschJozsa => "Deutsch–Jozsa",
Self::Qpe => "Quantum phase estimation",
Self::Grover => "Grover search",
Self::Qaoa => "QAOA · MaxCut",
Self::BitFlip => "Bit-flip error correction",
Self::Optimization => "Quantum natural SPSA",
}
}
pub fn description(self) -> &'static str {
match self {
Self::Bell => {
"A Hadamard and CNOT prepare a Bell pair. Each entangled qubit has a maximally mixed reduced state at the Bloch-ball center, despite the pure global state."
}
Self::Ghz => {
"Configurable GHZ preparation. Local reduced states become mixed while the joint distribution retains only the all-zero and all-one correlations."
}
Self::Interference => {
"H, Rz(theta), H converts relative phase into population. The binding theta=pi gives destructive interference at zero. Complex amplitudes retain global phase."
}
Self::Qutrit => {
"A dimension-three Fourier transform, a sign on level two, and inverse Fourier transform. Qutrit reduced density matrices and probabilities are shown without assigning a qubit Bloch sphere."
}
Self::PhotonicRouting => {
"Two ideally supplied dual-rail Bell resources and their actual compiled packet/fusion schedule. Quantum frames show resource preparation only; link transmission is scheduling metadata, not an applied loss channel. No fusion success or output quantum state is assumed."
}
Self::MixedRegister => {
"Two entangled pairs with different local dimensions, alongside two pure qubits. Qudit panels show populations; their density matrices and purity retain coherence information."
}
Self::Teleportation => {
"A shared Bell pair, two projective measurements and classical X/Z corrections transfer Ry(1.1) Rz(0.7) input states to Bob. Each transfer has three quantum wires and two classical bits."
}
Self::Toffoli => {
"A Toffoli flips its target only when both controls are one. Increase controls to explore a structured multi-controlled X without a dense exponential gate matrix."
}
Self::Qft => {
"The positive-sign QFT includes final SWAPs, with wire zero most significant. Compare forward/inverse phase patterns for a computational-basis input."
}
Self::DeutschJozsa => {
"An n-input parity or constant-one promise oracle acts on a |−> ancilla. Hadamards reveal a balanced oracle through a nonzero input-register result."
}
Self::Qpe => {
"Counting qubits control powers of P(2π phase) on eigenstate |1>, followed by inverse QFT with bit reversal. Compare exactly representable and off-grid phases."
}
Self::Grover => {
"Uniform preparation, a single marked-state phase oracle and diffusion amplify one target. Compare near-optimal iterations with over-rotation; this simulator remains exponential."
}
Self::Qaoa => {
"Parameterized cost and mixer layers for a ring graph. Inspect the circuit and measured cut expectation as graph size and depth grow; angles are fixed, not trained in this example."
}
Self::BitFlip => {
"Odd-length repetition encoding, injected X errors and coherent majority decoding. The logical state returns to q0, while other wires retain the syndrome. Corrects bit flips only, up to half the code distance rounded down."
}
Self::Optimization => {
"One-parameter Ry ansatz minimizes measured Z expectation using the core QN-SPSA fidelity-metric estimator. Six async Burn loss/overlap probes per update, scalar running metric and absolute-value regularization; no shot noise. Frames are actual iterates, including the input. Seed 731; final circuit binding retained."
}
}
}
}
pub async fn build(
kind: DemoKind,
device: &Device,
limits: TraceLimits,
) -> Result<VisualizationDocument> {
build_configured(kind, DemoConfig::for_demo(kind), device, limits).await
}
async fn build_basic(
kind: DemoKind,
device: &Device,
limits: TraceLimits,
) -> Result<VisualizationDocument> {
if kind == DemoKind::Optimization {
return optimization::build(device, limits).await;
}
let (mut circuit, mut labels, parameters) = match kind {
DemoKind::Ghz => (Circuit::new(Register::qubits(4)?, 0, 0), vec![], vec![]),
DemoKind::Interference => (
Circuit::new(Register::qubits(1)?, 1, 0),
vec![],
vec![std::f64::consts::PI],
),
DemoKind::Qutrit => (Circuit::new(Register::new(vec![3])?, 0, 0), vec![], vec![]),
DemoKind::PhotonicRouting => (
Circuit::new(Register::new(vec![3; 4])?, 0, 0),
vec![],
vec![],
),
_ => (Circuit::new(Register::qubits(2)?, 0, 0), vec![], vec![]),
};
let mut fabric = None;
match kind {
DemoKind::Bell | DemoKind::Ghz => {
circuit.unitary(vec![0], Unitary::h())?;
labels.push("H on q0".into());
for q in 1..circuit.register().wires() {
circuit.unitary(vec![q - 1, q], Unitary::cnot())?;
labels.push(format!("CNOT q{} → q{q}", q - 1));
}
}
DemoKind::Interference => {
circuit.unitary(vec![0], Unitary::h())?;
circuit.rotate(0, Rotation::qubit(Axis::Z, Angle::parameter(0)))?;
circuit.unitary(vec![0], Unitary::h())?;
labels = vec![
"H: create paths".into(),
"Rz(theta): relative phase".into(),
"H: recombine paths".into(),
];
}
DemoKind::Qutrit => {
circuit.unitary(vec![0], Unitary::fourier(3)?)?;
circuit.unitary(
vec![0],
Unitary::new(Matrix::real(3, vec![1., 0., 0., 0., 1., 0., 0., 0., -1.])?)?,
)?;
circuit.unitary(vec![0], Unitary::fourier(3)?.adjoint())?;
labels = vec!["F3".into(), "Phase on level 2".into(), "F3 inverse".into()];
}
DemoKind::PhotonicRouting => {
let resource = ResourceState::bell_pair();
for offset in [0, 2] {
for op in resource.circuit()?.operations() {
let mapped = match op {
Operation::Unitary { wires, gate } => Operation::Unitary {
wires: wires.iter().map(|q| q + offset).collect(),
gate: gate.clone(),
},
Operation::PhaseFlip { controls } => Operation::PhaseFlip {
controls: controls.iter().map(|&(q, l)| (q + offset, l)).collect(),
},
_ => {
return Err(burn_quantum::Error::Unsupported(
"unexpected resource preparation instruction".into(),
));
}
};
circuit.push(mapped)?;
labels.push(format!(
"Bell resource {}: operation {}",
offset / 2 + 1,
labels.len() + 1
));
}
}
let mut program = FusionProgram::new();
let a = program.add_resource(resource.clone(), NodeId(0))?;
let b = program.add_resource(resource, NodeId(1))?;
program.fuse(a[1], b[0], NodeId(3))?;
let physical = Fabric::new(
vec![
NodeKind::Source,
NodeKind::Source,
NodeKind::Switch,
NodeKind::Fusion,
]
.into_iter()
.map(|kind| FabricNode {
kind,
storage: RailTransmission::uniform(0.999).unwrap(),
})
.collect(),
[(0, 2, 2, 0.98), (1, 2, 3, 0.97), (2, 3, 2, 0.96)]
.into_iter()
.map(|(from, to, ticks, eta)| {
Ok(FabricLink {
from: NodeId(from),
to: NodeId(to),
ticks,
transmission: RailTransmission::uniform(eta)?,
})
})
.collect::<Result<_>>()?,
)?;
fabric = Some(FabricSnapshot::from_compiled(
&program.compile(&physical, CompileOptions::default())?,
));
}
_ => unreachable!("configurable demos are handled by the catalog"),
}
let trace = simulate(&circuit, ¶meters, &[], &labels, device, limits).await?;
let document = VisualizationDocument {
schema_version: 1,
title: kind.title().into(),
description: kind.description().into(),
circuit,
parameters,
inputs: vec![],
operation_labels: labels,
trace,
fabric,
optimization: vec![],
protocol: None,
};
document.validate_with(limits)?;
Ok(document)
}