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 scirs2_core::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.insert(neighbor) {
745 parent.insert(neighbor, current);
746 queue.push_back(neighbor);
747 }
748 }
749 }
750 }
751
752 Err(QuantRS2Error::InvalidParameter(format!(
753 "No path found between qubits {start:?} and {end:?}"
754 )))
755 }
756
757 fn optimize_for_platform(&self, gates: &[CompiledGate]) -> QuantRS2Result<Vec<CompiledGate>> {
759 let engine = self
760 .optimization_engine
761 .read()
762 .map_err(|e| QuantRS2Error::RuntimeError(format!("Lock poisoned: {e}")))?;
763
764 if let Some(optimizer) = engine.optimizers.get(&self.config.platform) {
765 let optimized = optimizer.optimize_sequence(gates, &self.config)?;
766 Ok(optimized.gates)
767 } else {
768 Ok(gates.to_vec())
770 }
771 }
772
773 fn is_z_rotation(&self, matrix: &DenseMatrix) -> QuantRS2Result<bool> {
775 let tolerance = self.config.tolerances.decomposition_tolerance;
777
778 let arr = matrix.as_array();
780 if arr[(0, 1)].norm() > tolerance || arr[(1, 0)].norm() > tolerance {
781 return Ok(false);
782 }
783
784 Ok(true)
785 }
786
787 fn extract_z_rotation_angle(&self, matrix: &DenseMatrix) -> QuantRS2Result<f64> {
788 let arr = matrix.as_array();
789 let z00 = arr[(0, 0)];
790 let z11 = arr[(1, 1)];
791
792 let angle = (z11 / z00).arg();
794 Ok(angle)
795 }
796
797 fn decompose_to_rx_rz(
798 &self,
799 matrix: &DenseMatrix,
800 ) -> QuantRS2Result<Vec<(NativeGateType, f64)>> {
801 let (theta, phi, lambda) = self.extract_euler_angles(matrix)?;
803
804 let mut decomposition = Vec::new();
805
806 if lambda.abs() > self.config.tolerances.parameter_tolerance {
807 decomposition.push((NativeGateType::Rz, lambda));
808 }
809 if theta.abs() > self.config.tolerances.parameter_tolerance {
810 decomposition.push((NativeGateType::Rx, theta));
811 }
812 if phi.abs() > self.config.tolerances.parameter_tolerance {
813 decomposition.push((NativeGateType::Rz, phi));
814 }
815
816 Ok(decomposition)
817 }
818
819 fn extract_euler_angles(&self, matrix: &DenseMatrix) -> QuantRS2Result<(f64, f64, f64)> {
820 let arr = matrix.as_array();
822 let u00 = arr[(0, 0)];
823 let u01 = arr[(0, 1)];
824 let u10 = arr[(1, 0)];
825 let u11 = arr[(1, 1)];
826
827 let theta: f64 = 2.0 * (u01.norm()).asin(); let phi = if theta.abs() < 1e-10 {
829 0.0
830 } else {
831 (u11 / u00).arg() + (u01 / (-u10)).arg()
832 };
833 let lambda = if theta.abs() < 1e-10 {
834 (u11 / u00).arg()
835 } else {
836 (u11 / u00).arg() - (u01 / (-u10)).arg()
837 };
838
839 Ok((theta, phi, lambda))
840 }
841
842 fn get_gate_fidelity(&self, gate_type: NativeGateType) -> f64 {
843 self.config
844 .native_gates
845 .gate_fidelities
846 .get(&gate_type)
847 .copied()
848 .unwrap_or(0.999) }
850
851 fn get_gate_duration(&self, gate_type: NativeGateType) -> Duration {
852 self.config
853 .native_gates
854 .gate_durations
855 .get(&gate_type)
856 .copied()
857 .unwrap_or(Duration::from_nanos(100)) }
859
860 const fn get_native_two_qubit_gate(&self) -> NativeGateType {
861 match self.config.platform {
862 HardwarePlatform::TrappedIon => NativeGateType::MS,
863 HardwarePlatform::Photonic | HardwarePlatform::NeutralAtom => NativeGateType::CZ,
864 HardwarePlatform::Superconducting | _ => NativeGateType::CNOT,
865 }
866 }
867
868 fn generate_cache_key(&self, gate: &dyn GateOp, qubits: &[QubitId]) -> String {
870 format!("{}_{:?}", gate.name(), qubits)
871 }
872
873 const fn find_native_single_qubit_gate(
875 &self,
876 _matrix: &DenseMatrix,
877 ) -> QuantRS2Result<Option<CompiledGate>> {
878 Ok(None)
881 }
882
883 const fn find_native_two_qubit_gate(
884 &self,
885 _matrix: &DenseMatrix,
886 _qubit1: QubitId,
887 _qubit2: QubitId,
888 ) -> QuantRS2Result<Option<CompiledGate>> {
889 Ok(None)
892 }
893
894 fn decompose_for_photonic_single(
895 &self,
896 _gate: &dyn GateOp,
897 _qubit: QubitId,
898 ) -> QuantRS2Result<Vec<CompiledGate>> {
899 Ok(vec![])
901 }
902
903 fn decompose_for_neutral_atom_single(
904 &self,
905 _gate: &dyn GateOp,
906 _qubit: QubitId,
907 ) -> QuantRS2Result<Vec<CompiledGate>> {
908 Ok(vec![])
910 }
911
912 fn decompose_universal_single(
913 &self,
914 _gate: &dyn GateOp,
915 _qubit: QubitId,
916 ) -> QuantRS2Result<Vec<CompiledGate>> {
917 Ok(vec![])
919 }
920
921 fn decompose_for_photonic_two(
922 &self,
923 _gate: &dyn GateOp,
924 _qubit1: QubitId,
925 _qubit2: QubitId,
926 ) -> QuantRS2Result<Vec<CompiledGate>> {
927 Ok(vec![])
929 }
930
931 fn decompose_for_neutral_atom_two(
932 &self,
933 _gate: &dyn GateOp,
934 _qubit1: QubitId,
935 _qubit2: QubitId,
936 ) -> QuantRS2Result<Vec<CompiledGate>> {
937 Ok(vec![])
939 }
940
941 fn decompose_universal_two(
942 &self,
943 _gate: &dyn GateOp,
944 _qubit1: QubitId,
945 _qubit2: QubitId,
946 ) -> QuantRS2Result<Vec<CompiledGate>> {
947 Ok(vec![])
949 }
950
951 fn compile_trapped_ion_multi(
952 &self,
953 _gate: &dyn GateOp,
954 _qubits: &[QubitId],
955 ) -> QuantRS2Result<Vec<CompiledGate>> {
956 Ok(vec![])
958 }
959
960 fn compile_neutral_atom_multi(
961 &self,
962 _gate: &dyn GateOp,
963 _qubits: &[QubitId],
964 ) -> QuantRS2Result<Vec<CompiledGate>> {
965 Ok(vec![])
967 }
968
969 fn decompose_to_two_qubit_gates(
970 &self,
971 _gate: &dyn GateOp,
972 _qubits: &[QubitId],
973 ) -> QuantRS2Result<Vec<CompiledGate>> {
974 Ok(vec![])
976 }
977
978 const fn decompose_to_ms_gates(
979 &self,
980 _matrix: &DenseMatrix,
981 ) -> QuantRS2Result<Vec<CompiledGate>> {
982 Ok(vec![])
984 }
985
986 const fn generate_pulse_sequence(
987 &self,
988 gate_type: NativeGateType,
989 parameters: &[f64],
990 ) -> QuantRS2Result<Option<PulseSequence>> {
991 if !self.config.use_pulse_optimization {
992 return Ok(None);
993 }
994
995 match self.config.platform {
997 HardwarePlatform::Superconducting => {
998 self.generate_superconducting_pulses(gate_type, parameters)
999 }
1000 HardwarePlatform::TrappedIon => self.generate_trapped_ion_pulses(gate_type, parameters),
1001 _ => Ok(None),
1002 }
1003 }
1004
1005 const fn generate_superconducting_pulses(
1006 &self,
1007 _gate_type: NativeGateType,
1008 _parameters: &[f64],
1009 ) -> QuantRS2Result<Option<PulseSequence>> {
1010 Ok(None)
1012 }
1013
1014 const fn generate_trapped_ion_pulses(
1015 &self,
1016 _gate_type: NativeGateType,
1017 _parameters: &[f64],
1018 ) -> QuantRS2Result<Option<PulseSequence>> {
1019 Ok(None)
1021 }
1022
1023 fn check_cache(&self, key: &str) -> QuantRS2Result<Option<Vec<CompiledGate>>> {
1025 let cache = self
1026 .decomposition_cache
1027 .read()
1028 .map_err(|e| QuantRS2Error::RuntimeError(format!("Cache lock poisoned: {e}")))?;
1029 Ok(cache.single_qubit_cache.get(key).cloned())
1030 }
1031
1032 fn cache_result(&self, key: &str, gates: &[CompiledGate]) -> QuantRS2Result<()> {
1033 let mut cache = self
1034 .decomposition_cache
1035 .write()
1036 .map_err(|e| QuantRS2Error::RuntimeError(format!("Cache lock poisoned: {e}")))?;
1037 cache
1038 .single_qubit_cache
1039 .insert(key.to_string(), gates.to_vec());
1040 cache.cache_stats.total_requests += 1;
1041 Ok(())
1042 }
1043
1044 fn record_cache_hit(&self) {
1045 if let Ok(mut cache) = self.decomposition_cache.write() {
1046 cache.cache_stats.cache_hits += 1;
1047 cache.cache_stats.hit_rate =
1048 cache.cache_stats.cache_hits as f64 / cache.cache_stats.total_requests as f64;
1049 }
1050 }
1051
1052 fn record_cache_miss(&self) {
1053 if let Ok(mut cache) = self.decomposition_cache.write() {
1054 cache.cache_stats.cache_misses += 1;
1055 }
1056 }
1057
1058 fn record_compilation_time(&self, duration: Duration) {
1059 if let Ok(mut monitor) = self.performance_monitor.write() {
1060 monitor.compilation_times.push(duration);
1061 }
1062 }
1063
1064 pub fn get_performance_stats(&self) -> CompilationPerformanceStats {
1066 let monitor = self
1067 .performance_monitor
1068 .read()
1069 .expect("performance monitor lock poisoned");
1070 let cache = self
1071 .decomposition_cache
1072 .read()
1073 .expect("cache lock poisoned");
1074
1075 let avg_time = if monitor.compilation_times.is_empty() {
1076 Duration::ZERO
1077 } else {
1078 monitor.compilation_times.iter().sum::<Duration>()
1079 / monitor.compilation_times.len() as u32
1080 };
1081
1082 CompilationPerformanceStats {
1083 average_compilation_time: avg_time,
1084 cache_statistics: cache.cache_stats.clone(),
1085 total_compilations: monitor.compilation_times.len(),
1086 }
1087 }
1088}
1089
1090#[derive(Debug, Clone)]
1092pub struct CompilationPerformanceStats {
1093 pub average_compilation_time: Duration,
1095 pub cache_statistics: CacheStatistics,
1097 pub total_compilations: usize,
1099}
1100
1101impl DecompositionCache {
1102 fn new() -> Self {
1103 Self {
1104 single_qubit_cache: HashMap::new(),
1105 two_qubit_cache: HashMap::new(),
1106 cache_stats: CacheStatistics::default(),
1107 }
1108 }
1109}
1110
1111impl HardwareOptimizationEngine {
1112 fn new(_config: &HardwareCompilationConfig) -> QuantRS2Result<Self> {
1113 let mut optimizers: HashMap<HardwarePlatform, Box<dyn PlatformOptimizer>> = HashMap::new();
1114
1115 optimizers.insert(
1117 HardwarePlatform::Superconducting,
1118 Box::new(SuperconductingOptimizer::new()),
1119 );
1120 optimizers.insert(
1121 HardwarePlatform::TrappedIon,
1122 Box::new(TrappedIonOptimizer::new()),
1123 );
1124 optimizers.insert(
1125 HardwarePlatform::Photonic,
1126 Box::new(PhotonicOptimizer::new()),
1127 );
1128 optimizers.insert(
1129 HardwarePlatform::NeutralAtom,
1130 Box::new(NeutralAtomOptimizer::new()),
1131 );
1132
1133 Ok(Self {
1134 optimizers,
1135 optimization_history: Vec::new(),
1136 })
1137 }
1138}
1139
1140impl CompilationPerformanceMonitor {
1141 const fn new() -> Self {
1142 Self {
1143 compilation_times: Vec::new(),
1144 gate_count_reductions: Vec::new(),
1145 fidelity_improvements: Vec::new(),
1146 cache_hit_rates: Vec::new(),
1147 }
1148 }
1149}
1150
1151#[derive(Debug)]
1153struct SuperconductingOptimizer;
1154
1155impl SuperconductingOptimizer {
1156 const fn new() -> Self {
1157 Self
1158 }
1159}
1160
1161impl PlatformOptimizer for SuperconductingOptimizer {
1162 fn optimize_sequence(
1163 &self,
1164 gates: &[CompiledGate],
1165 _config: &HardwareCompilationConfig,
1166 ) -> QuantRS2Result<OptimizedSequence> {
1167 let optimized_gates = self.fuse_virtual_z_gates(gates)?;
1173 let total_fidelity = self.estimate_fidelity(&optimized_gates);
1174 let total_time = optimized_gates.iter().map(|g| g.duration).sum();
1175
1176 Ok(OptimizedSequence {
1177 gates: optimized_gates,
1178 total_fidelity,
1179 total_time,
1180 metrics: self.calculate_metrics(gates, &[], total_fidelity),
1181 })
1182 }
1183
1184 fn estimate_fidelity(&self, sequence: &[CompiledGate]) -> f64 {
1185 sequence.iter().map(|g| g.fidelity).product()
1186 }
1187
1188 fn get_constraints(&self) -> PlatformConstraints {
1189 PlatformConstraints {
1190 max_qubits: 1000,
1191 gate_limitations: vec![],
1192 timing_constraints: TimingConstraints {
1193 min_gate_separation: Duration::from_nanos(10),
1194 max_parallel_ops: 100,
1195 qubit_timing: HashMap::new(),
1196 },
1197 error_model: ErrorModel {
1198 single_qubit_errors: HashMap::new(),
1199 two_qubit_errors: HashMap::new(),
1200 readout_errors: HashMap::new(),
1201 idle_decay_rates: HashMap::new(),
1202 },
1203 }
1204 }
1205}
1206
1207impl SuperconductingOptimizer {
1208 fn fuse_virtual_z_gates(&self, gates: &[CompiledGate]) -> QuantRS2Result<Vec<CompiledGate>> {
1209 let mut optimized = Vec::new();
1211 let mut current_z_angle = 0.0;
1212 let mut current_qubit = None;
1213
1214 for gate in gates {
1215 if gate.gate_type == NativeGateType::VirtualZ {
1216 if Some(gate.qubits[0]) == current_qubit {
1217 current_z_angle += gate.parameters[0];
1218 } else {
1219 if let Some(qubit) = current_qubit {
1220 if current_z_angle.abs() > 1e-10 {
1221 optimized.push(CompiledGate {
1222 gate_type: NativeGateType::VirtualZ,
1223 qubits: vec![qubit],
1224 parameters: vec![current_z_angle],
1225 fidelity: 1.0,
1226 duration: Duration::from_nanos(0),
1227 pulse_sequence: None,
1228 });
1229 }
1230 }
1231 current_qubit = Some(gate.qubits[0]);
1232 current_z_angle = gate.parameters[0];
1233 }
1234 } else {
1235 if let Some(qubit) = current_qubit {
1236 if current_z_angle.abs() > 1e-10 {
1237 optimized.push(CompiledGate {
1238 gate_type: NativeGateType::VirtualZ,
1239 qubits: vec![qubit],
1240 parameters: vec![current_z_angle],
1241 fidelity: 1.0,
1242 duration: Duration::from_nanos(0),
1243 pulse_sequence: None,
1244 });
1245 }
1246 current_qubit = None;
1247 current_z_angle = 0.0;
1248 }
1249 optimized.push(gate.clone());
1250 }
1251 }
1252
1253 if let Some(qubit) = current_qubit {
1255 if current_z_angle.abs() > 1e-10 {
1256 optimized.push(CompiledGate {
1257 gate_type: NativeGateType::VirtualZ,
1258 qubits: vec![qubit],
1259 parameters: vec![current_z_angle],
1260 fidelity: 1.0,
1261 duration: Duration::from_nanos(0),
1262 pulse_sequence: None,
1263 });
1264 }
1265 }
1266
1267 Ok(optimized)
1268 }
1269
1270 fn calculate_metrics(
1271 &self,
1272 original: &[CompiledGate],
1273 optimized: &[CompiledGate],
1274 fidelity: f64,
1275 ) -> OptimizationMetrics {
1276 OptimizationMetrics {
1277 original_gate_count: original.len(),
1278 optimized_gate_count: optimized.len(),
1279 gate_count_reduction: (original.len() - optimized.len()) as f64 / original.len() as f64
1280 * 100.0,
1281 original_depth: original.len(), optimized_depth: optimized.len(), depth_reduction: 0.0, fidelity_improvement: fidelity,
1285 compilation_time: Duration::from_millis(1),
1286 }
1287 }
1288}
1289
1290#[derive(Debug)]
1292struct TrappedIonOptimizer;
1293
1294impl TrappedIonOptimizer {
1295 const fn new() -> Self {
1296 Self
1297 }
1298}
1299
1300impl PlatformOptimizer for TrappedIonOptimizer {
1301 fn optimize_sequence(
1302 &self,
1303 gates: &[CompiledGate],
1304 _config: &HardwareCompilationConfig,
1305 ) -> QuantRS2Result<OptimizedSequence> {
1306 let optimized_gates = gates.to_vec(); let total_fidelity = self.estimate_fidelity(&optimized_gates);
1313 let total_time = optimized_gates.iter().map(|g| g.duration).sum();
1314
1315 Ok(OptimizedSequence {
1316 gates: optimized_gates,
1317 total_fidelity,
1318 total_time,
1319 metrics: OptimizationMetrics {
1320 original_gate_count: gates.len(),
1321 optimized_gate_count: gates.len(),
1322 gate_count_reduction: 0.0,
1323 original_depth: gates.len(),
1324 optimized_depth: gates.len(),
1325 depth_reduction: 0.0,
1326 fidelity_improvement: total_fidelity,
1327 compilation_time: Duration::from_millis(1),
1328 },
1329 })
1330 }
1331
1332 fn estimate_fidelity(&self, sequence: &[CompiledGate]) -> f64 {
1333 sequence.iter().map(|g| g.fidelity).product()
1334 }
1335
1336 fn get_constraints(&self) -> PlatformConstraints {
1337 PlatformConstraints {
1338 max_qubits: 100,
1339 gate_limitations: vec![],
1340 timing_constraints: TimingConstraints {
1341 min_gate_separation: Duration::from_micros(1),
1342 max_parallel_ops: 10,
1343 qubit_timing: HashMap::new(),
1344 },
1345 error_model: ErrorModel {
1346 single_qubit_errors: HashMap::new(),
1347 two_qubit_errors: HashMap::new(),
1348 readout_errors: HashMap::new(),
1349 idle_decay_rates: HashMap::new(),
1350 },
1351 }
1352 }
1353}
1354
1355#[derive(Debug)]
1356struct PhotonicOptimizer;
1357
1358impl PhotonicOptimizer {
1359 const fn new() -> Self {
1360 Self
1361 }
1362}
1363
1364impl PlatformOptimizer for PhotonicOptimizer {
1365 fn optimize_sequence(
1366 &self,
1367 gates: &[CompiledGate],
1368 _config: &HardwareCompilationConfig,
1369 ) -> QuantRS2Result<OptimizedSequence> {
1370 let optimized_gates = gates.to_vec();
1371 let total_fidelity = self.estimate_fidelity(&optimized_gates);
1372 let total_time = optimized_gates.iter().map(|g| g.duration).sum();
1373
1374 Ok(OptimizedSequence {
1375 gates: optimized_gates,
1376 total_fidelity,
1377 total_time,
1378 metrics: OptimizationMetrics {
1379 original_gate_count: gates.len(),
1380 optimized_gate_count: gates.len(),
1381 gate_count_reduction: 0.0,
1382 original_depth: gates.len(),
1383 optimized_depth: gates.len(),
1384 depth_reduction: 0.0,
1385 fidelity_improvement: total_fidelity,
1386 compilation_time: Duration::from_millis(1),
1387 },
1388 })
1389 }
1390
1391 fn estimate_fidelity(&self, sequence: &[CompiledGate]) -> f64 {
1392 sequence.iter().map(|g| g.fidelity).product()
1393 }
1394
1395 fn get_constraints(&self) -> PlatformConstraints {
1396 PlatformConstraints {
1397 max_qubits: 216, gate_limitations: vec![],
1399 timing_constraints: TimingConstraints {
1400 min_gate_separation: Duration::from_nanos(1),
1401 max_parallel_ops: 50,
1402 qubit_timing: HashMap::new(),
1403 },
1404 error_model: ErrorModel {
1405 single_qubit_errors: HashMap::new(),
1406 two_qubit_errors: HashMap::new(),
1407 readout_errors: HashMap::new(),
1408 idle_decay_rates: HashMap::new(),
1409 },
1410 }
1411 }
1412}
1413
1414#[derive(Debug)]
1415struct NeutralAtomOptimizer;
1416
1417impl NeutralAtomOptimizer {
1418 const fn new() -> Self {
1419 Self
1420 }
1421}
1422
1423impl PlatformOptimizer for NeutralAtomOptimizer {
1424 fn optimize_sequence(
1425 &self,
1426 gates: &[CompiledGate],
1427 _config: &HardwareCompilationConfig,
1428 ) -> QuantRS2Result<OptimizedSequence> {
1429 let optimized_gates = gates.to_vec();
1430 let total_fidelity = self.estimate_fidelity(&optimized_gates);
1431 let total_time = optimized_gates.iter().map(|g| g.duration).sum();
1432
1433 Ok(OptimizedSequence {
1434 gates: optimized_gates,
1435 total_fidelity,
1436 total_time,
1437 metrics: OptimizationMetrics {
1438 original_gate_count: gates.len(),
1439 optimized_gate_count: gates.len(),
1440 gate_count_reduction: 0.0,
1441 original_depth: gates.len(),
1442 optimized_depth: gates.len(),
1443 depth_reduction: 0.0,
1444 fidelity_improvement: total_fidelity,
1445 compilation_time: Duration::from_millis(1),
1446 },
1447 })
1448 }
1449
1450 fn estimate_fidelity(&self, sequence: &[CompiledGate]) -> f64 {
1451 sequence.iter().map(|g| g.fidelity).product()
1452 }
1453
1454 fn get_constraints(&self) -> PlatformConstraints {
1455 PlatformConstraints {
1456 max_qubits: 256,
1457 gate_limitations: vec![],
1458 timing_constraints: TimingConstraints {
1459 min_gate_separation: Duration::from_micros(1),
1460 max_parallel_ops: 20,
1461 qubit_timing: HashMap::new(),
1462 },
1463 error_model: ErrorModel {
1464 single_qubit_errors: HashMap::new(),
1465 two_qubit_errors: HashMap::new(),
1466 readout_errors: HashMap::new(),
1467 idle_decay_rates: HashMap::new(),
1468 },
1469 }
1470 }
1471}
1472
1473impl HardwareCompiler {
1475 pub fn for_superconducting(topology: HardwareTopology) -> QuantRS2Result<Self> {
1477 let config = HardwareCompilationConfig {
1478 platform: HardwarePlatform::Superconducting,
1479 native_gates: create_superconducting_gate_set(),
1480 topology,
1481 optimization_objectives: vec![
1482 OptimizationObjective::MinimizeGateCount,
1483 OptimizationObjective::MaximizeFidelity,
1484 ],
1485 tolerances: CompilationTolerances {
1486 decomposition_tolerance: 1e-12,
1487 parameter_tolerance: 1e-10,
1488 fidelity_threshold: 0.99,
1489 max_compilation_time: Duration::from_secs(60),
1490 },
1491 enable_crosstalk_mitigation: true,
1492 use_pulse_optimization: true,
1493 };
1494
1495 Self::new(config)
1496 }
1497
1498 pub fn for_trapped_ion(topology: HardwareTopology) -> QuantRS2Result<Self> {
1500 let config = HardwareCompilationConfig {
1501 platform: HardwarePlatform::TrappedIon,
1502 native_gates: create_trapped_ion_gate_set(),
1503 topology,
1504 optimization_objectives: vec![
1505 OptimizationObjective::MinimizeTime,
1506 OptimizationObjective::MaximizeFidelity,
1507 ],
1508 tolerances: CompilationTolerances {
1509 decomposition_tolerance: 1e-14,
1510 parameter_tolerance: 1e-12,
1511 fidelity_threshold: 0.995,
1512 max_compilation_time: Duration::from_secs(120),
1513 },
1514 enable_crosstalk_mitigation: false,
1515 use_pulse_optimization: true,
1516 };
1517
1518 Self::new(config)
1519 }
1520}
1521
1522fn create_superconducting_gate_set() -> NativeGateSet {
1524 let mut gate_fidelities = HashMap::new();
1525 gate_fidelities.insert(NativeGateType::VirtualZ, 1.0);
1526 gate_fidelities.insert(NativeGateType::Rx, 0.9995);
1527 gate_fidelities.insert(NativeGateType::Ry, 0.9995);
1528 gate_fidelities.insert(NativeGateType::CNOT, 0.995);
1529
1530 let mut gate_durations = HashMap::new();
1531 gate_durations.insert(NativeGateType::VirtualZ, Duration::from_nanos(0));
1532 gate_durations.insert(NativeGateType::Rx, Duration::from_nanos(20));
1533 gate_durations.insert(NativeGateType::Ry, Duration::from_nanos(20));
1534 gate_durations.insert(NativeGateType::CNOT, Duration::from_nanos(300));
1535
1536 NativeGateSet {
1537 single_qubit_gates: vec![
1538 NativeGateType::Rx,
1539 NativeGateType::Ry,
1540 NativeGateType::VirtualZ,
1541 ],
1542 two_qubit_gates: vec![NativeGateType::CNOT],
1543 multi_qubit_gates: vec![],
1544 parametric_constraints: HashMap::new(),
1545 gate_fidelities,
1546 gate_durations,
1547 }
1548}
1549
1550fn create_trapped_ion_gate_set() -> NativeGateSet {
1551 let mut gate_fidelities = HashMap::new();
1552 gate_fidelities.insert(NativeGateType::Rx, 0.9999);
1553 gate_fidelities.insert(NativeGateType::Ry, 0.9999);
1554 gate_fidelities.insert(NativeGateType::Rz, 0.9999);
1555 gate_fidelities.insert(NativeGateType::MS, 0.998);
1556
1557 let mut gate_durations = HashMap::new();
1558 gate_durations.insert(NativeGateType::Rx, Duration::from_micros(10));
1559 gate_durations.insert(NativeGateType::Ry, Duration::from_micros(10));
1560 gate_durations.insert(NativeGateType::Rz, Duration::from_micros(1));
1561 gate_durations.insert(NativeGateType::MS, Duration::from_micros(100));
1562
1563 NativeGateSet {
1564 single_qubit_gates: vec![NativeGateType::Rx, NativeGateType::Ry, NativeGateType::Rz],
1565 two_qubit_gates: vec![NativeGateType::MS],
1566 multi_qubit_gates: vec![NativeGateType::MS], parametric_constraints: HashMap::new(),
1568 gate_fidelities,
1569 gate_durations,
1570 }
1571}
1572
1573#[cfg(test)]
1574mod tests {
1575 use super::*;
1576 use crate::qubit::QubitId;
1577 use scirs2_core::Complex64;
1578 use std::collections::{HashMap, HashSet};
1579
1580 fn create_test_topology() -> HardwareTopology {
1581 let mut connectivity = HashMap::new();
1582 let mut qubit_positions = HashMap::new();
1583
1584 for i in 0..4 {
1586 let qubit = QubitId::new(i);
1587 qubit_positions.insert(qubit, (i as f64, 0.0, 0.0));
1588
1589 let mut neighbors = HashSet::new();
1590 if i > 0 {
1591 neighbors.insert(QubitId::new(i - 1));
1592 }
1593 if i < 3 {
1594 neighbors.insert(QubitId::new(i + 1));
1595 }
1596 connectivity.insert(qubit, neighbors);
1597 }
1598
1599 HardwareTopology {
1600 connectivity,
1601 qubit_positions,
1602 coupling_strengths: HashMap::new(),
1603 crosstalk_matrix: Array2::zeros((4, 4)),
1604 max_parallel_ops: 2,
1605 }
1606 }
1607
1608 #[test]
1609 fn test_superconducting_compiler_creation() {
1610 let topology = create_test_topology();
1611 let compiler = HardwareCompiler::for_superconducting(topology);
1612 assert!(compiler.is_ok());
1613
1614 let compiler = compiler.expect("superconducting compiler creation failed");
1615 assert_eq!(compiler.config.platform, HardwarePlatform::Superconducting);
1616 assert!(compiler
1617 .config
1618 .native_gates
1619 .single_qubit_gates
1620 .contains(&NativeGateType::VirtualZ));
1621 }
1622
1623 #[test]
1624 fn test_trapped_ion_compiler_creation() {
1625 let topology = create_test_topology();
1626 let compiler = HardwareCompiler::for_trapped_ion(topology);
1627 assert!(compiler.is_ok());
1628
1629 let compiler = compiler.expect("trapped ion compiler creation failed");
1630 assert_eq!(compiler.config.platform, HardwarePlatform::TrappedIon);
1631 assert!(compiler
1632 .config
1633 .native_gates
1634 .two_qubit_gates
1635 .contains(&NativeGateType::MS));
1636 }
1637
1638 #[test]
1639 fn test_connectivity_check() {
1640 let topology = create_test_topology();
1641 let compiler =
1642 HardwareCompiler::for_superconducting(topology).expect("compiler creation failed");
1643
1644 assert!(compiler
1646 .check_connectivity(QubitId::new(0), QubitId::new(1))
1647 .expect("connectivity check failed"));
1648 assert!(compiler
1649 .check_connectivity(QubitId::new(1), QubitId::new(2))
1650 .expect("connectivity check failed"));
1651
1652 assert!(!compiler
1654 .check_connectivity(QubitId::new(0), QubitId::new(2))
1655 .expect("connectivity check failed"));
1656 assert!(!compiler
1657 .check_connectivity(QubitId::new(0), QubitId::new(3))
1658 .expect("connectivity check failed"));
1659 }
1660
1661 #[test]
1662 fn test_shortest_path_finding() {
1663 let topology = create_test_topology();
1664 let compiler =
1665 HardwareCompiler::for_superconducting(topology).expect("compiler creation failed");
1666
1667 let path = compiler
1669 .find_shortest_path(QubitId::new(0), QubitId::new(1))
1670 .expect("path finding failed");
1671 assert_eq!(path, vec![QubitId::new(0), QubitId::new(1)]);
1672
1673 let path = compiler
1675 .find_shortest_path(QubitId::new(0), QubitId::new(3))
1676 .expect("path finding failed");
1677 assert_eq!(
1678 path,
1679 vec![
1680 QubitId::new(0),
1681 QubitId::new(1),
1682 QubitId::new(2),
1683 QubitId::new(3)
1684 ]
1685 );
1686 }
1687
1688 #[test]
1689 fn test_virtual_z_optimization() {
1690 let optimizer = SuperconductingOptimizer::new();
1691
1692 let gates = vec![
1693 CompiledGate {
1694 gate_type: NativeGateType::VirtualZ,
1695 qubits: vec![QubitId::new(0)],
1696 parameters: vec![0.5],
1697 fidelity: 1.0,
1698 duration: Duration::from_nanos(0),
1699 pulse_sequence: None,
1700 },
1701 CompiledGate {
1702 gate_type: NativeGateType::VirtualZ,
1703 qubits: vec![QubitId::new(0)],
1704 parameters: vec![0.3],
1705 fidelity: 1.0,
1706 duration: Duration::from_nanos(0),
1707 pulse_sequence: None,
1708 },
1709 CompiledGate {
1710 gate_type: NativeGateType::Rx,
1711 qubits: vec![QubitId::new(0)],
1712 parameters: vec![1.0],
1713 fidelity: 0.999,
1714 duration: Duration::from_nanos(20),
1715 pulse_sequence: None,
1716 },
1717 ];
1718
1719 let optimized = optimizer
1720 .fuse_virtual_z_gates(&gates)
1721 .expect("virtual z gate fusion failed");
1722 assert_eq!(optimized.len(), 2); assert_eq!(optimized[0].gate_type, NativeGateType::VirtualZ);
1724 assert!((optimized[0].parameters[0] - 0.8).abs() < 1e-10); }
1726
1727 #[test]
1728 fn test_gate_fidelity_calculation() {
1729 let topology = create_test_topology();
1730 let compiler =
1731 HardwareCompiler::for_superconducting(topology).expect("compiler creation failed");
1732
1733 assert_eq!(compiler.get_gate_fidelity(NativeGateType::VirtualZ), 1.0);
1735
1736 assert!(compiler.get_gate_fidelity(NativeGateType::Rx) > 0.999);
1738
1739 assert!(
1741 compiler.get_gate_fidelity(NativeGateType::CNOT)
1742 < compiler.get_gate_fidelity(NativeGateType::Rx)
1743 );
1744 }
1745
1746 #[test]
1747 fn test_platform_constraints() {
1748 let superconducting_optimizer = SuperconductingOptimizer::new();
1749 let constraints = superconducting_optimizer.get_constraints();
1750
1751 assert!(constraints.max_qubits >= 100); assert!(constraints.timing_constraints.min_gate_separation < Duration::from_micros(1));
1753 }
1754
1755 #[test]
1756 fn test_compilation_performance_tracking() {
1757 let topology = create_test_topology();
1758 let compiler =
1759 HardwareCompiler::for_superconducting(topology).expect("compiler creation failed");
1760
1761 compiler.record_compilation_time(Duration::from_millis(10));
1763 compiler.record_compilation_time(Duration::from_millis(15));
1764 compiler.record_compilation_time(Duration::from_millis(12));
1765
1766 let stats = compiler.get_performance_stats();
1767 assert_eq!(stats.total_compilations, 3);
1768 assert!(stats.average_compilation_time > Duration::from_millis(10));
1769 assert!(stats.average_compilation_time < Duration::from_millis(15));
1770 }
1771
1772 #[test]
1773 fn test_cache_functionality() {
1774 let topology = create_test_topology();
1775 let compiler =
1776 HardwareCompiler::for_superconducting(topology).expect("compiler creation failed");
1777
1778 let test_gates = vec![CompiledGate {
1779 gate_type: NativeGateType::Rx,
1780 qubits: vec![QubitId::new(0)],
1781 parameters: vec![1.0],
1782 fidelity: 0.999,
1783 duration: Duration::from_nanos(20),
1784 pulse_sequence: None,
1785 }];
1786
1787 let cache_key = "test_gate_0";
1789 compiler
1790 .cache_result(cache_key, &test_gates)
1791 .expect("cache result failed");
1792
1793 let cached_result = compiler.check_cache(cache_key).expect("check cache failed");
1795 assert!(cached_result.is_some());
1796
1797 let cached_gates = cached_result.expect("cached result should be Some");
1798 assert_eq!(cached_gates.len(), 1);
1799 assert_eq!(cached_gates[0].gate_type, NativeGateType::Rx);
1800 }
1801
1802 #[test]
1803 fn test_z_rotation_detection() {
1804 let topology = create_test_topology();
1805 let compiler =
1806 HardwareCompiler::for_superconducting(topology).expect("compiler creation failed");
1807
1808 let angle = std::f64::consts::PI / 4.0;
1810 let mut z_matrix = Array2::zeros((2, 2));
1811 z_matrix[(0, 0)] = Complex64::from_polar(1.0, -angle / 2.0);
1812 z_matrix[(1, 1)] = Complex64::from_polar(1.0, angle / 2.0);
1813
1814 let dense_z_matrix = DenseMatrix::new(z_matrix).expect("matrix creation failed");
1815 assert!(compiler
1816 .is_z_rotation(&dense_z_matrix)
1817 .expect("z rotation check failed"));
1818
1819 let extracted_angle = compiler
1820 .extract_z_rotation_angle(&dense_z_matrix)
1821 .expect("angle extraction failed");
1822 assert!((extracted_angle - angle).abs() < 1e-10);
1823 }
1824
1825 #[test]
1826 fn test_euler_angle_extraction() {
1827 let topology = create_test_topology();
1828 let compiler =
1829 HardwareCompiler::for_superconducting(topology).expect("compiler creation failed");
1830
1831 let mut identity = Array2::zeros((2, 2));
1833 identity[(0, 0)] = Complex64::new(1.0, 0.0);
1834 identity[(1, 1)] = Complex64::new(1.0, 0.0);
1835
1836 let dense_identity = DenseMatrix::new(identity).expect("matrix creation failed");
1837 let (theta, _phi, _lambda) = compiler
1838 .extract_euler_angles(&dense_identity)
1839 .expect("euler angle extraction failed");
1840
1841 assert!(theta.abs() < 1e-10);
1843 }
1844
1845 #[test]
1846 fn test_optimization_metrics_calculation() {
1847 let optimizer = SuperconductingOptimizer::new();
1848
1849 let original_gates = vec![
1850 CompiledGate {
1851 gate_type: NativeGateType::VirtualZ,
1852 qubits: vec![QubitId::new(0)],
1853 parameters: vec![0.5],
1854 fidelity: 1.0,
1855 duration: Duration::from_nanos(0),
1856 pulse_sequence: None,
1857 },
1858 CompiledGate {
1859 gate_type: NativeGateType::VirtualZ,
1860 qubits: vec![QubitId::new(0)],
1861 parameters: vec![0.3],
1862 fidelity: 1.0,
1863 duration: Duration::from_nanos(0),
1864 pulse_sequence: None,
1865 },
1866 ];
1867
1868 let optimized_gates = vec![CompiledGate {
1869 gate_type: NativeGateType::VirtualZ,
1870 qubits: vec![QubitId::new(0)],
1871 parameters: vec![0.8],
1872 fidelity: 1.0,
1873 duration: Duration::from_nanos(0),
1874 pulse_sequence: None,
1875 }];
1876
1877 let metrics = optimizer.calculate_metrics(&original_gates, &optimized_gates, 1.0);
1878
1879 assert_eq!(metrics.original_gate_count, 2);
1880 assert_eq!(metrics.optimized_gate_count, 1);
1881 assert_eq!(metrics.gate_count_reduction, 50.0); }
1883}