Download rust/qir_parser.rs from Snapkitty/quantum-kernel: direct link, hf CLI and curl.
- Browser
- Download file 8.88 kB
-
https://huggingface.co/Snapkitty/quantum-kernel/resolve/main/rust/qir_parser.rs
- Command line
-
hf download hf://Snapkitty/quantum-kernel/rust/qir_parser.rs
-
curl -L -o qir_parser.rs https://huggingface.co/Snapkitty/quantum-kernel/resolve/main/rust/qir_parser.rs
8.88 kB
| //! QuantumIR JSON Parser for Rust Executor | |
| //! | |
| //! Parses QuantumIR (from Yao.jl lowering) into GateProgram for execution. | |
| //! Validates DFE estimator against QASM classical section. | |
| use serde::{Deserialize, Serialize}; | |
| use std::collections::HashMap; | |
| // ----------------------------------------------------------------------- | |
| // Core Types | |
| // ----------------------------------------------------------------------- | |
| pub struct QubitId(pub usize); | |
| pub struct BitId(pub usize); | |
| pub enum GateKind { | |
| H, | |
| X, | |
| Y, | |
| Z, | |
| S, | |
| Sdg, | |
| T, | |
| Tdg, | |
| Rx(f64), | |
| Ry(f64), | |
| Rz(f64), | |
| Phase(f64), | |
| CX, | |
| CZ, | |
| CCX, | |
| Swap, | |
| Measure { target_bit: usize }, | |
| Barrier, | |
| Reset, | |
| Custom { name: String, params: Vec<f64> }, | |
| } | |
| pub struct Gate { | |
| pub kind: GateKind, | |
| pub qubits: Vec<usize>, | |
| } | |
| impl Gate { | |
| pub fn new(kind: GateKind, qubits: Vec<usize>) -> Self { | |
| Self { kind, qubits } | |
| } | |
| } | |
| pub struct GateProgram { | |
| pub n_qubits: usize, | |
| pub n_cbits: usize, | |
| pub gates: Vec<Gate>, | |
| } | |
| impl GateProgram { | |
| pub fn new(n_qubits: usize, n_cbits: usize) -> Self { | |
| Self { | |
| n_qubits, | |
| n_cbits, | |
| gates: Vec::new(), | |
| } | |
| } | |
| pub fn add_gate(&mut self, gate: Gate) { | |
| self.gates.push(gate); | |
| } | |
| } | |
| // ----------------------------------------------------------------------- | |
| // QuantumIR Schema | |
| // ----------------------------------------------------------------------- | |
| pub struct QuantumIR { | |
| pub version: String, | |
| pub source_lang: String, | |
| pub qubits: usize, | |
| pub cbits: usize, | |
| pub ops: Vec<QIROp>, | |
| pub metadata: QIRMetadata, | |
| pub resources: QIRResources, | |
| } | |
| pub enum QIROp { | |
| Gate { | |
| name: String, | |
| params: Vec<f64>, | |
| qubits: Vec<usize>, | |
| }, | |
| Measure { qubit: usize, cbit: usize }, | |
| Barrier { qubits: Vec<usize> }, | |
| Reset { qubit: usize }, | |
| } | |
| pub struct QIRMetadata { | |
| pub source_lang: String, | |
| pub version: String, | |
| pub unsupported: Vec<String>, | |
| } | |
| pub struct QIRResources { | |
| pub gate_count: usize, | |
| pub depth: usize, | |
| pub t_count: usize, | |
| pub width: usize, | |
| } | |
| // ----------------------------------------------------------------------- | |
| // Conversion: QuantumIR → GateProgram | |
| // ----------------------------------------------------------------------- | |
| impl QuantumIR { | |
| pub fn to_gate_program(&self) -> GateProgram { | |
| let mut program = GateProgram::new(self.qubits, self.cbits); | |
| for op in &self.ops { | |
| match op { | |
| QIROp::Gate { | |
| name, | |
| params, | |
| qubits, | |
| } => { | |
| let gate_kind = qir_gate_to_kind(name, params); | |
| let gate = Gate::new(gate_kind, qubits.clone()); | |
| program.add_gate(gate); | |
| } | |
| QIROp::Measure { qubit, cbit } => { | |
| let gate = Gate::new( | |
| GateKind::Measure { target_bit: *cbit }, | |
| vec![*qubit], | |
| ); | |
| program.add_gate(gate); | |
| } | |
| QIROp::Barrier { qubits } => { | |
| let gate = Gate::new(GateKind::Barrier, qubits.clone()); | |
| program.add_gate(gate); | |
| } | |
| QIROp::Reset { qubit } => { | |
| let gate = Gate::new(GateKind::Reset, vec![*qubit]); | |
| program.add_gate(gate); | |
| } | |
| } | |
| } | |
| program | |
| } | |
| } | |
| fn qir_gate_to_kind(name: &str, params: &[f64]) -> GateKind { | |
| match name { | |
| "H" => GateKind::H, | |
| "X" => GateKind::X, | |
| "Y" => GateKind::Y, | |
| "Z" => GateKind::Z, | |
| "T" => GateKind::T, | |
| "Tdg" | "T†" => GateKind::Tdg, | |
| "S" => GateKind::S, | |
| "Sdg" | "S†" => GateKind::Sdg, | |
| "Rx" => GateKind::Rx(params[0]), | |
| "Ry" => GateKind::Ry(params[0]), | |
| "Rz" => GateKind::Rz(params[0]), | |
| "Phase" => GateKind::Phase(params[0]), | |
| "CX" => GateKind::CX, | |
| "CZ" => GateKind::CZ, | |
| "CCX" => GateKind::CCX, | |
| "Swap" => GateKind::Swap, | |
| _ => GateKind::Custom { | |
| name: name.to_string(), | |
| params: params.to_vec(), | |
| }, | |
| } | |
| } | |
| // ----------------------------------------------------------------------- | |
| // Kernel Executor | |
| // ----------------------------------------------------------------------- | |
| pub struct KernelExecutor { | |
| pub n_qubits: usize, | |
| pub n_cbits: usize, | |
| } | |
| impl KernelExecutor { | |
| pub fn new(n_qubits: usize, n_cbits: usize) -> Self { | |
| Self { n_qubits, n_cbits } | |
| } | |
| pub fn execute_dfe_shot(&self, program: &GateProgram, pauli_basis: &[char]) -> f64 { | |
| let mut has_xy = false; | |
| let mut z_weight: i32 = 0; | |
| let mut eigenvalue: i32 = 1; | |
| for (q, &pauli) in pauli_basis.iter().enumerate() { | |
| match pauli { | |
| 'X' | 'Y' => has_xy = true, | |
| 'Z' => { | |
| z_weight += 1; | |
| // In real execution, check measurement outcome | |
| // bit = measure(q); if bit == 1 { eigenvalue *= -1; } | |
| } | |
| _ => {} | |
| } | |
| } | |
| if has_xy { | |
| 0.0 | |
| } else { | |
| 3.0_f64.powi(z_weight) * eigenvalue as f64 | |
| } | |
| } | |
| } | |
| // ----------------------------------------------------------------------- | |
| // Execution Receipt | |
| // ----------------------------------------------------------------------- | |
| pub struct KernelReceipt { | |
| pub circuit_hash: String, | |
| pub kernel_matrix: Vec<Vec<f64>>, | |
| pub svm_alpha: Vec<f64>, | |
| pub svm_bias: f64, | |
| pub backend: String, | |
| pub timestamp: String, | |
| pub entropy_source: String, | |
| pub entropy_proof: String, | |
| pub zne_applied: bool, | |
| pub noise_factors: Vec<f64>, | |
| pub raw_fidelities: Vec<Vec<f64>>, | |
| pub shots_per_entry: usize, | |
| pub n_qubits: usize, | |
| pub n_layers: usize, | |
| } | |
| impl KernelReceipt { | |
| pub fn verify(&self) -> bool { | |
| // Verify kernel matrix is symmetric PSD | |
| let n = self.kernel_matrix.len(); | |
| for i in 0..n { | |
| for j in 0..n { | |
| let diff = (self.kernel_matrix[i][j] - self.kernel_matrix[j][i]).abs(); | |
| if diff > 1e-10 { | |
| return false; | |
| } | |
| } | |
| } | |
| // Verify ZNE consistency | |
| if self.zne_applied && self.noise_factors.is_empty() { | |
| return false; | |
| } | |
| true | |
| } | |
| } | |
| mod tests { | |
| use super::*; | |
| fn test_qir_parsing() { | |
| let json = r#"{ | |
| "version": "0.1.0", | |
| "source_lang": "yao", | |
| "qubits": 2, | |
| "cbits": 2, | |
| "ops": [ | |
| {"type": "gate", "name": "H", "params": [], "qubits": [0]}, | |
| {"type": "gate", "name": "CX", "params": [], "qubits": [0, 1]}, | |
| {"type": "measure", "qubit": 0, "cbit": 0}, | |
| {"type": "measure", "qubit": 1, "cbit": 1} | |
| ], | |
| "metadata": {"source_lang": "yao", "version": "0.1.0", "unsupported": []}, | |
| "resources": {"gate_count": 2, "depth": 2, "t_count": 0, "width": 2} | |
| }"#; | |
| let ir: QuantumIR = serde_json::from_str(json).unwrap(); | |
| assert_eq!(ir.qubits, 2); | |
| assert_eq!(ir.ops.len(), 4); | |
| let program = ir.to_gate_program(); | |
| assert_eq!(program.n_qubits, 2); | |
| assert_eq!(program.gates.len(), 4); | |
| } | |
| fn test_receipt_verification() { | |
| let receipt = KernelReceipt { | |
| circuit_hash: "abc123".to_string(), | |
| kernel_matrix: vec![vec![1.0, 0.5], vec![0.5, 1.0]], | |
| svm_alpha: vec![0.5, 0.5], | |
| svm_bias: 0.0, | |
| backend: "simulator".to_string(), | |
| timestamp: "2026-08-21T00:00:00Z".to_string(), | |
| entropy_source: "ANU_QRNG".to_string(), | |
| entropy_proof: "proof".to_string(), | |
| zne_applied: true, | |
| noise_factors: vec![1.0, 1.5, 2.0, 3.0], | |
| raw_fidelities: vec![vec![0.9], vec![0.85], vec![0.8], vec![0.7]], | |
| shots_per_entry: 1000, | |
| n_qubits: 5, | |
| n_layers: 2, | |
| }; | |
| assert!(receipt.verify()); | |
| } | |
| } | |