Skip to main content

quantrs2_core/
scirs2_quantum_profiler_enhanced.rs

1//! Advanced Quantum Circuit Profiler with Enhanced SciRS2 Performance Metrics
2//!
3//! This module provides state-of-the-art quantum circuit profiling capabilities
4//! with comprehensive performance analysis, resource tracking, and optimization
5//! recommendations using SciRS2's advanced performance metrics.
6
7use crate::error::QuantRS2Error;
8use crate::gate_translation::GateType;
9use crate::scirs2_quantum_profiler::{
10    CircuitProfilingResult, GateProfilingResult, MemoryAnalysis, OptimizationRecommendation,
11    ProfilingPrecision, QuantumGate, SimdAnalysis,
12};
13use scirs2_core::Complex64;
14// use scirs2_core::parallel_ops::*;
15use crate::parallel_ops_stubs::*;
16// use scirs2_core::memory::BufferPool;
17use crate::buffer_pool::BufferPool;
18use crate::platform::PlatformCapabilities;
19use scirs2_core::ndarray::{Array1, Array2, ArrayView1};
20use serde::{Deserialize, Serialize};
21use std::collections::{BTreeMap, HashMap, VecDeque};
22use std::io::Write;
23use std::sync::{
24    atomic::{AtomicU64, AtomicUsize, Ordering},
25    Arc, Mutex,
26};
27use std::time::{Duration, Instant};
28
29/// Enhanced profiling configuration with SciRS2 metrics
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct EnhancedProfilingConfig {
32    /// Base profiling precision
33    pub precision: ProfilingPrecision,
34
35    /// Enable deep performance analysis
36    pub enable_deep_analysis: bool,
37
38    /// Track memory allocation patterns
39    pub track_memory_patterns: bool,
40
41    /// Profile SIMD operations in detail
42    pub profile_simd_operations: bool,
43
44    /// Track parallel execution patterns
45    pub track_parallel_patterns: bool,
46
47    /// Enable cache analysis
48    pub enable_cache_analysis: bool,
49
50    /// Memory bandwidth tracking
51    pub track_memory_bandwidth: bool,
52
53    /// Instruction-level profiling
54    pub enable_instruction_profiling: bool,
55
56    /// Quantum resource estimation
57    pub enable_resource_estimation: bool,
58
59    /// Noise impact analysis
60    pub analyze_noise_impact: bool,
61
62    /// Circuit optimization suggestions
63    pub generate_optimizations: bool,
64
65    /// Bottleneck detection depth
66    pub bottleneck_detection_depth: usize,
67
68    /// Performance prediction model
69    pub enable_performance_prediction: bool,
70
71    /// Hardware-specific optimizations
72    pub hardware_aware_profiling: bool,
73
74    /// Export formats for reports
75    pub export_formats: Vec<ExportFormat>,
76}
77
78impl Default for EnhancedProfilingConfig {
79    fn default() -> Self {
80        Self {
81            precision: ProfilingPrecision::High,
82            enable_deep_analysis: true,
83            track_memory_patterns: true,
84            profile_simd_operations: true,
85            track_parallel_patterns: true,
86            enable_cache_analysis: true,
87            track_memory_bandwidth: true,
88            enable_instruction_profiling: false,
89            enable_resource_estimation: true,
90            analyze_noise_impact: true,
91            generate_optimizations: true,
92            bottleneck_detection_depth: 5,
93            enable_performance_prediction: true,
94            hardware_aware_profiling: true,
95            export_formats: vec![ExportFormat::JSON, ExportFormat::HTML, ExportFormat::CSV],
96        }
97    }
98}
99
100/// Export formats for profiling reports
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
102pub enum ExportFormat {
103    JSON,
104    HTML,
105    CSV,
106    LaTeX,
107    Markdown,
108    Binary,
109}
110
111/// Performance metric types
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
113pub enum MetricType {
114    ExecutionTime,
115    MemoryUsage,
116    CacheHitRate,
117    SimdUtilization,
118    ParallelEfficiency,
119    MemoryBandwidth,
120    InstructionCount,
121    BranchMisprediction,
122    PowerConsumption,
123    ThermalThrottle,
124}
125
126/// Advanced performance metrics
127#[derive(Debug, Clone, Serialize, Deserialize)]
128pub struct PerformanceMetrics {
129    /// Raw metric values
130    pub values: HashMap<MetricType, f64>,
131
132    /// Time-series data for metrics
133    pub time_series: HashMap<MetricType, Vec<(f64, f64)>>,
134
135    /// Statistical analysis
136    pub statistics: MetricStatistics,
137
138    /// Correlations between metrics
139    pub correlations: HashMap<(MetricType, MetricType), f64>,
140
141    /// Anomaly detection results
142    pub anomalies: Vec<AnomalyEvent>,
143}
144
145/// Statistical analysis of metrics
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct MetricStatistics {
148    pub mean: HashMap<MetricType, f64>,
149    pub std_dev: HashMap<MetricType, f64>,
150    pub min: HashMap<MetricType, f64>,
151    pub max: HashMap<MetricType, f64>,
152    pub percentiles: HashMap<MetricType, BTreeMap<u8, f64>>,
153}
154
155/// Anomaly detection event
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct AnomalyEvent {
158    pub timestamp: f64,
159    pub metric: MetricType,
160    pub severity: AnomalySeverity,
161    pub description: String,
162    pub impact: f64,
163}
164
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
166pub enum AnomalySeverity {
167    Low,
168    Medium,
169    High,
170    Critical,
171}
172
173/// Circuit bottleneck analysis
174#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct BottleneckAnalysis {
176    /// Identified bottlenecks
177    pub bottlenecks: Vec<Bottleneck>,
178
179    /// Performance impact analysis
180    pub impact_analysis: HashMap<String, f64>,
181
182    /// Optimization opportunities
183    pub opportunities: Vec<OptimizationOpportunity>,
184
185    /// Resource utilization heatmap
186    pub resource_heatmap: Array2<f64>,
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize)]
190pub struct Bottleneck {
191    pub location: CircuitLocation,
192    pub bottleneck_type: BottleneckType,
193    pub severity: f64,
194    pub impact_percentage: f64,
195    pub suggested_fixes: Vec<String>,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
199pub enum BottleneckType {
200    MemoryBandwidth,
201    ComputeIntensive,
202    CacheMiss,
203    ParallelizationIssue,
204    SimdUnderutilization,
205    DataDependency,
206    ResourceContention,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct CircuitLocation {
211    pub gate_index: usize,
212    pub layer: usize,
213    pub qubits: Vec<usize>,
214    pub context: String,
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize)]
218pub struct OptimizationOpportunity {
219    pub opportunity_type: OpportunityType,
220    pub estimated_improvement: f64,
221    pub difficulty: Difficulty,
222    pub implementation: String,
223    pub trade_offs: Vec<String>,
224}
225
226#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
227pub enum OpportunityType {
228    GateFusion,
229    Parallelization,
230    SimdOptimization,
231    MemoryReordering,
232    CacheOptimization,
233    AlgorithmicImprovement,
234    HardwareSpecific,
235}
236
237#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
238pub enum Difficulty {
239    Trivial,
240    Easy,
241    Medium,
242    Hard,
243    Expert,
244}
245
246/// Hardware performance model
247#[derive(Serialize, Deserialize)]
248pub struct HardwarePerformanceModel {
249    /// Platform capabilities
250    #[serde(skip, default = "PlatformCapabilities::detect")]
251    pub platform: PlatformCapabilities,
252
253    /// Performance characteristics
254    pub characteristics: HardwareCharacteristics,
255
256    /// Scaling models
257    pub scaling_models: HashMap<String, ScalingModel>,
258
259    /// Optimization strategies
260    pub optimization_strategies: Vec<HardwareOptimizationStrategy>,
261}
262
263#[derive(Debug, Clone, Serialize, Deserialize)]
264pub struct HardwareCharacteristics {
265    pub cpu_frequency: f64,
266    pub cache_sizes: Vec<usize>,
267    pub memory_bandwidth: f64,
268    pub simd_width: usize,
269    pub num_cores: usize,
270    pub gpu_available: bool,
271    pub gpu_memory: Option<usize>,
272    pub quantum_accelerator: Option<String>,
273}
274
275#[derive(Debug, Clone, Serialize, Deserialize)]
276pub struct ScalingModel {
277    pub model_type: ScalingType,
278    pub parameters: HashMap<String, f64>,
279    pub confidence: f64,
280}
281
282#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
283pub enum ScalingType {
284    Linear,
285    Logarithmic,
286    Polynomial,
287    Exponential,
288    Custom,
289}
290
291#[derive(Debug, Clone, Serialize, Deserialize)]
292pub struct HardwareOptimizationStrategy {
293    pub strategy_name: String,
294    pub applicable_conditions: Vec<String>,
295    pub expected_speedup: f64,
296    pub implementation_cost: f64,
297}
298
299/// Enhanced quantum circuit profiler
300pub struct EnhancedQuantumProfiler {
301    config: EnhancedProfilingConfig,
302    platform_caps: PlatformCapabilities,
303    buffer_pool: Arc<BufferPool<Complex64>>,
304    metrics_collector: Arc<MetricsCollector>,
305    hardware_model: Option<HardwarePerformanceModel>,
306    profiling_state: Arc<Mutex<ProfilingState>>,
307}
308
309/// Real-time metrics collector
310struct MetricsCollector {
311    execution_times: Mutex<HashMap<String, Vec<Duration>>>,
312    memory_usage: AtomicUsize,
313    simd_ops_count: AtomicU64,
314    parallel_ops_count: AtomicU64,
315    cache_hits: AtomicU64,
316    cache_misses: AtomicU64,
317    bandwidth_bytes: AtomicU64,
318    start_time: Instant,
319}
320
321impl MetricsCollector {
322    fn new() -> Self {
323        Self {
324            execution_times: Mutex::new(HashMap::new()),
325            memory_usage: AtomicUsize::new(0),
326            simd_ops_count: AtomicU64::new(0),
327            parallel_ops_count: AtomicU64::new(0),
328            cache_hits: AtomicU64::new(0),
329            cache_misses: AtomicU64::new(0),
330            bandwidth_bytes: AtomicU64::new(0),
331            start_time: Instant::now(),
332        }
333    }
334
335    fn record_execution(&self, operation: &str, duration: Duration) {
336        let mut times = self
337            .execution_times
338            .lock()
339            .expect("Execution times lock poisoned");
340        times
341            .entry(operation.to_string())
342            .or_insert_with(Vec::new)
343            .push(duration);
344    }
345
346    fn record_memory(&self, bytes: usize) {
347        self.memory_usage.fetch_add(bytes, Ordering::Relaxed);
348    }
349
350    fn record_simd_op(&self) {
351        self.simd_ops_count.fetch_add(1, Ordering::Relaxed);
352    }
353
354    fn record_parallel_op(&self) {
355        self.parallel_ops_count.fetch_add(1, Ordering::Relaxed);
356    }
357
358    fn record_cache_access(&self, hit: bool) {
359        if hit {
360            self.cache_hits.fetch_add(1, Ordering::Relaxed);
361        } else {
362            self.cache_misses.fetch_add(1, Ordering::Relaxed);
363        }
364    }
365
366    fn record_bandwidth(&self, bytes: usize) {
367        self.bandwidth_bytes
368            .fetch_add(bytes as u64, Ordering::Relaxed);
369    }
370
371    fn get_elapsed(&self) -> Duration {
372        self.start_time.elapsed()
373    }
374}
375
376/// Profiling state management
377struct ProfilingState {
378    current_depth: usize,
379    call_stack: Vec<String>,
380    gate_timings: HashMap<usize, GateTimingInfo>,
381    memory_snapshots: VecDeque<MemorySnapshot>,
382    anomaly_detector: AnomalyDetector,
383}
384
385#[derive(Debug, Clone)]
386struct GateTimingInfo {
387    gate_type: GateType,
388    start_time: Instant,
389    end_time: Option<Instant>,
390    memory_before: usize,
391    memory_after: Option<usize>,
392    simd_ops: u64,
393    parallel_ops: u64,
394}
395
396#[derive(Debug, Clone)]
397struct MemorySnapshot {
398    timestamp: Instant,
399    total_memory: usize,
400    heap_memory: usize,
401    stack_memory: usize,
402    buffer_pool_memory: usize,
403}
404
405/// Anomaly detection system
406struct AnomalyDetector {
407    baseline_metrics: HashMap<MetricType, (f64, f64)>, // (mean, std_dev)
408    detection_threshold: f64,
409    history_window: usize,
410    metric_history: HashMap<MetricType, VecDeque<f64>>,
411}
412
413impl AnomalyDetector {
414    fn new(detection_threshold: f64, history_window: usize) -> Self {
415        Self {
416            baseline_metrics: HashMap::new(),
417            detection_threshold,
418            history_window,
419            metric_history: HashMap::new(),
420        }
421    }
422
423    fn update_metric(&mut self, metric: MetricType, value: f64) -> Option<AnomalyEvent> {
424        let history = self
425            .metric_history
426            .entry(metric)
427            .or_insert_with(VecDeque::new);
428        history.push_back(value);
429
430        if history.len() > self.history_window {
431            history.pop_front();
432        }
433
434        // Calculate statistics
435        if history.len() >= 10 {
436            let mean: f64 = history.iter().sum::<f64>() / history.len() as f64;
437            let variance: f64 =
438                history.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / history.len() as f64;
439            let std_dev = variance.sqrt();
440
441            self.baseline_metrics.insert(metric, (mean, std_dev));
442
443            // Check for anomaly
444            if let Some(&(baseline_mean, baseline_std)) = self.baseline_metrics.get(&metric) {
445                let z_score = (value - baseline_mean).abs() / baseline_std;
446
447                if z_score > self.detection_threshold {
448                    let severity = match z_score {
449                        z if z < 3.0 => AnomalySeverity::Low,
450                        z if z < 4.0 => AnomalySeverity::Medium,
451                        z if z < 5.0 => AnomalySeverity::High,
452                        _ => AnomalySeverity::Critical,
453                    };
454
455                    return Some(AnomalyEvent {
456                        timestamp: history.len() as f64,
457                        metric,
458                        severity,
459                        description: format!("Anomaly detected: z-score = {z_score:.2}"),
460                        impact: z_score / 10.0, // Normalized impact
461                    });
462                }
463            }
464        }
465
466        None
467    }
468}
469
470impl EnhancedQuantumProfiler {
471    /// Create a new enhanced profiler with default configuration
472    pub fn new() -> Self {
473        Self::with_config(EnhancedProfilingConfig::default())
474    }
475
476    /// Create a new enhanced profiler with custom configuration
477    pub fn with_config(config: EnhancedProfilingConfig) -> Self {
478        let platform_caps = PlatformCapabilities::detect();
479        let buffer_pool = Arc::new(BufferPool::new());
480        let metrics_collector = Arc::new(MetricsCollector::new());
481
482        let hardware_model = if config.hardware_aware_profiling {
483            Some(Self::build_hardware_model(&platform_caps))
484        } else {
485            None
486        };
487
488        let profiling_state = Arc::new(Mutex::new(ProfilingState {
489            current_depth: 0,
490            call_stack: Vec::new(),
491            gate_timings: HashMap::new(),
492            memory_snapshots: VecDeque::new(),
493            anomaly_detector: AnomalyDetector::new(3.0, 100),
494        }));
495
496        Self {
497            config,
498            platform_caps,
499            buffer_pool,
500            metrics_collector,
501            hardware_model,
502            profiling_state,
503        }
504    }
505
506    /// Real total memory (bytes) of the primary GPU as reported by the platform
507    /// detector's driver query, or `None` if no GPU is present / its memory is
508    /// unknown. This never fabricates a memory size.
509    fn gpu_total_memory_bytes(platform_caps: &PlatformCapabilities) -> Option<usize> {
510        if !platform_caps.gpu.available {
511            return None;
512        }
513        let devices = &platform_caps.gpu.devices;
514        let primary = platform_caps.gpu.primary_device.unwrap_or(0);
515        devices
516            .get(primary)
517            .or_else(|| devices.first())
518            .map(|device| device.memory_bytes)
519            .filter(|&bytes| bytes > 0)
520    }
521
522    /// Build hardware performance model
523    fn build_hardware_model(platform_caps: &PlatformCapabilities) -> HardwarePerformanceModel {
524        let characteristics = HardwareCharacteristics {
525            cpu_frequency: 3.0e9,                                      // 3 GHz estimate
526            cache_sizes: vec![32 * 1024, 256 * 1024, 8 * 1024 * 1024], // L1, L2, L3
527            memory_bandwidth: 50.0e9,                                  // 50 GB/s
528            simd_width: if platform_caps.simd_available() {
529                256
530            } else {
531                128
532            },
533            num_cores: platform_caps.cpu.logical_cores,
534            gpu_available: platform_caps.gpu_available(),
535            // Real per-device memory from the platform detector's driver query
536            // (e.g. OxiCUDA `total_memory_bytes`). `None` when no GPU is present
537            // or its memory could not be measured — never a fabricated constant.
538            gpu_memory: Self::gpu_total_memory_bytes(platform_caps),
539            quantum_accelerator: None,
540        };
541
542        let mut scaling_models = HashMap::new();
543        scaling_models.insert(
544            "gate_execution".to_string(),
545            ScalingModel {
546                model_type: ScalingType::Linear,
547                parameters: vec![("slope".to_string(), 1e-6), ("intercept".to_string(), 1e-7)]
548                    .into_iter()
549                    .collect(),
550                confidence: 0.95,
551            },
552        );
553
554        scaling_models.insert(
555            "memory_access".to_string(),
556            ScalingModel {
557                model_type: ScalingType::Logarithmic,
558                parameters: vec![("base".to_string(), 2.0), ("coefficient".to_string(), 1e-8)]
559                    .into_iter()
560                    .collect(),
561                confidence: 0.90,
562            },
563        );
564
565        let optimization_strategies = vec![
566            HardwareOptimizationStrategy {
567                strategy_name: "SIMD Vectorization".to_string(),
568                applicable_conditions: vec!["vector_friendly_gates".to_string()],
569                expected_speedup: 4.0,
570                implementation_cost: 0.2,
571            },
572            HardwareOptimizationStrategy {
573                strategy_name: "Parallel Execution".to_string(),
574                applicable_conditions: vec!["independent_gates".to_string()],
575                expected_speedup: characteristics.num_cores as f64 * 0.8,
576                implementation_cost: 0.3,
577            },
578            HardwareOptimizationStrategy {
579                strategy_name: "Cache Optimization".to_string(),
580                applicable_conditions: vec!["repeated_access_patterns".to_string()],
581                expected_speedup: 2.0,
582                implementation_cost: 0.1,
583            },
584        ];
585
586        HardwarePerformanceModel {
587            platform: PlatformCapabilities::detect(),
588            characteristics,
589            scaling_models,
590            optimization_strategies,
591        }
592    }
593
594    /// Profile a quantum circuit with enhanced metrics
595    pub fn profile_circuit(
596        &self,
597        circuit: &[QuantumGate],
598        num_qubits: usize,
599    ) -> Result<EnhancedProfilingReport, QuantRS2Error> {
600        let start_time = Instant::now();
601
602        // Initialize profiling
603        self.initialize_profiling(num_qubits)?;
604
605        // Profile each gate
606        let mut gate_results = Vec::new();
607        for (idx, gate) in circuit.iter().enumerate() {
608            let gate_result = self.profile_gate(gate, idx, num_qubits)?;
609            gate_results.push(gate_result);
610        }
611
612        // Collect overall metrics
613        let performance_metrics = self.collect_performance_metrics()?;
614
615        // Perform bottleneck analysis
616        let bottleneck_analysis = if self.config.enable_deep_analysis {
617            Some(self.analyze_bottlenecks(&gate_results, num_qubits)?)
618        } else {
619            None
620        };
621
622        // Generate optimization recommendations
623        let optimizations = if self.config.generate_optimizations {
624            self.generate_optimization_recommendations(&gate_results, &bottleneck_analysis)?
625        } else {
626            Vec::new()
627        };
628
629        // Predict performance on different hardware
630        let performance_predictions = if self.config.enable_performance_prediction {
631            Some(self.predict_performance(&gate_results, num_qubits)?)
632        } else {
633            None
634        };
635
636        // Create comprehensive report
637        let total_time = start_time.elapsed();
638
639        // Prepare export data before moving gate_results
640        let export_data = self.prepare_export_data(&gate_results)?;
641
642        Ok(EnhancedProfilingReport {
643            summary: ProfilingSummary {
644                total_execution_time: total_time,
645                num_gates: circuit.len(),
646                num_qubits,
647                platform_info: PlatformCapabilities::detect(),
648                profiling_config: self.config.clone(),
649            },
650            gate_results,
651            performance_metrics,
652            bottleneck_analysis,
653            optimizations,
654            performance_predictions,
655            export_data,
656        })
657    }
658
659    /// Initialize profiling state
660    fn initialize_profiling(&self, num_qubits: usize) -> Result<(), QuantRS2Error> {
661        let mut state = self
662            .profiling_state
663            .lock()
664            .map_err(|e| QuantRS2Error::RuntimeError(format!("Lock poisoned: {e}")))?;
665        state.current_depth = 0;
666        state.call_stack.clear();
667        state.gate_timings.clear();
668        state.memory_snapshots.clear();
669
670        // Take initial memory snapshot
671        let initial_snapshot = MemorySnapshot {
672            timestamp: Instant::now(),
673            total_memory: self.estimate_memory_usage(num_qubits),
674            heap_memory: 0,
675            stack_memory: 0,
676            buffer_pool_memory: 0,
677        };
678        state.memory_snapshots.push_back(initial_snapshot);
679
680        Ok(())
681    }
682
683    /// Profile individual gate
684    fn profile_gate(
685        &self,
686        gate: &QuantumGate,
687        gate_index: usize,
688        num_qubits: usize,
689    ) -> Result<EnhancedGateProfilingResult, QuantRS2Error> {
690        let start_time = Instant::now();
691        let memory_before = self.estimate_memory_usage(num_qubits);
692
693        // Record gate start
694        {
695            let mut state = self
696                .profiling_state
697                .lock()
698                .map_err(|e| QuantRS2Error::RuntimeError(format!("Lock poisoned: {e}")))?;
699            state.gate_timings.insert(
700                gate_index,
701                GateTimingInfo {
702                    gate_type: gate.gate_type().clone(),
703                    start_time,
704                    end_time: None,
705                    memory_before,
706                    memory_after: None,
707                    simd_ops: 0,
708                    parallel_ops: 0,
709                },
710            );
711        }
712
713        // Simulate gate execution with metrics collection
714        self.simulate_gate_execution(gate, num_qubits)?;
715
716        let end_time = Instant::now();
717        let memory_after = self.estimate_memory_usage(num_qubits);
718        let execution_time = end_time - start_time;
719
720        // Update gate timing info
721        {
722            let mut state = self
723                .profiling_state
724                .lock()
725                .map_err(|e| QuantRS2Error::RuntimeError(format!("Lock poisoned: {e}")))?;
726            if let Some(timing_info) = state.gate_timings.get_mut(&gate_index) {
727                timing_info.end_time = Some(end_time);
728                timing_info.memory_after = Some(memory_after);
729                timing_info.simd_ops = self
730                    .metrics_collector
731                    .simd_ops_count
732                    .load(Ordering::Relaxed);
733                timing_info.parallel_ops = self
734                    .metrics_collector
735                    .parallel_ops_count
736                    .load(Ordering::Relaxed);
737            }
738        }
739
740        // Record metrics
741        self.metrics_collector
742            .record_execution(&format!("{:?}", gate.gate_type()), execution_time);
743        self.metrics_collector
744            .record_memory(memory_after.saturating_sub(memory_before));
745
746        // Check for anomalies
747        let mut anomalies = Vec::new();
748        {
749            let mut state = self
750                .profiling_state
751                .lock()
752                .map_err(|e| QuantRS2Error::RuntimeError(format!("Lock poisoned: {e}")))?;
753            if let Some(anomaly) = state
754                .anomaly_detector
755                .update_metric(MetricType::ExecutionTime, execution_time.as_secs_f64())
756            {
757                anomalies.push(anomaly);
758            }
759        }
760
761        Ok(EnhancedGateProfilingResult {
762            gate_index,
763            gate_type: gate.gate_type().clone(),
764            execution_time,
765            memory_delta: memory_after as i64 - memory_before as i64,
766            simd_operations: self
767                .metrics_collector
768                .simd_ops_count
769                .load(Ordering::Relaxed),
770            parallel_operations: self
771                .metrics_collector
772                .parallel_ops_count
773                .load(Ordering::Relaxed),
774            cache_efficiency: self.calculate_cache_efficiency(),
775            bandwidth_usage: self.calculate_bandwidth_usage(execution_time),
776            anomalies,
777            detailed_metrics: self.collect_detailed_gate_metrics(gate, execution_time)?,
778        })
779    }
780
781    /// Simulate gate execution for profiling
782    fn simulate_gate_execution(
783        &self,
784        gate: &QuantumGate,
785        num_qubits: usize,
786    ) -> Result<(), QuantRS2Error> {
787        // Simulate different aspects based on gate type
788        match gate.gate_type() {
789            GateType::H | GateType::X | GateType::Y | GateType::Z => {
790                // Single-qubit gates
791                if self.platform_caps.simd_available() {
792                    self.metrics_collector.record_simd_op();
793                }
794                self.metrics_collector
795                    .record_bandwidth(16 * (1 << num_qubits)); // Complex64 operations
796            }
797            GateType::CNOT | GateType::CZ => {
798                // Two-qubit gates
799                if num_qubits > 10 {
800                    self.metrics_collector.record_parallel_op();
801                }
802                self.metrics_collector
803                    .record_bandwidth(32 * (1 << num_qubits));
804            }
805            _ => {
806                // Multi-qubit gates
807                self.metrics_collector.record_parallel_op();
808                self.metrics_collector
809                    .record_bandwidth(64 * (1 << num_qubits));
810            }
811        }
812
813        // Simulate cache behavior
814        use scirs2_core::random::prelude::*;
815        let cache_hit = thread_rng().random::<f64>() > 0.2; // 80% hit rate simulation
816        self.metrics_collector.record_cache_access(cache_hit);
817
818        Ok(())
819    }
820
821    /// Estimate memory usage
822    const fn estimate_memory_usage(&self, num_qubits: usize) -> usize {
823        let state_vector_size = (1 << num_qubits) * std::mem::size_of::<Complex64>();
824        let overhead = state_vector_size / 10; // 10% overhead estimate
825        state_vector_size + overhead
826    }
827
828    /// Calculate cache efficiency
829    fn calculate_cache_efficiency(&self) -> f64 {
830        let hits = self.metrics_collector.cache_hits.load(Ordering::Relaxed) as f64;
831        let misses = self.metrics_collector.cache_misses.load(Ordering::Relaxed) as f64;
832        let total = hits + misses;
833
834        if total > 0.0 {
835            hits / total
836        } else {
837            1.0 // Assume perfect efficiency if no data
838        }
839    }
840
841    /// Calculate bandwidth usage
842    fn calculate_bandwidth_usage(&self, duration: Duration) -> f64 {
843        let bytes = self
844            .metrics_collector
845            .bandwidth_bytes
846            .load(Ordering::Relaxed) as f64;
847        let seconds = duration.as_secs_f64();
848
849        if seconds > 0.0 {
850            bytes / seconds
851        } else {
852            0.0
853        }
854    }
855
856    /// Collect detailed gate metrics
857    fn collect_detailed_gate_metrics(
858        &self,
859        gate: &QuantumGate,
860        execution_time: Duration,
861    ) -> Result<HashMap<String, f64>, QuantRS2Error> {
862        let mut metrics = HashMap::new();
863
864        metrics.insert(
865            "execution_time_us".to_string(),
866            execution_time.as_micros() as f64,
867        );
868        metrics.insert(
869            "cache_efficiency".to_string(),
870            self.calculate_cache_efficiency(),
871        );
872        metrics.insert(
873            "bandwidth_mbps".to_string(),
874            self.calculate_bandwidth_usage(execution_time) / 1e6,
875        );
876
877        if let Some(ref hw_model) = self.hardware_model {
878            metrics.insert(
879                "theoretical_flops".to_string(),
880                self.estimate_flops(gate, &hw_model.characteristics),
881            );
882        }
883
884        Ok(metrics)
885    }
886
887    /// Estimate FLOPS for a gate
888    fn estimate_flops(&self, gate: &QuantumGate, hw_chars: &HardwareCharacteristics) -> f64 {
889        let base_flops = match gate.gate_type() {
890            GateType::H => 8.0, // 4 complex multiplications
891            GateType::X | GateType::Y | GateType::Z => 4.0,
892            GateType::CNOT | GateType::CZ => 16.0,
893            _ => 32.0, // Conservative estimate for complex gates
894        };
895
896        base_flops * hw_chars.cpu_frequency
897    }
898
899    /// Collect overall performance metrics
900    fn collect_performance_metrics(&self) -> Result<PerformanceMetrics, QuantRS2Error> {
901        let mut values = HashMap::new();
902        let elapsed = self.metrics_collector.get_elapsed();
903
904        values.insert(MetricType::ExecutionTime, elapsed.as_secs_f64());
905        values.insert(
906            MetricType::MemoryUsage,
907            self.metrics_collector.memory_usage.load(Ordering::Relaxed) as f64,
908        );
909        values.insert(
910            MetricType::SimdUtilization,
911            self.metrics_collector
912                .simd_ops_count
913                .load(Ordering::Relaxed) as f64,
914        );
915        values.insert(
916            MetricType::ParallelEfficiency,
917            self.metrics_collector
918                .parallel_ops_count
919                .load(Ordering::Relaxed) as f64,
920        );
921        values.insert(MetricType::CacheHitRate, self.calculate_cache_efficiency());
922        values.insert(
923            MetricType::MemoryBandwidth,
924            self.calculate_bandwidth_usage(elapsed),
925        );
926
927        // Calculate statistics
928        let statistics = self.calculate_metric_statistics(&values)?;
929
930        // Time series data (simplified for this implementation)
931        let mut time_series = HashMap::new();
932        for (metric, value) in &values {
933            time_series.insert(*metric, vec![(0.0, 0.0), (elapsed.as_secs_f64(), *value)]);
934        }
935
936        Ok(PerformanceMetrics {
937            values,
938            time_series,
939            statistics,
940            correlations: HashMap::new(), // Simplified
941            anomalies: Vec::new(),        // Collected separately
942        })
943    }
944
945    /// Calculate metric statistics
946    fn calculate_metric_statistics(
947        &self,
948        values: &HashMap<MetricType, f64>,
949    ) -> Result<MetricStatistics, QuantRS2Error> {
950        let mut mean = HashMap::new();
951        let mut std_dev = HashMap::new();
952        let mut min = HashMap::new();
953        let mut max = HashMap::new();
954        let mut percentiles = HashMap::new();
955
956        for (metric, value) in values {
957            mean.insert(*metric, *value);
958            std_dev.insert(*metric, 0.0); // Simplified
959            min.insert(*metric, *value);
960            max.insert(*metric, *value);
961
962            let mut percs = BTreeMap::new();
963            percs.insert(50, *value); // Median
964            percs.insert(95, *value * 1.1); // 95th percentile estimate
965            percs.insert(99, *value * 1.2); // 99th percentile estimate
966            percentiles.insert(*metric, percs);
967        }
968
969        Ok(MetricStatistics {
970            mean,
971            std_dev,
972            min,
973            max,
974            percentiles,
975        })
976    }
977
978    /// Analyze bottlenecks in the circuit
979    fn analyze_bottlenecks(
980        &self,
981        gate_results: &[EnhancedGateProfilingResult],
982        num_qubits: usize,
983    ) -> Result<BottleneckAnalysis, QuantRS2Error> {
984        let mut bottlenecks = Vec::new();
985        let mut impact_analysis = HashMap::new();
986        let mut opportunities = Vec::new();
987
988        // Find execution time bottlenecks
989        let total_time: Duration = gate_results.iter().map(|r| r.execution_time).sum();
990        let avg_time = total_time / gate_results.len() as u32;
991
992        for (idx, result) in gate_results.iter().enumerate() {
993            if result.execution_time > avg_time * 2 {
994                let impact = result.execution_time.as_secs_f64() / total_time.as_secs_f64();
995
996                bottlenecks.push(Bottleneck {
997                    location: CircuitLocation {
998                        gate_index: idx,
999                        layer: idx / num_qubits, // Simplified layer calculation
1000                        qubits: vec![idx % num_qubits], // Simplified
1001                        context: format!("Gate {:?} at index {}", result.gate_type, idx),
1002                    },
1003                    bottleneck_type: BottleneckType::ComputeIntensive,
1004                    severity: impact * 100.0,
1005                    impact_percentage: impact * 100.0,
1006                    suggested_fixes: vec![
1007                        "Consider gate decomposition".to_string(),
1008                        "Explore parallel execution".to_string(),
1009                    ],
1010                });
1011
1012                impact_analysis.insert(format!("gate_{idx}"), impact);
1013            }
1014
1015            // Check for low cache efficiency
1016            if result.cache_efficiency < 0.5 {
1017                bottlenecks.push(Bottleneck {
1018                    location: CircuitLocation {
1019                        gate_index: idx,
1020                        layer: idx / num_qubits,
1021                        qubits: vec![idx % num_qubits],
1022                        context: format!("Poor cache efficiency at gate {idx}"),
1023                    },
1024                    bottleneck_type: BottleneckType::CacheMiss,
1025                    severity: (1.0 - result.cache_efficiency) * 50.0,
1026                    impact_percentage: 10.0, // Estimated impact
1027                    suggested_fixes: vec![
1028                        "Reorder operations for better locality".to_string(),
1029                        "Consider data prefetching".to_string(),
1030                    ],
1031                });
1032            }
1033        }
1034
1035        // Identify optimization opportunities
1036        if self.platform_caps.simd_available() {
1037            let simd_utilization = gate_results
1038                .iter()
1039                .filter(|r| r.simd_operations > 0)
1040                .count() as f64
1041                / gate_results.len() as f64;
1042
1043            if simd_utilization < 0.5 {
1044                opportunities.push(OptimizationOpportunity {
1045                    opportunity_type: OpportunityType::SimdOptimization,
1046                    estimated_improvement: (1.0 - simd_utilization) * 2.0,
1047                    difficulty: Difficulty::Medium,
1048                    implementation: "Vectorize gate operations using AVX2".to_string(),
1049                    trade_offs: vec!["Increased code complexity".to_string()],
1050                });
1051            }
1052        }
1053
1054        // Create resource heatmap
1055        let resource_heatmap = Array2::zeros((gate_results.len(), 4)); // gates x resource types
1056
1057        Ok(BottleneckAnalysis {
1058            bottlenecks,
1059            impact_analysis,
1060            opportunities,
1061            resource_heatmap,
1062        })
1063    }
1064
1065    /// Generate optimization recommendations
1066    fn generate_optimization_recommendations(
1067        &self,
1068        gate_results: &[EnhancedGateProfilingResult],
1069        bottleneck_analysis: &Option<BottleneckAnalysis>,
1070    ) -> Result<Vec<EnhancedOptimizationRecommendation>, QuantRS2Error> {
1071        let mut recommendations = Vec::new();
1072
1073        // Gate fusion opportunities
1074        for window in gate_results.windows(2) {
1075            if Self::can_fuse_gates(&window[0].gate_type, &window[1].gate_type) {
1076                recommendations.push(EnhancedOptimizationRecommendation {
1077                    recommendation_type: RecommendationType::GateFusion,
1078                    priority: Priority::High,
1079                    estimated_speedup: 1.5,
1080                    implementation_difficulty: Difficulty::Easy,
1081                    description: format!(
1082                        "Fuse {:?} and {:?} gates",
1083                        window[0].gate_type, window[1].gate_type
1084                    ),
1085                    code_example: Some(
1086                        self.generate_fusion_code(&window[0].gate_type, &window[1].gate_type),
1087                    ),
1088                    prerequisites: vec!["Adjacent gates must commute".to_string()],
1089                    risks: vec!["May increase numerical error".to_string()],
1090                });
1091            }
1092        }
1093
1094        // Hardware-specific optimizations
1095        if let Some(ref hw_model) = self.hardware_model {
1096            for strategy in &hw_model.optimization_strategies {
1097                if strategy.expected_speedup > 1.5 {
1098                    recommendations.push(EnhancedOptimizationRecommendation {
1099                        recommendation_type: RecommendationType::HardwareSpecific,
1100                        priority: Priority::Medium,
1101                        estimated_speedup: strategy.expected_speedup,
1102                        implementation_difficulty: Difficulty::Hard,
1103                        description: strategy.strategy_name.clone(),
1104                        code_example: None,
1105                        prerequisites: strategy.applicable_conditions.clone(),
1106                        risks: vec!["Platform-specific code".to_string()],
1107                    });
1108                }
1109            }
1110        }
1111
1112        // Bottleneck-based recommendations
1113        if let Some(bottleneck_analysis) = bottleneck_analysis {
1114            for opportunity in &bottleneck_analysis.opportunities {
1115                recommendations.push(EnhancedOptimizationRecommendation {
1116                    recommendation_type: match opportunity.opportunity_type {
1117                        OpportunityType::GateFusion => RecommendationType::GateFusion,
1118                        OpportunityType::Parallelization => RecommendationType::Parallelization,
1119                        OpportunityType::SimdOptimization => RecommendationType::SimdVectorization,
1120                        OpportunityType::MemoryReordering => RecommendationType::MemoryOptimization,
1121                        OpportunityType::CacheOptimization => RecommendationType::CacheOptimization,
1122                        OpportunityType::AlgorithmicImprovement => {
1123                            RecommendationType::AlgorithmicChange
1124                        }
1125                        OpportunityType::HardwareSpecific => RecommendationType::HardwareSpecific,
1126                    },
1127                    priority: match opportunity.difficulty {
1128                        Difficulty::Trivial | Difficulty::Easy => Priority::High,
1129                        Difficulty::Medium => Priority::Medium,
1130                        Difficulty::Hard | Difficulty::Expert => Priority::Low,
1131                    },
1132                    estimated_speedup: opportunity.estimated_improvement,
1133                    implementation_difficulty: opportunity.difficulty,
1134                    description: opportunity.implementation.clone(),
1135                    code_example: None,
1136                    prerequisites: Vec::new(),
1137                    risks: opportunity.trade_offs.clone(),
1138                });
1139            }
1140        }
1141
1142        Ok(recommendations)
1143    }
1144
1145    /// Check if two gates can be fused
1146    const fn can_fuse_gates(gate1: &GateType, gate2: &GateType) -> bool {
1147        use GateType::{Rx, Ry, Rz, H, X, Y, Z};
1148        matches!(
1149            (gate1, gate2),
1150            (H, H) | (X, X) | (Y, Y) | (Z, Z) | // Self-inverse gates
1151            (Rz(_), Rz(_)) | (Rx(_), Rx(_)) | (Ry(_), Ry(_)) // Rotation gates
1152        )
1153    }
1154
1155    /// Generate fusion code example
1156    fn generate_fusion_code(&self, gate1: &GateType, gate2: &GateType) -> String {
1157        format!(
1158            "// Fused {gate1:?} and {gate2:?}\nlet fused_gate = FusedGate::new({gate1:?}, {gate2:?});\nfused_gate.apply(state);"
1159        )
1160    }
1161
1162    /// Predict performance on different hardware
1163    fn predict_performance(
1164        &self,
1165        gate_results: &[EnhancedGateProfilingResult],
1166        num_qubits: usize,
1167    ) -> Result<PerformancePredictions, QuantRS2Error> {
1168        let mut predictions = HashMap::new();
1169
1170        // Current hardware baseline
1171        let current_time: Duration = gate_results.iter().map(|r| r.execution_time).sum();
1172
1173        predictions.insert(
1174            "current".to_string(),
1175            PredictedPerformance {
1176                hardware_description: "Current Platform".to_string(),
1177                estimated_time: current_time,
1178                confidence: 1.0,
1179                limiting_factors: vec!["Actual measurement".to_string()],
1180            },
1181        );
1182
1183        // GPU prediction
1184        if self.platform_caps.gpu_available() {
1185            // Logarithmic speedup model, clamped to >= 1.0 so small/zero-qubit
1186            // circuits (where ln(n) <= 0) never divide by zero or predict a
1187            // GPU slower than the measured baseline.
1188            let gpu_speedup = ((num_qubits as f64).ln() * 2.0).max(1.0);
1189            predictions.insert(
1190                "gpu".to_string(),
1191                PredictedPerformance {
1192                    hardware_description: "GPU Acceleration".to_string(),
1193                    estimated_time: current_time.div_f64(gpu_speedup),
1194                    confidence: 0.8,
1195                    limiting_factors: vec!["Memory transfer overhead".to_string()],
1196                },
1197            );
1198        }
1199
1200        // Quantum hardware prediction
1201        predictions.insert(
1202            "quantum_hw".to_string(),
1203            PredictedPerformance {
1204                hardware_description: "Quantum Hardware (NISQ)".to_string(),
1205                estimated_time: Duration::from_millis(gate_results.len() as u64 * 10), // 10ms per gate
1206                confidence: 0.5,
1207                limiting_factors: vec![
1208                    "Gate fidelity".to_string(),
1209                    "Connectivity constraints".to_string(),
1210                    "Decoherence".to_string(),
1211                ],
1212            },
1213        );
1214
1215        // Cloud QPU prediction
1216        predictions.insert(
1217            "cloud_qpu".to_string(),
1218            PredictedPerformance {
1219                hardware_description: "Cloud Quantum Processor".to_string(),
1220                estimated_time: Duration::from_secs(1)
1221                    + Duration::from_millis(gate_results.len() as u64),
1222                confidence: 0.6,
1223                limiting_factors: vec!["Network latency".to_string(), "Queue time".to_string()],
1224            },
1225        );
1226
1227        // Generate hardware recommendations before moving predictions
1228        let hardware_recommendations =
1229            self.generate_hardware_recommendations(num_qubits, &predictions);
1230
1231        Ok(PerformancePredictions {
1232            predictions,
1233            scaling_analysis: self.analyze_scaling(num_qubits)?,
1234            hardware_recommendations,
1235        })
1236    }
1237
1238    /// Analyze scaling behavior
1239    fn analyze_scaling(&self, num_qubits: usize) -> Result<ScalingAnalysis, QuantRS2Error> {
1240        Ok(ScalingAnalysis {
1241            qubit_scaling: ScalingType::Exponential,
1242            gate_scaling: ScalingType::Linear,
1243            memory_scaling: ScalingType::Exponential,
1244            predicted_limits: HashMap::from([
1245                ("max_qubits_cpu".to_string(), 30.0),
1246                ("max_qubits_gpu".to_string(), 35.0),
1247                ("max_gates_per_second".to_string(), 1e6),
1248            ]),
1249        })
1250    }
1251
1252    /// Generate hardware recommendations
1253    fn generate_hardware_recommendations(
1254        &self,
1255        num_qubits: usize,
1256        predictions: &HashMap<String, PredictedPerformance>,
1257    ) -> Vec<String> {
1258        let mut recommendations = Vec::new();
1259
1260        if num_qubits > 20 {
1261            recommendations.push("Consider GPU acceleration for large circuits".to_string());
1262        }
1263
1264        if num_qubits > 30 {
1265            recommendations.push("Tensor network methods recommended".to_string());
1266        }
1267
1268        if let Some(gpu_pred) = predictions.get("gpu") {
1269            if gpu_pred.confidence > 0.7 {
1270                recommendations.push("GPU acceleration shows promising speedup".to_string());
1271            }
1272        }
1273
1274        recommendations
1275    }
1276
1277    /// Prepare export data
1278    fn prepare_export_data(
1279        &self,
1280        gate_results: &[EnhancedGateProfilingResult],
1281    ) -> Result<HashMap<ExportFormat, Vec<u8>>, QuantRS2Error> {
1282        let mut export_data = HashMap::new();
1283
1284        for format in &self.config.export_formats {
1285            let data = match format {
1286                ExportFormat::JSON => self.export_to_json(gate_results)?,
1287                ExportFormat::CSV => self.export_to_csv(gate_results)?,
1288                ExportFormat::HTML => self.export_to_html(gate_results)?,
1289                _ => Vec::new(), // Other formats not implemented in this example
1290            };
1291            export_data.insert(*format, data);
1292        }
1293
1294        Ok(export_data)
1295    }
1296
1297    /// Export to JSON format
1298    fn export_to_json(
1299        &self,
1300        gate_results: &[EnhancedGateProfilingResult],
1301    ) -> Result<Vec<u8>, QuantRS2Error> {
1302        let json = serde_json::to_vec_pretty(gate_results)
1303            .map_err(|e| QuantRS2Error::ComputationError(format!("CSV generation failed: {e}")))?;
1304        Ok(json)
1305    }
1306
1307    /// Export to CSV format
1308    fn export_to_csv(
1309        &self,
1310        gate_results: &[EnhancedGateProfilingResult],
1311    ) -> Result<Vec<u8>, QuantRS2Error> {
1312        let mut csv = Vec::new();
1313        writeln!(csv, "gate_index,gate_type,execution_time_us,memory_delta,simd_ops,parallel_ops,cache_efficiency")
1314            .map_err(|e| QuantRS2Error::ComputationError(format!("IO error: {e}")))?;
1315
1316        for result in gate_results {
1317            writeln!(
1318                csv,
1319                "{},{:?},{},{},{},{},{:.2}",
1320                result.gate_index,
1321                result.gate_type,
1322                result.execution_time.as_micros(),
1323                result.memory_delta,
1324                result.simd_operations,
1325                result.parallel_operations,
1326                result.cache_efficiency
1327            )
1328            .map_err(|e| QuantRS2Error::ComputationError(format!("IO error: {e}")))?;
1329        }
1330
1331        Ok(csv)
1332    }
1333
1334    /// Export to HTML format
1335    fn export_to_html(
1336        &self,
1337        gate_results: &[EnhancedGateProfilingResult],
1338    ) -> Result<Vec<u8>, QuantRS2Error> {
1339        let mut html = Vec::new();
1340        writeln!(
1341            html,
1342            "<html><head><title>Quantum Circuit Profiling Report</title>"
1343        )
1344        .map_err(|e| QuantRS2Error::ComputationError(format!("IO error: {e}")))?;
1345        writeln!(html, "<style>table {{ border-collapse: collapse; }} th, td {{ border: 1px solid black; padding: 8px; }}</style>")
1346            .map_err(|e| QuantRS2Error::ComputationError(format!("IO error: {e}")))?;
1347        writeln!(html, "</head><body><h1>Profiling Results</h1><table>")
1348            .map_err(|e| QuantRS2Error::ComputationError(format!("IO error: {e}")))?;
1349        writeln!(html, "<tr><th>Gate</th><th>Type</th><th>Time (μs)</th><th>Memory</th><th>SIMD</th><th>Parallel</th><th>Cache</th></tr>")
1350            .map_err(|e| QuantRS2Error::ComputationError(format!("IO error: {e}")))?;
1351
1352        for result in gate_results {
1353            writeln!(html, "<tr><td>{}</td><td>{:?}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{:.1}%</td></tr>",
1354                result.gate_index,
1355                result.gate_type,
1356                result.execution_time.as_micros(),
1357                result.memory_delta,
1358                result.simd_operations,
1359                result.parallel_operations,
1360                result.cache_efficiency * 100.0
1361            ).map_err(|e| QuantRS2Error::ComputationError(format!("IO error: {e}")))?;
1362        }
1363
1364        writeln!(html, "</table></body></html>")
1365            .map_err(|e| QuantRS2Error::ComputationError(format!("IO error: {e}")))?;
1366
1367        Ok(html)
1368    }
1369}
1370
1371/// Enhanced gate profiling result
1372#[derive(Debug, Clone, Serialize, Deserialize)]
1373pub struct EnhancedGateProfilingResult {
1374    pub gate_index: usize,
1375    pub gate_type: GateType,
1376    pub execution_time: Duration,
1377    pub memory_delta: i64,
1378    pub simd_operations: u64,
1379    pub parallel_operations: u64,
1380    pub cache_efficiency: f64,
1381    pub bandwidth_usage: f64,
1382    pub anomalies: Vec<AnomalyEvent>,
1383    pub detailed_metrics: HashMap<String, f64>,
1384}
1385
1386/// Enhanced optimization recommendation
1387#[derive(Debug, Clone, Serialize, Deserialize)]
1388pub struct EnhancedOptimizationRecommendation {
1389    pub recommendation_type: RecommendationType,
1390    pub priority: Priority,
1391    pub estimated_speedup: f64,
1392    pub implementation_difficulty: Difficulty,
1393    pub description: String,
1394    pub code_example: Option<String>,
1395    pub prerequisites: Vec<String>,
1396    pub risks: Vec<String>,
1397}
1398
1399#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1400pub enum RecommendationType {
1401    GateFusion,
1402    Parallelization,
1403    SimdVectorization,
1404    MemoryOptimization,
1405    CacheOptimization,
1406    AlgorithmicChange,
1407    HardwareSpecific,
1408}
1409
1410#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1411pub enum Priority {
1412    Low,
1413    Medium,
1414    High,
1415    Critical,
1416}
1417
1418/// Performance predictions
1419#[derive(Debug, Clone, Serialize, Deserialize)]
1420pub struct PerformancePredictions {
1421    pub predictions: HashMap<String, PredictedPerformance>,
1422    pub scaling_analysis: ScalingAnalysis,
1423    pub hardware_recommendations: Vec<String>,
1424}
1425
1426#[derive(Debug, Clone, Serialize, Deserialize)]
1427pub struct PredictedPerformance {
1428    pub hardware_description: String,
1429    pub estimated_time: Duration,
1430    pub confidence: f64,
1431    pub limiting_factors: Vec<String>,
1432}
1433
1434#[derive(Debug, Clone, Serialize, Deserialize)]
1435pub struct ScalingAnalysis {
1436    pub qubit_scaling: ScalingType,
1437    pub gate_scaling: ScalingType,
1438    pub memory_scaling: ScalingType,
1439    pub predicted_limits: HashMap<String, f64>,
1440}
1441
1442/// Enhanced profiling report
1443#[derive(Serialize, Deserialize)]
1444pub struct EnhancedProfilingReport {
1445    pub summary: ProfilingSummary,
1446    pub gate_results: Vec<EnhancedGateProfilingResult>,
1447    pub performance_metrics: PerformanceMetrics,
1448    pub bottleneck_analysis: Option<BottleneckAnalysis>,
1449    pub optimizations: Vec<EnhancedOptimizationRecommendation>,
1450    pub performance_predictions: Option<PerformancePredictions>,
1451    pub export_data: HashMap<ExportFormat, Vec<u8>>,
1452}
1453
1454#[derive(Serialize, Deserialize)]
1455pub struct ProfilingSummary {
1456    pub total_execution_time: Duration,
1457    pub num_gates: usize,
1458    pub num_qubits: usize,
1459    #[serde(skip, default = "PlatformCapabilities::detect")]
1460    pub platform_info: PlatformCapabilities,
1461    pub profiling_config: EnhancedProfilingConfig,
1462}
1463
1464#[cfg(test)]
1465mod tests {
1466    use super::*;
1467
1468    #[test]
1469    fn test_enhanced_profiler_creation() {
1470        let profiler = EnhancedQuantumProfiler::new();
1471        assert!(profiler.platform_caps.simd_available());
1472    }
1473
1474    #[test]
1475    fn test_gpu_memory_reflects_real_hardware_not_hardcoded() {
1476        // gpu_memory must come from the real platform detector (OxiCUDA device
1477        // query), never the old hardcoded 8 GiB constant.
1478        let caps = PlatformCapabilities::detect();
1479        let reported = EnhancedQuantumProfiler::gpu_total_memory_bytes(&caps);
1480
1481        if caps.gpu.available {
1482            // Must equal the detector's real per-device memory, not 8 GiB
1483            // (unless the device genuinely has exactly 8 GiB).
1484            let primary = caps.gpu.primary_device.unwrap_or(0);
1485            let expected = caps
1486                .gpu
1487                .devices
1488                .get(primary)
1489                .or_else(|| caps.gpu.devices.first())
1490                .map(|d| d.memory_bytes)
1491                .filter(|&b| b > 0);
1492            assert_eq!(
1493                reported, expected,
1494                "GPU memory must match the detector's real device query"
1495            );
1496        } else {
1497            // No GPU on this machine -> honest None, never a fabricated size.
1498            assert_eq!(
1499                reported, None,
1500                "with no GPU present, gpu_memory must be None, not a fabricated constant"
1501            );
1502        }
1503    }
1504
1505    #[test]
1506    fn test_basic_profiling() {
1507        let profiler = EnhancedQuantumProfiler::new();
1508        let gates = vec![
1509            QuantumGate::new(GateType::H, vec![0], None),
1510            QuantumGate::new(GateType::CNOT, vec![0, 1], None),
1511            QuantumGate::new(GateType::H, vec![1], None),
1512        ];
1513
1514        let result = profiler
1515            .profile_circuit(&gates, 2)
1516            .expect("Failed to profile circuit");
1517        assert_eq!(result.gate_results.len(), 3);
1518        assert!(result.summary.total_execution_time.as_nanos() > 0);
1519    }
1520
1521    #[test]
1522    fn test_bottleneck_detection() {
1523        let config = EnhancedProfilingConfig {
1524            enable_deep_analysis: true,
1525            ..Default::default()
1526        };
1527        let profiler = EnhancedQuantumProfiler::with_config(config);
1528
1529        let gates = vec![
1530            QuantumGate::new(GateType::H, vec![0], None),
1531            QuantumGate::new(GateType::T, vec![0], None),
1532            QuantumGate::new(GateType::H, vec![0], None),
1533        ];
1534
1535        let result = profiler
1536            .profile_circuit(&gates, 1)
1537            .expect("Failed to profile circuit");
1538        assert!(result.bottleneck_analysis.is_some());
1539    }
1540
1541    #[test]
1542    fn test_optimization_recommendations() {
1543        let config = EnhancedProfilingConfig {
1544            generate_optimizations: true,
1545            ..Default::default()
1546        };
1547        let profiler = EnhancedQuantumProfiler::with_config(config);
1548
1549        let gates = vec![
1550            QuantumGate::new(GateType::H, vec![0], None),
1551            QuantumGate::new(GateType::H, vec![0], None), // H^2 = I
1552        ];
1553
1554        let result = profiler
1555            .profile_circuit(&gates, 1)
1556            .expect("Failed to profile circuit");
1557        assert!(!result.optimizations.is_empty());
1558        assert!(result
1559            .optimizations
1560            .iter()
1561            .any(|opt| opt.recommendation_type == RecommendationType::GateFusion));
1562    }
1563
1564    #[test]
1565    fn test_performance_prediction() {
1566        let config = EnhancedProfilingConfig {
1567            enable_performance_prediction: true,
1568            ..Default::default()
1569        };
1570        let profiler = EnhancedQuantumProfiler::with_config(config);
1571
1572        let gates = vec![
1573            QuantumGate::new(GateType::X, vec![0], None),
1574            QuantumGate::new(GateType::Y, vec![1], None),
1575            QuantumGate::new(GateType::Z, vec![2], None),
1576        ];
1577
1578        let result = profiler
1579            .profile_circuit(&gates, 3)
1580            .expect("Failed to profile circuit");
1581        assert!(result.performance_predictions.is_some());
1582
1583        let predictions = result
1584            .performance_predictions
1585            .expect("Missing performance predictions");
1586        assert!(predictions.predictions.contains_key("current"));
1587        assert!(predictions.predictions.contains_key("quantum_hw"));
1588    }
1589
1590    #[test]
1591    fn test_export_formats() {
1592        let config = EnhancedProfilingConfig {
1593            export_formats: vec![ExportFormat::JSON, ExportFormat::CSV, ExportFormat::HTML],
1594            ..Default::default()
1595        };
1596        let profiler = EnhancedQuantumProfiler::with_config(config);
1597
1598        let gates = vec![QuantumGate::new(GateType::H, vec![0], None)];
1599
1600        let result = profiler
1601            .profile_circuit(&gates, 1)
1602            .expect("Failed to profile circuit");
1603        assert_eq!(result.export_data.len(), 3);
1604        assert!(result.export_data.contains_key(&ExportFormat::JSON));
1605        assert!(result.export_data.contains_key(&ExportFormat::CSV));
1606        assert!(result.export_data.contains_key(&ExportFormat::HTML));
1607    }
1608}