1use crate::builder::Circuit;
8use crate::scirs2_integration::{AnalyzerConfig, GraphMetrics, SciRS2CircuitAnalyzer};
9use quantrs2_core::{
11 error::{QuantRS2Error, QuantRS2Result},
12 gate::GateOp,
13 qubit::QubitId,
14};
15use scirs2_core::ndarray::{Array1, Array2};
16use scirs2_core::Complex64;
17use serde::{Deserialize, Serialize};
18use std::collections::{HashMap, HashSet, VecDeque};
19use std::sync::{Arc, Mutex, RwLock};
20use std::time::{Duration, Instant, SystemTime};
21
22pub struct QuantumDebugger<const N: usize> {
24 circuit: Circuit<N>,
26 execution_state: Arc<RwLock<ExecutionState<N>>>,
28 config: DebuggerConfig,
30 analyzer: SciRS2CircuitAnalyzer,
32 breakpoints: Arc<RwLock<BreakpointManager>>,
34 watch_manager: Arc<RwLock<WatchManager<N>>>,
36 execution_history: Arc<RwLock<ExecutionHistory<N>>>,
38 profiler: Arc<RwLock<PerformanceProfiler>>,
40 visualizer: Arc<RwLock<VisualizationEngine<N>>>,
42 error_detector: Arc<RwLock<ErrorDetector<N>>>,
44}
45
46#[derive(Debug, Clone)]
48pub struct ExecutionState<const N: usize> {
49 pub current_gate_index: usize,
51 pub current_state: Array1<Complex64>,
53 pub status: ExecutionStatus,
55 pub gates_executed: usize,
57 pub current_depth: usize,
59 pub memory_usage: MemoryUsage,
61 pub timing_info: TimingInfo,
63}
64
65#[derive(Debug, Clone, PartialEq, Eq)]
67pub enum ExecutionStatus {
68 Ready,
70 Running,
72 Paused,
74 Stopped,
76 Completed,
78 Error { message: String },
80 Stepping,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct DebuggerConfig {
87 pub enable_step_mode: bool,
89 pub enable_auto_visualization: bool,
91 pub enable_profiling: bool,
93 pub enable_memory_tracking: bool,
95 pub enable_error_detection: bool,
97 pub max_history_entries: usize,
99 pub visualization_frequency: Duration,
101 pub profiling_sample_rate: f64,
103 pub memory_warning_threshold: f64,
105 pub gate_timeout: Duration,
107}
108
109impl Default for DebuggerConfig {
110 fn default() -> Self {
111 Self {
112 enable_step_mode: true,
113 enable_auto_visualization: true,
114 enable_profiling: true,
115 enable_memory_tracking: true,
116 enable_error_detection: true,
117 max_history_entries: 1000,
118 visualization_frequency: Duration::from_millis(100),
119 profiling_sample_rate: 1.0,
120 memory_warning_threshold: 0.8,
121 gate_timeout: Duration::from_secs(30),
122 }
123 }
124}
125
126#[derive(Debug, Clone)]
128pub struct BreakpointManager {
129 pub gate_breakpoints: HashSet<usize>,
131 pub qubit_breakpoints: HashMap<QubitId, BreakpointCondition>,
133 pub state_breakpoints: Vec<StateBreakpoint>,
135 pub conditional_breakpoints: Vec<ConditionalBreakpoint>,
137 pub hit_counts: HashMap<String, usize>,
139}
140
141#[derive(Debug, Clone)]
143pub enum BreakpointCondition {
144 OnMeasurement,
146 OnEntanglement { threshold: f64 },
148 OnFidelityDrop { threshold: f64 },
150 OnAnyGate,
152 OnGateType { gate_types: Vec<String> },
154}
155
156#[derive(Debug, Clone)]
158pub struct StateBreakpoint {
159 pub id: String,
161 pub target_state: StatePattern,
163 pub tolerance: f64,
165 pub enabled: bool,
167}
168
169#[derive(Debug, Clone)]
171pub struct ConditionalBreakpoint {
172 pub id: String,
174 pub condition: BreakpointCondition,
176 pub action: BreakpointAction,
178 pub enabled: bool,
180}
181
182#[derive(Debug, Clone)]
184pub enum StatePattern {
185 AmplitudePattern { amplitudes: Vec<Complex64> },
187 ProbabilityPattern { probabilities: Vec<f64> },
189 EntanglementPattern { entanglement_measure: f64 },
191 Custom { name: String, description: String },
193}
194
195#[derive(Debug, Clone)]
197pub enum BreakpointAction {
198 Pause,
200 Log { message: String },
202 Snapshot,
204 CustomAnalysis { analysis_type: String },
206}
207
208#[derive(Debug, Clone)]
210pub struct WatchManager<const N: usize> {
211 pub watched_states: HashMap<String, WatchedState<N>>,
213 pub watched_gates: HashMap<String, WatchedGate>,
215 pub watched_metrics: HashMap<String, WatchedMetric>,
217 pub watch_expressions: Vec<WatchExpression>,
219}
220
221#[derive(Debug, Clone)]
223pub struct WatchedState<const N: usize> {
224 pub name: String,
226 pub current_state: Array1<Complex64>,
228 pub history: VecDeque<StateSnapshot<N>>,
230 pub config: WatchConfig,
232}
233
234#[derive(Debug, Clone)]
236pub struct WatchedGate {
237 pub name: String,
239 pub current_properties: GateProperties,
241 pub history: VecDeque<GateSnapshot>,
243 pub config: WatchConfig,
245}
246
247#[derive(Debug, Clone)]
249pub struct WatchedMetric {
250 pub name: String,
252 pub current_value: f64,
254 pub history: VecDeque<MetricSnapshot>,
256 pub config: WatchConfig,
258}
259
260#[derive(Debug, Clone)]
262pub struct WatchExpression {
263 pub id: String,
265 pub description: String,
267 pub expression_type: ExpressionType,
269 pub evaluation_history: VecDeque<ExpressionResult>,
271}
272
273#[derive(Debug, Clone)]
275pub enum ExpressionType {
276 StateExpression { formula: String },
278 GateExpression { formula: String },
280 PerformanceExpression { formula: String },
282 Custom { evaluator: String },
284}
285
286#[derive(Debug, Clone)]
288pub struct ExpressionResult {
289 pub timestamp: SystemTime,
291 pub value: ExpressionValue,
293 pub success: bool,
295 pub error_message: Option<String>,
297}
298
299#[derive(Debug, Clone)]
301pub enum ExpressionValue {
302 Number(f64),
304 Boolean(bool),
306 String(String),
308 Complex(Complex64),
310 Vector(Vec<f64>),
312}
313
314#[derive(Debug, Clone)]
316pub struct WatchConfig {
317 pub update_frequency: Duration,
319 pub max_history: usize,
321 pub alert_thresholds: HashMap<String, f64>,
323 pub auto_save: bool,
325}
326
327#[derive(Debug, Clone)]
329pub struct StateSnapshot<const N: usize> {
330 pub timestamp: SystemTime,
332 pub state: Array1<Complex64>,
334 pub gate_index: usize,
336 pub metadata: HashMap<String, String>,
338}
339
340#[derive(Debug, Clone)]
342pub struct GateSnapshot {
343 pub timestamp: SystemTime,
345 pub properties: GateProperties,
347 pub execution_metrics: GateExecutionMetrics,
349}
350
351#[derive(Debug, Clone)]
353pub struct GateProperties {
354 pub name: String,
356 pub matrix: Option<Array2<Complex64>>,
358 pub target_qubits: Vec<QubitId>,
360 pub control_qubits: Vec<QubitId>,
362 pub parameters: HashMap<String, f64>,
364 pub fidelity: Option<f64>,
366 pub execution_time: Duration,
368}
369
370#[derive(Debug, Clone)]
372pub struct GateExecutionMetrics {
373 pub execution_time: Duration,
375 pub memory_change: i64,
377 pub error_rate: Option<f64>,
379 pub resource_utilization: f64,
381}
382
383#[derive(Debug, Clone)]
385pub struct MetricSnapshot {
386 pub timestamp: SystemTime,
388 pub value: f64,
390 pub gate_index: usize,
392 pub context: HashMap<String, String>,
394}
395
396#[derive(Debug, Clone)]
398pub struct ExecutionHistory<const N: usize> {
399 pub entries: VecDeque<HistoryEntry<N>>,
401 pub max_entries: usize,
403 pub statistics: HistoryStatistics,
405}
406
407#[derive(Debug, Clone)]
409pub struct HistoryEntry<const N: usize> {
410 pub timestamp: SystemTime,
412 pub gate_executed: Option<Box<dyn GateOp>>,
414 pub state_before: Array1<Complex64>,
416 pub state_after: Array1<Complex64>,
418 pub execution_metrics: GateExecutionMetrics,
420 pub errors: Vec<DebugError>,
422}
423
424#[derive(Debug, Clone)]
426pub struct HistoryStatistics {
427 pub total_gates: usize,
429 pub average_execution_time: Duration,
431 pub total_execution_time: Duration,
433 pub memory_stats: MemoryStatistics,
435 pub error_stats: ErrorStatistics,
437}
438
439#[derive(Debug, Clone)]
441pub struct MemoryUsage {
442 pub current_usage: usize,
444 pub peak_usage: usize,
446 pub usage_history: VecDeque<MemorySnapshot>,
448 pub allocation_breakdown: HashMap<String, usize>,
450}
451
452#[derive(Debug, Clone)]
454pub struct MemorySnapshot {
455 pub timestamp: SystemTime,
457 pub usage: usize,
459 pub operation: String,
461}
462
463#[derive(Debug, Clone)]
465pub struct MemoryStatistics {
466 pub average_usage: f64,
468 pub peak_usage: usize,
470 pub efficiency_score: f64,
472 pub leak_indicators: Vec<String>,
474}
475
476#[derive(Debug, Clone)]
478pub struct TimingInfo {
479 pub start_time: SystemTime,
481 pub current_time: SystemTime,
483 pub total_duration: Duration,
485 pub gate_times: Vec<Duration>,
487 pub timing_stats: TimingStatistics,
489}
490
491#[derive(Debug, Clone)]
493pub struct TimingStatistics {
494 pub average_gate_time: Duration,
496 pub fastest_gate: Duration,
498 pub slowest_gate: Duration,
500 pub execution_variance: f64,
502}
503
504#[derive(Debug, Clone)]
506pub struct PerformanceProfiler {
507 pub config: ProfilerConfig,
509 pub samples: VecDeque<PerformanceSample>,
511 pub analysis_results: PerformanceAnalysis,
513 pub statistics: ProfilingStatistics,
515}
516
517#[derive(Debug, Clone)]
519pub struct ProfilerConfig {
520 pub sample_frequency: Duration,
522 pub max_samples: usize,
524 pub tracked_metrics: HashSet<String>,
526 pub analysis_depth: AnalysisDepth,
528}
529
530#[derive(Debug, Clone)]
532pub enum AnalysisDepth {
533 Basic,
535 Standard,
537 Comprehensive,
539 Deep,
541}
542
543#[derive(Debug, Clone)]
545pub struct PerformanceSample {
546 pub timestamp: SystemTime,
548 pub cpu_usage: f64,
550 pub memory_usage: usize,
552 pub gate_execution_time: Duration,
554 pub state_complexity: f64,
556 pub error_rates: HashMap<String, f64>,
558}
559
560#[derive(Debug, Clone)]
562pub struct PerformanceAnalysis {
563 pub trends: HashMap<String, TrendAnalysis>,
565 pub bottlenecks: Vec<PerformanceBottleneck>,
567 pub suggestions: Vec<OptimizationSuggestion>,
569 pub predictions: HashMap<String, PredictionResult>,
571}
572
573#[derive(Debug, Clone)]
575pub struct TrendAnalysis {
576 pub metric_name: String,
578 pub trend_direction: TrendDirection,
580 pub trend_strength: f64,
582 pub prediction: Option<f64>,
584 pub confidence: f64,
586}
587
588#[derive(Debug, Clone)]
590pub enum TrendDirection {
591 Increasing,
593 Decreasing,
595 Stable,
597 Oscillating,
599 Unknown,
601}
602
603#[derive(Debug, Clone)]
605pub struct PerformanceBottleneck {
606 pub bottleneck_type: BottleneckType,
608 pub severity: f64,
610 pub description: String,
612 pub recommendations: Vec<String>,
614 pub impact: ImpactAssessment,
616}
617
618#[derive(Debug, Clone)]
620pub enum BottleneckType {
621 CpuBound,
623 MemoryBound,
625 IoBound,
627 GateExecution,
629 StateVector,
631 Entanglement,
633}
634
635#[derive(Debug, Clone)]
637pub struct ImpactAssessment {
638 pub performance_impact: f64,
640 pub memory_impact: f64,
642 pub accuracy_impact: f64,
644 pub overall_impact: f64,
646}
647
648#[derive(Debug, Clone)]
650pub struct OptimizationSuggestion {
651 pub suggestion_type: SuggestionType,
653 pub priority: Priority,
655 pub expected_improvement: f64,
657 pub difficulty: Difficulty,
659 pub description: String,
661 pub implementation_steps: Vec<String>,
663}
664
665#[derive(Debug, Clone)]
667pub enum SuggestionType {
668 Algorithm,
670 Memory,
672 Circuit,
674 Hardware,
676 Parallelization,
678}
679
680#[derive(Debug, Clone)]
682pub enum Priority {
683 Low,
685 Medium,
687 High,
689 Critical,
691}
692
693#[derive(Debug, Clone)]
695pub enum Difficulty {
696 Easy,
698 Medium,
700 Hard,
702 VeryHard,
704}
705
706#[derive(Debug, Clone)]
708pub struct PredictionResult {
709 pub predicted_value: f64,
711 pub confidence_interval: (f64, f64),
713 pub accuracy: f64,
715 pub time_horizon: Duration,
717}
718
719#[derive(Debug, Clone)]
721pub struct ProfilingStatistics {
722 pub total_samples: usize,
724 pub profiling_duration: Duration,
726 pub average_sample_rate: f64,
728 pub performance_metrics: HashMap<String, f64>,
730}
731
732#[derive(Debug, Clone)]
734pub struct VisualizationEngine<const N: usize> {
735 pub config: VisualizationConfig,
737 pub current_visualizations: HashMap<String, Visualization<N>>,
739 pub visualization_history: VecDeque<VisualizationSnapshot<N>>,
741 pub rendering_stats: RenderingStatistics,
743}
744
745#[derive(Debug, Clone)]
747pub struct VisualizationConfig {
748 pub enable_realtime: bool,
750 pub enabled_types: HashSet<VisualizationType>,
752 pub update_frequency: Duration,
754 pub rendering_quality: RenderingQuality,
756 pub export_options: ExportOptions,
758}
759
760#[derive(Debug, Clone, Hash, Eq, PartialEq)]
762pub enum VisualizationType {
763 CircuitDiagram,
765 BlochSphere,
767 StateVector,
769 ProbabilityDistribution,
771 Entanglement,
773 Performance,
775 Memory,
777 ErrorAnalysis,
779}
780
781#[derive(Debug, Clone)]
783pub enum RenderingQuality {
784 Low,
786 Medium,
788 High,
790 Ultra,
792}
793
794#[derive(Debug, Clone)]
796pub struct ExportOptions {
797 pub formats: HashSet<ExportFormat>,
799 pub default_quality: RenderingQuality,
801 pub export_directory: Option<String>,
803 pub auto_export: bool,
805}
806
807#[derive(Debug, Clone, Hash, Eq, PartialEq)]
809pub enum ExportFormat {
810 PNG,
812 SVG,
814 PDF,
816 JSON,
818 CSV,
820 HTML,
822}
823
824#[derive(Debug, Clone)]
826pub struct Visualization<const N: usize> {
827 pub visualization_type: VisualizationType,
829 pub data: VisualizationData<N>,
831 pub metadata: VisualizationMetadata,
833 pub last_update: SystemTime,
835}
836
837#[derive(Debug, Clone)]
839pub enum VisualizationData<const N: usize> {
840 CircuitData {
842 gates: Vec<GateVisualization>,
843 connections: Vec<ConnectionVisualization>,
844 current_position: Option<usize>,
845 },
846 BlochData {
848 qubit_states: HashMap<QubitId, BlochVector>,
849 evolution_path: Vec<BlochVector>,
850 },
851 StateData {
853 amplitudes: Array1<Complex64>,
854 probabilities: Array1<f64>,
855 phases: Array1<f64>,
856 },
857 PerformanceData {
859 metrics: HashMap<String, Vec<f64>>,
860 timestamps: Vec<SystemTime>,
861 },
862}
863
864#[derive(Debug, Clone)]
866pub struct GateVisualization {
867 pub name: String,
869 pub position: (usize, usize),
871 pub gate_type: GateType,
873 pub attributes: GateAttributes,
875}
876
877#[derive(Debug, Clone)]
879pub struct ConnectionVisualization {
880 pub source: (usize, usize),
882 pub target: (usize, usize),
884 pub connection_type: ConnectionType,
886}
887
888#[derive(Debug, Clone)]
890pub enum GateType {
891 SingleQubit,
893 TwoQubit,
895 MultiQubit,
897 Measurement,
899 Barrier,
901}
902
903#[derive(Debug, Clone)]
905pub struct GateAttributes {
906 pub color: Option<String>,
908 pub size: Option<f64>,
910 pub style: Option<String>,
912 pub properties: HashMap<String, String>,
914}
915
916#[derive(Debug, Clone)]
918pub enum ConnectionType {
919 Control,
921 Target,
923 Classical,
925 Entanglement,
927}
928
929#[derive(Debug, Clone)]
931pub struct BlochVector {
932 pub x: f64,
934 pub y: f64,
936 pub z: f64,
938 pub timestamp: SystemTime,
940}
941
942#[derive(Debug, Clone)]
944pub struct VisualizationMetadata {
945 pub created: SystemTime,
947 pub modified: SystemTime,
949 pub size: (u32, u32),
951 pub render_time: Duration,
953 pub metadata: HashMap<String, String>,
955}
956
957#[derive(Debug, Clone)]
959pub struct VisualizationSnapshot<const N: usize> {
960 pub timestamp: SystemTime,
962 pub gate_index: usize,
964 pub visualization: Visualization<N>,
966 pub metadata: HashMap<String, String>,
968}
969
970#[derive(Debug, Clone)]
972pub struct RenderingStatistics {
973 pub total_renders: usize,
975 pub average_render_time: Duration,
977 pub total_render_time: Duration,
979 pub success_rate: f64,
981 pub memory_usage: usize,
983}
984
985#[derive(Debug, Clone)]
987pub struct ErrorDetector<const N: usize> {
988 pub config: ErrorDetectionConfig,
990 pub detected_errors: Vec<DebugError>,
992 pub error_statistics: ErrorStatistics,
994 pub analysis_results: ErrorAnalysisResults,
996}
997
998#[derive(Debug, Clone)]
1000pub struct ErrorDetectionConfig {
1001 pub enable_auto_detection: bool,
1003 pub sensitivity: f64,
1005 pub error_types: HashSet<ErrorType>,
1007 pub reporting_threshold: f64,
1009 pub max_errors: usize,
1011}
1012
1013#[derive(Debug, Clone, Hash, Eq, PartialEq)]
1015pub enum ErrorType {
1016 StateVectorError,
1018 GateExecutionError,
1020 MemoryError,
1022 TimingError,
1024 NumericalError,
1026 LogicalError,
1028}
1029
1030#[derive(Debug, Clone)]
1032pub struct DebugError {
1033 pub error_type: ErrorType,
1035 pub severity: ErrorSeverity,
1037 pub message: String,
1039 pub gate_index: Option<usize>,
1041 pub timestamp: SystemTime,
1043 pub context: HashMap<String, String>,
1045 pub suggested_fixes: Vec<String>,
1047}
1048
1049#[derive(Debug, Clone)]
1051pub enum ErrorSeverity {
1052 Low,
1054 Medium,
1056 High,
1058 Critical,
1060}
1061
1062#[derive(Debug, Clone)]
1064pub struct ErrorStatistics {
1065 pub total_errors: usize,
1067 pub errors_by_type: HashMap<ErrorType, usize>,
1069 pub errors_by_severity: HashMap<ErrorSeverity, usize>,
1071 pub error_rate: f64,
1073 pub error_trends: HashMap<ErrorType, TrendDirection>,
1075}
1076
1077#[derive(Debug, Clone)]
1079pub struct ErrorAnalysisResults {
1080 pub error_patterns: Vec<ErrorPattern>,
1082 pub root_causes: Vec<RootCause>,
1084 pub correlations: Vec<ErrorCorrelation>,
1086 pub predictions: HashMap<ErrorType, PredictionResult>,
1088}
1089
1090#[derive(Debug, Clone)]
1092pub struct ErrorPattern {
1093 pub pattern_type: PatternType,
1095 pub frequency: f64,
1097 pub description: String,
1099 pub confidence: f64,
1101}
1102
1103#[derive(Debug, Clone)]
1105pub enum PatternType {
1106 Periodic,
1108 Burst,
1110 Gradual,
1112 Random,
1114 Systematic,
1116}
1117
1118#[derive(Debug, Clone)]
1120pub struct RootCause {
1121 pub description: String,
1123 pub confidence: f64,
1125 pub contributing_factors: Vec<String>,
1127 pub solutions: Vec<Solution>,
1129}
1130
1131#[derive(Debug, Clone)]
1133pub struct Solution {
1134 pub description: String,
1136 pub difficulty: Difficulty,
1138 pub effectiveness: f64,
1140 pub steps: Vec<String>,
1142}
1143
1144#[derive(Debug, Clone)]
1146pub struct ErrorCorrelation {
1147 pub error_type_1: ErrorType,
1149 pub error_type_2: ErrorType,
1151 pub correlation_strength: f64,
1153 pub correlation_type: CorrelationType,
1155}
1156
1157#[derive(Debug, Clone)]
1159pub enum CorrelationType {
1160 Positive,
1162 Negative,
1164 None,
1166 Causal,
1168}
1169
1170impl<const N: usize> QuantumDebugger<N> {
1171 #[must_use]
1173 pub fn new(circuit: Circuit<N>) -> Self {
1174 let config = DebuggerConfig::default();
1175 let analyzer = SciRS2CircuitAnalyzer::with_config(AnalyzerConfig::default());
1176
1177 Self {
1178 circuit,
1179 execution_state: Arc::new(RwLock::new(ExecutionState {
1180 current_gate_index: 0,
1181 current_state: Array1::<Complex64>::zeros(1 << N),
1182 status: ExecutionStatus::Ready,
1183 gates_executed: 0,
1184 current_depth: 0,
1185 memory_usage: MemoryUsage {
1186 current_usage: 0,
1187 peak_usage: 0,
1188 usage_history: VecDeque::new(),
1189 allocation_breakdown: HashMap::new(),
1190 },
1191 timing_info: TimingInfo {
1192 start_time: SystemTime::now(),
1193 current_time: SystemTime::now(),
1194 total_duration: Duration::new(0, 0),
1195 gate_times: Vec::new(),
1196 timing_stats: TimingStatistics {
1197 average_gate_time: Duration::new(0, 0),
1198 fastest_gate: Duration::new(0, 0),
1199 slowest_gate: Duration::new(0, 0),
1200 execution_variance: 0.0,
1201 },
1202 },
1203 })),
1204 config: config.clone(),
1205 analyzer,
1206 breakpoints: Arc::new(RwLock::new(BreakpointManager {
1207 gate_breakpoints: HashSet::new(),
1208 qubit_breakpoints: HashMap::new(),
1209 state_breakpoints: Vec::new(),
1210 conditional_breakpoints: Vec::new(),
1211 hit_counts: HashMap::new(),
1212 })),
1213 watch_manager: Arc::new(RwLock::new(WatchManager {
1214 watched_states: HashMap::new(),
1215 watched_gates: HashMap::new(),
1216 watched_metrics: HashMap::new(),
1217 watch_expressions: Vec::new(),
1218 })),
1219 execution_history: Arc::new(RwLock::new(ExecutionHistory {
1220 entries: VecDeque::new(),
1221 max_entries: config.max_history_entries,
1222 statistics: HistoryStatistics {
1223 total_gates: 0,
1224 average_execution_time: Duration::new(0, 0),
1225 total_execution_time: Duration::new(0, 0),
1226 memory_stats: MemoryStatistics {
1227 average_usage: 0.0,
1228 peak_usage: 0,
1229 efficiency_score: 1.0,
1230 leak_indicators: Vec::new(),
1231 },
1232 error_stats: ErrorStatistics {
1233 total_errors: 0,
1234 errors_by_type: HashMap::new(),
1235 errors_by_severity: HashMap::new(),
1236 error_rate: 0.0,
1237 error_trends: HashMap::new(),
1238 },
1239 },
1240 })),
1241 profiler: Arc::new(RwLock::new(PerformanceProfiler {
1242 config: ProfilerConfig {
1243 sample_frequency: Duration::from_millis(10),
1244 max_samples: 10000,
1245 tracked_metrics: HashSet::new(),
1246 analysis_depth: AnalysisDepth::Standard,
1247 },
1248 samples: VecDeque::new(),
1249 analysis_results: PerformanceAnalysis {
1250 trends: HashMap::new(),
1251 bottlenecks: Vec::new(),
1252 suggestions: Vec::new(),
1253 predictions: HashMap::new(),
1254 },
1255 statistics: ProfilingStatistics {
1256 total_samples: 0,
1257 profiling_duration: Duration::new(0, 0),
1258 average_sample_rate: 0.0,
1259 performance_metrics: HashMap::new(),
1260 },
1261 })),
1262 visualizer: Arc::new(RwLock::new(VisualizationEngine {
1263 config: VisualizationConfig {
1264 enable_realtime: true,
1265 enabled_types: {
1266 let mut types = HashSet::new();
1267 types.insert(VisualizationType::CircuitDiagram);
1268 types.insert(VisualizationType::StateVector);
1269 types.insert(VisualizationType::BlochSphere);
1270 types
1271 },
1272 update_frequency: Duration::from_millis(100),
1273 rendering_quality: RenderingQuality::Medium,
1274 export_options: ExportOptions {
1275 formats: {
1276 let mut formats = HashSet::new();
1277 formats.insert(ExportFormat::PNG);
1278 formats.insert(ExportFormat::JSON);
1279 formats
1280 },
1281 default_quality: RenderingQuality::High,
1282 export_directory: None,
1283 auto_export: false,
1284 },
1285 },
1286 current_visualizations: HashMap::new(),
1287 visualization_history: VecDeque::new(),
1288 rendering_stats: RenderingStatistics {
1289 total_renders: 0,
1290 average_render_time: Duration::new(0, 0),
1291 total_render_time: Duration::new(0, 0),
1292 success_rate: 1.0,
1293 memory_usage: 0,
1294 },
1295 })),
1296 error_detector: Arc::new(RwLock::new(ErrorDetector {
1297 config: ErrorDetectionConfig {
1298 enable_auto_detection: true,
1299 sensitivity: 0.8,
1300 error_types: {
1301 let mut types = HashSet::new();
1302 types.insert(ErrorType::StateVectorError);
1303 types.insert(ErrorType::GateExecutionError);
1304 types.insert(ErrorType::NumericalError);
1305 types
1306 },
1307 reporting_threshold: 0.1,
1308 max_errors: 1000,
1309 },
1310 detected_errors: Vec::new(),
1311 error_statistics: ErrorStatistics {
1312 total_errors: 0,
1313 errors_by_type: HashMap::new(),
1314 errors_by_severity: HashMap::new(),
1315 error_rate: 0.0,
1316 error_trends: HashMap::new(),
1317 },
1318 analysis_results: ErrorAnalysisResults {
1319 error_patterns: Vec::new(),
1320 root_causes: Vec::new(),
1321 correlations: Vec::new(),
1322 predictions: HashMap::new(),
1323 },
1324 })),
1325 }
1326 }
1327
1328 #[must_use]
1330 pub fn with_config(circuit: Circuit<N>, config: DebuggerConfig) -> Self {
1331 let mut debugger = Self::new(circuit);
1332 debugger.config = config;
1333 debugger
1334 }
1335
1336 pub fn start_session(&mut self) -> QuantRS2Result<()> {
1338 {
1339 let mut state = self.execution_state.write().map_err(|_| {
1340 QuantRS2Error::InvalidOperation(
1341 "Failed to acquire execution state write lock".to_string(),
1342 )
1343 })?;
1344 state.status = ExecutionStatus::Running;
1345 state.timing_info.start_time = SystemTime::now();
1346 }
1347
1348 self.initialize_scirs2_analysis()?;
1350
1351 if self.config.enable_profiling {
1353 self.start_profiling()?;
1354 }
1355
1356 if self.config.enable_auto_visualization {
1358 self.initialize_visualization()?;
1359 }
1360
1361 Ok(())
1362 }
1363
1364 pub fn step_next(&mut self) -> QuantRS2Result<StepResult> {
1366 let start_time = Instant::now();
1367
1368 if self.should_break()? {
1370 let mut state = self.execution_state.write().map_err(|_| {
1371 QuantRS2Error::InvalidOperation(
1372 "Failed to acquire execution state write lock".to_string(),
1373 )
1374 })?;
1375 state.status = ExecutionStatus::Paused;
1376 return Ok(StepResult::Breakpoint);
1377 }
1378
1379 let gate_index = {
1381 let state = self.execution_state.read().map_err(|_| {
1382 QuantRS2Error::InvalidOperation(
1383 "Failed to acquire execution state read lock".to_string(),
1384 )
1385 })?;
1386 state.current_gate_index
1387 };
1388
1389 if gate_index >= self.circuit.gates().len() {
1390 let mut state = self.execution_state.write().map_err(|_| {
1391 QuantRS2Error::InvalidOperation(
1392 "Failed to acquire execution state write lock".to_string(),
1393 )
1394 })?;
1395 state.status = ExecutionStatus::Completed;
1396 return Ok(StepResult::Completed);
1397 }
1398
1399 self.pre_execution_analysis(gate_index)?;
1401
1402 let execution_result = self.execute_gate_with_monitoring(gate_index)?;
1404
1405 self.post_execution_analysis(gate_index, &execution_result)?;
1407
1408 {
1410 let mut state = self.execution_state.write().map_err(|_| {
1411 QuantRS2Error::InvalidOperation(
1412 "Failed to acquire execution state write lock".to_string(),
1413 )
1414 })?;
1415 state.current_gate_index += 1;
1416 state.gates_executed += 1;
1417 state.current_depth = self.calculate_current_depth()?;
1418 state.timing_info.gate_times.push(start_time.elapsed());
1419 }
1420
1421 if self.config.enable_auto_visualization {
1423 self.update_visualizations()?;
1424 }
1425
1426 Ok(StepResult::Success)
1427 }
1428
1429 pub fn run(&mut self) -> QuantRS2Result<ExecutionSummary> {
1431 self.start_session()?;
1432
1433 let mut step_count = 0;
1434 loop {
1435 match self.step_next()? {
1436 StepResult::Success => {
1437 step_count += 1;
1438 }
1439 StepResult::Breakpoint => {
1440 return Ok(ExecutionSummary {
1441 status: ExecutionStatus::Paused,
1442 steps_executed: step_count,
1443 final_state: self.get_current_state()?,
1444 execution_time: self.get_execution_time()?,
1445 memory_usage: self.get_memory_usage()?,
1446 });
1447 }
1448 StepResult::Completed => {
1449 break;
1450 }
1451 StepResult::Error(error) => {
1452 return Err(error);
1453 }
1454 }
1455 }
1456
1457 self.finalize_execution()?;
1459
1460 Ok(ExecutionSummary {
1461 status: ExecutionStatus::Completed,
1462 steps_executed: step_count,
1463 final_state: self.get_current_state()?,
1464 execution_time: self.get_execution_time()?,
1465 memory_usage: self.get_memory_usage()?,
1466 })
1467 }
1468
1469 pub fn pause(&mut self) -> QuantRS2Result<()> {
1471 let mut state = self.execution_state.write().map_err(|_| {
1472 QuantRS2Error::InvalidOperation(
1473 "Failed to acquire execution state write lock".to_string(),
1474 )
1475 })?;
1476 state.status = ExecutionStatus::Paused;
1477 Ok(())
1478 }
1479
1480 pub fn resume(&mut self) -> QuantRS2Result<()> {
1482 let mut state = self.execution_state.write().map_err(|_| {
1483 QuantRS2Error::InvalidOperation(
1484 "Failed to acquire execution state write lock".to_string(),
1485 )
1486 })?;
1487 state.status = ExecutionStatus::Running;
1488 Ok(())
1489 }
1490
1491 pub fn stop(&mut self) -> QuantRS2Result<()> {
1493 let mut state = self.execution_state.write().map_err(|_| {
1494 QuantRS2Error::InvalidOperation(
1495 "Failed to acquire execution state write lock".to_string(),
1496 )
1497 })?;
1498 state.status = ExecutionStatus::Stopped;
1499 Ok(())
1500 }
1501
1502 pub fn add_gate_breakpoint(&mut self, gate_index: usize) -> QuantRS2Result<()> {
1504 let mut breakpoints = self.breakpoints.write().map_err(|_| {
1505 QuantRS2Error::InvalidOperation("Failed to acquire breakpoints write lock".to_string())
1506 })?;
1507 breakpoints.gate_breakpoints.insert(gate_index);
1508 Ok(())
1509 }
1510
1511 pub fn add_qubit_breakpoint(
1513 &mut self,
1514 qubit: QubitId,
1515 condition: BreakpointCondition,
1516 ) -> QuantRS2Result<()> {
1517 let mut breakpoints = self.breakpoints.write().map_err(|_| {
1518 QuantRS2Error::InvalidOperation("Failed to acquire breakpoints write lock".to_string())
1519 })?;
1520 breakpoints.qubit_breakpoints.insert(qubit, condition);
1521 Ok(())
1522 }
1523
1524 pub fn add_state_breakpoint(
1526 &mut self,
1527 id: String,
1528 pattern: StatePattern,
1529 tolerance: f64,
1530 ) -> QuantRS2Result<()> {
1531 let mut breakpoints = self.breakpoints.write().map_err(|_| {
1532 QuantRS2Error::InvalidOperation("Failed to acquire breakpoints write lock".to_string())
1533 })?;
1534 breakpoints.state_breakpoints.push(StateBreakpoint {
1535 id,
1536 target_state: pattern,
1537 tolerance,
1538 enabled: true,
1539 });
1540 Ok(())
1541 }
1542
1543 pub fn get_current_state(&self) -> QuantRS2Result<Array1<Complex64>> {
1545 let state = self.execution_state.read().map_err(|_| {
1546 QuantRS2Error::InvalidOperation(
1547 "Failed to acquire execution state read lock".to_string(),
1548 )
1549 })?;
1550 Ok(state.current_state.clone())
1551 }
1552
1553 #[must_use]
1555 pub fn get_execution_status(&self) -> ExecutionStatus {
1556 let state = self
1557 .execution_state
1558 .read()
1559 .expect("execution state lock should not be poisoned");
1560 state.status.clone()
1561 }
1562
1563 pub fn get_performance_analysis(&self) -> QuantRS2Result<PerformanceAnalysis> {
1565 let profiler = self.profiler.read().map_err(|_| {
1566 QuantRS2Error::InvalidOperation("Failed to acquire profiler read lock".to_string())
1567 })?;
1568 Ok(profiler.analysis_results.clone())
1569 }
1570
1571 pub fn get_error_analysis(&self) -> QuantRS2Result<ErrorAnalysisResults> {
1573 let detector = self.error_detector.read().map_err(|_| {
1574 QuantRS2Error::InvalidOperation(
1575 "Failed to acquire error detector read lock".to_string(),
1576 )
1577 })?;
1578 Ok(detector.analysis_results.clone())
1579 }
1580
1581 pub fn export_session(&self, format: ExportFormat, path: &str) -> QuantRS2Result<()> {
1583 match format {
1584 ExportFormat::JSON => self.export_json(path),
1585 ExportFormat::HTML => self.export_html(path),
1586 ExportFormat::CSV => self.export_csv(path),
1587 _ => Err(QuantRS2Error::InvalidOperation(
1588 "Unsupported export format".to_string(),
1589 )),
1590 }
1591 }
1592
1593 fn initialize_scirs2_analysis(&self) -> QuantRS2Result<()> {
1596 let _graph = self.analyzer.circuit_to_scirs2_graph(&self.circuit)?;
1598 Ok(())
1599 }
1600
1601 const fn start_profiling(&self) -> QuantRS2Result<()> {
1602 Ok(())
1604 }
1605
1606 const fn initialize_visualization(&self) -> QuantRS2Result<()> {
1607 Ok(())
1609 }
1610
1611 fn should_break(&self) -> QuantRS2Result<bool> {
1612 let breakpoints = self.breakpoints.read().map_err(|_| {
1613 QuantRS2Error::InvalidOperation("Failed to acquire breakpoints read lock".to_string())
1614 })?;
1615 let state = self.execution_state.read().map_err(|_| {
1616 QuantRS2Error::InvalidOperation(
1617 "Failed to acquire execution state read lock".to_string(),
1618 )
1619 })?;
1620
1621 if breakpoints
1623 .gate_breakpoints
1624 .contains(&state.current_gate_index)
1625 {
1626 return Ok(true);
1627 }
1628
1629 Ok(false)
1631 }
1632
1633 const fn pre_execution_analysis(&self, _gate_index: usize) -> QuantRS2Result<()> {
1634 Ok(())
1636 }
1637
1638 const fn execute_gate_with_monitoring(
1639 &self,
1640 _gate_index: usize,
1641 ) -> QuantRS2Result<GateExecutionResult> {
1642 Ok(GateExecutionResult {
1644 success: true,
1645 execution_time: Duration::from_millis(1),
1646 memory_change: 0,
1647 errors: Vec::new(),
1648 })
1649 }
1650
1651 const fn post_execution_analysis(
1652 &self,
1653 _gate_index: usize,
1654 _result: &GateExecutionResult,
1655 ) -> QuantRS2Result<()> {
1656 Ok(())
1658 }
1659
1660 const fn calculate_current_depth(&self) -> QuantRS2Result<usize> {
1661 Ok(0)
1663 }
1664
1665 const fn update_visualizations(&self) -> QuantRS2Result<()> {
1666 Ok(())
1668 }
1669
1670 fn finalize_execution(&self) -> QuantRS2Result<()> {
1671 let mut state = self.execution_state.write().map_err(|_| {
1673 QuantRS2Error::InvalidOperation(
1674 "Failed to acquire execution state write lock".to_string(),
1675 )
1676 })?;
1677 state.status = ExecutionStatus::Completed;
1678 state.timing_info.current_time = SystemTime::now();
1679 Ok(())
1680 }
1681
1682 fn get_execution_time(&self) -> QuantRS2Result<Duration> {
1683 let state = self.execution_state.read().map_err(|_| {
1684 QuantRS2Error::InvalidOperation(
1685 "Failed to acquire execution state read lock".to_string(),
1686 )
1687 })?;
1688 Ok(state.timing_info.total_duration)
1689 }
1690
1691 fn get_memory_usage(&self) -> QuantRS2Result<MemoryUsage> {
1692 let state = self.execution_state.read().map_err(|_| {
1693 QuantRS2Error::InvalidOperation(
1694 "Failed to acquire execution state read lock".to_string(),
1695 )
1696 })?;
1697 Ok(state.memory_usage.clone())
1698 }
1699
1700 const fn export_json(&self, _path: &str) -> QuantRS2Result<()> {
1701 Ok(())
1703 }
1704
1705 const fn export_html(&self, _path: &str) -> QuantRS2Result<()> {
1706 Ok(())
1708 }
1709
1710 const fn export_csv(&self, _path: &str) -> QuantRS2Result<()> {
1711 Ok(())
1713 }
1714}
1715
1716#[derive(Debug, Clone)]
1718pub enum StepResult {
1719 Success,
1721 Breakpoint,
1723 Completed,
1725 Error(QuantRS2Error),
1727}
1728
1729#[derive(Debug, Clone)]
1731pub struct GateExecutionResult {
1732 pub success: bool,
1734 pub execution_time: Duration,
1736 pub memory_change: i64,
1738 pub errors: Vec<DebugError>,
1740}
1741
1742#[derive(Debug, Clone)]
1744pub struct ExecutionSummary {
1745 pub status: ExecutionStatus,
1747 pub steps_executed: usize,
1749 pub final_state: Array1<Complex64>,
1751 pub execution_time: Duration,
1753 pub memory_usage: MemoryUsage,
1755}
1756
1757#[cfg(test)]
1758mod tests {
1759 use super::*;
1760 use quantrs2_core::gate::multi::CNOT;
1761 use quantrs2_core::gate::single::Hadamard;
1762
1763 #[test]
1764 fn test_debugger_creation() {
1765 let circuit = Circuit::<2>::new();
1766 let debugger = QuantumDebugger::new(circuit);
1767
1768 assert_eq!(debugger.get_execution_status(), ExecutionStatus::Ready);
1769 }
1770
1771 #[test]
1772 fn test_breakpoint_management() {
1773 let circuit = Circuit::<2>::new();
1774 let mut debugger = QuantumDebugger::new(circuit);
1775
1776 debugger
1777 .add_gate_breakpoint(0)
1778 .expect("add_gate_breakpoint should succeed");
1779
1780 let breakpoints = debugger
1781 .breakpoints
1782 .read()
1783 .expect("breakpoints lock should not be poisoned");
1784 assert!(breakpoints.gate_breakpoints.contains(&0));
1785 }
1786
1787 #[test]
1788 fn test_step_execution() {
1789 let mut circuit = Circuit::<1>::new();
1790 circuit
1791 .add_gate(Hadamard { target: QubitId(0) })
1792 .expect("add_gate should succeed");
1793
1794 let mut debugger = QuantumDebugger::new(circuit);
1795 debugger
1796 .start_session()
1797 .expect("start_session should succeed");
1798
1799 let result = debugger.step_next().expect("step_next should succeed");
1800 match result {
1801 StepResult::Success => (),
1802 _ => panic!("Expected successful step execution"),
1803 }
1804 }
1805
1806 #[test]
1807 fn test_visualization_configuration() {
1808 let circuit = Circuit::<2>::new();
1809 let config = DebuggerConfig {
1810 enable_auto_visualization: true,
1811 ..Default::default()
1812 };
1813
1814 let debugger = QuantumDebugger::with_config(circuit, config);
1815
1816 let visualizer = debugger
1817 .visualizer
1818 .read()
1819 .expect("visualizer lock should not be poisoned");
1820 assert!(visualizer.config.enable_realtime);
1821 }
1822
1823 #[test]
1824 fn test_performance_profiling() {
1825 let mut circuit = Circuit::<2>::new();
1826 circuit
1827 .add_gate(Hadamard { target: QubitId(0) })
1828 .expect("add_gate Hadamard should succeed");
1829 circuit
1830 .add_gate(CNOT {
1831 control: QubitId(0),
1832 target: QubitId(1),
1833 })
1834 .expect("add_gate CNOT should succeed");
1835
1836 let config = DebuggerConfig {
1837 enable_profiling: true,
1838 ..Default::default()
1839 };
1840
1841 let mut debugger = QuantumDebugger::with_config(circuit, config);
1842 let _summary = debugger.run().expect("debugger run should succeed");
1843
1844 let analysis = debugger
1845 .get_performance_analysis()
1846 .expect("get_performance_analysis should succeed");
1847 assert!(!analysis.suggestions.is_empty() || analysis.suggestions.is_empty());
1848 }
1850
1851 #[test]
1852 fn test_error_detection() {
1853 let circuit = Circuit::<1>::new();
1854 let config = DebuggerConfig {
1855 enable_error_detection: true,
1856 ..Default::default()
1857 };
1858
1859 let debugger = QuantumDebugger::with_config(circuit, config);
1860
1861 let detector = debugger
1862 .error_detector
1863 .read()
1864 .expect("error_detector lock should not be poisoned");
1865 assert!(detector.config.enable_auto_detection);
1866 }
1867}