chess-vector-engine 0.5.1

Open source chess engine with hybrid vector-based position analysis, advanced tactical search, and NNUE neural network evaluation
Documentation
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!("=============================================");

    // Test different NNUE configurations
    let configs = vec![
        ("Vector Integrated", NNUEConfig::vector_integrated()),
        ("NNUE Focused", NNUEConfig::nnue_focused()),
        ("Experimental", NNUEConfig::experimental()),
        ("Default", NNUEConfig::default()),
    ];

    // Test positions with varying complexity
    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);

        // Create NNUE with this configuration
        let mut nnue = match NNUE::new(config.clone()) {
            Ok(nnue) => nnue,
            Err(e) => {
                println!("❌ Failed to create NNUE: {}", e);
                continue;
            }
        };

        // Individual position tests
        for (name, fen) in &test_positions {
            let board = Board::from_str(fen).unwrap();
            
            println!("\n  Testing: {}", name);

            // Test standard evaluation
            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();

            // Test optimized evaluation
            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);
                }

                // Test hybrid evaluation
                let vector_eval = Some(standard_avg * 0.1); // Mock vector evaluation
                let tactical_eval = Some(standard_avg * 1.2); // Mock tactical evaluation
                
                if let Ok(hybrid_eval) = nnue.evaluate_hybrid(&board, vector_eval, tactical_eval) {
                    println!("    Hybrid: {:.2} eval (blend of NNUE + vector + tactical)", hybrid_eval);
                }
            }
        }

        // Batch performance test
        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!");
}