1use crate::{
8 error::{QuantRS2Error, QuantRS2Result},
9 gate::GateOp,
10 matrix_ops::DenseMatrix,
11 pulse::PulseSequence,
12 qubit::QubitId,
13 synthesis::decompose_two_qubit_kak,
14};
15use ndarray::Array2;
16use std::{
17 collections::{HashMap, HashSet},
18 sync::{Arc, RwLock},
19 time::{Duration, Instant},
20};
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24pub enum HardwarePlatform {
25 Superconducting,
27 TrappedIon,
29 Photonic,
31 NeutralAtom,
33 SiliconQuantumDot,
35 Topological,
37 Universal,
39}
40
41#[derive(Debug, Clone)]
43pub struct NativeGateSet {
44 pub single_qubit_gates: Vec<NativeGateType>,
46 pub two_qubit_gates: Vec<NativeGateType>,
48 pub multi_qubit_gates: Vec<NativeGateType>,
50 pub parametric_constraints: HashMap<NativeGateType, ParameterConstraints>,
52 pub gate_fidelities: HashMap<NativeGateType, f64>,
54 pub gate_durations: HashMap<NativeGateType, Duration>,
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
60pub enum NativeGateType {
61 X,
63 Y,
64 Z,
65 Rx,
66 Ry,
67 Rz,
68 SqrtX,
69 SqrtY,
70 H,
71 S,
72 T,
73 Phase,
74
75 CNOT,
77 CZ,
78 CY,
79 XX,
80 YY,
81 ZZ,
82 MS, Iswap,
84 SqrtIswap,
85
86 Toffoli,
88 Fredkin,
89 GlobalPhase,
90
91 VirtualZ, BeamSplitter, Rydberg, }
96
97#[derive(Debug, Clone)]
99pub struct ParameterConstraints {
100 pub min_value: f64,
102 pub max_value: f64,
104 pub granularity: f64,
106 pub discrete_values: Option<Vec<f64>>,
108}
109
110#[derive(Debug, Clone)]
112pub struct HardwareTopology {
113 pub connectivity: HashMap<QubitId, HashSet<QubitId>>,
115 pub qubit_positions: HashMap<QubitId, (f64, f64, f64)>,
117 pub coupling_strengths: HashMap<(QubitId, QubitId), f64>,
119 pub crosstalk_matrix: Array2<f64>,
121 pub max_parallel_ops: usize,
123}
124
125#[derive(Debug, Clone)]
127pub struct HardwareCompilationConfig {
128 pub platform: HardwarePlatform,
130 pub native_gates: NativeGateSet,
132 pub topology: HardwareTopology,
134 pub optimization_objectives: Vec<OptimizationObjective>,
136 pub tolerances: CompilationTolerances,
138 pub enable_crosstalk_mitigation: bool,
140 pub use_pulse_optimization: bool,
142}
143
144#[derive(Debug, Clone, Copy, PartialEq, Eq)]
146pub enum OptimizationObjective {
147 MinimizeGateCount,
149 MinimizeDepth,
151 MaximizeFidelity,
153 MinimizeTime,
155 MinimizeCrosstalk,
157 Balanced,
159}
160
161#[derive(Debug, Clone)]
163pub struct CompilationTolerances {
164 pub decomposition_tolerance: f64,
166 pub parameter_tolerance: f64,
168 pub fidelity_threshold: f64,
170 pub max_compilation_time: Duration,
172}
173
174#[derive(Debug)]
176pub struct HardwareCompiler {
177 config: HardwareCompilationConfig,
178 decomposition_cache: Arc<RwLock<DecompositionCache>>,
179 optimization_engine: Arc<RwLock<HardwareOptimizationEngine>>,
180 performance_monitor: Arc<RwLock<CompilationPerformanceMonitor>>,
181}
182
183#[derive(Debug)]
185pub struct DecompositionCache {
186 single_qubit_cache: HashMap<String, Vec<CompiledGate>>,
188 two_qubit_cache: HashMap<String, Vec<CompiledGate>>,
190 cache_stats: CacheStatistics,
192}
193
194#[derive(Debug, Clone)]
196pub struct CompiledGate {
197 pub gate_type: NativeGateType,
199 pub qubits: Vec<QubitId>,
201 pub parameters: Vec<f64>,
203 pub fidelity: f64,
205 pub duration: Duration,
207 pub pulse_sequence: Option<PulseSequence>,
209}
210
211#[derive(Debug)]
213pub struct HardwareOptimizationEngine {
214 optimizers: HashMap<HardwarePlatform, Box<dyn PlatformOptimizer>>,
216 optimization_history: Vec<OptimizationRecord>,
218}
219
220pub trait PlatformOptimizer: std::fmt::Debug + Send + Sync {
222 fn optimize_sequence(
224 &self,
225 gates: &[CompiledGate],
226 config: &HardwareCompilationConfig,
227 ) -> QuantRS2Result<OptimizedSequence>;
228
229 fn estimate_fidelity(&self, sequence: &[CompiledGate]) -> f64;
231
232 fn get_constraints(&self) -> PlatformConstraints;
234}
235
236#[derive(Debug, Clone)]
238pub struct OptimizedSequence {
239 pub gates: Vec<CompiledGate>,
241 pub total_fidelity: f64,
243 pub total_time: Duration,
245 pub metrics: OptimizationMetrics,
247}
248
249#[derive(Debug, Clone)]
251pub struct PlatformConstraints {
252 pub max_qubits: usize,
254 pub gate_limitations: Vec<GateLimitation>,
256 pub timing_constraints: TimingConstraints,
258 pub error_model: ErrorModel,
260}
261
262#[derive(Debug, Clone)]
264pub enum GateLimitation {
265 DiscreteParameters(NativeGateType, Vec<f64>),
267 RestrictedConnectivity(NativeGateType, Vec<(QubitId, QubitId)>),
269 CoherenceLimit(NativeGateType, Duration),
271 RequiresCalibration(NativeGateType),
273}
274
275#[derive(Debug, Clone)]
277pub struct TimingConstraints {
278 pub min_gate_separation: Duration,
280 pub max_parallel_ops: usize,
282 pub qubit_timing: HashMap<QubitId, Duration>,
284}
285
286#[derive(Debug, Clone)]
288pub struct ErrorModel {
289 pub single_qubit_errors: HashMap<NativeGateType, f64>,
291 pub two_qubit_errors: HashMap<NativeGateType, f64>,
293 pub readout_errors: HashMap<QubitId, f64>,
295 pub idle_decay_rates: HashMap<QubitId, f64>,
297}
298
299#[derive(Debug)]
301pub struct CompilationPerformanceMonitor {
302 compilation_times: Vec<Duration>,
304 gate_count_reductions: Vec<f64>,
306 fidelity_improvements: Vec<f64>,
308 cache_hit_rates: Vec<f64>,
310}
311
312#[derive(Debug, Clone)]
314pub struct OptimizationMetrics {
315 pub original_gate_count: usize,
317 pub optimized_gate_count: usize,
319 pub gate_count_reduction: f64,
321 pub original_depth: usize,
323 pub optimized_depth: usize,
325 pub depth_reduction: f64,
327 pub fidelity_improvement: f64,
329 pub compilation_time: Duration,
331}
332
333#[derive(Debug, Clone)]
335pub struct OptimizationRecord {
336 pub timestamp: Instant,
338 pub platform: HardwarePlatform,
340 pub input_gates: usize,
342 pub output_gates: usize,
344 pub metrics: OptimizationMetrics,
346}
347
348#[derive(Debug, Clone, Default)]
350pub struct CacheStatistics {
351 pub total_requests: u64,
353 pub cache_hits: u64,
355 pub cache_misses: u64,
357 pub hit_rate: f64,
359}
360
361impl HardwareCompiler {
362 pub fn new(config: HardwareCompilationConfig) -> QuantRS2Result<Self> {
364 let decomposition_cache = Arc::new(RwLock::new(DecompositionCache::new()));
365 let optimization_engine = Arc::new(RwLock::new(HardwareOptimizationEngine::new(&config)?));
366 let performance_monitor = Arc::new(RwLock::new(CompilationPerformanceMonitor::new()));
367
368 Ok(Self {
369 config,
370 decomposition_cache,
371 optimization_engine,
372 performance_monitor,
373 })
374 }
375
376 pub fn compile_gate(
378 &self,
379 gate: &dyn GateOp,
380 qubits: &[QubitId],
381 ) -> QuantRS2Result<Vec<CompiledGate>> {
382 let start_time = Instant::now();
383
384 let cache_key = self.generate_cache_key(gate, qubits);
386 if let Some(cached_result) = self.check_cache(&cache_key)? {
387 self.record_cache_hit();
388 return Ok(cached_result);
389 }
390
391 self.record_cache_miss();
392
393 let compiled_gates = match qubits.len() {
395 1 => self.compile_single_qubit_gate(gate, qubits[0])?,
396 2 => self.compile_two_qubit_gate(gate, qubits[0], qubits[1])?,
397 _ => self.compile_multi_qubit_gate(gate, qubits)?,
398 };
399
400 let optimized_gates = self.optimize_for_platform(&compiled_gates)?;
402
403 self.cache_result(&cache_key, &optimized_gates)?;
405
406 let compilation_time = start_time.elapsed();
407 self.record_compilation_time(compilation_time);
408
409 Ok(optimized_gates)
410 }
411
412 fn compile_single_qubit_gate(
414 &self,
415 gate: &dyn GateOp,
416 qubit: QubitId,
417 ) -> QuantRS2Result<Vec<CompiledGate>> {
418 let matrix_vec = gate.matrix()?;
419 let matrix = DenseMatrix::from_vec(matrix_vec, 2)?; if let Some(native_gate) = self.find_native_single_qubit_gate(&matrix)? {
423 return Ok(vec![native_gate]);
424 }
425
426 match self.config.platform {
428 HardwarePlatform::Superconducting => {
429 self.decompose_for_superconducting_single(gate, qubit)
430 }
431 HardwarePlatform::TrappedIon => self.decompose_for_trapped_ion_single(gate, qubit),
432 HardwarePlatform::Photonic => self.decompose_for_photonic_single(gate, qubit),
433 HardwarePlatform::NeutralAtom => self.decompose_for_neutral_atom_single(gate, qubit),
434 _ => self.decompose_universal_single(gate, qubit),
435 }
436 }
437
438 fn compile_two_qubit_gate(
440 &self,
441 gate: &dyn GateOp,
442 qubit1: QubitId,
443 qubit2: QubitId,
444 ) -> QuantRS2Result<Vec<CompiledGate>> {
445 if !self.check_connectivity(qubit1, qubit2)? {
447 return self.handle_connectivity_constraint(gate, qubit1, qubit2);
448 }
449
450 let matrix_vec = gate.matrix()?;
451 let matrix = DenseMatrix::from_vec(matrix_vec, 4)?; if let Some(native_gate) = self.find_native_two_qubit_gate(&matrix, qubit1, qubit2)? {
455 return Ok(vec![native_gate]);
456 }
457
458 match self.config.platform {
460 HardwarePlatform::Superconducting => {
461 self.decompose_for_superconducting_two(gate, qubit1, qubit2)
462 }
463 HardwarePlatform::TrappedIon => {
464 self.decompose_for_trapped_ion_two(gate, qubit1, qubit2)
465 }
466 HardwarePlatform::Photonic => self.decompose_for_photonic_two(gate, qubit1, qubit2),
467 HardwarePlatform::NeutralAtom => {
468 self.decompose_for_neutral_atom_two(gate, qubit1, qubit2)
469 }
470 _ => self.decompose_universal_two(gate, qubit1, qubit2),
471 }
472 }
473
474 fn compile_multi_qubit_gate(
476 &self,
477 gate: &dyn GateOp,
478 qubits: &[QubitId],
479 ) -> QuantRS2Result<Vec<CompiledGate>> {
480 if self.config.native_gates.multi_qubit_gates.is_empty() {
482 return self.decompose_to_two_qubit_gates(gate, qubits);
483 }
484
485 match self.config.platform {
487 HardwarePlatform::TrappedIon => self.compile_trapped_ion_multi(gate, qubits),
488 HardwarePlatform::NeutralAtom => self.compile_neutral_atom_multi(gate, qubits),
489 _ => self.decompose_to_two_qubit_gates(gate, qubits),
490 }
491 }
492
493 fn decompose_for_superconducting_single(
495 &self,
496 gate: &dyn GateOp,
497 qubit: QubitId,
498 ) -> QuantRS2Result<Vec<CompiledGate>> {
499 let matrix_vec = gate.matrix()?;
500 let matrix = DenseMatrix::from_vec(matrix_vec, 2)?; if self.is_z_rotation(&matrix)? {
504 let angle = self.extract_z_rotation_angle(&matrix)?;
505 return Ok(vec![CompiledGate {
506 gate_type: NativeGateType::VirtualZ,
507 qubits: vec![qubit],
508 parameters: vec![angle],
509 fidelity: 1.0, duration: Duration::from_nanos(0), pulse_sequence: None,
512 }]);
513 }
514
515 let decomposition = self.decompose_to_rx_rz(&matrix)?;
517 let mut compiled_gates = Vec::new();
518
519 for (gate_type, angle) in decomposition {
520 compiled_gates.push(CompiledGate {
521 gate_type,
522 qubits: vec![qubit],
523 parameters: vec![angle],
524 fidelity: self.get_gate_fidelity(gate_type),
525 duration: self.get_gate_duration(gate_type),
526 pulse_sequence: self.generate_pulse_sequence(gate_type, &[angle])?,
527 });
528 }
529
530 Ok(compiled_gates)
531 }
532
533 fn decompose_for_trapped_ion_single(
535 &self,
536 gate: &dyn GateOp,
537 qubit: QubitId,
538 ) -> QuantRS2Result<Vec<CompiledGate>> {
539 let matrix_vec = gate.matrix()?;
540 let matrix = DenseMatrix::from_vec(matrix_vec, 2)?; let (theta, phi, lambda) = self.extract_euler_angles(&matrix)?;
544
545 let mut compiled_gates = Vec::new();
546
547 if lambda.abs() > self.config.tolerances.parameter_tolerance {
549 compiled_gates.push(CompiledGate {
550 gate_type: NativeGateType::Rz,
551 qubits: vec![qubit],
552 parameters: vec![lambda],
553 fidelity: self.get_gate_fidelity(NativeGateType::Rz),
554 duration: self.get_gate_duration(NativeGateType::Rz),
555 pulse_sequence: self.generate_pulse_sequence(NativeGateType::Rz, &[lambda])?,
556 });
557 }
558
559 if theta.abs() > self.config.tolerances.parameter_tolerance {
561 compiled_gates.push(CompiledGate {
562 gate_type: NativeGateType::Ry,
563 qubits: vec![qubit],
564 parameters: vec![theta],
565 fidelity: self.get_gate_fidelity(NativeGateType::Ry),
566 duration: self.get_gate_duration(NativeGateType::Ry),
567 pulse_sequence: self.generate_pulse_sequence(NativeGateType::Ry, &[theta])?,
568 });
569 }
570
571 if phi.abs() > self.config.tolerances.parameter_tolerance {
573 compiled_gates.push(CompiledGate {
574 gate_type: NativeGateType::Rz,
575 qubits: vec![qubit],
576 parameters: vec![phi],
577 fidelity: self.get_gate_fidelity(NativeGateType::Rz),
578 duration: self.get_gate_duration(NativeGateType::Rz),
579 pulse_sequence: self.generate_pulse_sequence(NativeGateType::Rz, &[phi])?,
580 });
581 }
582
583 Ok(compiled_gates)
584 }
585
586 fn decompose_for_superconducting_two(
588 &self,
589 gate: &dyn GateOp,
590 qubit1: QubitId,
591 qubit2: QubitId,
592 ) -> QuantRS2Result<Vec<CompiledGate>> {
593 let matrix_vec = gate.matrix()?;
594 let matrix = DenseMatrix::from_vec(matrix_vec, 4)?; let kak_decomp = decompose_two_qubit_kak(&matrix.as_array().view())?;
598 let mut compiled_gates = Vec::new();
599
600 let (_left_gate1, _left_gate2) = &kak_decomp.left_gates;
602 let interaction_strength = (kak_decomp.interaction.xx.abs()
607 + kak_decomp.interaction.yy.abs()
608 + kak_decomp.interaction.zz.abs())
609 .max(0.01);
610 let native_two_qubit = self.get_native_two_qubit_gate();
611
612 if interaction_strength > 0.01 {
614 compiled_gates.push(CompiledGate {
615 gate_type: native_two_qubit,
616 qubits: vec![qubit1, qubit2],
617 parameters: vec![interaction_strength],
618 fidelity: self.get_gate_fidelity(native_two_qubit),
619 duration: self.get_gate_duration(native_two_qubit),
620 pulse_sequence: self
621 .generate_pulse_sequence(native_two_qubit, &[interaction_strength])?,
622 });
623 }
624
625 let (_right_gate1, _right_gate2) = &kak_decomp.right_gates;
627 Ok(compiled_gates)
631 }
632
633 fn decompose_for_trapped_ion_two(
635 &self,
636 gate: &dyn GateOp,
637 qubit1: QubitId,
638 qubit2: QubitId,
639 ) -> QuantRS2Result<Vec<CompiledGate>> {
640 let matrix_vec = gate.matrix()?;
641 let matrix = DenseMatrix::from_vec(matrix_vec, 4)?; let ms_decomp = self.decompose_to_ms_gates(&matrix)?;
645 let mut compiled_gates = Vec::new();
646
647 for ms_gate in ms_decomp {
648 compiled_gates.push(CompiledGate {
649 gate_type: NativeGateType::MS,
650 qubits: vec![qubit1, qubit2],
651 parameters: ms_gate.parameters.clone(),
652 fidelity: self.get_gate_fidelity(NativeGateType::MS),
653 duration: self.get_gate_duration(NativeGateType::MS),
654 pulse_sequence: self
655 .generate_pulse_sequence(NativeGateType::MS, &ms_gate.parameters)?,
656 });
657 }
658
659 Ok(compiled_gates)
660 }
661
662 fn check_connectivity(&self, qubit1: QubitId, qubit2: QubitId) -> QuantRS2Result<bool> {
664 if let Some(neighbors) = self.config.topology.connectivity.get(&qubit1) {
665 Ok(neighbors.contains(&qubit2))
666 } else {
667 Ok(false)
668 }
669 }
670
671 fn handle_connectivity_constraint(
673 &self,
674 gate: &dyn GateOp,
675 qubit1: QubitId,
676 qubit2: QubitId,
677 ) -> QuantRS2Result<Vec<CompiledGate>> {
678 let path = self.find_shortest_path(qubit1, qubit2)?;
680 let mut compiled_gates = Vec::new();
681
682 for i in 0..path.len() - 2 {
684 compiled_gates.push(CompiledGate {
685 gate_type: NativeGateType::CNOT, qubits: vec![path[i], path[i + 1]],
687 parameters: vec![],
688 fidelity: self.get_gate_fidelity(NativeGateType::CNOT).powi(3),
689 duration: self.get_gate_duration(NativeGateType::CNOT) * 3,
690 pulse_sequence: None,
691 });
692 }
693
694 let original_gate_compiled =
696 self.compile_two_qubit_gate(gate, path[path.len() - 2], path[path.len() - 1])?;
697 compiled_gates.extend(original_gate_compiled);
698
699 for i in (0..path.len() - 2).rev() {
701 compiled_gates.push(CompiledGate {
702 gate_type: NativeGateType::CNOT,
703 qubits: vec![path[i], path[i + 1]],
704 parameters: vec![],
705 fidelity: self.get_gate_fidelity(NativeGateType::CNOT).powi(3),
706 duration: self.get_gate_duration(NativeGateType::CNOT) * 3,
707 pulse_sequence: None,
708 });
709 }
710
711 Ok(compiled_gates)
712 }
713
714 fn find_shortest_path(&self, start: QubitId, end: QubitId) -> QuantRS2Result<Vec<QubitId>> {
716 use std::collections::VecDeque;
718
719 let mut queue = VecDeque::new();
720 let mut visited = HashSet::new();
721 let mut parent = HashMap::new();
722
723 queue.push_back(start);
724 visited.insert(start);
725
726 while let Some(current) = queue.pop_front() {
727 if current == end {
728 let mut path = Vec::new();
730 let mut curr = end;
731 path.push(curr);
732
733 while let Some(&prev) = parent.get(&curr) {
734 path.push(prev);
735 curr = prev;
736 }
737
738 path.reverse();
739 return Ok(path);
740 }
741
742 if let Some(neighbors) = self.config.topology.connectivity.get(¤t) {
743 for &neighbor in neighbors {
744 if !visited.contains(&neighbor) {
745 visited.insert(neighbor);
746 parent.insert(neighbor, current);
747 queue.push_back(neighbor);
748 }
749 }
750 }
751 }
752
753 Err(QuantRS2Error::InvalidParameter(format!(
754 "No path found between qubits {:?} and {:?}",
755 start, end
756 )))
757 }
758
759 fn optimize_for_platform(&self, gates: &[CompiledGate]) -> QuantRS2Result<Vec<CompiledGate>> {
761 let engine = self.optimization_engine.read().unwrap();
762
763 if let Some(optimizer) = engine.optimizers.get(&self.config.platform) {
764 let optimized = optimizer.optimize_sequence(gates, &self.config)?;
765 Ok(optimized.gates)
766 } else {
767 Ok(gates.to_vec())
769 }
770 }
771
772 fn is_z_rotation(&self, matrix: &DenseMatrix) -> QuantRS2Result<bool> {
774 let tolerance = self.config.tolerances.decomposition_tolerance;
776
777 let arr = matrix.as_array();
779 if arr[(0, 1)].norm() > tolerance || arr[(1, 0)].norm() > tolerance {
780 return Ok(false);
781 }
782
783 Ok(true)
784 }
785
786 fn extract_z_rotation_angle(&self, matrix: &DenseMatrix) -> QuantRS2Result<f64> {
787 let arr = matrix.as_array();
788 let z00 = arr[(0, 0)];
789 let z11 = arr[(1, 1)];
790
791 let angle = (z11 / z00).arg();
793 Ok(angle)
794 }
795
796 fn decompose_to_rx_rz(
797 &self,
798 matrix: &DenseMatrix,
799 ) -> QuantRS2Result<Vec<(NativeGateType, f64)>> {
800 let (theta, phi, lambda) = self.extract_euler_angles(matrix)?;
802
803 let mut decomposition = Vec::new();
804
805 if lambda.abs() > self.config.tolerances.parameter_tolerance {
806 decomposition.push((NativeGateType::Rz, lambda));
807 }
808 if theta.abs() > self.config.tolerances.parameter_tolerance {
809 decomposition.push((NativeGateType::Rx, theta));
810 }
811 if phi.abs() > self.config.tolerances.parameter_tolerance {
812 decomposition.push((NativeGateType::Rz, phi));
813 }
814
815 Ok(decomposition)
816 }
817
818 fn extract_euler_angles(&self, matrix: &DenseMatrix) -> QuantRS2Result<(f64, f64, f64)> {
819 let arr = matrix.as_array();
821 let u00 = arr[(0, 0)];
822 let u01 = arr[(0, 1)];
823 let u10 = arr[(1, 0)];
824 let u11 = arr[(1, 1)];
825
826 let theta: f64 = 2.0 * (u01.norm()).asin(); let phi = if theta.abs() < 1e-10 {
828 0.0
829 } else {
830 (u11 / u00).arg() + (u01 / (-u10)).arg()
831 };
832 let lambda = if theta.abs() < 1e-10 {
833 (u11 / u00).arg()
834 } else {
835 (u11 / u00).arg() - (u01 / (-u10)).arg()
836 };
837
838 Ok((theta, phi, lambda))
839 }
840
841 fn get_gate_fidelity(&self, gate_type: NativeGateType) -> f64 {
842 self.config
843 .native_gates
844 .gate_fidelities
845 .get(&gate_type)
846 .copied()
847 .unwrap_or(0.999) }
849
850 fn get_gate_duration(&self, gate_type: NativeGateType) -> Duration {
851 self.config
852 .native_gates
853 .gate_durations
854 .get(&gate_type)
855 .copied()
856 .unwrap_or(Duration::from_nanos(100)) }
858
859 fn get_native_two_qubit_gate(&self) -> NativeGateType {
860 match self.config.platform {
861 HardwarePlatform::Superconducting => NativeGateType::CNOT,
862 HardwarePlatform::TrappedIon => NativeGateType::MS,
863 HardwarePlatform::Photonic => NativeGateType::CZ,
864 HardwarePlatform::NeutralAtom => NativeGateType::CZ,
865 _ => NativeGateType::CNOT,
866 }
867 }
868
869 fn generate_cache_key(&self, gate: &dyn GateOp, qubits: &[QubitId]) -> String {
871 format!("{}_{:?}", gate.name(), qubits)
872 }
873
874 fn find_native_single_qubit_gate(
876 &self,
877 _matrix: &DenseMatrix,
878 ) -> QuantRS2Result<Option<CompiledGate>> {
879 Ok(None)
882 }
883
884 fn find_native_two_qubit_gate(
885 &self,
886 _matrix: &DenseMatrix,
887 _qubit1: QubitId,
888 _qubit2: QubitId,
889 ) -> QuantRS2Result<Option<CompiledGate>> {
890 Ok(None)
893 }
894
895 fn decompose_for_photonic_single(
896 &self,
897 _gate: &dyn GateOp,
898 _qubit: QubitId,
899 ) -> QuantRS2Result<Vec<CompiledGate>> {
900 Ok(vec![])
902 }
903
904 fn decompose_for_neutral_atom_single(
905 &self,
906 _gate: &dyn GateOp,
907 _qubit: QubitId,
908 ) -> QuantRS2Result<Vec<CompiledGate>> {
909 Ok(vec![])
911 }
912
913 fn decompose_universal_single(
914 &self,
915 _gate: &dyn GateOp,
916 _qubit: QubitId,
917 ) -> QuantRS2Result<Vec<CompiledGate>> {
918 Ok(vec![])
920 }
921
922 fn decompose_for_photonic_two(
923 &self,
924 _gate: &dyn GateOp,
925 _qubit1: QubitId,
926 _qubit2: QubitId,
927 ) -> QuantRS2Result<Vec<CompiledGate>> {
928 Ok(vec![])
930 }
931
932 fn decompose_for_neutral_atom_two(
933 &self,
934 _gate: &dyn GateOp,
935 _qubit1: QubitId,
936 _qubit2: QubitId,
937 ) -> QuantRS2Result<Vec<CompiledGate>> {
938 Ok(vec![])
940 }
941
942 fn decompose_universal_two(
943 &self,
944 _gate: &dyn GateOp,
945 _qubit1: QubitId,
946 _qubit2: QubitId,
947 ) -> QuantRS2Result<Vec<CompiledGate>> {
948 Ok(vec![])
950 }
951
952 fn compile_trapped_ion_multi(
953 &self,
954 _gate: &dyn GateOp,
955 _qubits: &[QubitId],
956 ) -> QuantRS2Result<Vec<CompiledGate>> {
957 Ok(vec![])
959 }
960
961 fn compile_neutral_atom_multi(
962 &self,
963 _gate: &dyn GateOp,
964 _qubits: &[QubitId],
965 ) -> QuantRS2Result<Vec<CompiledGate>> {
966 Ok(vec![])
968 }
969
970 fn decompose_to_two_qubit_gates(
971 &self,
972 _gate: &dyn GateOp,
973 _qubits: &[QubitId],
974 ) -> QuantRS2Result<Vec<CompiledGate>> {
975 Ok(vec![])
977 }
978
979 fn decompose_to_ms_gates(&self, _matrix: &DenseMatrix) -> QuantRS2Result<Vec<CompiledGate>> {
980 Ok(vec![])
982 }
983
984 fn generate_pulse_sequence(
985 &self,
986 gate_type: NativeGateType,
987 parameters: &[f64],
988 ) -> QuantRS2Result<Option<PulseSequence>> {
989 if !self.config.use_pulse_optimization {
990 return Ok(None);
991 }
992
993 match self.config.platform {
995 HardwarePlatform::Superconducting => {
996 self.generate_superconducting_pulses(gate_type, parameters)
997 }
998 HardwarePlatform::TrappedIon => self.generate_trapped_ion_pulses(gate_type, parameters),
999 _ => Ok(None),
1000 }
1001 }
1002
1003 fn generate_superconducting_pulses(
1004 &self,
1005 _gate_type: NativeGateType,
1006 _parameters: &[f64],
1007 ) -> QuantRS2Result<Option<PulseSequence>> {
1008 Ok(None)
1010 }
1011
1012 fn generate_trapped_ion_pulses(
1013 &self,
1014 _gate_type: NativeGateType,
1015 _parameters: &[f64],
1016 ) -> QuantRS2Result<Option<PulseSequence>> {
1017 Ok(None)
1019 }
1020
1021 fn check_cache(&self, key: &str) -> QuantRS2Result<Option<Vec<CompiledGate>>> {
1023 let cache = self.decomposition_cache.read().unwrap();
1024 Ok(cache.single_qubit_cache.get(key).cloned())
1025 }
1026
1027 fn cache_result(&self, key: &str, gates: &[CompiledGate]) -> QuantRS2Result<()> {
1028 let mut cache = self.decomposition_cache.write().unwrap();
1029 cache
1030 .single_qubit_cache
1031 .insert(key.to_string(), gates.to_vec());
1032 cache.cache_stats.total_requests += 1;
1033 Ok(())
1034 }
1035
1036 fn record_cache_hit(&self) {
1037 let mut cache = self.decomposition_cache.write().unwrap();
1038 cache.cache_stats.cache_hits += 1;
1039 cache.cache_stats.hit_rate =
1040 cache.cache_stats.cache_hits as f64 / cache.cache_stats.total_requests as f64;
1041 }
1042
1043 fn record_cache_miss(&self) {
1044 let mut cache = self.decomposition_cache.write().unwrap();
1045 cache.cache_stats.cache_misses += 1;
1046 }
1047
1048 fn record_compilation_time(&self, duration: Duration) {
1049 let mut monitor = self.performance_monitor.write().unwrap();
1050 monitor.compilation_times.push(duration);
1051 }
1052
1053 pub fn get_performance_stats(&self) -> CompilationPerformanceStats {
1055 let monitor = self.performance_monitor.read().unwrap();
1056 let cache = self.decomposition_cache.read().unwrap();
1057
1058 CompilationPerformanceStats {
1059 average_compilation_time: monitor.compilation_times.iter().sum::<Duration>()
1060 / monitor.compilation_times.len() as u32,
1061 cache_statistics: cache.cache_stats.clone(),
1062 total_compilations: monitor.compilation_times.len(),
1063 }
1064 }
1065}
1066
1067#[derive(Debug, Clone)]
1069pub struct CompilationPerformanceStats {
1070 pub average_compilation_time: Duration,
1072 pub cache_statistics: CacheStatistics,
1074 pub total_compilations: usize,
1076}
1077
1078impl DecompositionCache {
1079 fn new() -> Self {
1080 Self {
1081 single_qubit_cache: HashMap::new(),
1082 two_qubit_cache: HashMap::new(),
1083 cache_stats: CacheStatistics::default(),
1084 }
1085 }
1086}
1087
1088impl HardwareOptimizationEngine {
1089 fn new(_config: &HardwareCompilationConfig) -> QuantRS2Result<Self> {
1090 let mut optimizers: HashMap<HardwarePlatform, Box<dyn PlatformOptimizer>> = HashMap::new();
1091
1092 optimizers.insert(
1094 HardwarePlatform::Superconducting,
1095 Box::new(SuperconductingOptimizer::new()),
1096 );
1097 optimizers.insert(
1098 HardwarePlatform::TrappedIon,
1099 Box::new(TrappedIonOptimizer::new()),
1100 );
1101 optimizers.insert(
1102 HardwarePlatform::Photonic,
1103 Box::new(PhotonicOptimizer::new()),
1104 );
1105 optimizers.insert(
1106 HardwarePlatform::NeutralAtom,
1107 Box::new(NeutralAtomOptimizer::new()),
1108 );
1109
1110 Ok(Self {
1111 optimizers,
1112 optimization_history: Vec::new(),
1113 })
1114 }
1115}
1116
1117impl CompilationPerformanceMonitor {
1118 fn new() -> Self {
1119 Self {
1120 compilation_times: Vec::new(),
1121 gate_count_reductions: Vec::new(),
1122 fidelity_improvements: Vec::new(),
1123 cache_hit_rates: Vec::new(),
1124 }
1125 }
1126}
1127
1128#[derive(Debug)]
1130struct SuperconductingOptimizer;
1131
1132impl SuperconductingOptimizer {
1133 fn new() -> Self {
1134 Self
1135 }
1136}
1137
1138impl PlatformOptimizer for SuperconductingOptimizer {
1139 fn optimize_sequence(
1140 &self,
1141 gates: &[CompiledGate],
1142 _config: &HardwareCompilationConfig,
1143 ) -> QuantRS2Result<OptimizedSequence> {
1144 let optimized_gates = self.fuse_virtual_z_gates(gates)?;
1150 let total_fidelity = self.estimate_fidelity(&optimized_gates);
1151 let total_time = optimized_gates.iter().map(|g| g.duration).sum();
1152
1153 Ok(OptimizedSequence {
1154 gates: optimized_gates,
1155 total_fidelity,
1156 total_time,
1157 metrics: self.calculate_metrics(gates, &[], total_fidelity),
1158 })
1159 }
1160
1161 fn estimate_fidelity(&self, sequence: &[CompiledGate]) -> f64 {
1162 sequence.iter().map(|g| g.fidelity).product()
1163 }
1164
1165 fn get_constraints(&self) -> PlatformConstraints {
1166 PlatformConstraints {
1167 max_qubits: 1000,
1168 gate_limitations: vec![],
1169 timing_constraints: TimingConstraints {
1170 min_gate_separation: Duration::from_nanos(10),
1171 max_parallel_ops: 100,
1172 qubit_timing: HashMap::new(),
1173 },
1174 error_model: ErrorModel {
1175 single_qubit_errors: HashMap::new(),
1176 two_qubit_errors: HashMap::new(),
1177 readout_errors: HashMap::new(),
1178 idle_decay_rates: HashMap::new(),
1179 },
1180 }
1181 }
1182}
1183
1184impl SuperconductingOptimizer {
1185 fn fuse_virtual_z_gates(&self, gates: &[CompiledGate]) -> QuantRS2Result<Vec<CompiledGate>> {
1186 let mut optimized = Vec::new();
1188 let mut current_z_angle = 0.0;
1189 let mut current_qubit = None;
1190
1191 for gate in gates {
1192 match gate.gate_type {
1193 NativeGateType::VirtualZ => {
1194 if Some(gate.qubits[0]) == current_qubit {
1195 current_z_angle += gate.parameters[0];
1196 } else {
1197 if let Some(qubit) = current_qubit {
1198 if current_z_angle.abs() > 1e-10 {
1199 optimized.push(CompiledGate {
1200 gate_type: NativeGateType::VirtualZ,
1201 qubits: vec![qubit],
1202 parameters: vec![current_z_angle],
1203 fidelity: 1.0,
1204 duration: Duration::from_nanos(0),
1205 pulse_sequence: None,
1206 });
1207 }
1208 }
1209 current_qubit = Some(gate.qubits[0]);
1210 current_z_angle = gate.parameters[0];
1211 }
1212 }
1213 _ => {
1214 if let Some(qubit) = current_qubit {
1215 if current_z_angle.abs() > 1e-10 {
1216 optimized.push(CompiledGate {
1217 gate_type: NativeGateType::VirtualZ,
1218 qubits: vec![qubit],
1219 parameters: vec![current_z_angle],
1220 fidelity: 1.0,
1221 duration: Duration::from_nanos(0),
1222 pulse_sequence: None,
1223 });
1224 }
1225 current_qubit = None;
1226 current_z_angle = 0.0;
1227 }
1228 optimized.push(gate.clone());
1229 }
1230 }
1231 }
1232
1233 if let Some(qubit) = current_qubit {
1235 if current_z_angle.abs() > 1e-10 {
1236 optimized.push(CompiledGate {
1237 gate_type: NativeGateType::VirtualZ,
1238 qubits: vec![qubit],
1239 parameters: vec![current_z_angle],
1240 fidelity: 1.0,
1241 duration: Duration::from_nanos(0),
1242 pulse_sequence: None,
1243 });
1244 }
1245 }
1246
1247 Ok(optimized)
1248 }
1249
1250 fn calculate_metrics(
1251 &self,
1252 original: &[CompiledGate],
1253 optimized: &[CompiledGate],
1254 fidelity: f64,
1255 ) -> OptimizationMetrics {
1256 OptimizationMetrics {
1257 original_gate_count: original.len(),
1258 optimized_gate_count: optimized.len(),
1259 gate_count_reduction: (original.len() - optimized.len()) as f64 / original.len() as f64
1260 * 100.0,
1261 original_depth: original.len(), optimized_depth: optimized.len(), depth_reduction: 0.0, fidelity_improvement: fidelity,
1265 compilation_time: Duration::from_millis(1),
1266 }
1267 }
1268}
1269
1270#[derive(Debug)]
1272struct TrappedIonOptimizer;
1273
1274impl TrappedIonOptimizer {
1275 fn new() -> Self {
1276 Self
1277 }
1278}
1279
1280impl PlatformOptimizer for TrappedIonOptimizer {
1281 fn optimize_sequence(
1282 &self,
1283 gates: &[CompiledGate],
1284 _config: &HardwareCompilationConfig,
1285 ) -> QuantRS2Result<OptimizedSequence> {
1286 let optimized_gates = gates.to_vec(); let total_fidelity = self.estimate_fidelity(&optimized_gates);
1293 let total_time = optimized_gates.iter().map(|g| g.duration).sum();
1294
1295 Ok(OptimizedSequence {
1296 gates: optimized_gates,
1297 total_fidelity,
1298 total_time,
1299 metrics: OptimizationMetrics {
1300 original_gate_count: gates.len(),
1301 optimized_gate_count: gates.len(),
1302 gate_count_reduction: 0.0,
1303 original_depth: gates.len(),
1304 optimized_depth: gates.len(),
1305 depth_reduction: 0.0,
1306 fidelity_improvement: total_fidelity,
1307 compilation_time: Duration::from_millis(1),
1308 },
1309 })
1310 }
1311
1312 fn estimate_fidelity(&self, sequence: &[CompiledGate]) -> f64 {
1313 sequence.iter().map(|g| g.fidelity).product()
1314 }
1315
1316 fn get_constraints(&self) -> PlatformConstraints {
1317 PlatformConstraints {
1318 max_qubits: 100,
1319 gate_limitations: vec![],
1320 timing_constraints: TimingConstraints {
1321 min_gate_separation: Duration::from_micros(1),
1322 max_parallel_ops: 10,
1323 qubit_timing: HashMap::new(),
1324 },
1325 error_model: ErrorModel {
1326 single_qubit_errors: HashMap::new(),
1327 two_qubit_errors: HashMap::new(),
1328 readout_errors: HashMap::new(),
1329 idle_decay_rates: HashMap::new(),
1330 },
1331 }
1332 }
1333}
1334
1335#[derive(Debug)]
1336struct PhotonicOptimizer;
1337
1338impl PhotonicOptimizer {
1339 fn new() -> Self {
1340 Self
1341 }
1342}
1343
1344impl PlatformOptimizer for PhotonicOptimizer {
1345 fn optimize_sequence(
1346 &self,
1347 gates: &[CompiledGate],
1348 _config: &HardwareCompilationConfig,
1349 ) -> QuantRS2Result<OptimizedSequence> {
1350 let optimized_gates = gates.to_vec();
1351 let total_fidelity = self.estimate_fidelity(&optimized_gates);
1352 let total_time = optimized_gates.iter().map(|g| g.duration).sum();
1353
1354 Ok(OptimizedSequence {
1355 gates: optimized_gates,
1356 total_fidelity,
1357 total_time,
1358 metrics: OptimizationMetrics {
1359 original_gate_count: gates.len(),
1360 optimized_gate_count: gates.len(),
1361 gate_count_reduction: 0.0,
1362 original_depth: gates.len(),
1363 optimized_depth: gates.len(),
1364 depth_reduction: 0.0,
1365 fidelity_improvement: total_fidelity,
1366 compilation_time: Duration::from_millis(1),
1367 },
1368 })
1369 }
1370
1371 fn estimate_fidelity(&self, sequence: &[CompiledGate]) -> f64 {
1372 sequence.iter().map(|g| g.fidelity).product()
1373 }
1374
1375 fn get_constraints(&self) -> PlatformConstraints {
1376 PlatformConstraints {
1377 max_qubits: 216, gate_limitations: vec![],
1379 timing_constraints: TimingConstraints {
1380 min_gate_separation: Duration::from_nanos(1),
1381 max_parallel_ops: 50,
1382 qubit_timing: HashMap::new(),
1383 },
1384 error_model: ErrorModel {
1385 single_qubit_errors: HashMap::new(),
1386 two_qubit_errors: HashMap::new(),
1387 readout_errors: HashMap::new(),
1388 idle_decay_rates: HashMap::new(),
1389 },
1390 }
1391 }
1392}
1393
1394#[derive(Debug)]
1395struct NeutralAtomOptimizer;
1396
1397impl NeutralAtomOptimizer {
1398 fn new() -> Self {
1399 Self
1400 }
1401}
1402
1403impl PlatformOptimizer for NeutralAtomOptimizer {
1404 fn optimize_sequence(
1405 &self,
1406 gates: &[CompiledGate],
1407 _config: &HardwareCompilationConfig,
1408 ) -> QuantRS2Result<OptimizedSequence> {
1409 let optimized_gates = gates.to_vec();
1410 let total_fidelity = self.estimate_fidelity(&optimized_gates);
1411 let total_time = optimized_gates.iter().map(|g| g.duration).sum();
1412
1413 Ok(OptimizedSequence {
1414 gates: optimized_gates,
1415 total_fidelity,
1416 total_time,
1417 metrics: OptimizationMetrics {
1418 original_gate_count: gates.len(),
1419 optimized_gate_count: gates.len(),
1420 gate_count_reduction: 0.0,
1421 original_depth: gates.len(),
1422 optimized_depth: gates.len(),
1423 depth_reduction: 0.0,
1424 fidelity_improvement: total_fidelity,
1425 compilation_time: Duration::from_millis(1),
1426 },
1427 })
1428 }
1429
1430 fn estimate_fidelity(&self, sequence: &[CompiledGate]) -> f64 {
1431 sequence.iter().map(|g| g.fidelity).product()
1432 }
1433
1434 fn get_constraints(&self) -> PlatformConstraints {
1435 PlatformConstraints {
1436 max_qubits: 256,
1437 gate_limitations: vec![],
1438 timing_constraints: TimingConstraints {
1439 min_gate_separation: Duration::from_micros(1),
1440 max_parallel_ops: 20,
1441 qubit_timing: HashMap::new(),
1442 },
1443 error_model: ErrorModel {
1444 single_qubit_errors: HashMap::new(),
1445 two_qubit_errors: HashMap::new(),
1446 readout_errors: HashMap::new(),
1447 idle_decay_rates: HashMap::new(),
1448 },
1449 }
1450 }
1451}
1452
1453impl HardwareCompiler {
1455 pub fn for_superconducting(topology: HardwareTopology) -> QuantRS2Result<Self> {
1457 let config = HardwareCompilationConfig {
1458 platform: HardwarePlatform::Superconducting,
1459 native_gates: create_superconducting_gate_set(),
1460 topology,
1461 optimization_objectives: vec![
1462 OptimizationObjective::MinimizeGateCount,
1463 OptimizationObjective::MaximizeFidelity,
1464 ],
1465 tolerances: CompilationTolerances {
1466 decomposition_tolerance: 1e-12,
1467 parameter_tolerance: 1e-10,
1468 fidelity_threshold: 0.99,
1469 max_compilation_time: Duration::from_secs(60),
1470 },
1471 enable_crosstalk_mitigation: true,
1472 use_pulse_optimization: true,
1473 };
1474
1475 Self::new(config)
1476 }
1477
1478 pub fn for_trapped_ion(topology: HardwareTopology) -> QuantRS2Result<Self> {
1480 let config = HardwareCompilationConfig {
1481 platform: HardwarePlatform::TrappedIon,
1482 native_gates: create_trapped_ion_gate_set(),
1483 topology,
1484 optimization_objectives: vec![
1485 OptimizationObjective::MinimizeTime,
1486 OptimizationObjective::MaximizeFidelity,
1487 ],
1488 tolerances: CompilationTolerances {
1489 decomposition_tolerance: 1e-14,
1490 parameter_tolerance: 1e-12,
1491 fidelity_threshold: 0.995,
1492 max_compilation_time: Duration::from_secs(120),
1493 },
1494 enable_crosstalk_mitigation: false,
1495 use_pulse_optimization: true,
1496 };
1497
1498 Self::new(config)
1499 }
1500}
1501
1502fn create_superconducting_gate_set() -> NativeGateSet {
1504 let mut gate_fidelities = HashMap::new();
1505 gate_fidelities.insert(NativeGateType::VirtualZ, 1.0);
1506 gate_fidelities.insert(NativeGateType::Rx, 0.9995);
1507 gate_fidelities.insert(NativeGateType::Ry, 0.9995);
1508 gate_fidelities.insert(NativeGateType::CNOT, 0.995);
1509
1510 let mut gate_durations = HashMap::new();
1511 gate_durations.insert(NativeGateType::VirtualZ, Duration::from_nanos(0));
1512 gate_durations.insert(NativeGateType::Rx, Duration::from_nanos(20));
1513 gate_durations.insert(NativeGateType::Ry, Duration::from_nanos(20));
1514 gate_durations.insert(NativeGateType::CNOT, Duration::from_nanos(300));
1515
1516 NativeGateSet {
1517 single_qubit_gates: vec![
1518 NativeGateType::Rx,
1519 NativeGateType::Ry,
1520 NativeGateType::VirtualZ,
1521 ],
1522 two_qubit_gates: vec![NativeGateType::CNOT],
1523 multi_qubit_gates: vec![],
1524 parametric_constraints: HashMap::new(),
1525 gate_fidelities,
1526 gate_durations,
1527 }
1528}
1529
1530fn create_trapped_ion_gate_set() -> NativeGateSet {
1531 let mut gate_fidelities = HashMap::new();
1532 gate_fidelities.insert(NativeGateType::Rx, 0.9999);
1533 gate_fidelities.insert(NativeGateType::Ry, 0.9999);
1534 gate_fidelities.insert(NativeGateType::Rz, 0.9999);
1535 gate_fidelities.insert(NativeGateType::MS, 0.998);
1536
1537 let mut gate_durations = HashMap::new();
1538 gate_durations.insert(NativeGateType::Rx, Duration::from_micros(10));
1539 gate_durations.insert(NativeGateType::Ry, Duration::from_micros(10));
1540 gate_durations.insert(NativeGateType::Rz, Duration::from_micros(1));
1541 gate_durations.insert(NativeGateType::MS, Duration::from_micros(100));
1542
1543 NativeGateSet {
1544 single_qubit_gates: vec![NativeGateType::Rx, NativeGateType::Ry, NativeGateType::Rz],
1545 two_qubit_gates: vec![NativeGateType::MS],
1546 multi_qubit_gates: vec![NativeGateType::MS], parametric_constraints: HashMap::new(),
1548 gate_fidelities,
1549 gate_durations,
1550 }
1551}
1552
1553#[cfg(test)]
1554mod tests {
1555 use super::*;
1556 use crate::qubit::QubitId;
1557 use num_complex::Complex64;
1558 use std::collections::{HashMap, HashSet};
1559
1560 fn create_test_topology() -> HardwareTopology {
1561 let mut connectivity = HashMap::new();
1562 let mut qubit_positions = HashMap::new();
1563
1564 for i in 0..4 {
1566 let qubit = QubitId::new(i);
1567 qubit_positions.insert(qubit, (i as f64, 0.0, 0.0));
1568
1569 let mut neighbors = HashSet::new();
1570 if i > 0 {
1571 neighbors.insert(QubitId::new(i - 1));
1572 }
1573 if i < 3 {
1574 neighbors.insert(QubitId::new(i + 1));
1575 }
1576 connectivity.insert(qubit, neighbors);
1577 }
1578
1579 HardwareTopology {
1580 connectivity,
1581 qubit_positions,
1582 coupling_strengths: HashMap::new(),
1583 crosstalk_matrix: Array2::zeros((4, 4)),
1584 max_parallel_ops: 2,
1585 }
1586 }
1587
1588 #[test]
1589 fn test_superconducting_compiler_creation() {
1590 let topology = create_test_topology();
1591 let compiler = HardwareCompiler::for_superconducting(topology);
1592 assert!(compiler.is_ok());
1593
1594 let compiler = compiler.unwrap();
1595 assert_eq!(compiler.config.platform, HardwarePlatform::Superconducting);
1596 assert!(compiler
1597 .config
1598 .native_gates
1599 .single_qubit_gates
1600 .contains(&NativeGateType::VirtualZ));
1601 }
1602
1603 #[test]
1604 fn test_trapped_ion_compiler_creation() {
1605 let topology = create_test_topology();
1606 let compiler = HardwareCompiler::for_trapped_ion(topology);
1607 assert!(compiler.is_ok());
1608
1609 let compiler = compiler.unwrap();
1610 assert_eq!(compiler.config.platform, HardwarePlatform::TrappedIon);
1611 assert!(compiler
1612 .config
1613 .native_gates
1614 .two_qubit_gates
1615 .contains(&NativeGateType::MS));
1616 }
1617
1618 #[test]
1619 fn test_connectivity_check() {
1620 let topology = create_test_topology();
1621 let compiler = HardwareCompiler::for_superconducting(topology).unwrap();
1622
1623 assert!(compiler
1625 .check_connectivity(QubitId::new(0), QubitId::new(1))
1626 .unwrap());
1627 assert!(compiler
1628 .check_connectivity(QubitId::new(1), QubitId::new(2))
1629 .unwrap());
1630
1631 assert!(!compiler
1633 .check_connectivity(QubitId::new(0), QubitId::new(2))
1634 .unwrap());
1635 assert!(!compiler
1636 .check_connectivity(QubitId::new(0), QubitId::new(3))
1637 .unwrap());
1638 }
1639
1640 #[test]
1641 fn test_shortest_path_finding() {
1642 let topology = create_test_topology();
1643 let compiler = HardwareCompiler::for_superconducting(topology).unwrap();
1644
1645 let path = compiler
1647 .find_shortest_path(QubitId::new(0), QubitId::new(1))
1648 .unwrap();
1649 assert_eq!(path, vec![QubitId::new(0), QubitId::new(1)]);
1650
1651 let path = compiler
1653 .find_shortest_path(QubitId::new(0), QubitId::new(3))
1654 .unwrap();
1655 assert_eq!(
1656 path,
1657 vec![
1658 QubitId::new(0),
1659 QubitId::new(1),
1660 QubitId::new(2),
1661 QubitId::new(3)
1662 ]
1663 );
1664 }
1665
1666 #[test]
1667 fn test_virtual_z_optimization() {
1668 let optimizer = SuperconductingOptimizer::new();
1669
1670 let gates = vec![
1671 CompiledGate {
1672 gate_type: NativeGateType::VirtualZ,
1673 qubits: vec![QubitId::new(0)],
1674 parameters: vec![0.5],
1675 fidelity: 1.0,
1676 duration: Duration::from_nanos(0),
1677 pulse_sequence: None,
1678 },
1679 CompiledGate {
1680 gate_type: NativeGateType::VirtualZ,
1681 qubits: vec![QubitId::new(0)],
1682 parameters: vec![0.3],
1683 fidelity: 1.0,
1684 duration: Duration::from_nanos(0),
1685 pulse_sequence: None,
1686 },
1687 CompiledGate {
1688 gate_type: NativeGateType::Rx,
1689 qubits: vec![QubitId::new(0)],
1690 parameters: vec![1.0],
1691 fidelity: 0.999,
1692 duration: Duration::from_nanos(20),
1693 pulse_sequence: None,
1694 },
1695 ];
1696
1697 let optimized = optimizer.fuse_virtual_z_gates(&gates).unwrap();
1698 assert_eq!(optimized.len(), 2); assert_eq!(optimized[0].gate_type, NativeGateType::VirtualZ);
1700 assert!((optimized[0].parameters[0] - 0.8).abs() < 1e-10); }
1702
1703 #[test]
1704 fn test_gate_fidelity_calculation() {
1705 let topology = create_test_topology();
1706 let compiler = HardwareCompiler::for_superconducting(topology).unwrap();
1707
1708 assert_eq!(compiler.get_gate_fidelity(NativeGateType::VirtualZ), 1.0);
1710
1711 assert!(compiler.get_gate_fidelity(NativeGateType::Rx) > 0.999);
1713
1714 assert!(
1716 compiler.get_gate_fidelity(NativeGateType::CNOT)
1717 < compiler.get_gate_fidelity(NativeGateType::Rx)
1718 );
1719 }
1720
1721 #[test]
1722 fn test_platform_constraints() {
1723 let superconducting_optimizer = SuperconductingOptimizer::new();
1724 let constraints = superconducting_optimizer.get_constraints();
1725
1726 assert!(constraints.max_qubits >= 100); assert!(constraints.timing_constraints.min_gate_separation < Duration::from_micros(1));
1728 }
1729
1730 #[test]
1731 fn test_compilation_performance_tracking() {
1732 let topology = create_test_topology();
1733 let compiler = HardwareCompiler::for_superconducting(topology).unwrap();
1734
1735 compiler.record_compilation_time(Duration::from_millis(10));
1737 compiler.record_compilation_time(Duration::from_millis(15));
1738 compiler.record_compilation_time(Duration::from_millis(12));
1739
1740 let stats = compiler.get_performance_stats();
1741 assert_eq!(stats.total_compilations, 3);
1742 assert!(stats.average_compilation_time > Duration::from_millis(10));
1743 assert!(stats.average_compilation_time < Duration::from_millis(15));
1744 }
1745
1746 #[test]
1747 fn test_cache_functionality() {
1748 let topology = create_test_topology();
1749 let compiler = HardwareCompiler::for_superconducting(topology).unwrap();
1750
1751 let test_gates = vec![CompiledGate {
1752 gate_type: NativeGateType::Rx,
1753 qubits: vec![QubitId::new(0)],
1754 parameters: vec![1.0],
1755 fidelity: 0.999,
1756 duration: Duration::from_nanos(20),
1757 pulse_sequence: None,
1758 }];
1759
1760 let cache_key = "test_gate_0";
1762 compiler.cache_result(cache_key, &test_gates).unwrap();
1763
1764 let cached_result = compiler.check_cache(cache_key).unwrap();
1766 assert!(cached_result.is_some());
1767
1768 let cached_gates = cached_result.unwrap();
1769 assert_eq!(cached_gates.len(), 1);
1770 assert_eq!(cached_gates[0].gate_type, NativeGateType::Rx);
1771 }
1772
1773 #[test]
1774 fn test_z_rotation_detection() {
1775 let topology = create_test_topology();
1776 let compiler = HardwareCompiler::for_superconducting(topology).unwrap();
1777
1778 let angle = std::f64::consts::PI / 4.0;
1780 let mut z_matrix = Array2::zeros((2, 2));
1781 z_matrix[(0, 0)] = Complex64::from_polar(1.0, -angle / 2.0);
1782 z_matrix[(1, 1)] = Complex64::from_polar(1.0, angle / 2.0);
1783
1784 let dense_z_matrix = DenseMatrix::new(z_matrix).unwrap();
1785 assert!(compiler.is_z_rotation(&dense_z_matrix).unwrap());
1786
1787 let extracted_angle = compiler.extract_z_rotation_angle(&dense_z_matrix).unwrap();
1788 assert!((extracted_angle - angle).abs() < 1e-10);
1789 }
1790
1791 #[test]
1792 fn test_euler_angle_extraction() {
1793 let topology = create_test_topology();
1794 let compiler = HardwareCompiler::for_superconducting(topology).unwrap();
1795
1796 let mut identity = Array2::zeros((2, 2));
1798 identity[(0, 0)] = Complex64::new(1.0, 0.0);
1799 identity[(1, 1)] = Complex64::new(1.0, 0.0);
1800
1801 let dense_identity = DenseMatrix::new(identity).unwrap();
1802 let (theta, phi, lambda) = compiler.extract_euler_angles(&dense_identity).unwrap();
1803
1804 assert!(theta.abs() < 1e-10);
1806 }
1807
1808 #[test]
1809 fn test_optimization_metrics_calculation() {
1810 let optimizer = SuperconductingOptimizer::new();
1811
1812 let original_gates = vec![
1813 CompiledGate {
1814 gate_type: NativeGateType::VirtualZ,
1815 qubits: vec![QubitId::new(0)],
1816 parameters: vec![0.5],
1817 fidelity: 1.0,
1818 duration: Duration::from_nanos(0),
1819 pulse_sequence: None,
1820 },
1821 CompiledGate {
1822 gate_type: NativeGateType::VirtualZ,
1823 qubits: vec![QubitId::new(0)],
1824 parameters: vec![0.3],
1825 fidelity: 1.0,
1826 duration: Duration::from_nanos(0),
1827 pulse_sequence: None,
1828 },
1829 ];
1830
1831 let optimized_gates = vec![CompiledGate {
1832 gate_type: NativeGateType::VirtualZ,
1833 qubits: vec![QubitId::new(0)],
1834 parameters: vec![0.8],
1835 fidelity: 1.0,
1836 duration: Duration::from_nanos(0),
1837 pulse_sequence: None,
1838 }];
1839
1840 let metrics = optimizer.calculate_metrics(&original_gates, &optimized_gates, 1.0);
1841
1842 assert_eq!(metrics.original_gate_count, 2);
1843 assert_eq!(metrics.optimized_gate_count, 1);
1844 assert_eq!(metrics.gate_count_reduction, 50.0); }
1846}