Skip to content

Commit

Permalink
Use a macro to define eval parameters
Browse files Browse the repository at this point in the history
This removes the duplication between Parameters and Trace where adding a
new eval parameter involved:

* Adding a new entry in two places in Trace
* Adding a new entry in three places in Parameters
  • Loading branch information
jgilchrist committed Jan 10, 2025
1 parent 078bc76 commit b4614e3
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 304 deletions.
135 changes: 135 additions & 0 deletions src/engine/eval/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
macro_rules! parameters {
(
$(
($param:ident, $size:expr, $type:ident, $name:expr)
),* $(,)?
) => {
#[cfg(not(feature = "release"))]
#[derive(Clone)]
pub struct Parameters {
$(
pub $param: [PhasedEval; $size],
)*
}

#[cfg(not(feature = "release"))]
impl Parameters {
pub fn new() -> Self {
Self {
$(
$param: [PhasedEval::ZERO; $size],
)*
}
}

#[expect(unused_assignments, reason = "The final idx value will never be used")]
pub fn from_array(arr: &[crate::utils::tuner::TunerEval; Trace::SIZE]) -> Self {
let mut evals = [PhasedEval::ZERO; Trace::SIZE];

for (i, param) in arr.iter().enumerate() {
evals[i] = param.to_phased_eval();
}

let mut parameter_components = Self::new();
let mut idx = 0;

$(
let param_len = parameter_components.$param.len();
parameter_components.$param.copy_from_slice(&evals[idx..idx + param_len]);
idx += param_len;
)*

parameter_components
}
}

#[cfg(not(feature = "release"))]
impl std::fmt::Display for Parameters {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
$(
match stringify!($type) {
"array" => crate::utils::tuner::parameters::print_array(f, &self.$param, $name)?,
"pst" => crate::utils::tuner::parameters::print_pst(f, &self.$param, $name)?,
"single" => crate::utils::tuner::parameters::print_single(f, &self.$param, $name)?,
_ => unimplemented!()
}
)*

Ok(())
}
}


#[derive(Default, Copy, Clone)]
pub struct TraceComponent(i32);

pub trait TraceComponentIncr {
fn incr(&mut self, player: Player);
fn add(&mut self, player: Player, n: i32);
}

impl TraceComponentIncr for TraceComponent {
fn incr(&mut self, player: Player) {
self.add(player, 1);
}

fn add(&mut self, player: Player, n: i32) {
let multiplier = if player == Player::White { 1 } else { -1 };

self.0 += n * multiplier;
}
}

impl TraceComponentIncr for [TraceComponent; 1] {
fn incr(&mut self, player: Player) {
self[0].incr(player)
}

fn add(&mut self, player: Player, n: i32) {
self[0].add(player, n);
}
}

pub struct Trace {
$(
pub $param: [TraceComponent; $size],
)*
}

impl Trace {
#[cfg(not(feature = "release"))]
pub const SIZE: usize = size_of::<Self>() / size_of::<TraceComponent>();

pub fn new() -> Self {
Self {
$(
$param: [TraceComponent::default(); $size],
)*
}
}

#[cfg(not(feature = "release"))]
#[expect(unused_assignments, reason = "The final idx value will never be used")]
#[expect(clippy::cast_precision_loss, reason = "known cast from i32 to f32")]
pub fn non_zero_coefficients(&self) -> Vec<crate::utils::tuner::NonZeroCoefficient> {
let mut result = Vec::new();
let mut idx = 0;

$(
for (i, component) in self.$param.iter().enumerate() {
let coefficient = component.0;

if coefficient != 0 {
result
.push(crate::utils::tuner::NonZeroCoefficient::new(idx + i, coefficient as f32));
}
}

idx += self.$param.len();
)*

result
}
}
};
}
3 changes: 1 addition & 2 deletions src/engine/eval/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use crate::chess::game::Game;
use crate::chess::piece::PieceKind;
use crate::chess::player::Player;
use crate::engine::eval::params::BISHOP_PAIR_BONUS;
use crate::engine::eval::trace::Trace;
use crate::engine::eval::PhasedEval;
use crate::engine::eval::{PhasedEval, Trace, TraceComponentIncr};

pub fn trace_psts_and_material(game: &Game, trace: &mut Trace) {
trace_psts_and_material_for_player(&game.board, Player::White, trace);
Expand Down
3 changes: 1 addition & 2 deletions src/engine/eval/mobility_and_king_safety.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use super::PhasedEval;
use super::{PhasedEval, Trace, TraceComponentIncr};
use crate::chess::bitboard::Bitboard;
use crate::chess::game::Game;
use crate::chess::movegen::tables;
use crate::chess::player::Player;
use crate::engine::eval::params::{
ATTACKED_KING_SQUARES, BISHOP_MOBILITY, KNIGHT_MOBILITY, QUEEN_MOBILITY, ROOK_MOBILITY,
};
use crate::engine::eval::trace::Trace;

fn mobility_and_opp_king_safety_for<const TRACE: bool>(
game: &Game,
Expand Down
24 changes: 21 additions & 3 deletions src/engine/eval/mod.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
#[macro_use]
mod macros;
mod material;
mod mobility_and_king_safety;
mod params;
pub mod pawn_structure;
mod phased_eval;
pub mod piece_square_tables;
mod player_eval;
pub mod trace;
mod white_eval;

use crate::chess::board::Board;
pub use player_eval::Eval;
pub use white_eval::WhiteEval;

use crate::chess::game::Game;
use crate::chess::piece::Piece;
use crate::chess::piece::{Piece, PieceKind};
use crate::chess::player::ByPlayer;
use crate::chess::player::Player;
use crate::chess::square::Square;
pub use crate::engine::eval::phased_eval::PhasedEval;
use crate::engine::eval::trace::Trace;

parameters!(
(material, PieceKind::N, array, "PIECE_VALUES"),
(pawn_pst, Square::N, pst, "PAWNS"),
(knight_pst, Square::N, pst, "KNIGHTS"),
(bishop_pst, Square::N, pst, "BISHOPS"),
(rook_pst, Square::N, pst, "ROOKS"),
(queen_pst, Square::N, pst, "QUEENS"),
(king_pst, Square::N, pst, "KING"),
(passed_pawn_pst, Square::N, pst, "PASSED_PAWNS"),
(knight_mobility, 9, array, "KNIGHT_MOBILITY"),
(bishop_mobility, 14, array, "BISHOP_MOBILITY"),
(rook_mobility, 15, array, "ROOK_MOBILITY"),
(queen_mobility, 28, array, "QUEEN_MOBILITY"),
(attacked_king_squares, 9, array, "ATTACKED_KING_SQUARES"),
(bishop_pair, 1, single, "BISHOP_PAIR_BONUS"),
);

pub fn init() {
piece_square_tables::init();
Expand Down
3 changes: 1 addition & 2 deletions src/engine/eval/pawn_structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use crate::chess::player::{ByPlayer, Player};
use crate::chess::square::{Rank, Square};
use crate::engine::eval::params::PieceSquareTableDefinition;
use crate::engine::eval::piece_square_tables::{flatten, flip, negate, PieceSquareTable};
use crate::engine::eval::trace::Trace;
use crate::engine::eval::{params, PhasedEval};
use crate::engine::eval::{params, PhasedEval, Trace, TraceComponentIncr};

pub fn eval<const TRACE: bool>(game: &Game, trace: &mut Trace) -> PhasedEval {
let eval = eval_passed_pawns::<TRACE>(game, trace);
Expand Down
132 changes: 0 additions & 132 deletions src/engine/eval/trace.rs

This file was deleted.

24 changes: 18 additions & 6 deletions src/utils/tuner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@
// which is in turn based on https://github.com/AndyGrant/Ethereal/blob/master/Tuning.pdf

use crate::chess::game::Game;
use crate::engine::eval::absolute_eval_with_trace;
use crate::engine::eval::trace::{NonZeroCoefficient, Trace};
use crate::utils::tuner::parameters::Parameters;
use crate::utils::tuner::tuner_eval::TunerEval;
use crate::engine::eval::{absolute_eval_with_trace, Parameters, Trace};
use indicatif::{ProgressBar, ProgressStyle};
use rayon::prelude::*;
use std::path::Path;

mod parameters;
pub mod parameters;
mod tuner_eval;

pub use tuner_eval::TunerEval;

enum Outcome {
Win,
Draw,
Expand All @@ -30,6 +29,18 @@ impl Outcome {
}
}

#[derive(Clone)]
pub struct NonZeroCoefficient {
pub idx: usize,
pub value: f32,
}

impl NonZeroCoefficient {
pub fn new(idx: usize, value: f32) -> Self {
Self { idx, value }
}
}

struct Entry {
outcome: Outcome,
coefficients: Vec<NonZeroCoefficient>,
Expand Down Expand Up @@ -214,6 +225,7 @@ pub fn tune(path: &Path, epochs: usize) {
epoch_progress.set_position((epoch + 1) as u64);
}

let parameters = Parameters::from_array(&parameters);
let mut parameters = Parameters::from_array(&parameters);
parameters.rebalance();
println!("{}", &parameters);
}
Loading

0 comments on commit b4614e3

Please sign in to comment.