1use crate::builder::Circuit;
8use crate::scirs2_integration::{AnalyzerConfig, GraphMetrics, SciRS2CircuitAnalyzer};
9use scirs2_core::ndarray::{Array1, Array2};
11use scirs2_core::Complex64;
12use quantrs2_core::{
13 error::{QuantRS2Error, QuantRS2Result},
14 gate::GateOp,
15 qubit::QubitId,
16};
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 pub fn new(circuit: Circuit<N>) -> Self {
1173 let config = DebuggerConfig::default();
1174 let analyzer = SciRS2CircuitAnalyzer::with_config(AnalyzerConfig::default());
1175
1176 Self {
1177 circuit,
1178 execution_state: Arc::new(RwLock::new(ExecutionState {
1179 current_gate_index: 0,
1180 current_state: Array1::<Complex64>::zeros(1 << N),
1181 status: ExecutionStatus::Ready,
1182 gates_executed: 0,
1183 current_depth: 0,
1184 memory_usage: MemoryUsage {
1185 current_usage: 0,
1186 peak_usage: 0,
1187 usage_history: VecDeque::new(),
1188 allocation_breakdown: HashMap::new(),
1189 },
1190 timing_info: TimingInfo {
1191 start_time: SystemTime::now(),
1192 current_time: SystemTime::now(),
1193 total_duration: Duration::new(0, 0),
1194 gate_times: Vec::new(),
1195 timing_stats: TimingStatistics {
1196 average_gate_time: Duration::new(0, 0),
1197 fastest_gate: Duration::new(0, 0),
1198 slowest_gate: Duration::new(0, 0),
1199 execution_variance: 0.0,
1200 },
1201 },
1202 })),
1203 config: config.clone(),
1204 analyzer,
1205 breakpoints: Arc::new(RwLock::new(BreakpointManager {
1206 gate_breakpoints: HashSet::new(),
1207 qubit_breakpoints: HashMap::new(),
1208 state_breakpoints: Vec::new(),
1209 conditional_breakpoints: Vec::new(),
1210 hit_counts: HashMap::new(),
1211 })),
1212 watch_manager: Arc::new(RwLock::new(WatchManager {
1213 watched_states: HashMap::new(),
1214 watched_gates: HashMap::new(),
1215 watched_metrics: HashMap::new(),
1216 watch_expressions: Vec::new(),
1217 })),
1218 execution_history: Arc::new(RwLock::new(ExecutionHistory {
1219 entries: VecDeque::new(),
1220 max_entries: config.max_history_entries,
1221 statistics: HistoryStatistics {
1222 total_gates: 0,
1223 average_execution_time: Duration::new(0, 0),
1224 total_execution_time: Duration::new(0, 0),
1225 memory_stats: MemoryStatistics {
1226 average_usage: 0.0,
1227 peak_usage: 0,
1228 efficiency_score: 1.0,
1229 leak_indicators: Vec::new(),
1230 },
1231 error_stats: ErrorStatistics {
1232 total_errors: 0,
1233 errors_by_type: HashMap::new(),
1234 errors_by_severity: HashMap::new(),
1235 error_rate: 0.0,
1236 error_trends: HashMap::new(),
1237 },
1238 },
1239 })),
1240 profiler: Arc::new(RwLock::new(PerformanceProfiler {
1241 config: ProfilerConfig {
1242 sample_frequency: Duration::from_millis(10),
1243 max_samples: 10000,
1244 tracked_metrics: HashSet::new(),
1245 analysis_depth: AnalysisDepth::Standard,
1246 },
1247 samples: VecDeque::new(),
1248 analysis_results: PerformanceAnalysis {
1249 trends: HashMap::new(),
1250 bottlenecks: Vec::new(),
1251 suggestions: Vec::new(),
1252 predictions: HashMap::new(),
1253 },
1254 statistics: ProfilingStatistics {
1255 total_samples: 0,
1256 profiling_duration: Duration::new(0, 0),
1257 average_sample_rate: 0.0,
1258 performance_metrics: HashMap::new(),
1259 },
1260 })),
1261 visualizer: Arc::new(RwLock::new(VisualizationEngine {
1262 config: VisualizationConfig {
1263 enable_realtime: true,
1264 enabled_types: {
1265 let mut types = HashSet::new();
1266 types.insert(VisualizationType::CircuitDiagram);
1267 types.insert(VisualizationType::StateVector);
1268 types.insert(VisualizationType::BlochSphere);
1269 types
1270 },
1271 update_frequency: Duration::from_millis(100),
1272 rendering_quality: RenderingQuality::Medium,
1273 export_options: ExportOptions {
1274 formats: {
1275 let mut formats = HashSet::new();
1276 formats.insert(ExportFormat::PNG);
1277 formats.insert(ExportFormat::JSON);
1278 formats
1279 },
1280 default_quality: RenderingQuality::High,
1281 export_directory: None,
1282 auto_export: false,
1283 },
1284 },
1285 current_visualizations: HashMap::new(),
1286 visualization_history: VecDeque::new(),
1287 rendering_stats: RenderingStatistics {
1288 total_renders: 0,
1289 average_render_time: Duration::new(0, 0),
1290 total_render_time: Duration::new(0, 0),
1291 success_rate: 1.0,
1292 memory_usage: 0,
1293 },
1294 })),
1295 error_detector: Arc::new(RwLock::new(ErrorDetector {
1296 config: ErrorDetectionConfig {
1297 enable_auto_detection: true,
1298 sensitivity: 0.8,
1299 error_types: {
1300 let mut types = HashSet::new();
1301 types.insert(ErrorType::StateVectorError);
1302 types.insert(ErrorType::GateExecutionError);
1303 types.insert(ErrorType::NumericalError);
1304 types
1305 },
1306 reporting_threshold: 0.1,
1307 max_errors: 1000,
1308 },
1309 detected_errors: Vec::new(),
1310 error_statistics: ErrorStatistics {
1311 total_errors: 0,
1312 errors_by_type: HashMap::new(),
1313 errors_by_severity: HashMap::new(),
1314 error_rate: 0.0,
1315 error_trends: HashMap::new(),
1316 },
1317 analysis_results: ErrorAnalysisResults {
1318 error_patterns: Vec::new(),
1319 root_causes: Vec::new(),
1320 correlations: Vec::new(),
1321 predictions: HashMap::new(),
1322 },
1323 })),
1324 }
1325 }
1326
1327 pub fn with_config(circuit: Circuit<N>, config: DebuggerConfig) -> Self {
1329 let mut debugger = Self::new(circuit);
1330 debugger.config = config;
1331 debugger
1332 }
1333
1334 pub fn start_session(&mut self) -> QuantRS2Result<()> {
1336 {
1337 let mut state = self.execution_state.write().unwrap();
1338 state.status = ExecutionStatus::Running;
1339 state.timing_info.start_time = SystemTime::now();
1340 }
1341
1342 self.initialize_scirs2_analysis()?;
1344
1345 if self.config.enable_profiling {
1347 self.start_profiling()?;
1348 }
1349
1350 if self.config.enable_auto_visualization {
1352 self.initialize_visualization()?;
1353 }
1354
1355 Ok(())
1356 }
1357
1358 pub fn step_next(&mut self) -> QuantRS2Result<StepResult> {
1360 let start_time = Instant::now();
1361
1362 if self.should_break()? {
1364 let mut state = self.execution_state.write().unwrap();
1365 state.status = ExecutionStatus::Paused;
1366 return Ok(StepResult::Breakpoint);
1367 }
1368
1369 let gate_index = {
1371 let state = self.execution_state.read().unwrap();
1372 state.current_gate_index
1373 };
1374
1375 if gate_index >= self.circuit.gates().len() {
1376 let mut state = self.execution_state.write().unwrap();
1377 state.status = ExecutionStatus::Completed;
1378 return Ok(StepResult::Completed);
1379 }
1380
1381 self.pre_execution_analysis(gate_index)?;
1383
1384 let execution_result = self.execute_gate_with_monitoring(gate_index)?;
1386
1387 self.post_execution_analysis(gate_index, &execution_result)?;
1389
1390 {
1392 let mut state = self.execution_state.write().unwrap();
1393 state.current_gate_index += 1;
1394 state.gates_executed += 1;
1395 state.current_depth = self.calculate_current_depth()?;
1396 state.timing_info.gate_times.push(start_time.elapsed());
1397 }
1398
1399 if self.config.enable_auto_visualization {
1401 self.update_visualizations()?;
1402 }
1403
1404 Ok(StepResult::Success)
1405 }
1406
1407 pub fn run(&mut self) -> QuantRS2Result<ExecutionSummary> {
1409 self.start_session()?;
1410
1411 let mut step_count = 0;
1412 loop {
1413 match self.step_next()? {
1414 StepResult::Success => {
1415 step_count += 1;
1416 }
1417 StepResult::Breakpoint => {
1418 return Ok(ExecutionSummary {
1419 status: ExecutionStatus::Paused,
1420 steps_executed: step_count,
1421 final_state: self.get_current_state()?,
1422 execution_time: self.get_execution_time()?,
1423 memory_usage: self.get_memory_usage()?,
1424 });
1425 }
1426 StepResult::Completed => {
1427 break;
1428 }
1429 StepResult::Error(error) => {
1430 return Err(error);
1431 }
1432 }
1433 }
1434
1435 self.finalize_execution()?;
1437
1438 Ok(ExecutionSummary {
1439 status: ExecutionStatus::Completed,
1440 steps_executed: step_count,
1441 final_state: self.get_current_state()?,
1442 execution_time: self.get_execution_time()?,
1443 memory_usage: self.get_memory_usage()?,
1444 })
1445 }
1446
1447 pub fn pause(&mut self) -> QuantRS2Result<()> {
1449 let mut state = self.execution_state.write().unwrap();
1450 state.status = ExecutionStatus::Paused;
1451 Ok(())
1452 }
1453
1454 pub fn resume(&mut self) -> QuantRS2Result<()> {
1456 let mut state = self.execution_state.write().unwrap();
1457 state.status = ExecutionStatus::Running;
1458 Ok(())
1459 }
1460
1461 pub fn stop(&mut self) -> QuantRS2Result<()> {
1463 let mut state = self.execution_state.write().unwrap();
1464 state.status = ExecutionStatus::Stopped;
1465 Ok(())
1466 }
1467
1468 pub fn add_gate_breakpoint(&mut self, gate_index: usize) -> QuantRS2Result<()> {
1470 let mut breakpoints = self.breakpoints.write().unwrap();
1471 breakpoints.gate_breakpoints.insert(gate_index);
1472 Ok(())
1473 }
1474
1475 pub fn add_qubit_breakpoint(
1477 &mut self,
1478 qubit: QubitId,
1479 condition: BreakpointCondition,
1480 ) -> QuantRS2Result<()> {
1481 let mut breakpoints = self.breakpoints.write().unwrap();
1482 breakpoints.qubit_breakpoints.insert(qubit, condition);
1483 Ok(())
1484 }
1485
1486 pub fn add_state_breakpoint(
1488 &mut self,
1489 id: String,
1490 pattern: StatePattern,
1491 tolerance: f64,
1492 ) -> QuantRS2Result<()> {
1493 let mut breakpoints = self.breakpoints.write().unwrap();
1494 breakpoints.state_breakpoints.push(StateBreakpoint {
1495 id,
1496 target_state: pattern,
1497 tolerance,
1498 enabled: true,
1499 });
1500 Ok(())
1501 }
1502
1503 pub fn get_current_state(&self) -> QuantRS2Result<Array1<Complex64>> {
1505 let state = self.execution_state.read().unwrap();
1506 Ok(state.current_state.clone())
1507 }
1508
1509 pub fn get_execution_status(&self) -> ExecutionStatus {
1511 let state = self.execution_state.read().unwrap();
1512 state.status.clone()
1513 }
1514
1515 pub fn get_performance_analysis(&self) -> QuantRS2Result<PerformanceAnalysis> {
1517 let profiler = self.profiler.read().unwrap();
1518 Ok(profiler.analysis_results.clone())
1519 }
1520
1521 pub fn get_error_analysis(&self) -> QuantRS2Result<ErrorAnalysisResults> {
1523 let detector = self.error_detector.read().unwrap();
1524 Ok(detector.analysis_results.clone())
1525 }
1526
1527 pub fn export_session(&self, format: ExportFormat, path: &str) -> QuantRS2Result<()> {
1529 match format {
1530 ExportFormat::JSON => self.export_json(path),
1531 ExportFormat::HTML => self.export_html(path),
1532 ExportFormat::CSV => self.export_csv(path),
1533 _ => Err(QuantRS2Error::InvalidOperation(
1534 "Unsupported export format".to_string(),
1535 )),
1536 }
1537 }
1538
1539 fn initialize_scirs2_analysis(&mut self) -> QuantRS2Result<()> {
1542 let _graph = self.analyzer.circuit_to_scirs2_graph(&self.circuit)?;
1544 Ok(())
1545 }
1546
1547 fn start_profiling(&mut self) -> QuantRS2Result<()> {
1548 Ok(())
1550 }
1551
1552 fn initialize_visualization(&mut self) -> QuantRS2Result<()> {
1553 Ok(())
1555 }
1556
1557 fn should_break(&self) -> QuantRS2Result<bool> {
1558 let breakpoints = self.breakpoints.read().unwrap();
1559 let state = self.execution_state.read().unwrap();
1560
1561 if breakpoints
1563 .gate_breakpoints
1564 .contains(&state.current_gate_index)
1565 {
1566 return Ok(true);
1567 }
1568
1569 Ok(false)
1571 }
1572
1573 fn pre_execution_analysis(&mut self, _gate_index: usize) -> QuantRS2Result<()> {
1574 Ok(())
1576 }
1577
1578 fn execute_gate_with_monitoring(
1579 &mut self,
1580 _gate_index: usize,
1581 ) -> QuantRS2Result<GateExecutionResult> {
1582 Ok(GateExecutionResult {
1584 success: true,
1585 execution_time: Duration::from_millis(1),
1586 memory_change: 0,
1587 errors: Vec::new(),
1588 })
1589 }
1590
1591 fn post_execution_analysis(
1592 &mut self,
1593 _gate_index: usize,
1594 _result: &GateExecutionResult,
1595 ) -> QuantRS2Result<()> {
1596 Ok(())
1598 }
1599
1600 fn calculate_current_depth(&self) -> QuantRS2Result<usize> {
1601 Ok(0)
1603 }
1604
1605 fn update_visualizations(&mut self) -> QuantRS2Result<()> {
1606 Ok(())
1608 }
1609
1610 fn finalize_execution(&mut self) -> QuantRS2Result<()> {
1611 let mut state = self.execution_state.write().unwrap();
1613 state.status = ExecutionStatus::Completed;
1614 state.timing_info.current_time = SystemTime::now();
1615 Ok(())
1616 }
1617
1618 fn get_execution_time(&self) -> QuantRS2Result<Duration> {
1619 let state = self.execution_state.read().unwrap();
1620 Ok(state.timing_info.total_duration)
1621 }
1622
1623 fn get_memory_usage(&self) -> QuantRS2Result<MemoryUsage> {
1624 let state = self.execution_state.read().unwrap();
1625 Ok(state.memory_usage.clone())
1626 }
1627
1628 fn export_json(&self, _path: &str) -> QuantRS2Result<()> {
1629 Ok(())
1631 }
1632
1633 fn export_html(&self, _path: &str) -> QuantRS2Result<()> {
1634 Ok(())
1636 }
1637
1638 fn export_csv(&self, _path: &str) -> QuantRS2Result<()> {
1639 Ok(())
1641 }
1642}
1643
1644#[derive(Debug, Clone)]
1646pub enum StepResult {
1647 Success,
1649 Breakpoint,
1651 Completed,
1653 Error(QuantRS2Error),
1655}
1656
1657#[derive(Debug, Clone)]
1659pub struct GateExecutionResult {
1660 pub success: bool,
1662 pub execution_time: Duration,
1664 pub memory_change: i64,
1666 pub errors: Vec<DebugError>,
1668}
1669
1670#[derive(Debug, Clone)]
1672pub struct ExecutionSummary {
1673 pub status: ExecutionStatus,
1675 pub steps_executed: usize,
1677 pub final_state: Array1<Complex64>,
1679 pub execution_time: Duration,
1681 pub memory_usage: MemoryUsage,
1683}
1684
1685#[cfg(test)]
1686mod tests {
1687 use super::*;
1688 use quantrs2_core::gate::multi::CNOT;
1689 use quantrs2_core::gate::single::Hadamard;
1690
1691 #[test]
1692 fn test_debugger_creation() {
1693 let circuit = Circuit::<2>::new();
1694 let debugger = QuantumDebugger::new(circuit);
1695
1696 assert_eq!(debugger.get_execution_status(), ExecutionStatus::Ready);
1697 }
1698
1699 #[test]
1700 fn test_breakpoint_management() {
1701 let circuit = Circuit::<2>::new();
1702 let mut debugger = QuantumDebugger::new(circuit);
1703
1704 debugger.add_gate_breakpoint(0).unwrap();
1705
1706 let breakpoints = debugger.breakpoints.read().unwrap();
1707 assert!(breakpoints.gate_breakpoints.contains(&0));
1708 }
1709
1710 #[test]
1711 fn test_step_execution() {
1712 let mut circuit = Circuit::<1>::new();
1713 circuit.add_gate(Hadamard { target: QubitId(0) }).unwrap();
1714
1715 let mut debugger = QuantumDebugger::new(circuit);
1716 debugger.start_session().unwrap();
1717
1718 let result = debugger.step_next().unwrap();
1719 match result {
1720 StepResult::Success => (),
1721 _ => panic!("Expected successful step execution"),
1722 }
1723 }
1724
1725 #[test]
1726 fn test_visualization_configuration() {
1727 let circuit = Circuit::<2>::new();
1728 let mut config = DebuggerConfig::default();
1729 config.enable_auto_visualization = true;
1730
1731 let debugger = QuantumDebugger::with_config(circuit, config);
1732
1733 let visualizer = debugger.visualizer.read().unwrap();
1734 assert!(visualizer.config.enable_realtime);
1735 }
1736
1737 #[test]
1738 fn test_performance_profiling() {
1739 let mut circuit = Circuit::<2>::new();
1740 circuit.add_gate(Hadamard { target: QubitId(0) }).unwrap();
1741 circuit
1742 .add_gate(CNOT {
1743 control: QubitId(0),
1744 target: QubitId(1),
1745 })
1746 .unwrap();
1747
1748 let mut config = DebuggerConfig::default();
1749 config.enable_profiling = true;
1750
1751 let mut debugger = QuantumDebugger::with_config(circuit, config);
1752 let _summary = debugger.run().unwrap();
1753
1754 let analysis = debugger.get_performance_analysis().unwrap();
1755 assert!(!analysis.suggestions.is_empty() || analysis.suggestions.is_empty());
1756 }
1758
1759 #[test]
1760 fn test_error_detection() {
1761 let circuit = Circuit::<1>::new();
1762 let mut config = DebuggerConfig::default();
1763 config.enable_error_detection = true;
1764
1765 let debugger = QuantumDebugger::with_config(circuit, config);
1766
1767 let detector = debugger.error_detector.read().unwrap();
1768 assert!(detector.config.enable_auto_detection);
1769 }
1770}