From 3c684e1e0e9dff8c233b77017e3b8fddfd0f86f5 Mon Sep 17 00:00:00 2001 From: TheRealGioviok <425gioviok@gmail.com> Date: Tue, 2 Jun 2026 20:01:53 +0200 Subject: [PATCH 1/4] Bench: 14469242 --- src/evaltune_main.cpp | 390 +++++++++++++++++++++++------------------- src/evaluation.cpp | 187 +++++++++++++------- src/util/pretty.hpp | 21 ++- 3 files changed, 355 insertions(+), 243 deletions(-) diff --git a/src/evaltune_main.cpp b/src/evaltune_main.cpp index 3c91fd78..8ec27c3c 100644 --- a/src/evaltune_main.cpp +++ b/src/evaltune_main.cpp @@ -27,6 +27,8 @@ using namespace Clockwork; using namespace Clockwork::Autograd; +void print_params(); + int main() { // Todo: make these CLI-specifiable @@ -182,17 +184,21 @@ int main() { // The optimizer will now start with all-zero parameters AdamW optim(parameter_count, 1, 0.9, 0.999, 1e-8, 0.0); + #ifdef PROFILE_RUN const i32 epochs = 8; #else const i32 epochs = 450; #endif + const f64 K = 1.0 / 400; std::mt19937 rng(std::random_device{}()); std::vector indices(positions.size()); - // Initialize indices 1..N + + // Initialize indices 0..N-1 std::iota(indices.begin(), indices.end(), 0); + advise_huge_pages(indices.data(), indices.size() * sizeof(size_t)); const size_t total_batches = (positions.size() + batch_size - 1) / batch_size; @@ -205,12 +211,17 @@ int main() { advise_huge_pages(tg.pair_parameters.data(), tg.pair_parameters.size() * sizeof(f64x2)); } + // Running batch loss accumulator + std::atomic running_loss_accum{0.0}; + std::barrier epoch_barrier{thread_count + 1}; + std::barrier batch_barrier{thread_count + 1, [&]() noexcept { // Reduce all thread gradients into thread_grads[0] for (u32 i = 1; i < thread_count; ++i) { thread_grads[0].accumulate(thread_grads[i]); } + // Apply optimizer optim.step(current_parameter_values, thread_grads[0]); }}; @@ -221,6 +232,7 @@ int main() { // Pre-allocated buffers (reused across micro-batches) std::vector outputs; std::vector targets; + outputs.reserve(micro_batch_size); targets.reserve(micro_batch_size); @@ -230,6 +242,7 @@ int main() { for (size_t batch_start = 0; batch_start < positions.size(); batch_start += batch_size) { + size_t batch_end = std::min(batch_start + batch_size, positions.size()); size_t this_batch_size = batch_end - batch_start; @@ -239,16 +252,22 @@ int main() { // Clear thread-local gradients for this batch auto& my_grads = thread_grads[t]; + std::fill(my_grads.parameters.begin(), my_grads.parameters.end(), 0.0); + for (auto& p : my_grads.pair_parameters) { p = f64x2::zero(); } Graph::get().copy_parameter_values(current_parameter_values); + // Thread-local scalar loss accumulator + f64 local_batch_loss = 0.0; + // Process micro-batches to keep tape small for (size_t mb_start = sub_start; mb_start < sub_end; mb_start += micro_batch_size) { + size_t mb_end = std::min(mb_start + micro_batch_size, sub_end); outputs.clear(); @@ -256,14 +275,19 @@ int main() { // Forward pass for this micro-batch for (size_t j = mb_start; j < mb_end; ++j) { + size_t idx = indices[j]; outputs.push_back((evaluate_white_pov(positions[idx]) * K).sigmoid()); targets.push_back(results[idx]); } // Backward pass - ValueHandle loss = mse(outputs, targets) - * ValueHandle::create(1.0 / double(this_batch_size)); + ValueHandle loss = mse(outputs, targets); + + local_batch_loss += loss.get_value(); + + ValueHandle scaled_loss = + loss * ValueHandle::create(1.0 / double(this_batch_size)); Graph::get().backward(); @@ -274,6 +298,10 @@ int main() { Graph::get().zero_grad(); } + // Publish loss once per batch (very low overhead) + running_loss_accum.fetch_add(local_batch_loss / double(this_batch_size), + std::memory_order_relaxed); + batch_barrier.arrive_and_wait(); } } @@ -322,8 +350,12 @@ int main() { epoch_barrier.arrive_and_wait(); for (size_t bi = 0, bstart = 0; bstart < positions.size(); bstart += batch_size, ++bi) { + batch_barrier.arrive_and_wait(); - print_progress(bi + 1, total_batches); + + const f64 running_loss = running_loss_accum.exchange(0.0, std::memory_order_relaxed); + + print_progress(bi + 1, total_batches, running_loss); } std::cout << "\n"; @@ -333,189 +365,195 @@ int main() { Graph::get().cleanup(); Graph::get().zero_grad(); + #ifndef PROFILE_RUN - std::cout << "inline const PParam PAWN_MAT = " << PAWN_MAT << ";" << std::endl; - std::cout << "inline const PParam KNIGHT_MAT = " << KNIGHT_MAT << ";" << std::endl; - std::cout << "inline const PParam BISHOP_MAT = " << BISHOP_MAT << ";" << std::endl; - std::cout << "inline const PParam ROOK_MAT = " << ROOK_MAT << ";" << std::endl; - std::cout << "inline const PParam QUEEN_MAT = " << QUEEN_MAT << ";" << std::endl; - std::cout << "inline const PParam TEMPO_VAL = " << TEMPO_VAL << ";" << std::endl; - std::cout << std::endl; - - std::cout << "inline const PParam BISHOP_XRAY_PAWNS = " << BISHOP_XRAY_PAWNS << ";" - << std::endl; - std::cout << "inline const PParam BISHOP_PAIR_VAL = " << BISHOP_PAIR_VAL << ";" - << std::endl; - std::cout << "inline const PParam ROOK_OPEN_VAL = " << ROOK_OPEN_VAL << ";" - << std::endl; - std::cout << "inline const PParam ROOK_SEMIOPEN_VAL = " << ROOK_SEMIOPEN_VAL << ";" - << std::endl; - std::cout << "inline const PParam MINOR_BEHIND_PAWN = " << MINOR_BEHIND_PAWN << ";" - << std::endl; - std::cout << "inline const PParam RESTRICTED_SQUARES = " << RESTRICTED_SQUARES << ";" - << std::endl; + print_params(); +#endif - std::cout << std::endl; - std::cout << "inline const PParam DOUBLED_PAWN_VAL = " << DOUBLED_PAWN_VAL << ";" - << std::endl; - std::cout << "inline const PParam ISOLATED_PAWN_VAL = " << ISOLATED_PAWN_VAL << ";" - << std::endl; - std::cout << std::endl; + const auto end = time::Clock::now(); - std::cout << "inline const PParam POTENTIAL_CHECKER_VAL = " << POTENTIAL_CHECKER_VAL << ";" - << std::endl; + std::cout << "// Epoch duration: " << time::cast(end - start).count() + << "s\n"; + } - std::cout << "inline const PParam OUTPOST_KNIGHT_VAL = " << OUTPOST_KNIGHT_VAL << ";" - << std::endl; - std::cout << "inline const PParam OUTPOST_BISHOP_VAL = " << OUTPOST_BISHOP_VAL << ";" - << std::endl; + return 0; +} - std::cout << std::endl; - - std::cout << "inline const PParam PAWN_PUSH_THREAT_KNIGHT = " << PAWN_PUSH_THREAT_KNIGHT - << ";" << std::endl; - std::cout << "inline const PParam PAWN_PUSH_THREAT_BISHOP = " << PAWN_PUSH_THREAT_BISHOP - << ";" << std::endl; - std::cout << "inline const PParam PAWN_PUSH_THREAT_ROOK = " << PAWN_PUSH_THREAT_ROOK - << ";" << std::endl; - std::cout << "inline const PParam PAWN_PUSH_THREAT_QUEEN = " << PAWN_PUSH_THREAT_QUEEN - << ";" << std::endl; - std::cout << std::endl; - - auto print_table = [](const std::string& name, const auto& table) { - std::cout << "inline const std::array " << name - << " = {" << std::endl - << " "; - for (const auto& val : table) { - std::cout << " " << val << ","; - } - std::cout << std::endl << "};" << std::endl; - }; - - print_table("PAWN_PHALANX", PAWN_PHALANX); - print_table("DEFENDED_PAWN", DEFENDED_PAWN); - print_table("PASSED_PAWN", PASSED_PAWN); - print_table("DEFENDED_PASSED_PUSH", DEFENDED_PASSED_PUSH); - print_table("BLOCKED_PASSED_PAWN", BLOCKED_PASSED_PAWN); - std::cout << std::endl; - - print_table("FRIENDLY_KING_PASSED_PAWN_DISTANCE", FRIENDLY_KING_PASSED_PAWN_DISTANCE); - print_table("ENEMY_KING_PASSED_PAWN_DISTANCE", ENEMY_KING_PASSED_PAWN_DISTANCE); - std::cout << std::endl; - - print_table("KNIGHT_MOBILITY", KNIGHT_MOBILITY); - print_table("BISHOP_MOBILITY", BISHOP_MOBILITY); - print_table("ROOK_MOBILITY", ROOK_MOBILITY); - print_table("QUEEN_MOBILITY", QUEEN_MOBILITY); - std::cout << std::endl; - - std::cout << "inline const PParam PAWN_THREAT_KNIGHT = " << PAWN_THREAT_KNIGHT << ";" - << std::endl; - std::cout << "inline const PParam PAWN_THREAT_BISHOP = " << PAWN_THREAT_BISHOP << ";" - << std::endl; - std::cout << "inline const PParam PAWN_THREAT_ROOK = " << PAWN_THREAT_ROOK << ";" - << std::endl; - std::cout << "inline const PParam PAWN_THREAT_QUEEN = " << PAWN_THREAT_QUEEN << ";" - << std::endl; - std::cout << std::endl; +void print_params() { - print_table("MINOR_THREAT", MINOR_THREAT); - print_table("ROOK_THREAT", ROOK_THREAT); - std::cout << "inline const PParam KING_THREAT = " << KING_THREAT << ";" << std::endl; - std::cout << "inline const PParam HANGING_PAWN = " << HANGING_PAWN << ";" << std::endl; - std::cout << "inline const PParam HANGING_NON_PAWN = " << HANGING_NON_PAWN << ";" + auto print_table = [](const std::string& name, const auto& table) { + std::cout << "inline const std::array " << name << " = {" << std::endl - << std::endl; + << " "; + for (const auto& val : table) { + std::cout << " " << val << ","; + } + std::cout << std::endl << "};" << std::endl; + }; - print_table("BISHOP_PAWNS", BISHOP_PAWNS); - std::cout << std::endl; - std::cout << "inline const PParam ROOK_LINEUP = " << ROOK_LINEUP << ";" << std::endl; - std::cout << std::endl; - auto printPsqtArray = [](const std::string& name, const auto& arr) { - std::cout << "inline const std::array " << name << " = {" - << std::endl; - for (std::size_t i = 0; i < arr.size(); ++i) { - if ((i & 7) == 0) { - std::cout << " "; - } - std::stringstream ss; - ss << arr[i] << ","; - std::cout << std::left << std::setw(16) << ss.str(); - if ((i & 7) == 7) { - std::cout << "//" << std::endl; - } + auto printPsqtArray = [](const std::string& name, const auto& arr) { + std::cout << "inline const std::array " << name << " = {" + << std::endl; + for (std::size_t i = 0; i < arr.size(); ++i) { + if ((i & 7) == 0) { + std::cout << " "; } - std::cout << "};" << std::endl; - }; - - printPsqtArray("PAWN_PSQT", PAWN_PSQT); - printPsqtArray("KNIGHT_PSQT", KNIGHT_PSQT); - printPsqtArray("BISHOP_PSQT", BISHOP_PSQT); - printPsqtArray("ROOK_PSQT", ROOK_PSQT); - printPsqtArray("QUEEN_PSQT", QUEEN_PSQT); - printPsqtArray("KING_PSQT", KING_PSQT); - std::cout << std::endl; - - auto print_2d_array = [](const std::string& name, const auto& arr) { - std::cout << "inline const std::array, " - << arr.size() << "> " << name << " = {{" << std::endl; - for (const auto& subarr : arr) { - std::cout << " {{"; - for (const auto& val : subarr) { - std::cout << " " << val << ","; - } - std::cout << " }}," << std::endl; + std::stringstream ss; + ss << arr[i] << ","; + std::cout << std::left << std::setw(16) << ss.str(); + if ((i & 7) == 7) { + std::cout << "//" << std::endl; } - std::cout << "}};" << std::endl; - }; - - std::cout << "inline const PParam KS_NO_QUEEN = " << KS_NO_QUEEN << ";" << std::endl; - std::cout << std::endl; - - print_table("PT_INNER_RING_ATTACKS", PT_INNER_RING_ATTACKS); - print_table("PT_OUTER_RING_ATTACKS", PT_OUTER_RING_ATTACKS); - std::cout << std::endl; - + } + std::cout << "};" << std::endl; + }; - std::cout << "inline const PParam KS_FLANK_ATTACK = " << KS_FLANK_ATTACK << ";" - << std::endl; - std::cout << "inline const PParam KS_FLANK_DEFENSE = " << KS_FLANK_DEFENSE << ";" - << std::endl; - std::cout << "inline const PParam KS_FLANK_DOUBLE_ATTACK = " << KS_FLANK_DOUBLE_ATTACK - << ";" << std::endl; - std::cout << "inline const PParam KS_FLANK_DOUBLE_DEFENSE = " << KS_FLANK_DOUBLE_DEFENSE - << ";" << std::endl; - std::cout << std::endl; - - print_2d_array("KING_SHELTER", KING_SHELTER); - print_table("BLOCKED_SHELTER_STORM", BLOCKED_SHELTER_STORM); - print_2d_array("SHELTER_STORM", SHELTER_STORM); - - auto print_sigmoid = [](const std::string& name, const auto& sigmoid, const i32 templ) { - PairHandle a_h = static_cast(sigmoid.a()); - PairHandle c_h = static_cast(sigmoid.c()); - std::cout << "inline TunableSigmoid<" << templ << "> " << name << "(\n" - << "\t" << std::lround(a_h.first()) << ", " << std::lround(a_h.second()) - << ", " << std::lround(c_h.first()) << ", " << std::lround(c_h.second()) - << "\n" - << ");\n"; - }; - print_sigmoid("KING_SAFETY_ACTIVATION", KING_SAFETY_ACTIVATION, 32); - - std::cout << std::endl; - - std::cout << "inline VParam WINNABLE_PAWNS = " << WINNABLE_PAWNS << ";\n"; - std::cout << "inline VParam WINNABLE_SYM = " << WINNABLE_SYM << ";\n"; - std::cout << "inline VParam WINNABLE_ASYM = " << WINNABLE_ASYM << ";\n"; - std::cout << "inline VParam WINNABLE_PAWN_ENDGAME = " << WINNABLE_PAWN_ENDGAME << ";\n"; - std::cout << "inline VParam WINNABLE_BIAS = " << WINNABLE_BIAS << ";\n"; - std::cout << std::endl; + auto print_2d_array = [](const std::string& name, const auto& arr) { + std::cout << "inline const std::array, " + << arr.size() << "> " << name << " = {{" << std::endl; + for (const auto& subarr : arr) { + std::cout << " {{"; + for (const auto& val : subarr) { + std::cout << " " << val << ","; + } + std::cout << " }}," << std::endl; + } + std::cout << "}};" << std::endl; + }; -#endif - const auto end = time::Clock::now(); - std::cout << "// Epoch duration: " << time::cast(end - start).count() - << "s\n"; - } + auto print_sigmoid = [](const std::string& name, const auto& sigmoid, const i32 templ) { + PairHandle a_h = static_cast(sigmoid.a()); + PairHandle c_h = static_cast(sigmoid.c()); + std::cout << "inline TunableSigmoid<" << templ << "> " << name << "(\n" + << "\t" << std::lround(a_h.first()) << ", " << std::lround(a_h.second()) << ", " + << std::lround(c_h.first()) << ", " << std::lround(c_h.second()) << "\n" + << ");\n"; + }; - return 0; + std::cout << "inline const PParam PAWN_MAT = " << PAWN_MAT << ";" << std::endl; + std::cout << "inline const PParam KNIGHT_MAT = " << KNIGHT_MAT << ";" << std::endl; + std::cout << "inline const PParam BISHOP_MAT = " << BISHOP_MAT << ";" << std::endl; + std::cout << "inline const PParam ROOK_MAT = " << ROOK_MAT << ";" << std::endl; + std::cout << "inline const PParam QUEEN_MAT = " << QUEEN_MAT << ";" << std::endl; + std::cout << std::endl; + + std::cout << "inline const PParam TEMPO_VAL = " << TEMPO_VAL << ";" << std::endl; + std::cout << std::endl; + + std::cout << "inline const PParam BISHOP_XRAY_PAWNS = " << BISHOP_XRAY_PAWNS << ";" + << std::endl; + std::cout << "inline const PParam BISHOP_PAIR_VAL = " << BISHOP_PAIR_VAL << ";" << std::endl; + std::cout << "inline const PParam ROOK_OPEN_VAL = " << ROOK_OPEN_VAL << ";" << std::endl; + std::cout << "inline const PParam ROOK_SEMIOPEN_VAL = " << ROOK_SEMIOPEN_VAL << ";" + << std::endl; + std::cout << "inline const PParam MINOR_BEHIND_PAWN = " << MINOR_BEHIND_PAWN << ";" + << std::endl; + std::cout << "inline const PParam RESTRICTED_SQUARES = " << RESTRICTED_SQUARES << ";" + << std::endl; + + std::cout << std::endl; + std::cout << "inline const PParam DOUBLED_PAWN_VAL = " << DOUBLED_PAWN_VAL << ";" << std::endl; + std::cout << "inline const PParam ISOLATED_PAWN_VAL = " << ISOLATED_PAWN_VAL << ";" + << std::endl; + std::cout << std::endl; + + std::cout << "inline const PParam POTENTIAL_CHECKER_VAL = " << POTENTIAL_CHECKER_VAL << ";" + << std::endl; + + std::cout << "inline const PParam OUTPOST_KNIGHT_VAL = " << OUTPOST_KNIGHT_VAL << ";" + << std::endl; + std::cout << "inline const PParam OUTPOST_BISHOP_VAL = " << OUTPOST_BISHOP_VAL << ";" + << std::endl; + + std::cout << std::endl; + + std::cout << "inline const PParam PAWN_PUSH_THREAT_KNIGHT = " << PAWN_PUSH_THREAT_KNIGHT << ";" + << std::endl; + std::cout << "inline const PParam PAWN_PUSH_THREAT_BISHOP = " << PAWN_PUSH_THREAT_BISHOP << ";" + << std::endl; + std::cout << "inline const PParam PAWN_PUSH_THREAT_ROOK = " << PAWN_PUSH_THREAT_ROOK << ";" + << std::endl; + std::cout << "inline const PParam PAWN_PUSH_THREAT_QUEEN = " << PAWN_PUSH_THREAT_QUEEN << ";" + << std::endl; + std::cout << std::endl; + + print_table("PAWN_PHALANX", PAWN_PHALANX); + print_table("DEFENDED_PAWN", DEFENDED_PAWN); + print_table("PASSED_PAWN", PASSED_PAWN); + print_table("DEFENDED_PASSED_PUSH", DEFENDED_PASSED_PUSH); + print_table("BLOCKED_PASSED_PAWN", BLOCKED_PASSED_PAWN); + std::cout << std::endl; + + print_table("FRIENDLY_KING_PASSED_PAWN_DISTANCE", FRIENDLY_KING_PASSED_PAWN_DISTANCE); + print_table("ENEMY_KING_PASSED_PAWN_DISTANCE", ENEMY_KING_PASSED_PAWN_DISTANCE); + std::cout << std::endl; + + print_table("KNIGHT_MOBILITY", KNIGHT_MOBILITY); + print_table("BISHOP_MOBILITY", BISHOP_MOBILITY); + print_table("ROOK_MOBILITY", ROOK_MOBILITY); + print_table("QUEEN_MOBILITY", QUEEN_MOBILITY); + std::cout << std::endl; + + std::cout << "inline const PParam PAWN_THREAT_KNIGHT = " << PAWN_THREAT_KNIGHT << ";" + << std::endl; + std::cout << "inline const PParam PAWN_THREAT_BISHOP = " << PAWN_THREAT_BISHOP << ";" + << std::endl; + std::cout << "inline const PParam PAWN_THREAT_ROOK = " << PAWN_THREAT_ROOK << ";" + << std::endl; + std::cout << "inline const PParam PAWN_THREAT_QUEEN = " << PAWN_THREAT_QUEEN << ";" + << std::endl; + std::cout << std::endl; + + print_table("MINOR_THREAT", MINOR_THREAT); + print_table("ROOK_THREAT", ROOK_THREAT); + std::cout << "inline const PParam KING_THREAT = " << KING_THREAT << ";" << std::endl; + std::cout << "inline const PParam HANGING_PAWN = " << HANGING_PAWN << ";" << std::endl; + std::cout << "inline const PParam HANGING_NON_PAWN = " << HANGING_NON_PAWN << ";" << std::endl + << std::endl; + + print_table("BISHOP_PAWNS", BISHOP_PAWNS); + std::cout << std::endl; + std::cout << "inline const PParam ROOK_LINEUP = " << ROOK_LINEUP << ";" << std::endl; + std::cout << std::endl; + + + printPsqtArray("PAWN_PSQT", PAWN_PSQT); + printPsqtArray("KNIGHT_PSQT", KNIGHT_PSQT); + printPsqtArray("BISHOP_PSQT", BISHOP_PSQT); + printPsqtArray("ROOK_PSQT", ROOK_PSQT); + printPsqtArray("QUEEN_PSQT", QUEEN_PSQT); + printPsqtArray("KING_PSQT", KING_PSQT); + std::cout << std::endl; + + + std::cout << "inline const PParam KS_NO_QUEEN = " << KS_NO_QUEEN << ";" << std::endl; + std::cout << std::endl; + + print_table("PT_INNER_RING_ATTACKS", PT_INNER_RING_ATTACKS); + print_table("PT_OUTER_RING_ATTACKS", PT_OUTER_RING_ATTACKS); + std::cout << std::endl; + + + std::cout << "inline const PParam KS_FLANK_ATTACK = " << KS_FLANK_ATTACK << ";" << std::endl; + std::cout << "inline const PParam KS_FLANK_DEFENSE = " << KS_FLANK_DEFENSE << ";" << std::endl; + std::cout << "inline const PParam KS_FLANK_DOUBLE_ATTACK = " << KS_FLANK_DOUBLE_ATTACK << ";" + << std::endl; + std::cout << "inline const PParam KS_FLANK_DOUBLE_DEFENSE = " << KS_FLANK_DOUBLE_DEFENSE << ";" + << std::endl; + std::cout << std::endl; + + print_2d_array("KING_SHELTER", KING_SHELTER); + print_table("BLOCKED_SHELTER_STORM", BLOCKED_SHELTER_STORM); + print_2d_array("SHELTER_STORM", SHELTER_STORM); + + + print_sigmoid("KING_SAFETY_ACTIVATION", KING_SAFETY_ACTIVATION, 32); + std::cout << std::endl; + + std::cout << "inline VParam WINNABLE_PAWNS = " << WINNABLE_PAWNS << ";\n"; + std::cout << "inline VParam WINNABLE_SYM = " << WINNABLE_SYM << ";\n"; + std::cout << "inline VParam WINNABLE_ASYM = " << WINNABLE_ASYM << ";\n"; + std::cout << "inline VParam WINNABLE_PAWN_ENDGAME = " << WINNABLE_PAWN_ENDGAME << ";\n"; + std::cout << "inline VParam WINNABLE_BIAS = " << WINNABLE_BIAS << ";\n"; + std::cout << std::endl; } diff --git a/src/evaluation.cpp b/src/evaluation.cpp index 96af22fd..56ccdf30 100644 --- a/src/evaluation.cpp +++ b/src/evaluation.cpp @@ -11,6 +11,67 @@ namespace Clockwork { + +struct EvalData { + i32 wp_count[2][6]; + i32 bp_count[2][6]; + i32 wcount; + i32 bcount; + + Bitboard any_attacks_by[2]; + Bitboard any2_attacks_by[2]; + Bitboard attacks_by_pt[2][7]; + + void init(const Position& pos) { + any_attacks_by[0] = pos.attack_table(Color::White).get_attacked_bitboard(); + any_attacks_by[1] = pos.attack_table(Color::Black).get_attacked_bitboard(); + any2_attacks_by[0] = pos.attacked_by_two_or_more(Color::White); + any2_attacks_by[1] = pos.attacked_by_two_or_more(Color::Black); + + for (PieceType pt : {PieceType::Pawn, PieceType::Knight, PieceType::Bishop, PieceType::Rook, + PieceType::Queen}) { + wp_count[static_cast(Color::White)][static_cast(pt)] = + pos.ipiece_count(Color::White, pt); + bp_count[static_cast(Color::Black)][static_cast(pt)] = + pos.ipiece_count(Color::Black, pt); + + attacks_by_pt[static_cast(Color::White)][static_cast(pt)] = + pos.attacked_by(Color::White, pt); + attacks_by_pt[static_cast(Color::Black)][static_cast(pt)] = + pos.attacked_by(Color::Black, pt); + + wcount += wp_count[static_cast(Color::White)][static_cast(pt)]; + bcount += bp_count[static_cast(Color::Black)][static_cast(pt)]; + } + + attacks_by_pt[static_cast(Color::White)][static_cast(PieceType::King)] = + pos.attacked_by(Color::White, PieceType::King); + attacks_by_pt[static_cast(Color::Black)][static_cast(PieceType::King)] = + pos.attacked_by(Color::Black, PieceType::King); + } + + inline i32 ipiece_count(const Color color, const PieceType pt) const { + return color == Color::White ? wp_count[static_cast(color)][static_cast(pt)] + : bp_count[static_cast(color)][static_cast(pt)]; + } + + inline i32 piece_count(const Color color) const { + return color == Color::White ? wcount : bcount; + } + + inline Bitboard attacked_by(const Color color, const PieceType pt) const { + return attacks_by_pt[static_cast(color)][static_cast(pt)]; + } + + inline Bitboard attacked_by(const Color color) const { + return any_attacks_by[static_cast(color)]; + } + + inline Bitboard attacked_by_2(const Color color) const { + return any2_attacks_by[static_cast(color)]; + } +}; + static i32 chebyshev_distance(Square a, Square b) { i32 file_dist = std::abs(a.file() - b.file()); i32 rank_dist = std::abs(a.rank() - b.rank()); @@ -123,14 +184,14 @@ std::array, 2> passed_pawn_spans = []() { }(); template -PScore king_shelter(const Position& pos) { +PScore king_shelter(const Position& pos, const EvalData& eval_data) { constexpr Color opp = ~color; Square king_square = pos.king_sq(color); Bitboard b = ~Bitboard::forward_ranks(opp, king_square); // Squares ahead or on king's rank Bitboard our_pawns = - pos.bitboard_for(color, PieceType::Pawn) & b & ~pos.attacked_by(opp, PieceType::Pawn); + pos.bitboard_for(color, PieceType::Pawn) & b & ~eval_data.attacked_by(opp, PieceType::Pawn); Bitboard their_pawns = pos.bitboard_for(opp, PieceType::Pawn) & b; PScore score = PSCORE_ZERO; @@ -163,7 +224,7 @@ PScore king_shelter(const Position& pos) { } template -std::tuple evaluate_pawns(const Position& pos) { +std::tuple evaluate_pawns(const Position& pos, const EvalData& data) { constexpr i32 RANK_2 = 1; constexpr i32 RANK_3 = 2; constexpr Color them = color == Color::White ? Color::Black : Color::White; @@ -214,7 +275,7 @@ std::tuple evaluate_pawns(const Position& pos) { eval += PAWN_PHALANX[static_cast(sq.relative_sq(color).rank() - RANK_2)]; } - Bitboard defended = pawns & pos.attacked_by(color, PieceType::Pawn); + Bitboard defended = pawns & data.attacked_by(color, PieceType::Pawn); for (Square sq : defended) { eval += DEFENDED_PAWN[static_cast(sq.relative_sq(color).rank() - RANK_3)]; } @@ -250,7 +311,7 @@ PScore evaluate_pawn_push_threats(const Position& pos) { } template -PScore evaluate_pieces(const Position& pos) { +PScore evaluate_pieces(const Position& pos, const EvalData& data) { constexpr Color opp = ~color; PScore eval = PSCORE_ZERO; Bitboard own_pawns = pos.bitboard_for(color, PieceType::Pawn); @@ -260,7 +321,7 @@ PScore evaluate_pieces(const Position& pos) { ? Bitboard::rank_mask(1) | Bitboard::rank_mask(2) : Bitboard::rank_mask(5) | Bitboard::rank_mask(6); Bitboard own_early_pawns = own_pawns & early_ranks; - Bitboard bb = (blocked_pawns | own_early_pawns) | pos.attacked_by(opp, PieceType::Pawn); + Bitboard bb = (blocked_pawns | own_early_pawns) | data.attacked_by(opp, PieceType::Pawn); Bitboard bb2 = bb; for (PieceId id : pos.get_piece_mask(color, PieceType::Knight)) { eval += KNIGHT_MOBILITY[pos.mobility_of(color, id, ~bb)]; @@ -279,7 +340,7 @@ PScore evaluate_pieces(const Position& pos) { Bitboard xray = diagonal_squares_table[sq.raw]; eval += BISHOP_XRAY_PAWNS * (xray & pos.bitboard_for(opp, PieceType::Pawn)).ipopcount(); } - bb2 |= pos.attacked_by(opp, PieceType::Knight) | pos.attacked_by(opp, PieceType::Bishop); + bb2 |= data.attacked_by(opp, PieceType::Knight) | data.attacked_by(opp, PieceType::Bishop); for (PieceId id : pos.get_piece_mask(color, PieceType::Rook)) { eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb)]; eval += ROOK_MOBILITY[pos.mobility_of(color, id, ~bb2)]; @@ -291,7 +352,7 @@ PScore evaluate_pieces(const Position& pos) { | pos.bitboard_for(color, PieceType::Queen))) .ipopcount(); } - bb2 |= pos.attacked_by(opp, PieceType::Rook); + bb2 |= data.attacked_by(opp, PieceType::Rook); for (PieceId id : pos.get_piece_mask(color, PieceType::Queen)) { eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb)]; eval += QUEEN_MOBILITY[pos.mobility_of(color, id, ~bb2)]; @@ -304,7 +365,7 @@ PScore evaluate_pieces(const Position& pos) { } template -PScore evaluate_outposts(const Position& pos) { +PScore evaluate_outposts(const Position& pos, const EvalData& data) { // First calculate all the viable outpost squares // A viable outpost square is one that is not attackable by enemy pawns and is: // - on ranks 4,5,6 for white (5,4,3 for black) @@ -320,7 +381,7 @@ PScore evaluate_outposts(const Position& pos) { Bitboard opp_pawn_span = pawn_spans(opp_pawns); Bitboard opp_pawn_span_attacks = static_pawn_attacks( opp_pawn_span); // Note, this does NOT consider pins! Might need to test this more thoroughly. - Bitboard pawn_defended_squares = pos.attacked_by(color, PieceType::Pawn); + Bitboard pawn_defended_squares = data.attacked_by(color, PieceType::Pawn); Bitboard viable_outposts = viable_outposts_ranks & pawn_defended_squares & ~opp_pawn_span_attacks; // Check for minor pieces on outposts @@ -334,7 +395,7 @@ PScore evaluate_outposts(const Position& pos) { template -PScore evaluate_potential_checkers(const Position& pos) { +PScore evaluate_potential_checkers(const Position& pos, const EvalData& data) { constexpr Color opp = ~color; const PieceMask orth = pos.get_piece_mask(opp); @@ -355,7 +416,7 @@ PScore evaluate_potential_checkers(const Position& pos) { } template -PScore evaluate_king_safety(const Position& pos) { +PScore evaluate_king_safety(const Position& pos, const EvalData& data) { constexpr Color opp = ~color; // Iterate over the opponent's attack bbs @@ -370,7 +431,7 @@ PScore evaluate_king_safety(const Position& pos) { // Piece attacks in inner/outer ring for (PieceType pt : {PieceType::Pawn, PieceType::Knight, PieceType::Bishop, PieceType::Rook, PieceType::Queen}) { - Bitboard attacked = pos.attacked_by(opp, pt); + Bitboard attacked = data.attacked_by(opp, pt); Bitboard inner = attacked & king_ring; Bitboard outer = attacked & extended_ring & ~king_ring; eval += PT_INNER_RING_ATTACKS[static_cast(pt) - static_cast(PieceType::Pawn)] @@ -380,11 +441,11 @@ PScore evaluate_king_safety(const Position& pos) { } // Flank attack / defense status - Bitboard defended_by_us = pos.attack_table(color).get_attacked_bitboard(); - Bitboard double_defended_by_us = pos.attacked_by_two_or_more(color); + Bitboard defended_by_us = data.attacked_by(color); + Bitboard double_defended_by_us = data.attacked_by_2(color); - Bitboard attacked_by_them = pos.attack_table(opp).get_attacked_bitboard(); - Bitboard double_attacked_by_them = pos.attacked_by_two_or_more(opp); + Bitboard attacked_by_them = data.attacked_by(opp); + Bitboard double_attacked_by_them = data.attacked_by_2(opp); eval += KS_FLANK_DEFENSE * (defended_by_us & flank).ipopcount(); eval += KS_FLANK_ATTACK * (attacked_by_them & flank).ipopcount(); @@ -392,7 +453,7 @@ PScore evaluate_king_safety(const Position& pos) { eval += KS_FLANK_DOUBLE_ATTACK * (double_attacked_by_them & flank).ipopcount(); // King shelter evaluation - eval += king_shelter(pos); + eval += king_shelter(pos, data); eval += KS_NO_QUEEN * (pos.bitboard_for(opp, PieceType::Queen).empty()); @@ -400,7 +461,7 @@ PScore evaluate_king_safety(const Position& pos) { } template -PScore evaluate_threats(const Position& pos) { +PScore evaluate_threats(const Position& pos, const EvalData& data) { constexpr Color opp = ~color; PScore eval = PSCORE_ZERO; @@ -408,44 +469,42 @@ PScore evaluate_threats(const Position& pos) { opp_pawn = pos.bitboard_for(opp, PieceType::Pawn); opp_non_pawn = pos.board().get_color_bitboard(opp) & ~opp_pawn; - strongly_protected = pos.attacked_by(opp, PieceType::Pawn) - | (pos.attacked_by_two_or_more(opp) & ~pos.attacked_by_two_or_more(opp)); + strongly_protected = + data.attacked_by(opp, PieceType::Pawn) | (data.attacked_by_2(opp) & ~data.attacked_by_2(opp)); defended = opp_non_pawn & strongly_protected; - weak = pos.board().get_color_bitboard(opp) & ~strongly_protected - & pos.attack_table(color).get_attacked_bitboard(); + weak = pos.board().get_color_bitboard(opp) & ~strongly_protected & data.attacked_by(color); if ((defended | weak).any()) { // Minor threats b = (defended | weak) - & (pos.attacked_by(color, PieceType::Knight) | pos.attacked_by(color, PieceType::Bishop)); + & (data.attacked_by(color, PieceType::Knight) + | data.attacked_by(color, PieceType::Bishop)); for (Square sq : b) { PieceType pt = pos.piece_at(sq); eval += MINOR_THREAT[static_cast(pt) - static_cast(PieceType::Pawn)]; } // Rook threats - b = weak & pos.attacked_by(color, PieceType::Rook); + b = weak & data.attacked_by(color, PieceType::Rook); for (Square sq : b) { PieceType pt = pos.piece_at(sq); eval += ROOK_THREAT[static_cast(pt) - static_cast(PieceType::Pawn)]; } // King threats - if ((weak & pos.attacked_by(color, PieceType::King)).any()) { + if ((weak & data.attacked_by(color, PieceType::King)).any()) { eval += KING_THREAT; } // Hanging pieces - b = weak - & (~pos.attack_table(opp).get_attacked_bitboard() - | (opp_non_pawn & pos.attacked_by_two_or_more(color))); + b = weak & (~data.attacked_by(opp) | (opp_non_pawn & data.attacked_by_2(color))); eval += HANGING_PAWN * (b & opp_pawn).ipopcount(); eval += HANGING_NON_PAWN * (b & opp_non_pawn).ipopcount(); } - Bitboard pawn_attacks = pos.attacked_by(color, PieceType::Pawn); + Bitboard pawn_attacks = data.attacked_by(color, PieceType::Pawn); eval += PAWN_THREAT_KNIGHT * (pos.bitboard_for(opp, PieceType::Knight) & pawn_attacks).ipopcount(); eval += @@ -458,7 +517,7 @@ PScore evaluate_threats(const Position& pos) { } template -PScore evaluate_space(const Position& pos) { +PScore evaluate_space(const Position& pos, const EvalData& data) { PScore eval = PSCORE_ZERO; constexpr Color them = color == Color::White ? Color::Black : Color::White; Bitboard ourfiles = Bitboard::fill_verticals(pos.bitboard_for(color, PieceType::Pawn)); @@ -477,14 +536,11 @@ PScore evaluate_space(const Position& pos) { & (pos.bitboard_for(them, PieceType::Pawn) | pos.bitboard_for(color, PieceType::Pawn))) .ipopcount(); - Bitboard strongly_defended = - pos.attacked_by(color, PieceType::Pawn) - | (pos.attacked_by_two_or_more(color) & ~pos.attacked_by_two_or_more(them)); + Bitboard strongly_defended = data.attacked_by(color, PieceType::Pawn) + | (data.attacked_by_2(color) & ~data.attacked_by_2(them)); eval += RESTRICTED_SQUARES - * (pos.attack_table(color).get_attacked_bitboard() & ~strongly_defended - & pos.attack_table(them).get_attacked_bitboard()) - .ipopcount(); + * (data.attacked_by(color) & ~strongly_defended & data.attacked_by(them)).ipopcount(); return eval; } @@ -528,17 +584,19 @@ PScore apply_eg_scale(const Position& pos, isize strong_phase, isize weak_phase, i32 strong_passers, - i32 weak_passers) { + i32 weak_passers, + EvalData& eval_data) { // Strong pawn scaling const Color strong_side = eval.eg() > 0 ? Color::White : Color::Black; + // Swap phases if we're in the weak side's perspective if (strong_side == Color::Black) { std::swap(strong_phase, weak_phase); std::swap(strong_passers, weak_passers); } - const isize strong_pawn_count = pos.ipiece_count(strong_side, PieceType::Pawn); - const isize weak_pawn_count = pos.ipiece_count(~strong_side, PieceType::Pawn); + const isize strong_pawn_count = eval_data.ipiece_count(strong_side, PieceType::Pawn); + const isize weak_pawn_count = eval_data.ipiece_count(~strong_side, PieceType::Pawn); // Pawnless position scaling: if our material advantage is very thin and we have no pawns, scale down the eval significantly, as trading can lead to KBK or KNK draws if (strong_pawn_count == 0) { @@ -561,16 +619,20 @@ PScore apply_eg_scale(const Position& pos, } Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { - const Color us = pos.active_color(); - const isize white_phase = pos.ipiece_count(Color::White, PieceType::Knight) - + pos.ipiece_count(Color::White, PieceType::Bishop) - + pos.ipiece_count(Color::White, PieceType::Rook) * 2 - + pos.ipiece_count(Color::White, PieceType::Queen) * 4; + const Color us = pos.active_color(); + + EvalData eval_data; + eval_data.init(pos); + + const isize white_phase = eval_data.ipiece_count(Color::White, PieceType::Knight) + + eval_data.ipiece_count(Color::White, PieceType::Bishop) + + eval_data.ipiece_count(Color::White, PieceType::Rook) * 2 + + eval_data.ipiece_count(Color::White, PieceType::Queen) * 4; - const isize black_phase = pos.ipiece_count(Color::Black, PieceType::Knight) - + pos.ipiece_count(Color::Black, PieceType::Bishop) - + pos.ipiece_count(Color::Black, PieceType::Rook) * 2 - + pos.ipiece_count(Color::Black, PieceType::Queen) * 4; + const isize black_phase = eval_data.ipiece_count(Color::Black, PieceType::Knight) + + eval_data.ipiece_count(Color::Black, PieceType::Bishop) + + eval_data.ipiece_count(Color::Black, PieceType::Rook) * 2 + + eval_data.ipiece_count(Color::Black, PieceType::Queen) * 4; usize phase = std::min(white_phase + black_phase, 24); @@ -579,27 +641,31 @@ Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { PScore eval = psqt_state.score(); // Used for linear components // pawn eval - auto [white_pawn_eval, white_passers] = evaluate_pawns(pos); - auto [black_pawn_eval, black_passers] = evaluate_pawns(pos); + auto [white_pawn_eval, white_passers] = evaluate_pawns(pos, eval_data); + auto [black_pawn_eval, black_passers] = evaluate_pawns(pos, eval_data); eval += white_pawn_eval - black_pawn_eval; // pieces & space - eval += evaluate_pieces(pos) - evaluate_pieces(pos); - eval += evaluate_outposts(pos) - evaluate_outposts(pos); - eval += evaluate_space(pos) - evaluate_space(pos); + eval += + evaluate_pieces(pos, eval_data) - evaluate_pieces(pos, eval_data); + eval += evaluate_outposts(pos, eval_data) + - evaluate_outposts(pos, eval_data); + eval += + evaluate_space(pos, eval_data) - evaluate_space(pos, eval_data); // Threats - eval += evaluate_threats(pos) - evaluate_threats(pos); + eval += evaluate_threats(pos, eval_data) + - evaluate_threats(pos, eval_data); eval += evaluate_pawn_push_threats(pos) - evaluate_pawn_push_threats(pos); // King safety - eval += evaluate_potential_checkers(pos) - - evaluate_potential_checkers(pos); + eval += evaluate_potential_checkers(pos, eval_data) + - evaluate_potential_checkers(pos, eval_data); // Nonlinear king safety components - PScore white_king_attack_total = evaluate_king_safety(pos); - PScore black_king_attack_total = evaluate_king_safety(pos); + PScore white_king_attack_total = evaluate_king_safety(pos, eval_data); + PScore black_king_attack_total = evaluate_king_safety(pos, eval_data); // Nonlinear adjustment eval += king_safety_activation(white_king_attack_total) @@ -611,7 +677,8 @@ Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { eval = apply_winnable(pos, eval, phase); // Eg scaling - eval = apply_eg_scale(pos, eval, white_phase, black_phase, white_passers, black_passers); + eval = + apply_eg_scale(pos, eval, white_phase, black_phase, white_passers, black_passers, eval_data); return static_cast(eval.phase<24>(static_cast(phase))); }; diff --git a/src/util/pretty.hpp b/src/util/pretty.hpp index 92f2a1f6..4143b41b 100644 --- a/src/util/pretty.hpp +++ b/src/util/pretty.hpp @@ -2,9 +2,13 @@ #include "types.hpp" +#include +#include +#include + namespace Clockwork { -inline void print_progress(size_t current, size_t total, size_t bar_width = 40) { +inline void print_progress(size_t current, size_t total, f32 loss, size_t bar_width = 40) { if (total == 0) { std::cout << "\r[error: total=0]" << std::flush; return; @@ -12,24 +16,27 @@ inline void print_progress(size_t current, size_t total, size_t bar_width = 40) f32 progress = static_cast(current) / static_cast(total); if (progress > 1.0f) { - progress = 1.0f; // clamp if overshoot + progress = 1.0f; } - size_t pos = static_cast(bar_width * progress); + size_t pos = static_cast(static_cast(bar_width) * progress); + + std::ostringstream loss_ss; + loss_ss << std::fixed << std::setprecision(6) << loss; std::cout << "\r["; for (size_t i = 0; i < bar_width; ++i) { if (i < pos) { - std::cout << "="; + std::cout << '='; } else if (i == pos) { - std::cout << ">"; + std::cout << '>'; } else { - std::cout << " "; + std::cout << ' '; } } std::cout << "] " << static_cast(progress * 100.0f) << "% (" << current << "/" << total - << ")" << std::flush; + << ") loss=" << loss_ss.str() << std::flush; } } // namespace Clockwork From d51d68c7e8146e044a9214931301e7d726a35147 Mon Sep 17 00:00:00 2001 From: TheRealGioviok <425gioviok@gmail.com> Date: Tue, 2 Jun 2026 20:38:07 +0200 Subject: [PATCH 2/4] Bench: 14469242 --- src/evaluation.cpp | 58 +++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/src/evaluation.cpp b/src/evaluation.cpp index 56ccdf30..faa740c2 100644 --- a/src/evaluation.cpp +++ b/src/evaluation.cpp @@ -13,8 +13,7 @@ namespace Clockwork { struct EvalData { - i32 wp_count[2][6]; - i32 bp_count[2][6]; + i32 m_piece_count[2][6]; i32 wcount; i32 bcount; @@ -30,18 +29,18 @@ struct EvalData { for (PieceType pt : {PieceType::Pawn, PieceType::Knight, PieceType::Bishop, PieceType::Rook, PieceType::Queen}) { - wp_count[static_cast(Color::White)][static_cast(pt)] = - pos.ipiece_count(Color::White, pt); - bp_count[static_cast(Color::Black)][static_cast(pt)] = - pos.ipiece_count(Color::Black, pt); + m_piece_count[static_cast(Color::White)][static_cast(pt)] = + pos.i32piece_count(Color::White, pt); + m_piece_count[static_cast(Color::Black)][static_cast(pt)] = + pos.i32piece_count(Color::Black, pt); attacks_by_pt[static_cast(Color::White)][static_cast(pt)] = pos.attacked_by(Color::White, pt); attacks_by_pt[static_cast(Color::Black)][static_cast(pt)] = pos.attacked_by(Color::Black, pt); - wcount += wp_count[static_cast(Color::White)][static_cast(pt)]; - bcount += bp_count[static_cast(Color::Black)][static_cast(pt)]; + wcount += m_piece_count[static_cast(Color::White)][static_cast(pt)]; + bcount += m_piece_count[static_cast(Color::Black)][static_cast(pt)]; } attacks_by_pt[static_cast(Color::White)][static_cast(PieceType::King)] = @@ -50,9 +49,8 @@ struct EvalData { pos.attacked_by(Color::Black, PieceType::King); } - inline i32 ipiece_count(const Color color, const PieceType pt) const { - return color == Color::White ? wp_count[static_cast(color)][static_cast(pt)] - : bp_count[static_cast(color)][static_cast(pt)]; + inline i32 piece_count(const Color color, const PieceType pt) const { + return m_piece_count[static_cast(color)][static_cast(pt)]; } inline i32 piece_count(const Color color) const { @@ -395,7 +393,7 @@ PScore evaluate_outposts(const Position& pos, const EvalData& data) { template -PScore evaluate_potential_checkers(const Position& pos, const EvalData& data) { +PScore evaluate_potential_checkers(const Position& pos) { constexpr Color opp = ~color; const PieceMask orth = pos.get_piece_mask(opp); @@ -465,7 +463,7 @@ PScore evaluate_threats(const Position& pos, const EvalData& data) { constexpr Color opp = ~color; PScore eval = PSCORE_ZERO; - Bitboard b, weak, defended, opp_pawn, opp_non_pawn, strongly_protected, safe; + Bitboard b, weak, defended, opp_pawn, opp_non_pawn, strongly_protected; opp_pawn = pos.bitboard_for(opp, PieceType::Pawn); opp_non_pawn = pos.board().get_color_bitboard(opp) & ~opp_pawn; @@ -552,7 +550,7 @@ PScore king_safety_activation(PScore& king_safety_score) { return activated; } -PScore apply_winnable(const Position& pos, PScore& score, usize phase) { +PScore apply_winnable(const Position& pos, PScore& score, i32 phase) { bool pawn_endgame = phase == 0; @@ -581,8 +579,8 @@ PScore apply_winnable(const Position& pos, PScore& score, usize phase) { PScore apply_eg_scale(const Position& pos, PScore& eval, - isize strong_phase, - isize weak_phase, + i32 strong_phase, + i32 weak_phase, i32 strong_passers, i32 weak_passers, EvalData& eval_data) { @@ -595,8 +593,8 @@ PScore apply_eg_scale(const Position& pos, std::swap(strong_passers, weak_passers); } - const isize strong_pawn_count = eval_data.ipiece_count(strong_side, PieceType::Pawn); - const isize weak_pawn_count = eval_data.ipiece_count(~strong_side, PieceType::Pawn); + const i32 strong_pawn_count = eval_data.piece_count(strong_side, PieceType::Pawn); + const i32 weak_pawn_count = eval_data.piece_count(~strong_side, PieceType::Pawn); // Pawnless position scaling: if our material advantage is very thin and we have no pawns, scale down the eval significantly, as trading can lead to KBK or KNK draws if (strong_pawn_count == 0) { @@ -624,19 +622,17 @@ Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { EvalData eval_data; eval_data.init(pos); - const isize white_phase = eval_data.ipiece_count(Color::White, PieceType::Knight) - + eval_data.ipiece_count(Color::White, PieceType::Bishop) - + eval_data.ipiece_count(Color::White, PieceType::Rook) * 2 - + eval_data.ipiece_count(Color::White, PieceType::Queen) * 4; + const i32 white_phase = eval_data.piece_count(Color::White, PieceType::Knight) + + eval_data.piece_count(Color::White, PieceType::Bishop) + + eval_data.piece_count(Color::White, PieceType::Rook) * 2 + + eval_data.piece_count(Color::White, PieceType::Queen) * 4; - const isize black_phase = eval_data.ipiece_count(Color::Black, PieceType::Knight) - + eval_data.ipiece_count(Color::Black, PieceType::Bishop) - + eval_data.ipiece_count(Color::Black, PieceType::Rook) * 2 - + eval_data.ipiece_count(Color::Black, PieceType::Queen) * 4; + const i32 black_phase = eval_data.piece_count(Color::Black, PieceType::Knight) + + eval_data.piece_count(Color::Black, PieceType::Bishop) + + eval_data.piece_count(Color::Black, PieceType::Rook) * 2 + + eval_data.piece_count(Color::Black, PieceType::Queen) * 4; - usize phase = std::min(white_phase + black_phase, 24); - - phase = std::min(phase, 24); + i32 phase = std::min(white_phase + black_phase, 24); PScore eval = psqt_state.score(); // Used for linear components @@ -660,8 +656,8 @@ Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { evaluate_pawn_push_threats(pos) - evaluate_pawn_push_threats(pos); // King safety - eval += evaluate_potential_checkers(pos, eval_data) - - evaluate_potential_checkers(pos, eval_data); + eval += evaluate_potential_checkers(pos) + - evaluate_potential_checkers(pos); // Nonlinear king safety components PScore white_king_attack_total = evaluate_king_safety(pos, eval_data); From 27011c7d87bcb4159339eb903bbf5af7a422af69 Mon Sep 17 00:00:00 2001 From: TheRealGioviok <425gioviok@gmail.com> Date: Tue, 2 Jun 2026 20:38:46 +0200 Subject: [PATCH 3/4] Bench: 14469242 --- src/position.hpp | 4 ++++ src/uci.cpp | 2 +- src/util/pretty.hpp | 12 ++++++------ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/position.hpp b/src/position.hpp index 7bd05f35..f3df59bf 100644 --- a/src/position.hpp +++ b/src/position.hpp @@ -236,6 +236,10 @@ struct Position { return static_cast(piece_count(color, ptype)); } + [[nodiscard]] i32 i32piece_count(Color color, PieceType ptype) const { + return static_cast(piece_count(color, ptype)); + } + [[nodiscard]] bool is_kp_endgame() const { for (Color color : {Color::White, Color::Black}) { if (!(piece_count(color) == 1 + piece_count(color, PieceType::Pawn))) { diff --git a/src/uci.cpp b/src/uci.cpp index 25b163a4..b4f5b774 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -123,7 +123,7 @@ void UCIHandler::handle_bench(std::istringstream& is) { // Note: This function is left here so that one doesn't need to reimplement it every time we need to expose a function through uci. // The professional thing to do is to empty the body of the function / put a placeholder in here when finished (and before pr). -void UCIHandler::handle_debug(std::istringstream& is) { +void UCIHandler::handle_debug(std::istringstream&) { std::cout << "readyok" << std::endl; } diff --git a/src/util/pretty.hpp b/src/util/pretty.hpp index 4143b41b..5a448ce9 100644 --- a/src/util/pretty.hpp +++ b/src/util/pretty.hpp @@ -8,18 +8,18 @@ namespace Clockwork { -inline void print_progress(size_t current, size_t total, f32 loss, size_t bar_width = 40) { +inline void print_progress(size_t current, size_t total, f64 loss, size_t bar_width = 40) { if (total == 0) { std::cout << "\r[error: total=0]" << std::flush; return; } - f32 progress = static_cast(current) / static_cast(total); - if (progress > 1.0f) { - progress = 1.0f; + f64 progress = static_cast(current) / static_cast(total); + if (progress > 1.0) { + progress = 1.0; } - size_t pos = static_cast(static_cast(bar_width) * progress); + size_t pos = static_cast(static_cast(bar_width) * progress); std::ostringstream loss_ss; loss_ss << std::fixed << std::setprecision(6) << loss; @@ -35,7 +35,7 @@ inline void print_progress(size_t current, size_t total, f32 loss, size_t bar_wi } } - std::cout << "] " << static_cast(progress * 100.0f) << "% (" << current << "/" << total + std::cout << "] " << static_cast(progress * 100.0) << "% (" << current << "/" << total << ") loss=" << loss_ss.str() << std::flush; } From 0b49e76745d29a382b03f2bc82149711b7b1c967 Mon Sep 17 00:00:00 2001 From: TheRealGioviok <425gioviok@gmail.com> Date: Tue, 2 Jun 2026 20:41:08 +0200 Subject: [PATCH 4/4] format Bench: 14469242 --- src/evaluation.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/evaluation.cpp b/src/evaluation.cpp index faa740c2..a590c48a 100644 --- a/src/evaluation.cpp +++ b/src/evaluation.cpp @@ -579,8 +579,8 @@ PScore apply_winnable(const Position& pos, PScore& score, i32 phase) { PScore apply_eg_scale(const Position& pos, PScore& eval, - i32 strong_phase, - i32 weak_phase, + i32 strong_phase, + i32 weak_phase, i32 strong_passers, i32 weak_passers, EvalData& eval_data) { @@ -623,14 +623,14 @@ Score evaluate_white_pov(const Position& pos, const PsqtState& psqt_state) { eval_data.init(pos); const i32 white_phase = eval_data.piece_count(Color::White, PieceType::Knight) - + eval_data.piece_count(Color::White, PieceType::Bishop) - + eval_data.piece_count(Color::White, PieceType::Rook) * 2 - + eval_data.piece_count(Color::White, PieceType::Queen) * 4; + + eval_data.piece_count(Color::White, PieceType::Bishop) + + eval_data.piece_count(Color::White, PieceType::Rook) * 2 + + eval_data.piece_count(Color::White, PieceType::Queen) * 4; const i32 black_phase = eval_data.piece_count(Color::Black, PieceType::Knight) - + eval_data.piece_count(Color::Black, PieceType::Bishop) - + eval_data.piece_count(Color::Black, PieceType::Rook) * 2 - + eval_data.piece_count(Color::Black, PieceType::Queen) * 4; + + eval_data.piece_count(Color::Black, PieceType::Bishop) + + eval_data.piece_count(Color::Black, PieceType::Rook) * 2 + + eval_data.piece_count(Color::Black, PieceType::Queen) * 4; i32 phase = std::min(white_phase + black_phase, 24);