From b558ca6b9d1b5d2015054eec0ca6a9779225a7e7 Mon Sep 17 00:00:00 2001 From: connormcmonigle Date: Tue, 20 Jun 2023 18:45:13 -0700 Subject: [PATCH] reset-cache-cleanup (#162) ELO | -0.69 +- 1.05 (95%) SPRT | 8.0+0.08s Threads=1 Hash=32MB LLR | 2.97 (-2.94, 2.94) [-3.00, 0.00] GAMES | N: 197768 W: 46691 L: 47083 D: 103994 bench: 3853493 --- include/board.h | 26 ++++++++++-------- include/nnue_feature_reset_cache.h | 32 +++++----------------- include/piece_configuration.h | 44 ++++++++++++++++++++++++++++++ include/square.h | 10 ++++++- 4 files changed, 74 insertions(+), 38 deletions(-) create mode 100644 include/piece_configuration.h diff --git a/include/board.h b/include/board.h index 3a10b0a..cc94ed2 100644 --- a/include/board.h +++ b/include/board.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -829,31 +830,32 @@ struct board { template void half_feature_partial_reset_(const move& mv, T0& feature_reset_cache, T1& sided_set) const { namespace h_ka = feature::half_ka; - const square our_king = mv.to(); - auto* entry = feature_reset_cache.template us().look_up(our_king); + + auto& entry = feature_reset_cache.template us().look_up(our_king); + sided_piece_configuration& config = entry.config; over_types([&](const piece_type& pt) { - square_set& them_entry_plane = entry->config.template them().get_plane(pt); - square_set& us_entry_plane = entry->config.template us().get_plane(pt); + const square_set them_entry_plane = config.them().get_plane(pt); + const square_set us_entry_plane = config.us().get_plane(pt); const square_set them_board_plane = man_.them().get_plane(pt).excluding(mv.to()); const square_set us_board_plane = [&] { - if (pt == piece_type::king) { return man_.us().get_plane(pt).excluding(mv.from()).insert(mv.to()); } + if (pt == piece_type::king) { return square_set::of(our_king); } return man_.us().get_plane(pt).excluding(mv.from()); }(); - for (const auto sq : (us_entry_plane & ~us_board_plane)) { entry->erase(h_ka::index(our_king, pt, sq)); } - for (const auto sq : (them_entry_plane & ~them_board_plane)) { entry->erase(h_ka::index>(our_king, pt, sq)); } + for (const auto sq : them_entry_plane & ~them_board_plane) { entry.erase(h_ka::index>(our_king, pt, sq)); } + for (const auto sq : (us_entry_plane & ~us_board_plane)) { entry.erase(h_ka::index(our_king, pt, sq)); } - for (const auto sq : (us_board_plane & ~us_entry_plane)) { entry->insert(h_ka::index(our_king, pt, sq)); } - for (const auto sq : (them_board_plane & ~them_entry_plane)) { entry->insert(h_ka::index>(our_king, pt, sq)); } + for (const auto sq : them_board_plane & ~them_entry_plane) { entry.insert(h_ka::index>(our_king, pt, sq)); } + for (const auto sq : us_board_plane & ~us_entry_plane) { entry.insert(h_ka::index(our_king, pt, sq)); } - us_entry_plane = us_board_plane; - them_entry_plane = them_board_plane; + config.them().set_plane(pt, them_board_plane); + config.us().set_plane(pt, us_board_plane); }); - entry->copy_state_to(sided_set.template us()); + entry.copy_state_to(sided_set.template us()); } template diff --git a/include/nnue_feature_reset_cache.h b/include/nnue_feature_reset_cache.h index e2de206..9352023 100644 --- a/include/nnue_feature_reset_cache.h +++ b/include/nnue_feature_reset_cache.h @@ -18,35 +18,17 @@ #pragma once #include +#include #include #include -#include -#include +#include +#include #include #include namespace nnue { -struct piece_configuration { - chess::square_set pawn_{}; - chess::square_set knight_{}; - chess::square_set bishop_{}; - chess::square_set rook_{}; - chess::square_set queen_{}; - chess::square_set king_{}; - - chess::square_set& get_plane(const chess::piece_type& pt) { return chess::get_member(pt, *this); } - const chess::square_set& get_plane(const chess::piece_type& pt) const { return chess::get_member(pt, *this); } -}; - -struct sided_piece_configuration : chess::sided { - piece_configuration white; - piece_configuration black; - - sided_piece_configuration() : white{}, black{} {} -}; - struct feature_reset_cache_entry { static constexpr size_t dim = weights::base_dim; @@ -54,8 +36,8 @@ struct feature_reset_cache_entry { using weights_type = big_affine; const weights_type* weights_; + chess::sided_piece_configuration config; aligned_slice slice_; - sided_piece_configuration config; void insert(const size_t& idx) { weights_->insert_idx(idx, slice_); } void erase(const size_t& idx) { weights_->erase_idx(idx, slice_); } @@ -64,12 +46,12 @@ struct feature_reset_cache_entry { void reinitialize(const weights_type* weights, const aligned_slice& slice) { weights_ = weights; slice_ = slice; - config = sided_piece_configuration{}; slice_.copy_from(weights_->b); + config = chess::sided_piece_configuration{}; } - feature_reset_cache_entry() : slice_{nullptr}, config{} {} + feature_reset_cache_entry() : config{}, slice_{nullptr} {} }; struct feature_reset_cache { @@ -79,7 +61,7 @@ struct feature_reset_cache { stack_scratchpad scratchpad_{}; feature_reset_cache_entry entries_[num_squares]{}; - feature_reset_cache_entry* look_up(const chess::square& sq) { return entries_ + sq.index(); } + feature_reset_cache_entry& look_up(const chess::square& sq) { return entries_[sq.index()]; } void reinitialize(const weights* weights) { for (size_t i(0); i < num_squares; ++i) { diff --git a/include/piece_configuration.h b/include/piece_configuration.h new file mode 100644 index 0000000..d2a822e --- /dev/null +++ b/include/piece_configuration.h @@ -0,0 +1,44 @@ +/* + Seer is a UCI chess engine by Connor McMonigle + Copyright (C) 2021 Connor McMonigle + + Seer is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Seer is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include +#include + +namespace chess { + +struct piece_configuration { + square_set pawn_{}; + square_set knight_{}; + square_set bishop_{}; + square_set rook_{}; + square_set queen_{}; + square_set king_{}; + + const square_set& get_plane(const piece_type& pt) const { return get_member(pt, *this); } + void set_plane(const piece_type& pt, const square_set& plane) { get_member(pt, *this) = plane; } +}; + +struct sided_piece_configuration : sided { + piece_configuration white; + piece_configuration black; + + sided_piece_configuration() : white{}, black{} {} +}; + +} // namespace chess diff --git a/include/square.h b/include/square.h index 79d9d1c..8c6f9a3 100644 --- a/include/square.h +++ b/include/square.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -210,11 +211,18 @@ struct square_set { } template - constexpr bool occ(I idx) const { + constexpr bool occ(const I& idx) const { static_assert(std::is_integral_v, "idx must be of integral type"); return static_cast(data & (one << static_cast(idx))); } + template + static constexpr square_set of(Ts&& ... ts) { + auto bit_board = [](auto&& sq) { return sq.bit_board(); }; + auto bit_wise_or = [](auto&& ... args) { return (args | ...); }; + return square_set(bit_wise_or(bit_board(std::forward(ts))...)); + } + constexpr square_set() : data{0} {} constexpr square_set(const std::uint64_t& set) : data{set} {} };