comprehensive_benchmarking_demo/
comprehensive_benchmarking_demo.rs1use quantrs2_ml::benchmarking::algorithm_benchmarks::{QAOABenchmark, QNNBenchmark, VQEBenchmark};
7use quantrs2_ml::benchmarking::benchmark_utils::create_benchmark_backends;
8use quantrs2_ml::benchmarking::{Benchmark, BenchmarkConfig, BenchmarkFramework, BenchmarkResults};
9use quantrs2_ml::prelude::*;
10use quantrs2_ml::simulator_backends::Backend;
11use std::time::Duration;
12
13#[derive(Debug, Clone)]
15pub struct BenchmarkContext {
16 pub config: String,
17}
18
19impl Default for BenchmarkContext {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl BenchmarkContext {
26 #[must_use]
27 pub fn new() -> Self {
28 Self {
29 config: "default".to_string(),
30 }
31 }
32}
33
34fn main() -> Result<()> {
35 println!("=== Comprehensive Quantum ML Benchmarking Demo ===\n");
36
37 println!("1. Initializing benchmarking framework...");
39
40 let config = BenchmarkConfig {
41 repetitions: 3,
42 warmup_runs: 1,
43 max_time_per_benchmark: 60.0, profile_memory: true,
45 analyze_convergence: true,
46 confidence_level: 0.95,
47 ..Default::default()
48 };
49
50 let mut framework = BenchmarkFramework::new().with_config(config);
51
52 println!(" - Framework initialized");
53 println!(" - Output directory: benchmark_results/");
54 println!(" - Repetitions per benchmark: 3");
55
56 println!("\n2. Registering benchmarks...");
58
59 framework.register_benchmark("vqe_4q", Box::new(VQEBenchmark::new(4, 8)));
61 framework.register_benchmark("vqe_6q", Box::new(VQEBenchmark::new(6, 12)));
62 framework.register_benchmark("vqe_8q", Box::new(VQEBenchmark::new(8, 16)));
63
64 framework.register_benchmark("qaoa_4q", Box::new(QAOABenchmark::new(4, 2, 8)));
66 framework.register_benchmark("qaoa_6q", Box::new(QAOABenchmark::new(6, 3, 12)));
67
68 framework.register_benchmark("qnn_4q", Box::new(QNNBenchmark::new(4, 2, 100)));
70 framework.register_benchmark("qnn_6q", Box::new(QNNBenchmark::new(6, 3, 100)));
71
72 println!(" - Registered 7 benchmarks total");
73
74 println!("\n3. Setting up backends...");
76
77 let backends = create_benchmark_backends();
78 let backend_refs: Vec<&Backend> = backends.iter().collect();
79
80 println!(" - Created {} backends", backends.len());
81 for backend in &backends {
82 println!(" - {}", backend.name());
83 }
84
85 println!("\n4. Running all benchmarks...");
87
88 framework.run_all_benchmarks(&backend_refs)?;
89
90 println!(" - All benchmarks completed");
91
92 println!("\n5. Generating benchmark report...");
94
95 let report = framework.generate_report();
96 println!("\n{}", report.to_string());
97
98 println!("\n6. Detailed Results Analysis:");
100
101 let results = framework.run_all_benchmarks(&backend_refs)?;
103 print_performance_summary(results);
104 print_scaling_analysis(results);
105 print_memory_analysis(results);
106
107 println!("\n=== Comprehensive Benchmarking Demo Complete ===");
108
109 Ok(())
110}
111
112fn print_performance_summary(results: &BenchmarkResults) {
113 println!("\n Performance Summary:");
114 println!(" ===================");
115
116 for (name, summary) in results.summaries() {
118 println!(" {name}:");
119 println!(" - Mean time: {:.3}s", summary.mean_time.as_secs_f64());
120 println!(" - Min time: {:.3}s", summary.min_time.as_secs_f64());
121 println!(" - Max time: {:.3}s", summary.max_time.as_secs_f64());
122 println!(" - Success rate: {:.1}%", summary.success_rate * 100.0);
123 if let Some(memory) = summary.mean_memory {
124 println!(
125 " - Memory usage: {:.1} MB",
126 memory as f64 / 1024.0 / 1024.0
127 );
128 }
129 println!();
130 }
131}
132
133fn print_scaling_analysis(results: &BenchmarkResults) {
134 println!(" Scaling Analysis:");
135 println!(" =================");
136
137 let mut vqe_results = Vec::new();
139 let mut qaoa_results = Vec::new();
140 let mut qnn_results = Vec::new();
141
142 for (name, summary) in results.summaries() {
143 if name.starts_with("vqe_") {
144 vqe_results.push((name, summary));
145 } else if name.starts_with("qaoa_") {
146 qaoa_results.push((name, summary));
147 } else if name.starts_with("qnn_") {
148 qnn_results.push((name, summary));
149 }
150 }
151
152 if !vqe_results.is_empty() {
154 println!(" VQE Algorithm Scaling:");
155 vqe_results.sort_by_key(|(name, _)| (*name).clone());
156 for (name, summary) in vqe_results {
157 let qubits = extract_qubit_count(name);
158 println!(
159 " - {} qubits: {:.3}s",
160 qubits,
161 summary.mean_time.as_secs_f64()
162 );
163 }
164 println!(" - Scaling trend: Exponential (as expected for VQE)");
165 println!();
166 }
167
168 if !qaoa_results.is_empty() {
170 println!(" QAOA Algorithm Scaling:");
171 qaoa_results.sort_by_key(|(name, _)| (*name).clone());
172 for (name, summary) in qaoa_results {
173 let qubits = extract_qubit_count(name);
174 println!(
175 " - {} qubits: {:.3}s",
176 qubits,
177 summary.mean_time.as_secs_f64()
178 );
179 }
180 println!(" - Scaling trend: Polynomial (as expected for QAOA)");
181 println!();
182 }
183
184 if !qnn_results.is_empty() {
186 println!(" QNN Algorithm Scaling:");
187 qnn_results.sort_by_key(|(name, _)| (*name).clone());
188 for (name, summary) in qnn_results {
189 let qubits = extract_qubit_count(name);
190 println!(
191 " - {} qubits: {:.3}s",
192 qubits,
193 summary.mean_time.as_secs_f64()
194 );
195 }
196 println!(" - Scaling trend: Polynomial (training overhead)");
197 println!();
198 }
199}
200
201fn print_memory_analysis(results: &BenchmarkResults) {
202 println!(" Memory Usage Analysis:");
203 println!(" =====================");
204
205 let mut memory_data = Vec::new();
206 for (name, summary) in results.summaries() {
207 if let Some(memory) = summary.mean_memory {
208 let qubits = extract_qubit_count(name);
209 memory_data.push((qubits, memory, name));
210 }
211 }
212
213 if !memory_data.is_empty() {
214 memory_data.sort_by_key(|(qubits, _, _)| *qubits);
215
216 println!(" Memory scaling by qubit count:");
217 for (qubits, memory, name) in memory_data {
218 println!(
219 " - {} qubits ({}): {:.1} MB",
220 qubits,
221 name,
222 memory as f64 / 1024.0 / 1024.0
223 );
224 }
225 println!(" - Expected scaling: O(2^n) for statevector simulation");
226 println!();
227 }
228
229 println!(" Recommendations:");
231 println!(" - Use statevector backend for circuits ≤ 12 qubits");
232 println!(" - Use MPS backend for larger circuits with limited entanglement");
233 println!(" - Consider circuit optimization for memory-constrained environments");
234}
235
236fn extract_qubit_count(benchmark_name: &str) -> usize {
237 for part in benchmark_name.split('_') {
239 if part.ends_with('q') {
240 if let Ok(num) = part.trim_end_matches('q').parse::<usize>() {
241 return num;
242 }
243 }
244 }
245 0 }
247
248fn analyze_backend_performance(results: &BenchmarkResults) {
250 println!(" Backend Performance Comparison:");
251 println!(" ==============================");
252
253 let mut backend_performance = std::collections::HashMap::new();
255
256 for (name, summary) in results.summaries() {
257 let backend_type = extract_backend_type(name);
258 backend_performance
259 .entry(backend_type)
260 .or_insert_with(Vec::new)
261 .push(summary.mean_time.as_secs_f64());
262 }
263
264 for (backend, times) in backend_performance {
265 let avg_time = times.iter().sum::<f64>() / times.len() as f64;
266 println!(" - {backend} backend: {avg_time:.3}s average");
267 }
268}
269
270fn extract_backend_type(benchmark_name: &str) -> &str {
271 if benchmark_name.contains("statevector") {
272 "Statevector"
273 } else if benchmark_name.contains("mps") {
274 "MPS"
275 } else if benchmark_name.contains("gpu") {
276 "GPU"
277 } else {
278 "Unknown"
279 }
280}
281
282#[cfg(test)]
284mod tests {
285 use super::*;
286
287 #[test]
288 fn test_extract_qubit_count() {
289 assert_eq!(extract_qubit_count("vqe_4q_statevector"), 4);
290 assert_eq!(extract_qubit_count("qaoa_6q_mps"), 6);
291 assert_eq!(extract_qubit_count("qnn_8q_gpu"), 8);
292 assert_eq!(extract_qubit_count("unknown_format"), 0);
293 }
294
295 #[test]
296 fn test_extract_backend_type() {
297 assert_eq!(extract_backend_type("vqe_4q_statevector"), "Statevector");
298 assert_eq!(extract_backend_type("qaoa_6q_mps"), "MPS");
299 assert_eq!(extract_backend_type("qnn_8q_gpu"), "GPU");
300 assert_eq!(extract_backend_type("unknown_backend"), "Unknown");
301 }
302}
303
304fn create_algorithm_comparison_benchmarks() -> Result<Vec<Box<dyn Benchmark>>> {
306 let mut benchmarks = Vec::new();
307 Ok(benchmarks)
308}
309
310fn create_scaling_benchmarks() -> Result<Vec<Box<dyn Benchmark>>> {
311 let mut benchmarks = Vec::new();
312 Ok(benchmarks)
313}
314
315fn create_hardware_benchmarks() -> Result<Vec<Box<dyn Benchmark>>> {
316 let mut benchmarks = Vec::new();
317 Ok(benchmarks)
318}
319
320fn create_framework_benchmarks() -> Result<Vec<Box<dyn Benchmark>>> {
321 let mut benchmarks = Vec::new();
322 Ok(benchmarks)
323}