quantrs2 0.1.3

Comprehensive Rust quantum computing framework - unified entry point for quantum simulation, algorithm development, and hardware interaction
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
#![allow(clippy::pedantic, clippy::assertions_on_constants)]
//! End-to-End Workflow Integration Tests
//!
//! This test suite validates complete quantum computing workflows using the quantrs2 facade,
//! demonstrating real-world usage patterns and ensuring all components work together seamlessly.

use quantrs2::config::Config;
use quantrs2::diagnostics;
use quantrs2::error::QuantRS2Result;
use quantrs2::utils;
use quantrs2::version;

// Test module organization
mod workflow_validation {
    use super::*;

    /// Test that the system is ready for quantum computation
    #[test]
    fn test_system_readiness_workflow() {
        // Step 1: Check version compatibility
        let version_check = version::check_compatibility();
        assert!(
            version_check.is_ok(),
            "Version compatibility check failed: {version_check:?}"
        );

        // Step 2: Run diagnostics
        let report = diagnostics::run_diagnostics();
        assert!(
            report.errors().is_empty(),
            "System has critical errors: {:?}",
            report.errors()
        );

        // Step 3: Verify essential capabilities
        let memory_mb = report.capabilities.total_memory_bytes / (1024 * 1024);
        let has_enough_memory = memory_mb >= 1024; // At least 1GB
        let has_cpu_cores = report.capabilities.cpu_cores >= 1;

        assert!(
            has_enough_memory,
            "Insufficient memory for quantum computation"
        );
        assert!(has_cpu_cores, "No CPU cores detected");

        println!("✅ System readiness workflow: PASSED");
        println!("   - Memory: {memory_mb} MB");
        println!("   - CPU cores: {}", report.capabilities.cpu_cores);
    }

    /// Test configuration workflow
    #[test]
    fn test_configuration_workflow() {
        // Step 1: Create configuration
        let cfg = Config::global();

        // Step 2: Apply sensible defaults
        let default_threads = 4;
        let default_memory_gb = 8;

        cfg.set_num_threads(default_threads);
        cfg.set_memory_limit_gb(default_memory_gb);

        // Step 3: Verify configuration was applied
        let config_snapshot = cfg.snapshot();
        assert_eq!(
            config_snapshot.num_threads,
            Some(default_threads),
            "Thread count not set correctly"
        );
        assert_eq!(
            config_snapshot.memory_limit_bytes,
            Some(default_memory_gb * 1024 * 1024 * 1024),
            "Memory limit not set correctly"
        );

        // Step 4: Validate configuration makes sense
        let max_qubits = utils::max_qubits_for_memory(default_memory_gb * 1024 * 1024 * 1024);
        assert!(
            max_qubits >= 10,
            "Configuration should support at least 10 qubits"
        );

        println!("✅ Configuration workflow: PASSED");
        println!("   - Threads: {default_threads}");
        println!("   - Memory limit: {default_memory_gb} GB");
        println!("   - Max qubits: {max_qubits}");
    }
}

mod memory_planning_workflow {
    use super::*;

    /// Test memory estimation workflow for circuit planning
    #[test]
    fn test_memory_estimation_workflow() {
        // Scenario: Planning a quantum simulation project

        // Step 1: Determine available resources
        let report = diagnostics::run_diagnostics();
        let available_memory_bytes = report.capabilities.total_memory_bytes;
        let available_memory_mb = available_memory_bytes / (1024 * 1024);

        // Reserve some memory for OS and other processes (20%)
        let usable_memory = ((available_memory_bytes as f64) * 0.8) as usize;

        // Step 2: Calculate maximum qubits
        let max_qubits = utils::max_qubits_for_memory(usable_memory);

        // Step 3: Validate against realistic bounds
        assert!(
            max_qubits >= 5,
            "Should be able to simulate at least 5 qubits"
        );
        assert!(
            max_qubits <= 40,
            "Max qubits seems unrealistic: {max_qubits}"
        );

        // Step 4: Plan for different qubit counts
        let test_qubits = vec![10, 15, 20, 25];
        let mut feasible_simulations = Vec::new();

        for &qubits in &test_qubits {
            let required = utils::estimate_statevector_memory(qubits);
            if required <= usable_memory {
                feasible_simulations.push(qubits);
            }
        }

        assert!(
            !feasible_simulations.is_empty(),
            "Should be able to run at least one simulation"
        );

        println!("✅ Memory estimation workflow: PASSED");
        println!("   - Available memory: {available_memory_mb} MB");
        println!("   - Max qubits: {max_qubits}");
        println!("   - Feasible simulations: {feasible_simulations:?} qubits");
    }

    /// Test capacity planning for large-scale simulation
    #[test]
    fn test_capacity_planning_workflow() {
        // Step 1: Define simulation requirements
        let target_qubits = 20;
        let target_shots = 1000;

        // Step 2: Estimate resource requirements
        let memory_needed = utils::estimate_statevector_memory(target_qubits);
        let memory_needed_mb = memory_needed / (1024 * 1024);

        // Step 3: Check if feasible on current hardware
        let report = diagnostics::run_diagnostics();
        let available_mb = (report.capabilities.total_memory_bytes / (1024 * 1024)) as usize;

        let is_feasible = memory_needed_mb < (((available_mb as f64) * 0.8) as usize);

        if is_feasible {
            println!("✅ Capacity planning: FEASIBLE");
            println!("   - Target: {target_qubits} qubits, {target_shots} shots");
            println!("   - Required: {memory_needed_mb} MB");
            println!("   - Available: {available_mb} MB");
        } else {
            println!("⚠️  Capacity planning: NOT FEASIBLE");
            println!("   - Target: {target_qubits} qubits, {target_shots} shots");
            println!("   - Required: {memory_needed_mb} MB");
            println!("   - Available: {available_mb} MB");
            println!("   - Recommendation: Use tensor network or reduce qubit count");
        }

        // Step 4: Always passes - this is informational
        assert!(true, "Capacity planning workflow completed");
    }
}

mod error_handling_workflow {
    use super::*;
    use quantrs2::error::{ErrorCategory, QuantRS2ErrorExt};

    /// Test error categorization and handling workflow
    #[test]
    fn test_error_categorization_workflow() {
        // Create various error types
        let errors = vec![
            quantrs2::error::QuantRS2Error::InvalidQubitId(999),
            quantrs2::error::QuantRS2Error::InvalidInput("Test error for workflow".to_string()),
        ];

        for error in errors {
            // Step 1: Categorize error
            let category = error.category();

            // Step 2: Determine if recoverable
            let is_recoverable = error.is_recoverable();

            // Step 3: Get user-friendly message
            let user_msg = error.user_message();

            // Validate error handling path
            match category {
                ErrorCategory::Core => {
                    assert!(
                        !user_msg.is_empty(),
                        "Core errors should have user messages"
                    );
                }
                ErrorCategory::Circuit => {
                    assert!(
                        !user_msg.is_empty(),
                        "Circuit errors should have user messages"
                    );
                }
                _ => {}
            }

            println!("✅ Error handled: {category:?}");
            println!("   - Recoverable: {is_recoverable}");
            println!("   - Message: {user_msg}");
        }
    }

    /// Test error context accumulation workflow
    #[test]
    fn test_error_context_workflow() {
        use quantrs2::error::with_context;

        // Simulate nested operation failures
        let base_error = quantrs2::error::QuantRS2Error::InvalidQubitId(10);

        // Add context as error propagates
        let error_with_context = with_context(base_error, "in quantum algorithm layer 3");
        let error_with_full_context =
            with_context(error_with_context, "while executing VQE optimization");

        // Verify error handling works with context
        // The actual context format may vary by error type implementation
        let error_display = format!("{error_with_full_context}");
        assert!(
            !error_display.is_empty(),
            "Error should have a display representation"
        );

        println!("✅ Error context workflow: PASSED");
        println!("   - Error with context: {error_with_full_context}");
    }
}

mod version_compatibility_workflow {
    use super::*;

    /// Test version information retrieval workflow
    #[test]
    fn test_version_info_workflow() {
        // Step 1: Get version information
        let version_info = version::VersionInfo::current();

        // Step 2: Validate version strings
        let quantrs2_version = &version_info.quantrs2;
        let scirs2_version = &version_info.scirs2;

        assert!(
            !quantrs2_version.is_empty(),
            "QuantRS2 version should not be empty"
        );
        assert!(
            !scirs2_version.is_empty(),
            "SciRS2 version should not be empty"
        );

        // Step 3: Check version format (semantic versioning)
        assert!(
            quantrs2_version.contains('.'),
            "Version should follow semantic versioning"
        );

        // Step 4: Get detailed version string
        let detailed = version_info.detailed_version_string();
        assert!(
            detailed.contains("QuantRS2"),
            "Detailed version should mention QuantRS2"
        );

        println!("✅ Version info workflow: PASSED");
        println!("   - QuantRS2: {quantrs2_version}");
        println!("   - SciRS2: {scirs2_version}");
    }

    /// Test compatibility validation workflow
    #[test]
    fn test_compatibility_validation_workflow() {
        // Step 1: Check compatibility
        let compat_result = version::check_compatibility();

        // Step 2: Handle result
        match compat_result {
            Ok(()) => {
                println!("✅ Compatibility validation: PASSED");
                println!("   - All dependencies compatible");
            }
            Err(issues) => {
                println!("⚠️  Compatibility validation: ISSUES FOUND");
                for issue in issues {
                    println!("   - {issue}");
                }
                // Don't fail the test - compatibility issues may be warnings
            }
        }

        // Test always passes - compatibility check is informational
        assert!(true, "Compatibility check workflow completed");
    }
}

mod utility_functions_workflow {
    use super::*;

    /// Test quantum math utilities workflow
    #[test]
    fn test_quantum_math_workflow() {
        // Step 1: Probability normalization
        let mut probabilities = vec![0.3, 0.5, 0.1];
        let was_normalized = utils::normalize_probabilities(&mut probabilities);
        assert!(was_normalized, "Probabilities should be normalizable");

        let sum: f64 = probabilities.iter().sum();
        assert!(
            (sum - 1.0).abs() < 1e-10,
            "Normalized probabilities should sum to 1"
        );

        // Step 2: Probability validation
        for &p in &probabilities {
            assert!(
                utils::is_valid_probability(p),
                "Probability should be valid"
            );
            assert!(
                utils::clamp_probability(p) == p,
                "Valid probability should not be clamped"
            );
        }

        // Step 3: Information theory calculations
        let entropy = utils::entropy(&probabilities);
        assert!(entropy >= 0.0, "Entropy should be non-negative");
        assert!(entropy <= 2.0, "Entropy should be bounded");

        println!("✅ Quantum math workflow: PASSED");
        println!("   - Original: {:?}", vec![0.3, 0.5, 0.1]);
        println!("   - Normalized: {probabilities:?}");
        println!("   - Entropy: {entropy:.6}");
    }

    /// Test Hilbert space utilities workflow
    #[test]
    fn test_hilbert_space_workflow() {
        // Step 1: Calculate Hilbert space dimensions
        let test_cases = vec![1, 2, 3, 5, 10];

        for qubits in test_cases {
            let dim = utils::hilbert_dim(qubits);
            let expected = 2_usize.pow(qubits);

            assert_eq!(
                dim, expected,
                "Hilbert dimension incorrect for {qubits} qubits"
            );

            // Step 2: Reverse calculation
            let recovered_qubits = utils::num_qubits_from_dim(dim);
            assert_eq!(
                recovered_qubits,
                Some(qubits),
                "Could not recover qubit count from dimension"
            );
        }

        println!("✅ Hilbert space workflow: PASSED");
        println!("   - Tested qubit counts: 1-10");
    }

    /// Test formatting utilities workflow
    #[test]
    fn test_formatting_workflow() {
        use std::time::Duration;

        // Step 1: Memory formatting
        let memory_values = vec![
            (1024, "1.00 KB"),
            (1024 * 1024, "1.00 MB"),
            (1024 * 1024 * 1024, "1.00 GB"),
        ];

        for (bytes, expected_prefix) in memory_values {
            let formatted = utils::format_memory(bytes);
            assert!(
                formatted.contains(expected_prefix.split_whitespace().next().unwrap()),
                "Memory formatting incorrect: expected {expected_prefix}, got {formatted}"
            );
        }

        // Step 2: Duration formatting
        let duration_tests = vec![
            Duration::from_millis(500),
            Duration::from_secs(2),
            Duration::from_secs(65),
        ];

        for duration in duration_tests {
            let formatted = utils::format_duration(duration);
            assert!(
                !formatted.is_empty(),
                "Duration formatting should not be empty"
            );
        }

        println!("✅ Formatting workflow: PASSED");
    }
}

mod complete_application_workflow {
    use super::*;

    /// Test a complete application initialization workflow
    #[test]
    fn test_complete_initialization_workflow() {
        println!("\n========================================");
        println!("Complete Application Workflow Test");
        println!("========================================\n");

        // Step 1: Display banner
        println!("Starting Quantum Computing Application...\n");

        // Step 2: Check versions
        println!("📦 Checking versions...");
        let version_info = version::VersionInfo::current();
        println!("   QuantRS2: {}", version_info.quantrs2);
        println!("   SciRS2:   {}", version_info.scirs2);

        let compat_check = version::check_compatibility();
        match compat_check {
            Ok(()) => println!("   ✅ Compatibility: OK"),
            Err(issues) => {
                println!("   ⚠️  Compatibility issues:");
                for issue in issues {
                    println!("      - {issue}");
                }
            }
        }

        // Step 3: Run diagnostics
        println!("\n🔍 Running system diagnostics...");
        let report = diagnostics::run_diagnostics();

        println!("   CPU cores:    {}", report.capabilities.cpu_cores);
        println!(
            "   Memory:       {} MB",
            report.capabilities.total_memory_bytes / (1024 * 1024)
        );
        println!(
            "   GPU:          {}",
            if report.capabilities.has_gpu {
                ""
            } else {
                ""
            }
        );
        println!(
            "   SIMD (AVX2):  {}",
            if report.capabilities.has_avx2 {
                ""
            } else {
                ""
            }
        );

        if !report.errors().is_empty() {
            println!("   ⚠️  Errors found:");
            for error in report.errors() {
                println!("      - {error}");
            }
        }

        // Step 4: Configure system
        println!("\n⚙️  Configuring system...");
        let cfg = Config::global();
        cfg.set_num_threads(4);
        cfg.set_memory_limit_gb(8);

        // Get config snapshot to read values
        let config_data = cfg.snapshot();
        println!("   Threads:      {}", config_data.num_threads.unwrap_or(4));
        let mem_limit_gb = config_data
            .memory_limit_bytes
            .map_or(8, |b| b / (1024 * 1024 * 1024));
        println!("   Memory limit: {mem_limit_gb} GB");

        // Step 5: Plan simulation capacity
        println!("\n📊 Planning simulation capacity...");
        let max_qubits = utils::max_qubits_for_memory(8 * 1024 * 1024 * 1024);
        println!("   Max qubits:   {max_qubits}");

        let test_qubit_counts = vec![5, 10, 15, 20];
        for &qubits in &test_qubit_counts {
            let memory = utils::estimate_statevector_memory(qubits);
            let memory_mb = memory / (1024 * 1024);
            let feasible = memory_mb < 8 * 1024;
            println!(
                "   {} qubits:     {} MB {}",
                qubits,
                memory_mb,
                if feasible { "" } else { "" }
            );
        }

        // Step 6: Ready to run
        println!("\n✅ Application initialization complete!");
        println!("   Ready for quantum computation.\n");

        println!("========================================\n");

        // Verify critical conditions
        assert!(
            report.capabilities.cpu_cores >= 1,
            "Need at least 1 CPU core"
        );
        assert!(max_qubits >= 5, "Should support at least 5 qubits");
    }

    /// Test graceful degradation workflow
    #[test]
    fn test_graceful_degradation_workflow() {
        println!("\n========================================");
        println!("Graceful Degradation Workflow Test");
        println!("========================================\n");

        let report = diagnostics::run_diagnostics();

        // Check for GPU
        if report.capabilities.has_gpu {
            println!("✅ GPU available: Using GPU acceleration");
        } else {
            println!("⚠️  No GPU: Falling back to CPU simulation");
        }

        // Check for SIMD
        if report.capabilities.has_avx2 {
            println!("✅ AVX2 available: Using vectorized operations");
        } else {
            println!("⚠️  No SIMD: Using scalar operations (SSE2 detection not exposed)");
        }

        // Check memory
        let available_mb = report.capabilities.total_memory_bytes / (1024 * 1024);
        if available_mb >= 16 * 1024 {
            println!("✅ High memory: Can simulate large circuits (25+ qubits)");
        } else if available_mb >= 8 * 1024 {
            println!("⚠️  Medium memory: Limited to medium circuits (20-25 qubits)");
        } else {
            println!("⚠️  Low memory: Limited to small circuits (<20 qubits)");
        }

        println!("\n✅ Graceful degradation strategy determined");
        println!("========================================\n");

        // Always passes - this is about strategy
        assert!(true, "Degradation workflow completed");
    }
}

// Summary test to verify all workflows
#[test]
fn test_all_workflows_integration() {
    println!("\n╔═══════════════════════════════════════════════════════════╗");
    println!("║  End-to-End Workflow Integration Test Suite              ║");
    println!("╚═══════════════════════════════════════════════════════════╝\n");

    // This test verifies that all workflow tests can be discovered and run
    let workflow_count = 12; // Total number of workflow tests above

    println!("{workflow_count} end-to-end workflow tests defined");
    println!("✅ All workflows use quantrs2 facade consistently");
    println!("✅ Tests cover: initialization, configuration, error handling, capacity planning");
    println!("\nRun individual workflow tests with:");
    println!("  cargo test --test integration_end_to_end_workflows -- --nocapture\n");
}