Skip to main content

quantrs2_sim/circuit_interfaces/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use crate::error::{Result, SimulatorError};
6use crate::scirs2_integration::SciRS2Backend;
7use crate::sparse::CSRMatrix;
8use crate::statevector::StateVectorSimulator;
9#[cfg(feature = "advanced_math")]
10#[allow(unused_imports)]
11use crate::tensor_network::TensorNetwork;
12use scirs2_core::ndarray::{Array1, Array2};
13use scirs2_core::Complex64;
14use serde::{Deserialize, Serialize};
15use std::collections::hash_map::DefaultHasher;
16use std::collections::HashMap;
17use std::hash::{Hash, Hasher};
18use std::sync::{Arc, Mutex};
19
20/// Stabilizer operation for Clifford circuits
21#[derive(Debug, Clone)]
22pub enum StabilizerOp {
23    H(usize),
24    S(usize),
25    CNOT(usize, usize),
26    X(usize),
27    Y(usize),
28    Z(usize),
29}
30/// Circuit interface for simulation backends
31pub struct CircuitInterface {
32    /// Configuration
33    config: CircuitInterfaceConfig,
34    /// `SciRS2` backend for optimization
35    backend: Option<SciRS2Backend>,
36    /// Circuit cache
37    circuit_cache: Arc<Mutex<HashMap<u64, CompiledCircuit>>>,
38    /// Performance statistics
39    stats: CircuitInterfaceStats,
40}
41impl CircuitInterface {
42    /// Create new circuit interface
43    pub fn new(config: CircuitInterfaceConfig) -> Result<Self> {
44        Ok(Self {
45            config,
46            backend: None,
47            circuit_cache: Arc::new(Mutex::new(HashMap::new())),
48            stats: CircuitInterfaceStats::default(),
49        })
50    }
51    /// Initialize with `SciRS2` backend
52    pub fn with_backend(mut self) -> Result<Self> {
53        self.backend = Some(SciRS2Backend::new());
54        Ok(self)
55    }
56    /// Compile circuit for execution
57    pub fn compile_circuit(
58        &mut self,
59        circuit: &InterfaceCircuit,
60        backend: SimulationBackend,
61    ) -> Result<CompiledCircuit> {
62        let start_time = std::time::Instant::now();
63        let circuit_hash = self.calculate_circuit_hash(circuit);
64        if self.config.enable_circuit_cache {
65            let cache = self
66                .circuit_cache
67                .lock()
68                .expect("circuit cache lock should not be poisoned");
69            if let Some(compiled) = cache.get(&circuit_hash) {
70                self.stats.cache_hit_rate = self
71                    .stats
72                    .cache_hit_rate
73                    .mul_add(self.stats.circuits_compiled as f64, 1.0)
74                    / (self.stats.circuits_compiled + 1) as f64;
75                return Ok(compiled.clone());
76            }
77        }
78        let selected_backend = if backend == SimulationBackend::Auto {
79            self.select_optimal_backend(circuit)?
80        } else {
81            backend
82        };
83        let mut optimized_circuit = circuit.clone();
84        let mut optimization_passes = Vec::new();
85        if self.config.enable_optimization {
86            let opt_result = optimized_circuit.optimize();
87            optimization_passes.push("basic_optimization".to_string());
88            self.stats.optimization_stats.total_gates_eliminated += opt_result.gates_eliminated;
89            self.stats.optimization_stats.total_depth_reduction += opt_result.depth_reduction;
90        }
91        let backend_data = self.compile_for_backend(&optimized_circuit, selected_backend)?;
92        let estimated_execution_time_ms =
93            self.estimate_execution_time(&optimized_circuit, selected_backend);
94        let estimated_memory_bytes =
95            self.estimate_memory_requirements(&optimized_circuit, selected_backend);
96        let compilation_time_ms = start_time.elapsed().as_secs_f64() * 1000.0;
97        let compiled = CompiledCircuit {
98            original: circuit.clone(),
99            optimized_gates: optimized_circuit.gates,
100            backend_data,
101            metadata: CompilationMetadata {
102                compilation_time_ms,
103                backend: selected_backend,
104                optimization_passes,
105                estimated_execution_time_ms,
106                estimated_memory_bytes,
107            },
108        };
109        if self.config.enable_circuit_cache {
110            let mut cache = self
111                .circuit_cache
112                .lock()
113                .expect("circuit cache lock should not be poisoned");
114            if cache.len() >= self.config.max_cache_size {
115                if let Some(oldest_key) = cache.keys().next().copied() {
116                    cache.remove(&oldest_key);
117                }
118            }
119            cache.insert(circuit_hash, compiled.clone());
120        }
121        self.stats.circuits_compiled += 1;
122        self.stats.total_compilation_time_ms += compilation_time_ms;
123        *self
124            .stats
125            .backend_selections
126            .entry(format!("{selected_backend:?}"))
127            .or_insert(0) += 1;
128        Ok(compiled)
129    }
130    /// Execute compiled circuit
131    pub fn execute_circuit(
132        &mut self,
133        compiled: &CompiledCircuit,
134        initial_state: Option<Array1<Complex64>>,
135    ) -> Result<CircuitExecutionResult> {
136        let start_time = std::time::Instant::now();
137        let result = match compiled.metadata.backend {
138            SimulationBackend::StateVector => self.execute_statevector(compiled, initial_state)?,
139            SimulationBackend::MPS => self.execute_mps(compiled, initial_state)?,
140            SimulationBackend::Stabilizer => self.execute_stabilizer(compiled)?,
141            SimulationBackend::Sparse => self.execute_sparse(compiled, initial_state)?,
142            #[cfg(feature = "advanced_math")]
143            SimulationBackend::TensorNetwork => {
144                self.execute_tensor_network(compiled, initial_state)?
145            }
146            #[cfg(not(feature = "advanced_math"))]
147            SimulationBackend::TensorNetwork => {
148                return Err(SimulatorError::UnsupportedOperation(
149                    "Tensor network simulation requires advanced_math feature".to_string(),
150                ));
151            }
152            SimulationBackend::Auto => {
153                unreachable!("Auto backend should be resolved during compilation")
154            }
155        };
156        let execution_time_ms = start_time.elapsed().as_secs_f64() * 1000.0;
157        Ok(CircuitExecutionResult {
158            final_state: result.final_state,
159            measurement_results: result.measurement_results,
160            classical_bits: result.classical_bits,
161            execution_time_ms,
162            backend_used: compiled.metadata.backend,
163            memory_used_bytes: result.memory_used_bytes,
164        })
165    }
166    /// Select optimal backend for circuit
167    fn select_optimal_backend(&self, circuit: &InterfaceCircuit) -> Result<SimulationBackend> {
168        let num_qubits = circuit.num_qubits;
169        let two_qubit_gates = circuit.metadata.two_qubit_gates;
170        let total_gates = circuit.gates.len();
171        if self.is_clifford_circuit(circuit) {
172            return Ok(SimulationBackend::Stabilizer);
173        }
174        if num_qubits <= self.config.max_statevector_qubits {
175            return Ok(SimulationBackend::StateVector);
176        }
177        let entanglement_score = two_qubit_gates as f64 / total_gates as f64;
178        if entanglement_score < 0.3 {
179            return Ok(SimulationBackend::MPS);
180        }
181        let sparsity_score = self.estimate_sparsity(circuit);
182        if sparsity_score > 0.8 {
183            return Ok(SimulationBackend::Sparse);
184        }
185        if self.has_tensor_network_structure(circuit) {
186            return Ok(SimulationBackend::TensorNetwork);
187        }
188        Ok(SimulationBackend::MPS)
189    }
190    /// Check if circuit is Clifford
191    pub fn is_clifford_circuit(&self, circuit: &InterfaceCircuit) -> bool {
192        circuit.gates.iter().all(|gate| {
193            matches!(
194                gate.gate_type,
195                InterfaceGateType::Identity
196                    | InterfaceGateType::PauliX
197                    | InterfaceGateType::PauliY
198                    | InterfaceGateType::PauliZ
199                    | InterfaceGateType::Hadamard
200                    | InterfaceGateType::S
201                    | InterfaceGateType::CNOT
202                    | InterfaceGateType::CZ
203                    | InterfaceGateType::SWAP
204                    | InterfaceGateType::Measure
205                    | InterfaceGateType::Reset
206            )
207        })
208    }
209    /// Estimate circuit sparsity
210    fn estimate_sparsity(&self, circuit: &InterfaceCircuit) -> f64 {
211        let single_qubit_gates = circuit.gates.iter().filter(|g| g.num_qubits() == 1).count();
212        single_qubit_gates as f64 / circuit.gates.len() as f64
213    }
214    /// Check if circuit has tensor network structure
215    fn has_tensor_network_structure(&self, circuit: &InterfaceCircuit) -> bool {
216        let depth = circuit.metadata.depth;
217        let num_qubits = circuit.num_qubits;
218        depth > num_qubits && circuit.metadata.complexity_score > 100.0
219    }
220    /// Compile circuit for specific backend
221    fn compile_for_backend(
222        &self,
223        circuit: &InterfaceCircuit,
224        backend: SimulationBackend,
225    ) -> Result<BackendCompiledData> {
226        match backend {
227            SimulationBackend::StateVector => {
228                let mut unitary_matrices = Vec::new();
229                let mut gate_indices = Vec::new();
230                for gate in &circuit.gates {
231                    if gate.is_unitary() {
232                        unitary_matrices.push(gate.unitary_matrix()?);
233                        gate_indices.push(gate.qubits.clone());
234                    }
235                }
236                Ok(BackendCompiledData::StateVector {
237                    unitary_matrices,
238                    gate_indices,
239                })
240            }
241            SimulationBackend::MPS => {
242                let bond_dimensions = self.calculate_optimal_bond_dimensions(circuit);
243                let truncation_thresholds = vec![1e-12; circuit.gates.len()];
244                Ok(BackendCompiledData::MPS {
245                    bond_dimensions,
246                    truncation_thresholds,
247                })
248            }
249            SimulationBackend::Stabilizer => {
250                let mut clifford_sequence = Vec::new();
251                for gate in &circuit.gates {
252                    match &gate.gate_type {
253                        InterfaceGateType::Hadamard => {
254                            clifford_sequence.push(StabilizerOp::H(gate.qubits[0]));
255                        }
256                        InterfaceGateType::S => {
257                            clifford_sequence.push(StabilizerOp::S(gate.qubits[0]));
258                        }
259                        InterfaceGateType::PauliX => {
260                            clifford_sequence.push(StabilizerOp::X(gate.qubits[0]));
261                        }
262                        InterfaceGateType::PauliY => {
263                            clifford_sequence.push(StabilizerOp::Y(gate.qubits[0]));
264                        }
265                        InterfaceGateType::PauliZ => {
266                            clifford_sequence.push(StabilizerOp::Z(gate.qubits[0]));
267                        }
268                        InterfaceGateType::CNOT => clifford_sequence
269                            .push(StabilizerOp::CNOT(gate.qubits[0], gate.qubits[1])),
270                        _ => {}
271                    }
272                }
273                Ok(BackendCompiledData::Stabilizer { clifford_sequence })
274            }
275            SimulationBackend::Sparse => {
276                let sparse_matrices = Vec::new();
277                Ok(BackendCompiledData::Sparse { sparse_matrices })
278            }
279            SimulationBackend::TensorNetwork => {
280                let mut unitary_matrices = Vec::new();
281                let mut gate_indices = Vec::new();
282                for gate in &circuit.gates {
283                    if gate.is_unitary() {
284                        unitary_matrices.push(gate.unitary_matrix()?);
285                        gate_indices.push(gate.qubits.clone());
286                    }
287                }
288                Ok(BackendCompiledData::StateVector {
289                    unitary_matrices,
290                    gate_indices,
291                })
292            }
293            SimulationBackend::Auto => unreachable!(),
294        }
295    }
296    /// Calculate optimal bond dimensions for MPS
297    fn calculate_optimal_bond_dimensions(&self, circuit: &InterfaceCircuit) -> Vec<usize> {
298        let base_bond_dim = self.config.max_mps_bond_dim.min(64);
299        vec![base_bond_dim; circuit.num_qubits - 1]
300    }
301    /// Execute state vector simulation
302    fn execute_statevector(
303        &self,
304        compiled: &CompiledCircuit,
305        initial_state: Option<Array1<Complex64>>,
306    ) -> Result<BackendExecutionResult> {
307        let _simulator = StateVectorSimulator::new();
308        let num_qubits = compiled.original.num_qubits;
309        let state_size = 1 << num_qubits;
310        let final_state = initial_state.unwrap_or_else(|| {
311            let mut state = Array1::zeros(state_size);
312            state[0] = Complex64::new(1.0, 0.0);
313            state
314        });
315        let memory_used = final_state.len() * std::mem::size_of::<Complex64>();
316        Ok(BackendExecutionResult {
317            final_state: Some(final_state),
318            measurement_results: Vec::new(),
319            classical_bits: vec![false; compiled.original.num_classical],
320            memory_used_bytes: memory_used,
321        })
322    }
323    /// Execute MPS simulation
324    fn execute_mps(
325        &self,
326        compiled: &CompiledCircuit,
327        initial_state: Option<Array1<Complex64>>,
328    ) -> Result<BackendExecutionResult> {
329        Ok(BackendExecutionResult {
330            final_state: None,
331            measurement_results: Vec::new(),
332            classical_bits: vec![false; compiled.original.num_classical],
333            memory_used_bytes: 0,
334        })
335    }
336    /// Execute stabilizer simulation
337    fn execute_stabilizer(&self, compiled: &CompiledCircuit) -> Result<BackendExecutionResult> {
338        Ok(BackendExecutionResult {
339            final_state: None,
340            measurement_results: Vec::new(),
341            classical_bits: vec![false; compiled.original.num_classical],
342            memory_used_bytes: 0,
343        })
344    }
345    /// Execute sparse simulation
346    fn execute_sparse(
347        &self,
348        compiled: &CompiledCircuit,
349        initial_state: Option<Array1<Complex64>>,
350    ) -> Result<BackendExecutionResult> {
351        Ok(BackendExecutionResult {
352            final_state: None,
353            measurement_results: Vec::new(),
354            classical_bits: vec![false; compiled.original.num_classical],
355            memory_used_bytes: 0,
356        })
357    }
358    /// Execute tensor network simulation
359    #[cfg(feature = "advanced_math")]
360    fn execute_tensor_network(
361        &self,
362        compiled: &CompiledCircuit,
363        initial_state: Option<Array1<Complex64>>,
364    ) -> Result<BackendExecutionResult> {
365        Ok(BackendExecutionResult {
366            final_state: None,
367            measurement_results: Vec::new(),
368            classical_bits: vec![false; compiled.original.num_classical],
369            memory_used_bytes: 0,
370        })
371    }
372    #[cfg(not(feature = "advanced_math"))]
373    fn execute_tensor_network(
374        &self,
375        _compiled: &CompiledCircuit,
376        _initial_state: Option<Array1<Complex64>>,
377    ) -> Result<BackendExecutionResult> {
378        Err(SimulatorError::UnsupportedOperation(
379            "Tensor network simulation requires advanced_math feature".to_string(),
380        ))
381    }
382    /// Calculate circuit hash for caching
383    fn calculate_circuit_hash(&self, circuit: &InterfaceCircuit) -> u64 {
384        let mut hasher = DefaultHasher::new();
385        circuit.num_qubits.hash(&mut hasher);
386        circuit.num_classical.hash(&mut hasher);
387        for gate in &circuit.gates {
388            std::mem::discriminant(&gate.gate_type).hash(&mut hasher);
389            match &gate.gate_type {
390                InterfaceGateType::Phase(angle)
391                | InterfaceGateType::RX(angle)
392                | InterfaceGateType::RY(angle)
393                | InterfaceGateType::RZ(angle) => {
394                    angle.to_bits().hash(&mut hasher);
395                }
396                _ => {}
397            }
398            gate.qubits.hash(&mut hasher);
399        }
400        hasher.finish()
401    }
402    /// Estimate execution time
403    fn estimate_execution_time(
404        &self,
405        circuit: &InterfaceCircuit,
406        backend: SimulationBackend,
407    ) -> f64 {
408        let base_time_per_gate = match backend {
409            SimulationBackend::StateVector => 0.1,
410            SimulationBackend::MPS => 1.0,
411            SimulationBackend::Stabilizer => 0.01,
412            SimulationBackend::Sparse => 0.5,
413            SimulationBackend::TensorNetwork => 2.0,
414            SimulationBackend::Auto => 1.0,
415        };
416        circuit.gates.len() as f64 * base_time_per_gate * (1.1_f64).powi(circuit.num_qubits as i32)
417    }
418    /// Estimate memory requirements
419    fn estimate_memory_requirements(
420        &self,
421        circuit: &InterfaceCircuit,
422        backend: SimulationBackend,
423    ) -> usize {
424        match backend {
425            SimulationBackend::StateVector => {
426                (1_usize << circuit.num_qubits) * std::mem::size_of::<Complex64>()
427            }
428            SimulationBackend::MPS => {
429                circuit.num_qubits
430                    * self.config.max_mps_bond_dim
431                    * self.config.max_mps_bond_dim
432                    * std::mem::size_of::<Complex64>()
433            }
434            SimulationBackend::Stabilizer => circuit.num_qubits * circuit.num_qubits * 2,
435            SimulationBackend::Sparse => {
436                circuit.gates.len() * 1000 * std::mem::size_of::<Complex64>()
437            }
438            SimulationBackend::TensorNetwork => {
439                circuit.num_qubits * 64 * std::mem::size_of::<Complex64>()
440            }
441            SimulationBackend::Auto => 0,
442        }
443    }
444    /// Get performance statistics
445    #[must_use]
446    pub const fn get_stats(&self) -> &CircuitInterfaceStats {
447        &self.stats
448    }
449    /// Reset performance statistics
450    pub fn reset_stats(&mut self) {
451        self.stats = CircuitInterfaceStats::default();
452    }
453}
454/// Circuit metadata
455#[derive(Debug, Clone, Default, Serialize, Deserialize)]
456pub struct CircuitMetadata {
457    /// Circuit name
458    pub name: Option<String>,
459    /// Circuit description
460    pub description: Option<String>,
461    /// Creation timestamp
462    #[serde(skip)]
463    pub created_at: Option<std::time::SystemTime>,
464    /// Circuit depth
465    pub depth: usize,
466    /// Number of two-qubit gates
467    pub two_qubit_gates: usize,
468    /// Circuit complexity score
469    pub complexity_score: f64,
470    /// Estimated classical simulation complexity
471    pub classical_complexity: Option<f64>,
472}
473/// Backend-specific compiled data
474#[derive(Debug, Clone)]
475pub enum BackendCompiledData {
476    StateVector {
477        unitary_matrices: Vec<Array2<Complex64>>,
478        gate_indices: Vec<Vec<usize>>,
479    },
480    MPS {
481        bond_dimensions: Vec<usize>,
482        truncation_thresholds: Vec<f64>,
483    },
484    Stabilizer {
485        clifford_sequence: Vec<StabilizerOp>,
486    },
487    Sparse {
488        sparse_matrices: Vec<CSRMatrix>,
489    },
490}
491/// Circuit interface utilities
492pub struct CircuitInterfaceUtils;
493impl CircuitInterfaceUtils {
494    /// Create a test circuit
495    #[must_use]
496    pub fn create_test_circuit(circuit_type: &str, num_qubits: usize) -> InterfaceCircuit {
497        let mut circuit = InterfaceCircuit::new(num_qubits, num_qubits);
498        match circuit_type {
499            "ghz" => {
500                circuit.add_gate(InterfaceGate::new(InterfaceGateType::Hadamard, vec![0]));
501                for i in 1..num_qubits {
502                    circuit.add_gate(InterfaceGate::new(InterfaceGateType::CNOT, vec![0, i]));
503                }
504            }
505            "qft" => {
506                for i in 0..num_qubits {
507                    circuit.add_gate(InterfaceGate::new(InterfaceGateType::Hadamard, vec![i]));
508                    for j in i + 1..num_qubits {
509                        let angle = std::f64::consts::PI / f64::from(1 << (j - i));
510                        circuit.add_gate(InterfaceGate::new(
511                            InterfaceGateType::CRZ(angle),
512                            vec![j, i],
513                        ));
514                    }
515                }
516            }
517            "random" => {
518                for _ in 0..num_qubits * 5 {
519                    let qubit = fastrand::usize(0..num_qubits);
520                    let gate_type = match fastrand::usize(0..4) {
521                        0 => InterfaceGateType::Hadamard,
522                        1 => InterfaceGateType::RX(fastrand::f64() * 2.0 * std::f64::consts::PI),
523                        2 => InterfaceGateType::RY(fastrand::f64() * 2.0 * std::f64::consts::PI),
524                        _ => InterfaceGateType::RZ(fastrand::f64() * 2.0 * std::f64::consts::PI),
525                    };
526                    circuit.add_gate(InterfaceGate::new(gate_type, vec![qubit]));
527                }
528            }
529            _ => {
530                for i in 0..num_qubits {
531                    circuit.add_gate(InterfaceGate::new(InterfaceGateType::Identity, vec![i]));
532                }
533            }
534        }
535        circuit
536    }
537    /// Benchmark circuit interface
538    pub fn benchmark_interface(
539        config: CircuitInterfaceConfig,
540    ) -> Result<InterfaceBenchmarkResults> {
541        let mut interface = CircuitInterface::new(config)?;
542        let mut results = InterfaceBenchmarkResults::default();
543        let circuit_types = vec!["ghz", "qft", "random"];
544        let qubit_counts = vec![5, 10, 15, 20];
545        for circuit_type in circuit_types {
546            for &num_qubits in &qubit_counts {
547                let circuit = Self::create_test_circuit(circuit_type, num_qubits);
548                let start = std::time::Instant::now();
549                let compiled = interface.compile_circuit(&circuit, SimulationBackend::Auto)?;
550                let compilation_time = start.elapsed().as_secs_f64() * 1000.0;
551                let start = std::time::Instant::now();
552                let _result = interface.execute_circuit(&compiled, None)?;
553                let execution_time = start.elapsed().as_secs_f64() * 1000.0;
554                results
555                    .compilation_times
556                    .push((format!("{circuit_type}_{num_qubits}"), compilation_time));
557                results
558                    .execution_times
559                    .push((format!("{circuit_type}_{num_qubits}"), execution_time));
560            }
561        }
562        results.interface_stats = interface.get_stats().clone();
563        Ok(results)
564    }
565}
566/// Interface benchmark results
567#[derive(Debug, Clone, Default)]
568pub struct InterfaceBenchmarkResults {
569    /// Compilation times (`circuit_name`, `time_ms`)
570    pub compilation_times: Vec<(String, f64)>,
571    /// Execution times (`circuit_name`, `time_ms`)
572    pub execution_times: Vec<(String, f64)>,
573    /// Interface statistics
574    pub interface_stats: CircuitInterfaceStats,
575}
576/// Quantum circuit representation for interface
577#[derive(Debug, Clone, Serialize, Deserialize)]
578pub struct InterfaceCircuit {
579    /// Number of qubits
580    pub num_qubits: usize,
581    /// Number of classical bits
582    pub num_classical: usize,
583    /// Gates in the circuit
584    pub gates: Vec<InterfaceGate>,
585    /// Circuit metadata
586    pub metadata: CircuitMetadata,
587}
588impl InterfaceCircuit {
589    /// Create a new circuit
590    #[must_use]
591    pub fn new(num_qubits: usize, num_classical: usize) -> Self {
592        Self {
593            num_qubits,
594            num_classical,
595            gates: Vec::new(),
596            metadata: CircuitMetadata::default(),
597        }
598    }
599    /// Add a gate to the circuit
600    pub fn add_gate(&mut self, mut gate: InterfaceGate) {
601        gate.position = self.gates.len();
602        self.gates.push(gate);
603        self.update_metadata();
604    }
605    /// Add multiple gates to the circuit
606    pub fn add_gates(&mut self, gates: Vec<InterfaceGate>) {
607        for gate in gates {
608            self.add_gate(gate);
609        }
610    }
611    /// Update circuit metadata
612    fn update_metadata(&mut self) {
613        let depth = self.calculate_depth();
614        let two_qubit_gates = self.gates.iter().filter(|g| g.num_qubits() == 2).count();
615        let complexity_score = self.calculate_complexity_score();
616        self.metadata.depth = depth;
617        self.metadata.two_qubit_gates = two_qubit_gates;
618        self.metadata.complexity_score = complexity_score;
619    }
620    /// Calculate circuit depth
621    #[must_use]
622    pub fn calculate_depth(&self) -> usize {
623        if self.gates.is_empty() {
624            return 0;
625        }
626        let mut qubit_depths = vec![0; self.num_qubits];
627        for gate in &self.gates {
628            let valid_qubits: Vec<usize> = gate
629                .qubits
630                .iter()
631                .filter(|&&q| q < self.num_qubits)
632                .copied()
633                .collect();
634            if valid_qubits.is_empty() {
635                continue;
636            }
637            let max_depth = valid_qubits
638                .iter()
639                .map(|&q| qubit_depths[q])
640                .max()
641                .unwrap_or(0);
642            for &qubit in &valid_qubits {
643                qubit_depths[qubit] = max_depth + 1;
644            }
645        }
646        qubit_depths.into_iter().max().unwrap_or(0)
647    }
648    /// Calculate complexity score
649    fn calculate_complexity_score(&self) -> f64 {
650        let mut score = 0.0;
651        for gate in &self.gates {
652            let gate_score = match gate.num_qubits() {
653                1 => 1.0,
654                2 => 5.0,
655                3 => 25.0,
656                n => (5.0_f64).powi(n as i32 - 1),
657            };
658            score += gate_score;
659        }
660        score
661    }
662    /// Extract subcircuit
663    pub fn subcircuit(&self, start: usize, end: usize) -> Result<Self> {
664        if start >= end || end > self.gates.len() {
665            return Err(SimulatorError::InvalidInput(
666                "Invalid subcircuit range".to_string(),
667            ));
668        }
669        let mut subcircuit = Self::new(self.num_qubits, self.num_classical);
670        subcircuit.gates = self.gates[start..end].to_vec();
671        subcircuit.update_metadata();
672        Ok(subcircuit)
673    }
674    /// Optimize the circuit
675    pub fn optimize(&mut self) -> CircuitOptimizationResult {
676        let original_gates = self.gates.len();
677        let original_depth = self.metadata.depth;
678        self.remove_identity_gates();
679        self.cancel_adjacent_gates();
680        self.merge_rotation_gates();
681        self.optimize_cnot_patterns();
682        self.update_metadata();
683        CircuitOptimizationResult {
684            original_gates,
685            optimized_gates: self.gates.len(),
686            original_depth,
687            optimized_depth: self.metadata.depth,
688            gates_eliminated: original_gates.saturating_sub(self.gates.len()),
689            depth_reduction: original_depth.saturating_sub(self.metadata.depth),
690        }
691    }
692    /// Remove identity gates
693    fn remove_identity_gates(&mut self) {
694        self.gates
695            .retain(|gate| !matches!(gate.gate_type, InterfaceGateType::Identity));
696    }
697    /// Cancel adjacent gates
698    fn cancel_adjacent_gates(&mut self) {
699        let mut i = 0;
700        while i + 1 < self.gates.len() {
701            if self.gates_cancel(&self.gates[i], &self.gates[i + 1]) {
702                self.gates.remove(i);
703                self.gates.remove(i);
704                if i > 0 {
705                    i = i.saturating_sub(1);
706                }
707            } else {
708                i += 1;
709            }
710        }
711    }
712    /// Check if two gates cancel each other
713    fn gates_cancel(&self, gate1: &InterfaceGate, gate2: &InterfaceGate) -> bool {
714        if gate1.qubits != gate2.qubits {
715            return false;
716        }
717        match (&gate1.gate_type, &gate2.gate_type) {
718            (InterfaceGateType::PauliX, InterfaceGateType::PauliX)
719            | (InterfaceGateType::PauliY, InterfaceGateType::PauliY)
720            | (InterfaceGateType::PauliZ, InterfaceGateType::PauliZ)
721            | (InterfaceGateType::Hadamard, InterfaceGateType::Hadamard)
722            | (InterfaceGateType::S, InterfaceGateType::S)
723            | (InterfaceGateType::CNOT, InterfaceGateType::CNOT)
724            | (InterfaceGateType::CZ, InterfaceGateType::CZ)
725            | (InterfaceGateType::SWAP, InterfaceGateType::SWAP) => true,
726            _ => false,
727        }
728    }
729    /// Merge rotation gates
730    fn merge_rotation_gates(&mut self) {
731        let mut i = 0;
732        while i + 1 < self.gates.len() {
733            if let Some(merged) = self.try_merge_rotations(&self.gates[i], &self.gates[i + 1]) {
734                self.gates[i] = merged;
735                self.gates.remove(i + 1);
736            } else {
737                i += 1;
738            }
739        }
740    }
741    /// Try to merge two rotation gates
742    fn try_merge_rotations(
743        &self,
744        gate1: &InterfaceGate,
745        gate2: &InterfaceGate,
746    ) -> Option<InterfaceGate> {
747        if gate1.qubits != gate2.qubits {
748            return None;
749        }
750        match (&gate1.gate_type, &gate2.gate_type) {
751            (InterfaceGateType::RX(angle1), InterfaceGateType::RX(angle2)) => Some(
752                InterfaceGate::new(InterfaceGateType::RX(angle1 + angle2), gate1.qubits.clone()),
753            ),
754            (InterfaceGateType::RY(angle1), InterfaceGateType::RY(angle2)) => Some(
755                InterfaceGate::new(InterfaceGateType::RY(angle1 + angle2), gate1.qubits.clone()),
756            ),
757            (InterfaceGateType::RZ(angle1), InterfaceGateType::RZ(angle2)) => Some(
758                InterfaceGate::new(InterfaceGateType::RZ(angle1 + angle2), gate1.qubits.clone()),
759            ),
760            _ => None,
761        }
762    }
763    /// Optimize CNOT patterns
764    fn optimize_cnot_patterns(&mut self) {
765        let mut i = 0;
766        while i + 2 < self.gates.len() {
767            if self.is_cnot_chain(i) {
768                self.optimize_cnot_chain(i);
769            }
770            i += 1;
771        }
772    }
773    /// Check if there's a CNOT chain starting at position i
774    fn is_cnot_chain(&self, start: usize) -> bool {
775        if start + 2 >= self.gates.len() {
776            return false;
777        }
778        for i in start..start + 3 {
779            if !matches!(self.gates[i].gate_type, InterfaceGateType::CNOT) {
780                return false;
781            }
782        }
783        true
784    }
785    /// Optimize a CNOT chain
786    fn optimize_cnot_chain(&mut self, start: usize) {
787        if start + 2 < self.gates.len() {
788            let gate1 = &self.gates[start];
789            let gate2 = &self.gates[start + 1];
790            let gate3 = &self.gates[start + 2];
791            if gate1.qubits == gate2.qubits && gate2.qubits == gate3.qubits {
792                self.gates.drain(start + 1..start + 3);
793            }
794        }
795    }
796}
797/// Circuit optimization result
798#[derive(Debug, Clone)]
799pub struct CircuitOptimizationResult {
800    /// Original number of gates
801    pub original_gates: usize,
802    /// Optimized number of gates
803    pub optimized_gates: usize,
804    /// Original circuit depth
805    pub original_depth: usize,
806    /// Optimized circuit depth
807    pub optimized_depth: usize,
808    /// Number of gates eliminated
809    pub gates_eliminated: usize,
810    /// Depth reduction achieved
811    pub depth_reduction: usize,
812}
813/// Quantum gate representation for circuit interface
814#[derive(Debug, Clone, Serialize, Deserialize)]
815pub struct InterfaceGate {
816    /// Gate type and parameters
817    pub gate_type: InterfaceGateType,
818    /// Qubits this gate acts on
819    pub qubits: Vec<usize>,
820    /// Classical register targets (for measurements)
821    pub classical_targets: Vec<usize>,
822    /// Gate position in the circuit
823    pub position: usize,
824    /// Conditional execution (if classical bit is 1)
825    pub condition: Option<usize>,
826    /// Gate label for debugging
827    pub label: Option<String>,
828}
829impl InterfaceGate {
830    /// Create a new interface gate
831    #[must_use]
832    pub const fn new(gate_type: InterfaceGateType, qubits: Vec<usize>) -> Self {
833        Self {
834            gate_type,
835            qubits,
836            classical_targets: Vec::new(),
837            position: 0,
838            condition: None,
839            label: None,
840        }
841    }
842    /// Create a measurement gate
843    #[must_use]
844    pub fn measurement(qubit: usize, classical_bit: usize) -> Self {
845        Self {
846            gate_type: InterfaceGateType::Measure,
847            qubits: vec![qubit],
848            classical_targets: vec![classical_bit],
849            position: 0,
850            condition: None,
851            label: None,
852        }
853    }
854    /// Create a conditional gate
855    #[must_use]
856    pub const fn conditional(mut self, condition: usize) -> Self {
857        self.condition = Some(condition);
858        self
859    }
860    /// Add a label to the gate
861    #[must_use]
862    pub fn with_label(mut self, label: String) -> Self {
863        self.label = Some(label);
864        self
865    }
866    /// Get the unitary matrix for this gate
867    pub fn unitary_matrix(&self) -> Result<Array2<Complex64>> {
868        match &self.gate_type {
869            InterfaceGateType::Identity => Ok(Array2::eye(2)),
870            InterfaceGateType::PauliX => Ok(Array2::from_shape_vec(
871                (2, 2),
872                vec![
873                    Complex64::new(0.0, 0.0),
874                    Complex64::new(1.0, 0.0),
875                    Complex64::new(1.0, 0.0),
876                    Complex64::new(0.0, 0.0),
877                ],
878            )
879            .expect("PauliX matrix shape matches data length")),
880            InterfaceGateType::PauliY => Ok(Array2::from_shape_vec(
881                (2, 2),
882                vec![
883                    Complex64::new(0.0, 0.0),
884                    Complex64::new(0.0, -1.0),
885                    Complex64::new(0.0, 1.0),
886                    Complex64::new(0.0, 0.0),
887                ],
888            )
889            .expect("PauliY matrix shape matches data length")),
890            InterfaceGateType::PauliZ => Ok(Array2::from_shape_vec(
891                (2, 2),
892                vec![
893                    Complex64::new(1.0, 0.0),
894                    Complex64::new(0.0, 0.0),
895                    Complex64::new(0.0, 0.0),
896                    Complex64::new(-1.0, 0.0),
897                ],
898            )
899            .expect("PauliZ matrix shape matches data length")),
900            InterfaceGateType::Hadamard => {
901                let inv_sqrt2 = 1.0 / (2.0_f64).sqrt();
902                Ok(Array2::from_shape_vec(
903                    (2, 2),
904                    vec![
905                        Complex64::new(inv_sqrt2, 0.0),
906                        Complex64::new(inv_sqrt2, 0.0),
907                        Complex64::new(inv_sqrt2, 0.0),
908                        Complex64::new(-inv_sqrt2, 0.0),
909                    ],
910                )
911                .expect("Hadamard matrix shape matches data length"))
912            }
913            InterfaceGateType::S => Ok(Array2::from_shape_vec(
914                (2, 2),
915                vec![
916                    Complex64::new(1.0, 0.0),
917                    Complex64::new(0.0, 0.0),
918                    Complex64::new(0.0, 0.0),
919                    Complex64::new(0.0, 1.0),
920                ],
921            )
922            .expect("S gate matrix shape matches data length")),
923            InterfaceGateType::T => {
924                let phase = Complex64::new(0.0, std::f64::consts::PI / 4.0).exp();
925                Ok(Array2::from_shape_vec(
926                    (2, 2),
927                    vec![
928                        Complex64::new(1.0, 0.0),
929                        Complex64::new(0.0, 0.0),
930                        Complex64::new(0.0, 0.0),
931                        phase,
932                    ],
933                )
934                .expect("T gate matrix shape matches data length"))
935            }
936            InterfaceGateType::Phase(theta) => {
937                let phase = Complex64::new(0.0, *theta).exp();
938                Ok(Array2::from_shape_vec(
939                    (2, 2),
940                    vec![
941                        Complex64::new(1.0, 0.0),
942                        Complex64::new(0.0, 0.0),
943                        Complex64::new(0.0, 0.0),
944                        phase,
945                    ],
946                )
947                .expect("Phase gate matrix shape matches data length"))
948            }
949            InterfaceGateType::RX(theta) => {
950                let cos_half = (theta / 2.0).cos();
951                let sin_half = (theta / 2.0).sin();
952                Ok(Array2::from_shape_vec(
953                    (2, 2),
954                    vec![
955                        Complex64::new(cos_half, 0.0),
956                        Complex64::new(0.0, -sin_half),
957                        Complex64::new(0.0, -sin_half),
958                        Complex64::new(cos_half, 0.0),
959                    ],
960                )
961                .expect("RX gate matrix shape matches data length"))
962            }
963            InterfaceGateType::RY(theta) => {
964                let cos_half = (theta / 2.0).cos();
965                let sin_half = (theta / 2.0).sin();
966                Ok(Array2::from_shape_vec(
967                    (2, 2),
968                    vec![
969                        Complex64::new(cos_half, 0.0),
970                        Complex64::new(-sin_half, 0.0),
971                        Complex64::new(sin_half, 0.0),
972                        Complex64::new(cos_half, 0.0),
973                    ],
974                )
975                .expect("RY gate matrix shape matches data length"))
976            }
977            InterfaceGateType::RZ(theta) => {
978                let exp_neg = Complex64::new(0.0, -theta / 2.0).exp();
979                let exp_pos = Complex64::new(0.0, theta / 2.0).exp();
980                Ok(Array2::from_shape_vec(
981                    (2, 2),
982                    vec![
983                        exp_neg,
984                        Complex64::new(0.0, 0.0),
985                        Complex64::new(0.0, 0.0),
986                        exp_pos,
987                    ],
988                )
989                .expect("RZ gate matrix shape matches data length"))
990            }
991            InterfaceGateType::CNOT => Ok(Array2::from_shape_vec(
992                (4, 4),
993                vec![
994                    Complex64::new(1.0, 0.0),
995                    Complex64::new(0.0, 0.0),
996                    Complex64::new(0.0, 0.0),
997                    Complex64::new(0.0, 0.0),
998                    Complex64::new(0.0, 0.0),
999                    Complex64::new(1.0, 0.0),
1000                    Complex64::new(0.0, 0.0),
1001                    Complex64::new(0.0, 0.0),
1002                    Complex64::new(0.0, 0.0),
1003                    Complex64::new(0.0, 0.0),
1004                    Complex64::new(0.0, 0.0),
1005                    Complex64::new(1.0, 0.0),
1006                    Complex64::new(0.0, 0.0),
1007                    Complex64::new(0.0, 0.0),
1008                    Complex64::new(1.0, 0.0),
1009                    Complex64::new(0.0, 0.0),
1010                ],
1011            )
1012            .expect("CNOT matrix shape matches data length")),
1013            InterfaceGateType::CZ => Ok(Array2::from_shape_vec(
1014                (4, 4),
1015                vec![
1016                    Complex64::new(1.0, 0.0),
1017                    Complex64::new(0.0, 0.0),
1018                    Complex64::new(0.0, 0.0),
1019                    Complex64::new(0.0, 0.0),
1020                    Complex64::new(0.0, 0.0),
1021                    Complex64::new(1.0, 0.0),
1022                    Complex64::new(0.0, 0.0),
1023                    Complex64::new(0.0, 0.0),
1024                    Complex64::new(0.0, 0.0),
1025                    Complex64::new(0.0, 0.0),
1026                    Complex64::new(1.0, 0.0),
1027                    Complex64::new(0.0, 0.0),
1028                    Complex64::new(0.0, 0.0),
1029                    Complex64::new(0.0, 0.0),
1030                    Complex64::new(0.0, 0.0),
1031                    Complex64::new(-1.0, 0.0),
1032                ],
1033            )
1034            .expect("CZ matrix shape matches data length")),
1035            InterfaceGateType::SWAP => Ok(Array2::from_shape_vec(
1036                (4, 4),
1037                vec![
1038                    Complex64::new(1.0, 0.0),
1039                    Complex64::new(0.0, 0.0),
1040                    Complex64::new(0.0, 0.0),
1041                    Complex64::new(0.0, 0.0),
1042                    Complex64::new(0.0, 0.0),
1043                    Complex64::new(0.0, 0.0),
1044                    Complex64::new(1.0, 0.0),
1045                    Complex64::new(0.0, 0.0),
1046                    Complex64::new(0.0, 0.0),
1047                    Complex64::new(1.0, 0.0),
1048                    Complex64::new(0.0, 0.0),
1049                    Complex64::new(0.0, 0.0),
1050                    Complex64::new(0.0, 0.0),
1051                    Complex64::new(0.0, 0.0),
1052                    Complex64::new(0.0, 0.0),
1053                    Complex64::new(1.0, 0.0),
1054                ],
1055            )
1056            .expect("SWAP matrix shape matches data length")),
1057            InterfaceGateType::MultiControlledZ(num_controls) => {
1058                let total_qubits = num_controls + 1;
1059                let dim = 1 << total_qubits;
1060                let mut matrix = Array2::eye(dim);
1061                let target_state = (1 << total_qubits) - 1;
1062                matrix[(target_state, target_state)] = Complex64::new(-1.0, 0.0);
1063                Ok(matrix)
1064            }
1065            InterfaceGateType::MultiControlledX(num_controls) => {
1066                let total_qubits = num_controls + 1;
1067                let dim = 1 << total_qubits;
1068                let mut matrix = Array2::eye(dim);
1069                let control_pattern = (1 << *num_controls) - 1;
1070                let target_bit = 1 << num_controls;
1071                let state0 = control_pattern;
1072                let state1 = control_pattern | target_bit;
1073                matrix[(state0, state0)] = Complex64::new(0.0, 0.0);
1074                matrix[(state1, state1)] = Complex64::new(0.0, 0.0);
1075                matrix[(state0, state1)] = Complex64::new(1.0, 0.0);
1076                matrix[(state1, state0)] = Complex64::new(1.0, 0.0);
1077                Ok(matrix)
1078            }
1079            InterfaceGateType::CPhase(phase) => {
1080                let phase_factor = Complex64::new(0.0, *phase).exp();
1081                Ok(Array2::from_shape_vec(
1082                    (4, 4),
1083                    vec![
1084                        Complex64::new(1.0, 0.0),
1085                        Complex64::new(0.0, 0.0),
1086                        Complex64::new(0.0, 0.0),
1087                        Complex64::new(0.0, 0.0),
1088                        Complex64::new(0.0, 0.0),
1089                        Complex64::new(1.0, 0.0),
1090                        Complex64::new(0.0, 0.0),
1091                        Complex64::new(0.0, 0.0),
1092                        Complex64::new(0.0, 0.0),
1093                        Complex64::new(0.0, 0.0),
1094                        Complex64::new(1.0, 0.0),
1095                        Complex64::new(0.0, 0.0),
1096                        Complex64::new(0.0, 0.0),
1097                        Complex64::new(0.0, 0.0),
1098                        Complex64::new(0.0, 0.0),
1099                        phase_factor,
1100                    ],
1101                )
1102                .expect("CPhase matrix shape matches data length"))
1103            }
1104            InterfaceGateType::Custom(_, matrix) => Ok(matrix.clone()),
1105            _ => Err(SimulatorError::UnsupportedOperation(format!(
1106                "Unitary matrix not available for gate type: {:?}",
1107                self.gate_type
1108            ))),
1109        }
1110    }
1111    /// Check if this gate is a measurement
1112    #[must_use]
1113    pub const fn is_measurement(&self) -> bool {
1114        matches!(self.gate_type, InterfaceGateType::Measure)
1115    }
1116    /// Check if this gate is unitary
1117    #[must_use]
1118    pub const fn is_unitary(&self) -> bool {
1119        !matches!(
1120            self.gate_type,
1121            InterfaceGateType::Measure | InterfaceGateType::Reset
1122        )
1123    }
1124    /// Get the number of qubits this gate acts on
1125    #[must_use]
1126    pub fn num_qubits(&self) -> usize {
1127        match &self.gate_type {
1128            InterfaceGateType::MultiControlledX(n) | InterfaceGateType::MultiControlledZ(n) => {
1129                n + 1
1130            }
1131            _ => self.qubits.len(),
1132        }
1133    }
1134}
1135/// Circuit interface performance statistics
1136#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1137pub struct CircuitInterfaceStats {
1138    /// Total circuits compiled
1139    pub circuits_compiled: usize,
1140    /// Total compilation time
1141    pub total_compilation_time_ms: f64,
1142    /// Cache hit rate
1143    pub cache_hit_rate: f64,
1144    /// Backend selection counts
1145    pub backend_selections: HashMap<String, usize>,
1146    /// Optimization statistics
1147    pub optimization_stats: OptimizationStats,
1148}
1149/// Compiled circuit representation
1150#[derive(Debug, Clone)]
1151pub struct CompiledCircuit {
1152    /// Original circuit
1153    pub original: InterfaceCircuit,
1154    /// Optimized gate sequence
1155    pub optimized_gates: Vec<InterfaceGate>,
1156    /// Backend-specific compiled representation
1157    pub backend_data: BackendCompiledData,
1158    /// Compilation metadata
1159    pub metadata: CompilationMetadata,
1160}
1161/// Backend execution result
1162#[derive(Debug)]
1163struct BackendExecutionResult {
1164    final_state: Option<Array1<Complex64>>,
1165    measurement_results: Vec<bool>,
1166    classical_bits: Vec<bool>,
1167    memory_used_bytes: usize,
1168}
1169/// Circuit interface configuration
1170#[derive(Debug, Clone)]
1171pub struct CircuitInterfaceConfig {
1172    /// Enable automatic backend selection
1173    pub auto_backend_selection: bool,
1174    /// Enable circuit optimization during translation
1175    pub enable_optimization: bool,
1176    /// Maximum qubits for state vector simulation
1177    pub max_statevector_qubits: usize,
1178    /// Maximum bond dimension for MPS simulation
1179    pub max_mps_bond_dim: usize,
1180    /// Enable parallel gate compilation
1181    pub parallel_compilation: bool,
1182    /// Cache compiled circuits
1183    pub enable_circuit_cache: bool,
1184    /// Maximum cache size
1185    pub max_cache_size: usize,
1186    /// Enable circuit analysis and profiling
1187    pub enable_profiling: bool,
1188}
1189/// Quantum gate types for circuit interface
1190#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1191pub enum InterfaceGateType {
1192    Identity,
1193    PauliX,
1194    X,
1195    PauliY,
1196    PauliZ,
1197    Hadamard,
1198    H,
1199    S,
1200    T,
1201    Phase(f64),
1202    RX(f64),
1203    RY(f64),
1204    RZ(f64),
1205    U1(f64),
1206    U2(f64, f64),
1207    U3(f64, f64, f64),
1208    CNOT,
1209    CZ,
1210    CY,
1211    SWAP,
1212    ISwap,
1213    CRX(f64),
1214    CRY(f64),
1215    CRZ(f64),
1216    CPhase(f64),
1217    Toffoli,
1218    Fredkin,
1219    MultiControlledX(usize),
1220    MultiControlledZ(usize),
1221    Custom(String, Array2<Complex64>),
1222    Measure,
1223    Reset,
1224}
1225/// Optimization statistics
1226#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1227pub struct OptimizationStats {
1228    /// Total gates eliminated
1229    pub total_gates_eliminated: usize,
1230    /// Total depth reduction
1231    pub total_depth_reduction: usize,
1232    /// Average optimization ratio
1233    pub average_optimization_ratio: f64,
1234}
1235/// Circuit execution result
1236#[derive(Debug)]
1237pub struct CircuitExecutionResult {
1238    /// Final quantum state (if available)
1239    pub final_state: Option<Array1<Complex64>>,
1240    /// Measurement results
1241    pub measurement_results: Vec<bool>,
1242    /// Classical bit values
1243    pub classical_bits: Vec<bool>,
1244    /// Execution time in milliseconds
1245    pub execution_time_ms: f64,
1246    /// Backend used for execution
1247    pub backend_used: SimulationBackend,
1248    /// Memory used in bytes
1249    pub memory_used_bytes: usize,
1250}
1251/// Compilation metadata
1252#[derive(Debug, Clone)]
1253pub struct CompilationMetadata {
1254    /// Compilation time in milliseconds
1255    pub compilation_time_ms: f64,
1256    /// Backend used for compilation
1257    pub backend: SimulationBackend,
1258    /// Optimization passes applied
1259    pub optimization_passes: Vec<String>,
1260    /// Estimated execution time
1261    pub estimated_execution_time_ms: f64,
1262    /// Memory requirements estimate
1263    pub estimated_memory_bytes: usize,
1264}
1265/// Circuit execution backend
1266#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1267pub enum SimulationBackend {
1268    /// State vector simulation
1269    StateVector,
1270    /// Matrix Product State simulation
1271    MPS,
1272    /// Stabilizer simulation (for Clifford circuits)
1273    Stabilizer,
1274    /// Sparse matrix simulation
1275    Sparse,
1276    /// Tensor network simulation
1277    TensorNetwork,
1278    /// Automatic backend selection
1279    Auto,
1280}