SNAPKITTYWEST's picture
chore: push full sov-kernel-monster content from local build
9425aed verified
Raw
History Blame Contribute Delete
13.9 kB
//! Example: Complete Phase 2 Quantum Backend Setup & Noise Application
//!
//! Demonstrates:
//! 1. Backend contract creation (5-qubit device)
//! 2. Calibration binding with WORM hash
//! 3. Topology queries
//! 4. Noise channel application
//! 5. Trace/PSD verification
use phase2_quantum_backend::backend_contract::*;
use phase2_quantum_backend::noise_channel::*;
use phase2_quantum_backend::topology::*;
use std::collections::{BTreeMap, HashMap};
use tch::{Device, Kind, Tensor};
fn main() {
println!("=== Phase 2 Quantum Backend Example ===\n");
// ─────────────────────────────────────────────────────────────
// STEP 1: Define 5-Qubit Linear Topology
// ─────────────────────────────────────────────────────────────
println!("Step 1: Create 5-qubit linear topology");
let mut connectivity = vec![vec![false; 5]; 5];
for i in 0..5 {
connectivity[i][i] = true; // self-loops
if i + 1 < 5 {
connectivity[i][i + 1] = true;
connectivity[i + 1][i] = true;
}
}
let coupling_graph = CouplingGraph::new(connectivity).unwrap();
println!("βœ“ Linear topology: 0-1-2-3-4\n");
// ─────────────────────────────────────────────────────────────
// STEP 2: Create Per-Qubit Calibrations
// ─────────────────────────────────────────────────────────────
println!("Step 2: Create per-qubit calibrations");
let mut qubit_cals = BTreeMap::new();
for q in 0..5 {
let cal = QubitCalibration::new(
q,
5.0 + q as f64 * 0.05, // frequency: 5.0-5.2 GHz
100.0, // T1: 100 ΞΌs
50.0, // T2: 50 ΞΌs (T2 < T1 βœ“)
0.001, // 1-qubit error: 0.1%
0.01, // 2-qubit error: 1%
0.02, // readout 0β†’1: 2%
0.01, // readout 1β†’0: 1%
).unwrap();
qubit_cals.insert(q, cal);
}
println!("βœ“ Calibrated {} qubits\n", qubit_cals.len());
// ─────────────────────────────────────────────────────────────
// STEP 3: Create Calibration Snapshot with Hash
// ─────────────────────────────────────────────────────────────
println!("Step 3: Create calibration snapshot (WORM binding)");
let calibration = CalibrationSnapshot::new(
"ibm_fake_device_5q".to_string(),
1234567890,
qubit_cals,
BTreeMap::new(),
).unwrap();
println!("βœ“ Device: {}", calibration.device_id);
println!("βœ“ Calibration hash: {}\n", &calibration.calibration_hash[..16]);
let cal_hash = calibration.calibration_hash.clone();
// ─────────────────────────────────────────────────────────────
// STEP 4: Define Native Gates & Timing
// ─────────────────────────────────────────────────────────────
println!("Step 4: Define native gates and timing constraints");
let native_gates = vec![
NativeGate::H,
NativeGate::X,
NativeGate::Y,
NativeGate::Z,
NativeGate::Rx,
NativeGate::CX,
NativeGate::CZ,
];
let timing = TimingConstraints::new(
10.0, // min gate duration: 10 ns
100.0, // max gate duration: 100 ns
200.0, // measurement window: 200 ns
500.0, // reset time: 500 ns
10000.0, // coherence limit: 10000 ns (10 ΞΌs)
).unwrap();
println!("βœ“ Native gates: {:?}", native_gates);
println!("βœ“ Timing: [{:.0}, {:.0}] ns\n", 10.0, 100.0);
// ─────────────────────────────────────────────────────────────
// STEP 5: Construct Full Backend Contract
// ─────────────────────────────────────────────────────────────
println!("Step 5: Construct full backend contract");
let backend = QuantumBackend::new(
5,
coupling_graph,
native_gates,
HashMap::new(),
calibration,
timing,
).unwrap();
println!("βœ“ Backend hash: {}", &backend.backend_hash[..16]);
println!("βœ“ Contract validated βœ“\n");
// ─────────────────────────────────────────────────────────────
// STEP 6: Topology Queries
// ─────────────────────────────────────────────────────────────
println!("Step 6: Topology analysis");
let is_linear = TopologyAnalyzer::is_linear(&backend.coupling_graph).unwrap();
println!("βœ“ Is linear: {}", is_linear);
let diameter = TopologyAnalyzer::diameter(&backend.coupling_graph).unwrap();
println!("βœ“ Diameter: {}", diameter);
let path = TopologyAnalyzer::shortest_path(&backend.coupling_graph, 0, 4).unwrap();
println!("βœ“ Shortest path (0β†’4): {:?}", path);
let avg_degree = TopologyAnalyzer::average_degree(&backend.coupling_graph).unwrap();
println!("βœ“ Average degree: {:.2}\n", avg_degree);
// ─────────────────────────────────────────────────────────────
// STEP 7: Apply Noise Channels
// ─────────────────────────────────────────────────────────────
println!("Step 7: Apply noise channels");
// Create maximally mixed initial state
let rho_init = Tensor::eye(2, (Kind::Double, Device::Cpu)) * 0.5;
println!("βœ“ Initial state: maximally mixed I/2");
// ─────────────────────────────────────────────────────────────
// 7a. Depolarizing noise
// ─────────────────────────────────────────────────────────────
let depo_channel = DepolarizingChannel::new(0.01).unwrap();
let rho_depo = depo_channel.apply(&rho_init).unwrap();
let trace_depo: f64 = rho_depo.trace().double_value(&[]);
println!("\n7a. Depolarizing (p=0.01):");
println!(" Trace: {:.15}", trace_depo);
println!(" βœ“ Trace β‰ˆ 1 (error: {:.2e})", (trace_depo - 1.0).abs());
// ─────────────────────────────────────────────────────────────
// 7b. Amplitude damping
// ─────────────────────────────────────────────────────────────
let amp_channel = AmplitudeDampingChannel::new(0.05).unwrap();
let rho_amp = amp_channel.apply(&rho_init).unwrap();
let trace_amp: f64 = rho_amp.trace().double_value(&[]);
println!("\n7b. Amplitude damping (Ξ³=0.05):");
println!(" Trace: {:.15}", trace_amp);
println!(" βœ“ Trace β‰ˆ 1 (error: {:.2e})", (trace_amp - 1.0).abs());
// ─────────────────────────────────────────────────────────────
// 7c. Phase damping
// ─────────────────────────────────────────────────────────────
let phase_channel = PhaseDampingChannel::new(0.03).unwrap();
let rho_phase = phase_channel.apply(&rho_init).unwrap();
let trace_phase: f64 = rho_phase.trace().double_value(&[]);
println!("\n7c. Phase damping (Ξ³=0.03):");
println!(" Trace: {:.15}", trace_phase);
println!(" βœ“ Trace β‰ˆ 1 (error: {:.2e})", (trace_phase - 1.0).abs());
// ─────────────────────────────────────────────────────────────
// 7d. Readout error
// ─────────────────────────────────────────────────────────────
let readout_channel = ReadoutErrorChannel::new(0.02, 0.01).unwrap();
let rho_readout = readout_channel.apply(&rho_init).unwrap();
let trace_readout: f64 = rho_readout.trace().double_value(&[]);
println!("\n7d. Readout error (p_01=0.02, p_10=0.01):");
println!(" Trace: {:.15}", trace_readout);
println!(" βœ“ Trace β‰ˆ 1 (error: {:.2e})", (trace_readout - 1.0).abs());
// ─────────────────────────────────────────────────────────────
// 7e. Pauli channel
// ─────────────────────────────────────────────────────────────
let pauli_channel = PauliChannel::new(0.01, 0.01, 0.02).unwrap();
let rho_pauli = pauli_channel.apply(&rho_init).unwrap();
let trace_pauli: f64 = rho_pauli.trace().double_value(&[]);
println!("\n7e. Pauli channel (px=0.01, py=0.01, pz=0.02):");
println!(" Trace: {:.15}", trace_pauli);
println!(" βœ“ Trace β‰ˆ 1 (error: {:.2e})", (trace_pauli - 1.0).abs());
// ─────────────────────────────────────────────────────────────
// STEP 8: Verify PSD (Positive Semi-Definiteness)
// ─────────────────────────────────────────────────────────────
println!("\n\nStep 8: Verify positive semi-definiteness");
let verify_psd = |name: &str, rho: &Tensor| {
let (evals, _) = rho.linalg_eigh("L");
let min_eval: f64 = evals.min().double_value(&[]);
println!("{}: min eigenvalue = {:.2e}", name, min_eval);
assert!(
min_eval >= -1e-10,
"PSD violated for {}",
name
);
println!(" βœ“ PSD preserved");
};
verify_psd("Depolarizing", &rho_depo);
verify_psd("Amplitude damping", &rho_amp);
verify_psd("Phase damping", &rho_phase);
verify_psd("Readout error", &rho_readout);
verify_psd("Pauli", &rho_pauli);
// ─────────────────────────────────────────────────────────────
// STEP 9: Verify Kraus Trace Preservation
// ─────────────────────────────────────────────────────────────
println!("\n\nStep 9: Verify Kraus trace preservation (Ξ£ E_k† E_k = I)");
depo_channel.verify_trace_preservation().unwrap();
println!("βœ“ Depolarizing: Ξ£ E_k† E_k = I");
amp_channel.verify_trace_preservation().unwrap();
println!("βœ“ Amplitude damping: Ξ£ E_k† E_k = I");
phase_channel.verify_trace_preservation().unwrap();
println!("βœ“ Phase damping: Ξ£ E_k† E_k = I");
readout_channel.verify_trace_preservation().unwrap();
println!("βœ“ Readout error: Ξ£ E_k† E_k = I");
pauli_channel.verify_trace_preservation().unwrap();
println!("βœ“ Pauli channel: Ξ£ E_k† E_k = I");
// ─────────────────────────────────────────────────────────────
// SUMMARY
// ─────────────────────────────────────────────────────────────
println!("\n\n=== Summary ===");
println!("βœ“ Backend contract created & validated");
println!("βœ“ Calibration snapshot: {} hash", &cal_hash[..16]);
println!("βœ“ Topology: {} qubits, linear path", 5);
println!("βœ“ All 5 noise channels working");
println!("βœ“ Trace preservation: 100%");
println!("βœ“ PSD preservation: 100%");
println!("βœ“ Kraus trace condition: All verified βœ“");
println!("\n=== Phase 2 Complete ===");
}