From a01eb2353803c1a14337ccf689f94b5b9c35f5a4 Mon Sep 17 00:00:00 2001 From: hachem Date: Wed, 10 Dec 2025 06:59:01 +0100 Subject: [add]: Kernel+Kernel Batching --- tester/src/kernels.rs | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 tester/src/kernels.rs (limited to 'tester/src/kernels.rs') diff --git a/tester/src/kernels.rs b/tester/src/kernels.rs new file mode 100644 index 0000000..fabe394 --- /dev/null +++ b/tester/src/kernels.rs @@ -0,0 +1,218 @@ +use crate::common::{print_section, states_equal, BenchmarkResult}; +use libpsi_core::{QuantumCircuit, Runtime}; +use std::f64::consts::PI; +use std::time::Instant; + +pub fn run_all(results: &mut Vec) { + println!("═══════════════════════════════════════════════════════════════"); + println!(" KERNEL BATCHING TESTS"); + println!("═══════════════════════════════════════════════════════════════\n"); + + test_kernel_fusion(results); + test_batched_vs_basic(results); + test_batched_large_circuits(results); +} + +pub fn test_kernel_fusion(results: &mut Vec) { + print_section("Kernel Fusion Test"); + + let builder = || { + let mut circuit = QuantumCircuit::new(2); + circuit.h(0).t(0).s(0).x(0).h(1).z(1); + circuit + }; + + let circuit = builder(); + let batch = Runtime::build_kernel_batch(2, circuit.operations()); + let original_count = batch.len(); + println!("Original kernels: {}", original_count); + for (i, k) in batch.kernels().iter().enumerate() { + println!(" {}: {} on {:?}", i, k.name, k.targets); + } + + let mut optimized_batch = Runtime::build_kernel_batch(2, circuit.operations()); + optimized_batch.optimize(); + let optimized_count = optimized_batch.len(); + println!("\nOptimized kernels: {}", optimized_count); + for (i, k) in optimized_batch.kernels().iter().enumerate() { + println!(" {}: {} on {:?}", i, k.name, k.targets); + } + + let reduction = ((original_count - optimized_count) as f64 / original_count as f64) * 100.0; + println!( + "\nKernel reduction: {} → {} ({:.0}% fewer)", + original_count, optimized_count, reduction + ); + + let mut basic = builder(); + let start = Instant::now(); + basic.compute_with(Runtime::BasicRT); + let basic_time = start.elapsed(); + + let mut batched = builder(); + let start = Instant::now(); + batched.compute_with(Runtime::BatchedRT); + let batched_time = start.elapsed(); + + let match_result = states_equal(basic.state(), batched.state()); + println!("Results match: {}\n", if match_result { "✓" } else { "✗" }); + + results.push(BenchmarkResult { + name: format!("Fusion ({}→{} kernels)", original_count, optimized_count), + basic_time, + mt_time: batched_time, + results_match: match_result, + }); + + let fusion_heavy = || { + let mut circuit = QuantumCircuit::new(1); + circuit.h(0).t(0).s(0).x(0).y(0).z(0).h(0).t(0); + circuit + }; + + let circuit2 = fusion_heavy(); + let batch2 = Runtime::build_kernel_batch(1, circuit2.operations()); + let orig2 = batch2.len(); + let mut opt_batch2 = Runtime::build_kernel_batch(1, circuit2.operations()); + opt_batch2.optimize(); + let opt2 = opt_batch2.len(); + + let mut basic2 = fusion_heavy(); + let start = Instant::now(); + basic2.compute_with(Runtime::BasicRT); + let basic_time2 = start.elapsed(); + + let mut batched2 = fusion_heavy(); + let start = Instant::now(); + batched2.compute_with(Runtime::BatchedRT); + let batched_time2 = start.elapsed(); + + let match2 = states_equal(basic2.state(), batched2.state()); + + results.push(BenchmarkResult { + name: format!("Heavy fusion ({}→{} kernels)", orig2, opt2), + basic_time: basic_time2, + mt_time: batched_time2, + results_match: match2, + }); +} + +pub fn test_batched_vs_basic(results: &mut Vec) { + print_section("Batched vs Basic Runtime Comparison"); + + let test_cases: Vec<(&str, Box QuantumCircuit>)> = vec![ + ( + "Bell State", + Box::new(|| { + let mut c = QuantumCircuit::new(2); + c.h(0).cnot(0, 1); + c + }), + ), + ( + "GHZ State", + Box::new(|| { + let mut c = QuantumCircuit::new(3); + c.h(0).cnot(0, 1).cnot(0, 2); + c + }), + ), + ( + "Rotation Chain", + Box::new(|| { + let mut c = QuantumCircuit::new(3); + c.rx(0, PI / 4.0) + .ry(0, PI / 4.0) + .rz(0, PI / 4.0) + .rx(1, PI / 3.0) + .ry(1, PI / 3.0); + c + }), + ), + ( + "Mixed Gates", + Box::new(|| { + let mut c = QuantumCircuit::new(4); + c.h(0).h(1).h(2).h(3).cnot(0, 1).cnot(2, 3).cz(1, 2); + c + }), + ), + ]; + + for (name, builder) in test_cases { + let mut basic = builder(); + let start = Instant::now(); + basic.compute_with(Runtime::BasicRT); + let basic_time = start.elapsed(); + + let mut batched = builder(); + let start = Instant::now(); + batched.compute_with(Runtime::BatchedRT); + let batched_time = start.elapsed(); + + let match_result = states_equal(basic.state(), batched.state()); + + println!( + "{}: Basic={:.2}μs, Batched={:.2}μs, Match={}", + name, + basic_time.as_secs_f64() * 1_000_000.0, + batched_time.as_secs_f64() * 1_000_000.0, + if match_result { "✓" } else { "✗" } + ); + + results.push(BenchmarkResult { + name: format!("Batched: {}", name), + basic_time, + mt_time: batched_time, + results_match: match_result, + }); + } + println!(); +} + +pub fn test_batched_large_circuits(results: &mut Vec) { + print_section("Batched Runtime on Large Circuits"); + + let sizes = [8, 10, 12]; + + for &n in &sizes { + let builder = || { + let mut circuit = QuantumCircuit::new(n); + for i in 0..n { + circuit.h(i); + } + for i in 0..(n - 1) { + circuit.cnot(i, i + 1); + } + circuit + }; + + let mut basic_mt = builder(); + let start = Instant::now(); + basic_mt.compute_with(Runtime::BasicRTMT); + let basic_mt_time = start.elapsed(); + + let mut batched_mt = builder(); + let start = Instant::now(); + batched_mt.compute_with(Runtime::BatchedRTMT); + let batched_mt_time = start.elapsed(); + + let match_result = states_equal(basic_mt.state(), batched_mt.state()); + + println!( + "{}-qubit: BasicRTMT={:.3}ms, BatchedRTMT={:.3}ms, Match={}", + n, + basic_mt_time.as_secs_f64() * 1000.0, + batched_mt_time.as_secs_f64() * 1000.0, + if match_result { "✓" } else { "✗" } + ); + + results.push(BenchmarkResult { + name: format!("{}-qubit batched", n), + basic_time: basic_mt_time, + mt_time: batched_mt_time, + results_match: match_result, + }); + } + println!(); +} -- cgit v1.3