use chess::Board;
use chess_vector_engine::nnue::{NNUE, NNUEConfig};
use std::str::FromStr;
use std::time::Instant;
fn main() {
println!("ð§ NNUE Neural Network Optimization Benchmark");
println!("=============================================");
let configs = vec![
("Vector Integrated", NNUEConfig::vector_integrated()),
("NNUE Focused", NNUEConfig::nnue_focused()),
("Experimental", NNUEConfig::experimental()),
("Default", NNUEConfig::default()),
];
let test_positions = vec![
("Starting Position", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"),
("Sicilian Defense", "rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2"),
("Middle Game", "r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 4 4"),
("Complex Tactical", "r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1"),
("Endgame", "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 1"),
];
let boards: Vec<Board> = test_positions
.iter()
.map(|(_, fen)| Board::from_str(fen).unwrap())
.collect();
for (config_name, config) in &configs {
println!("\n=== {} Configuration ===", config_name);
println!("Vector blend weight: {:.1}", config.vector_blend_weight);
println!("Hidden size: {}, layers: {}", config.hidden_size, config.num_hidden_layers);
let mut nnue = match NNUE::new(config.clone()) {
Ok(nnue) => nnue,
Err(e) => {
println!("â Failed to create NNUE: {}", e);
continue;
}
};
for (name, fen) in &test_positions {
let board = Board::from_str(fen).unwrap();
println!("\n Testing: {}", name);
let start = Instant::now();
let mut standard_results = Vec::new();
for _ in 0..100 {
match nnue.evaluate(&board) {
Ok(eval) => standard_results.push(eval),
Err(e) => {
println!(" â Standard evaluation failed: {}", e);
break;
}
}
}
let standard_time = start.elapsed();
let start = Instant::now();
let mut optimized_results = Vec::new();
for _ in 0..100 {
match nnue.evaluate_optimized(&board) {
Ok(eval) => optimized_results.push(eval),
Err(e) => {
println!(" â Optimized evaluation failed: {}", e);
break;
}
}
}
let optimized_time = start.elapsed();
if !standard_results.is_empty() && !optimized_results.is_empty() {
let standard_avg = standard_results.iter().sum::<f32>() / standard_results.len() as f32;
let optimized_avg = optimized_results.iter().sum::<f32>() / optimized_results.len() as f32;
println!(" Standard: {:.2} eval, {}Ξs avg", standard_avg, standard_time.as_micros() / 100);
println!(" Optimized: {:.2} eval, {}Ξs avg", optimized_avg, optimized_time.as_micros() / 100);
if optimized_time.as_micros() > 0 {
let speedup = standard_time.as_micros() as f64 / optimized_time.as_micros() as f64;
println!(" Speedup: {:.2}x", speedup);
}
let vector_eval = Some(standard_avg * 0.1); let tactical_eval = Some(standard_avg * 1.2);
if let Ok(hybrid_eval) = nnue.evaluate_hybrid(&board, vector_eval, tactical_eval) {
println!(" Hybrid: {:.2} eval (blend of NNUE + vector + tactical)", hybrid_eval);
}
}
}
println!("\n === Batch Performance Test ===");
if let Ok(benchmark_result) = nnue.benchmark_performance(&boards, 50) {
println!(" Total evaluations: {}", benchmark_result.total_evaluations);
println!(" Standard: {:.0} evals/sec", benchmark_result.standard_nps);
println!(" Optimized: {:.0} evals/sec", benchmark_result.optimized_nps);
println!(" Incremental: {:.0} evals/sec", benchmark_result.incremental_nps);
println!(" Optimized speedup: {:.2}x", benchmark_result.speedup_optimized);
println!(" Incremental speedup: {:.2}x", benchmark_result.speedup_incremental);
}
}
println!("\n=== NNUE Optimization Summary ===");
println!("â
Real incremental updates implemented");
println!("â
Optimized feature extraction with stack allocation");
println!("â
Fast forward pass with reduced memory allocations");
println!("â
Intelligent hybrid evaluation blending");
println!("â
Game phase-aware weight adjustment");
println!("â
Production-ready NNUE with proper accumulator");
println!("ð Neural network optimizations complete!");
}