quantrs2_sim/
memory_verification_simple.rs

1//! Simplified memory efficiency verification module
2//!
3//! This module provides practical testing and verification of memory optimizations
4//! implemented throughout the quantum simulation framework.
5
6use crate::statevector::StateVectorSimulator;
7use scirs2_core::Complex64;
8use std::time::Instant;
9
10/// Memory verification results
11#[derive(Debug, Clone)]
12pub struct VerificationResults {
13    pub buffer_pool_test_passed: bool,
14    pub simd_test_passed: bool,
15    pub parallel_test_passed: bool,
16    pub overall_performance_ratio: f64,
17}
18
19/// Simplified memory efficiency verifier
20pub struct MemoryVerifier {
21    test_qubit_counts: Vec<usize>,
22    test_iterations: usize,
23}
24
25impl MemoryVerifier {
26    /// Create a new memory verifier
27    #[must_use]
28    pub fn new() -> Self {
29        Self {
30            test_qubit_counts: vec![4, 6, 8, 10],
31            test_iterations: 5,
32        }
33    }
34
35    /// Run simplified memory verification
36    #[must_use]
37    pub fn verify_optimizations(&self) -> VerificationResults {
38        println!("🔍 Starting memory efficiency verification...");
39
40        // Test 1: Buffer pool functionality
41        let buffer_pool_test_passed = self.test_buffer_pool_functionality();
42        println!(
43            "✅ Buffer pool test: {}",
44            if buffer_pool_test_passed {
45                "PASSED"
46            } else {
47                "FAILED"
48            }
49        );
50
51        // Test 2: SIMD functionality
52        let simd_test_passed = self.test_simd_functionality();
53        println!(
54            "✅ SIMD test: {}",
55            if simd_test_passed { "PASSED" } else { "FAILED" }
56        );
57
58        // Test 3: Parallel processing functionality
59        let parallel_test_passed = self.test_parallel_functionality();
60        println!(
61            "✅ Parallel processing test: {}",
62            if parallel_test_passed {
63                "PASSED"
64            } else {
65                "FAILED"
66            }
67        );
68
69        // Test 4: Overall performance comparison
70        let overall_performance_ratio = self.test_overall_performance();
71        println!("✅ Performance improvement: {overall_performance_ratio:.2}x");
72
73        VerificationResults {
74            buffer_pool_test_passed,
75            simd_test_passed,
76            parallel_test_passed,
77            overall_performance_ratio,
78        }
79    }
80
81    /// Test buffer pool functionality
82    fn test_buffer_pool_functionality(&self) -> bool {
83        // Test buffer pool allocation and reuse
84        for &num_qubits in &self.test_qubit_counts {
85            if num_qubits <= 8 {
86                // Keep tests reasonable
87                let sim = StateVectorSimulator::with_buffer_pool(true, 4, 1 << num_qubits);
88
89                // Test buffer allocation and return
90                for _ in 0..self.test_iterations {
91                    let mut pool = sim
92                        .get_buffer_pool()
93                        .lock()
94                        .unwrap_or_else(|e| e.into_inner());
95                    let buffer1 = pool.get_buffer(1 << num_qubits);
96                    let buffer2 = pool.get_buffer(1 << num_qubits);
97
98                    // Verify buffers are properly allocated
99                    if buffer1.len() != (1 << num_qubits) || buffer2.len() != (1 << num_qubits) {
100                        return false;
101                    }
102
103                    pool.return_buffer(buffer1);
104                    pool.return_buffer(buffer2);
105                }
106            }
107        }
108        true
109    }
110
111    /// Test SIMD functionality
112    fn test_simd_functionality(&self) -> bool {
113        let test_size = 128;
114
115        // Test SIMD gate operations
116        for _ in 0..self.test_iterations {
117            let in_amps0: Vec<Complex64> = vec![Complex64::new(1.0, 0.0); test_size];
118            let in_amps1: Vec<Complex64> = vec![Complex64::new(0.0, 0.0); test_size];
119            let mut out_amps0: Vec<Complex64> = vec![Complex64::new(0.0, 0.0); test_size];
120            let mut out_amps1: Vec<Complex64> = vec![Complex64::new(0.0, 0.0); test_size];
121
122            // Test SIMD X gate
123            crate::optimized_simd::apply_x_gate_simd(
124                &in_amps0,
125                &in_amps1,
126                &mut out_amps0,
127                &mut out_amps1,
128            );
129
130            // Verify X gate worked correctly (should swap amplitudes)
131            for i in 0..test_size {
132                if (out_amps0[i] - in_amps1[i]).norm() > 1e-10
133                    || (out_amps1[i] - in_amps0[i]).norm() > 1e-10
134                {
135                    return false;
136                }
137            }
138
139            // Test SIMD Hadamard gate
140            let mut h_out0: Vec<Complex64> = vec![Complex64::new(0.0, 0.0); test_size];
141            let mut h_out1: Vec<Complex64> = vec![Complex64::new(0.0, 0.0); test_size];
142
143            crate::optimized_simd::apply_h_gate_simd(
144                &in_amps0,
145                &in_amps1,
146                &mut h_out0,
147                &mut h_out1,
148            );
149
150            // Verify Hadamard gate produces expected output
151            let expected_coeff = 1.0 / 2.0_f64.sqrt();
152            for i in 0..test_size {
153                let expected_0 = expected_coeff * (in_amps0[i] + in_amps1[i]);
154                let expected_1 = expected_coeff * (in_amps0[i] - in_amps1[i]);
155
156                if (h_out0[i] - expected_0).norm() > 1e-10
157                    || (h_out1[i] - expected_1).norm() > 1e-10
158                {
159                    return false;
160                }
161            }
162        }
163
164        true
165    }
166
167    /// Test parallel processing functionality
168    fn test_parallel_functionality(&self) -> bool {
169        use scirs2_core::parallel_ops::{
170            IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator,
171        };
172
173        let test_size = 1000;
174
175        // Test parallel iteration and computation
176        for _ in 0..self.test_iterations {
177            let data: Vec<Complex64> = (0..test_size)
178                .map(|i| Complex64::new(f64::from(i), f64::from(i * 2)))
179                .collect();
180
181            // Test parallel map
182            let sequential_result: Vec<f64> =
183                data.iter().map(scirs2_core::Complex::norm_sqr).collect();
184            let parallel_result: Vec<f64> = data
185                .par_iter()
186                .map(scirs2_core::Complex::norm_sqr)
187                .collect();
188
189            // Verify results are identical
190            if sequential_result.len() != parallel_result.len() {
191                return false;
192            }
193
194            for i in 0..sequential_result.len() {
195                if (sequential_result[i] - parallel_result[i]).abs() > 1e-10 {
196                    return false;
197                }
198            }
199        }
200
201        true
202    }
203
204    /// Test overall performance improvement
205    fn test_overall_performance(&self) -> f64 {
206        let test_qubit_count = 8; // Larger test for meaningful comparison
207        let iterations = 100;
208
209        // Test with repeated allocations (inefficient)
210        let start = Instant::now();
211        for _ in 0..iterations {
212            // Repeatedly allocate without pooling
213            for _ in 0..10 {
214                let dim = 1 << test_qubit_count;
215                let _state1: Vec<Complex64> = vec![Complex64::new(0.0, 0.0); dim];
216                let _state2: Vec<Complex64> = vec![Complex64::new(1.0, 0.0); dim];
217                // Let them drop immediately (inefficient)
218            }
219        }
220        let inefficient_time = start.elapsed();
221
222        // Test with buffer pool (efficient)
223        let start = Instant::now();
224        let sim = StateVectorSimulator::high_performance();
225        for _ in 0..iterations {
226            // Reuse buffers through pooling
227            for _ in 0..10 {
228                let mut pool = sim
229                    .get_buffer_pool()
230                    .lock()
231                    .unwrap_or_else(|e| e.into_inner());
232                let buffer1 = pool.get_buffer(1 << test_qubit_count);
233                let buffer2 = pool.get_buffer(1 << test_qubit_count);
234
235                // Do some work with buffers
236                drop(buffer1);
237                drop(buffer2);
238                // Return happens automatically through drop, but in real usage
239                // we'd explicitly return them
240            }
241        }
242        let efficient_time = start.elapsed();
243
244        // Calculate performance ratio
245        if efficient_time.as_nanos() > 0 {
246            inefficient_time.as_nanos() as f64 / efficient_time.as_nanos() as f64
247        } else {
248            1.0
249        }
250    }
251
252    /// Generate verification report
253    #[must_use]
254    pub fn generate_report(&self, results: &VerificationResults) -> String {
255        format!(
256            r"
257📊 Memory Efficiency Verification Report
258==========================================
259
260🔧 Buffer Pool Test
261  • Status: {}
262  • Result: Buffer pool allocations and returns work correctly
263
264⚡ SIMD Operations Test
265  • Status: {}
266  • Result: SIMD gate operations produce correct results
267
268🔄 Parallel Processing Test
269  • Status: {}
270  • Result: Parallel operations produce identical results to sequential
271
272📈 Overall Performance
273  • Performance Ratio: {:.2}x
274  • Status: {}
275
276✅ Summary
277{}
278",
279            if results.buffer_pool_test_passed {
280                "✅ PASSED"
281            } else {
282                "❌ FAILED"
283            },
284            if results.simd_test_passed {
285                "✅ PASSED"
286            } else {
287                "❌ FAILED"
288            },
289            if results.parallel_test_passed {
290                "✅ PASSED"
291            } else {
292                "❌ FAILED"
293            },
294            results.overall_performance_ratio,
295            if results.overall_performance_ratio > 1.0 {
296                "✅ IMPROVED"
297            } else {
298                "⚠️  NO IMPROVEMENT"
299            },
300            if results.buffer_pool_test_passed
301                && results.simd_test_passed
302                && results.parallel_test_passed
303            {
304                "All memory optimizations are functioning correctly! The quantum simulation framework\nis ready for production use with verified memory efficiency improvements."
305            } else {
306                "Some optimization tests failed. Please review the implementation to ensure\nall memory optimizations are working correctly."
307            }
308        )
309    }
310}
311
312impl Default for MemoryVerifier {
313    fn default() -> Self {
314        Self::new()
315    }
316}
317
318/// Public interface for running memory verification
319#[must_use]
320pub fn run_memory_verification() -> VerificationResults {
321    let verifier = MemoryVerifier::new();
322    let results = verifier.verify_optimizations();
323
324    println!("{}", verifier.generate_report(&results));
325
326    results
327}
328
329#[cfg(test)]
330mod tests {
331    use super::*;
332
333    #[test]
334    fn test_memory_verification() {
335        let results = run_memory_verification();
336
337        // Assert optimizations are working
338        assert!(
339            results.buffer_pool_test_passed,
340            "Buffer pool test should pass"
341        );
342        assert!(results.simd_test_passed, "SIMD test should pass");
343        assert!(
344            results.parallel_test_passed,
345            "Parallel processing test should pass"
346        );
347        assert!(
348            results.overall_performance_ratio > 0.1,
349            "Performance should be reasonable (may have overhead for small operations)"
350        );
351    }
352
353    #[test]
354    fn test_individual_components() {
355        let verifier = MemoryVerifier::new();
356
357        assert!(
358            verifier.test_buffer_pool_functionality(),
359            "Buffer pool should work correctly"
360        );
361        assert!(
362            verifier.test_simd_functionality(),
363            "SIMD operations should work correctly"
364        );
365        assert!(
366            verifier.test_parallel_functionality(),
367            "Parallel processing should work correctly"
368        );
369    }
370}