aboutsummaryrefslogtreecommitdiff
path: root/tester
diff options
context:
space:
mode:
Diffstat (limited to 'tester')
-rw-r--r--tester/Cargo.toml1
-rw-r--r--tester/src/main.rs8
-rw-r--r--tester/src/simd.rs210
3 files changed, 219 insertions, 0 deletions
diff --git a/tester/Cargo.toml b/tester/Cargo.toml
index c536f89..e912889 100644
--- a/tester/Cargo.toml
+++ b/tester/Cargo.toml
@@ -2,6 +2,7 @@
name = "tester"
version = "0.1.0"
edition = "2021"
+authors = ["Hachem"]
[dependencies]
libpsi-core ={ path = "../libpsi-core"}
diff --git a/tester/src/main.rs b/tester/src/main.rs
index 1fb4d32..854472c 100644
--- a/tester/src/main.rs
+++ b/tester/src/main.rs
@@ -4,6 +4,7 @@ mod common;
mod custom_gates;
mod kernels;
mod non_clifford;
+mod simd;
use common::{print_benchmark_table, print_summary, BenchmarkResult};
use std::env;
@@ -23,6 +24,7 @@ fn print_usage() {
println!(" non-clifford Run non-Clifford gate tests only");
println!(" custom Run custom gate tests only");
println!(" kernels Run kernel batching tests only");
+ println!(" simd Run SIMD acceleration tests only");
println!(" bench Run benchmark tests only");
println!(" help Show this help message");
println!();
@@ -31,6 +33,7 @@ fn print_usage() {
println!(" tester clifford # Run only Clifford gate tests");
println!(" tester non-clifford # Run only rotation/parametric gate tests");
println!(" tester kernels # Run only kernel batching tests");
+ println!(" tester simd # Run only SIMD tests");
println!(" tester custom bench # Run custom gates and benchmarks");
}
@@ -54,6 +57,7 @@ fn main() {
let run_non_clifford = run_all || args.iter().any(|a| a == "non-clifford");
let run_custom = run_all || args.iter().any(|a| a == "custom");
let run_kernels = run_all || args.iter().any(|a| a == "kernels");
+ let run_simd = run_all || args.iter().any(|a| a == "simd");
let run_bench = run_all || args.iter().any(|a| a == "bench");
if run_clifford {
@@ -72,6 +76,10 @@ fn main() {
kernels::run_all(&mut results);
}
+ if run_simd {
+ simd::run_all(&mut results);
+ }
+
if run_bench {
benchmarks::run_all(&mut results);
}
diff --git a/tester/src/simd.rs b/tester/src/simd.rs
new file mode 100644
index 0000000..7ab71b6
--- /dev/null
+++ b/tester/src/simd.rs
@@ -0,0 +1,210 @@
+use crate::common::{print_section, states_equal, BenchmarkResult};
+use libpsi_core::{get_simd_info, QuantumCircuit, Runtime};
+use std::f64::consts::PI;
+use std::time::Instant;
+
+pub fn run_all(results: &mut Vec<BenchmarkResult>) {
+ println!("═══════════════════════════════════════════════════════════════");
+ println!(" SIMD ACCELERATION TESTS");
+ println!("═══════════════════════════════════════════════════════════════\n");
+
+ println!("Detected: {}\n", get_simd_info());
+
+ test_simd_correctness(results);
+ test_simd_vs_batched(results);
+ test_simd_large_circuits(results);
+}
+
+pub fn test_simd_correctness(results: &mut Vec<BenchmarkResult>) {
+ print_section("SIMD Correctness Verification");
+
+ let test_cases: Vec<(&str, Box<dyn Fn() -> QuantumCircuit>)> = vec![
+ (
+ "Bell State",
+ Box::new(|| {
+ let mut c = QuantumCircuit::new(2);
+ c.h(0).cnot(0, 1);
+ c
+ }),
+ ),
+ (
+ "GHZ-3",
+ 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 Single-Qubit",
+ Box::new(|| {
+ let mut c = QuantumCircuit::new(4);
+ c.h(0).t(0).s(0).x(0).h(1).y(1).z(1).h(2).t(2).h(3).s(3);
+ c
+ }),
+ ),
+ ];
+
+ for (name, builder) in test_cases {
+ let mut basic = builder();
+ basic.compute_with(Runtime::BasicRT);
+
+ let mut simd = builder();
+ simd.compute_with(Runtime::SimdRT);
+
+ let match_result = states_equal(basic.state(), simd.state());
+
+ println!(
+ "{}: {}",
+ name,
+ if match_result {
+ "✓ Match"
+ } else {
+ "✗ MISMATCH"
+ }
+ );
+
+ results.push(BenchmarkResult {
+ name: format!("SIMD verify: {}", name),
+ basic_time: std::time::Duration::from_micros(0),
+ mt_time: std::time::Duration::from_micros(0),
+ results_match: match_result,
+ });
+ }
+ println!();
+}
+
+pub fn test_simd_vs_batched(results: &mut Vec<BenchmarkResult>) {
+ print_section("SIMD vs Batched Runtime Comparison");
+
+ let test_cases: Vec<(&str, Box<dyn Fn() -> QuantumCircuit>)> = vec![
+ (
+ "Single-Qubit Heavy (6q)",
+ Box::new(|| {
+ let mut c = QuantumCircuit::new(6);
+ for q in 0..6 {
+ c.h(q).t(q).s(q).x(q).y(q).z(q);
+ }
+ c
+ }),
+ ),
+ (
+ "Rotation Circuit (5q)",
+ Box::new(|| {
+ let mut c = QuantumCircuit::new(5);
+ for q in 0..5 {
+ c.rx(q, PI / 4.0).ry(q, PI / 3.0).rz(q, PI / 6.0);
+ }
+ c
+ }),
+ ),
+ (
+ "Deep Single-Qubit (4q)",
+ Box::new(|| {
+ let mut c = QuantumCircuit::new(4);
+ for _ in 0..10 {
+ for q in 0..4 {
+ c.h(q).t(q);
+ }
+ }
+ c
+ }),
+ ),
+ ];
+
+ for (name, builder) in test_cases {
+ let mut batched = builder();
+ let start = Instant::now();
+ batched.compute_with(Runtime::BatchedRT);
+ let batched_time = start.elapsed();
+
+ let mut simd = builder();
+ let start = Instant::now();
+ simd.compute_with(Runtime::SimdRT);
+ let simd_time = start.elapsed();
+
+ let match_result = states_equal(batched.state(), simd.state());
+
+ let speedup = batched_time.as_secs_f64() / simd_time.as_secs_f64();
+ println!(
+ "{}: Batched={:.2}μs, SIMD={:.2}μs, Speedup={:.2}x, Match={}",
+ name,
+ batched_time.as_secs_f64() * 1_000_000.0,
+ simd_time.as_secs_f64() * 1_000_000.0,
+ speedup,
+ if match_result { "✓" } else { "✗" }
+ );
+
+ results.push(BenchmarkResult {
+ name: format!("SIMD: {}", name),
+ basic_time: batched_time,
+ mt_time: simd_time,
+ results_match: match_result,
+ });
+ }
+ println!();
+}
+
+pub fn test_simd_large_circuits(results: &mut Vec<BenchmarkResult>) {
+ print_section("SIMD on Large Circuits (Multi-threaded)");
+
+ 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);
+ }
+ for i in 0..n {
+ circuit.t(i).s(i);
+ }
+ circuit
+ };
+
+ let mut batched_mt = builder();
+ let start = Instant::now();
+ batched_mt.compute_with(Runtime::BatchedRTMT);
+ let batched_time = start.elapsed();
+
+ let mut simd_mt = builder();
+ let start = Instant::now();
+ simd_mt.compute_with(Runtime::SimdRTMT);
+ let simd_time = start.elapsed();
+
+ let match_result = states_equal(batched_mt.state(), simd_mt.state());
+
+ let speedup = batched_time.as_secs_f64() / simd_time.as_secs_f64();
+ println!(
+ "{}-qubit: BatchedMT={:.3}ms, SIMD_MT={:.3}ms, Speedup={:.2}x, Match={}",
+ n,
+ batched_time.as_secs_f64() * 1000.0,
+ simd_time.as_secs_f64() * 1000.0,
+ speedup,
+ if match_result { "✓" } else { "✗" }
+ );
+
+ results.push(BenchmarkResult {
+ name: format!("{}-qubit SIMD", n),
+ basic_time: batched_time,
+ mt_time: simd_time,
+ results_match: match_result,
+ });
+ }
+ println!();
+}