From 7beff18ef0b131277cdd695fc01c0632a47c8540 Mon Sep 17 00:00:00 2001 From: Disservin Date: Tue, 25 Mar 2025 22:21:48 +0100 Subject: [PATCH 01/11] Retire Acc Pointer Since @xu-shawn's refactor the acc pointer has become a bit unnecessary, we can achieve the same behavior by using the dimension size to get the right accumulator from the `AccumulatorState`. I think the acc pointer has become a bit of a burden required to be passed through multiple different functions together with the necessary templating required. Passed Non-Regression STC: https://tests.stockfishchess.org/tests/view/67ed600f31d7cf8afdc45183 LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 279744 W: 72037 L: 72082 D: 135625 Ptnml(0-2): 673, 29918, 78767, 29809, 705 closes https://github.com/official-stockfish/Stockfish/pull/5942 No functional change --- src/nnue/network.cpp | 22 ++-- src/nnue/network.h | 6 +- src/nnue/nnue_accumulator.cpp | 172 +++++++++++++--------------- src/nnue/nnue_accumulator.h | 73 +++++++----- src/nnue/nnue_feature_transformer.h | 7 +- 5 files changed, 135 insertions(+), 145 deletions(-) diff --git a/src/nnue/network.cpp b/src/nnue/network.cpp index cba3abc63..e23294e4f 100644 --- a/src/nnue/network.cpp +++ b/src/nnue/network.cpp @@ -219,13 +219,13 @@ Network::evaluate(const Position& pos #if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN) TransformedFeatureType - transformedFeaturesUnaligned[FeatureTransformer::BufferSize + transformedFeaturesUnaligned[FeatureTransformer::BufferSize + alignment / sizeof(TransformedFeatureType)]; auto* transformedFeatures = align_ptr_up(&transformedFeaturesUnaligned[0]); #else - alignas(alignment) TransformedFeatureType - transformedFeatures[FeatureTransformer::BufferSize]; + alignas(alignment) + TransformedFeatureType transformedFeatures[FeatureTransformer::BufferSize]; #endif ASSERT_ALIGNED(transformedFeatures, alignment); @@ -290,13 +290,13 @@ Network::trace_evaluate(const Position& #if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN) TransformedFeatureType - transformedFeaturesUnaligned[FeatureTransformer::BufferSize + transformedFeaturesUnaligned[FeatureTransformer::BufferSize + alignment / sizeof(TransformedFeatureType)]; auto* transformedFeatures = align_ptr_up(&transformedFeaturesUnaligned[0]); #else - alignas(alignment) TransformedFeatureType - transformedFeatures[FeatureTransformer::BufferSize]; + alignas(alignment) + TransformedFeatureType transformedFeatures[FeatureTransformer::BufferSize]; #endif ASSERT_ALIGNED(transformedFeatures, alignment); @@ -452,12 +452,10 @@ bool Network::write_parameters(std::ostream& stream, // Explicit template instantiations -template class Network< - NetworkArchitecture, - FeatureTransformer>; +template class Network, + FeatureTransformer>; -template class Network< - NetworkArchitecture, - FeatureTransformer>; +template class Network, + FeatureTransformer>; } // namespace Stockfish::Eval::NNUE diff --git a/src/nnue/network.h b/src/nnue/network.h index 21df4b0a1..cd32c5312 100644 --- a/src/nnue/network.h +++ b/src/nnue/network.h @@ -110,13 +110,11 @@ class Network { }; // Definitions of the network types -using SmallFeatureTransformer = - FeatureTransformer; +using SmallFeatureTransformer = FeatureTransformer; using SmallNetworkArchitecture = NetworkArchitecture; -using BigFeatureTransformer = - FeatureTransformer; +using BigFeatureTransformer = FeatureTransformer; using BigNetworkArchitecture = NetworkArchitecture; using NetworkBig = Network; diff --git a/src/nnue/nnue_accumulator.cpp b/src/nnue/nnue_accumulator.cpp index efa8df905..37af7a0fa 100644 --- a/src/nnue/nnue_accumulator.cpp +++ b/src/nnue/nnue_accumulator.cpp @@ -48,22 +48,20 @@ namespace Stockfish::Eval::NNUE { namespace { -template AccumulatorState::*accPtr> +template void update_accumulator_incremental( - const FeatureTransformer& featureTransformer, - const Square ksq, - AccumulatorState& target_state, - const AccumulatorState& computed); + const FeatureTransformer& featureTransformer, + const Square ksq, + AccumulatorState& target_state, + const AccumulatorState& computed); -template AccumulatorState::*accPtr> -void update_accumulator_refresh_cache( - const FeatureTransformer& featureTransformer, - const Position& pos, - AccumulatorState& accumulatorState, - AccumulatorCaches::Cache& cache); +template +void update_accumulator_refresh_cache(const FeatureTransformer& featureTransformer, + const Position& pos, + AccumulatorState& accumulatorState, + AccumulatorCaches::Cache& cache); } @@ -86,18 +84,14 @@ void AccumulatorStack::reset(const Position& rootPos, AccumulatorCaches& caches) noexcept { m_current_idx = 1; - update_accumulator_refresh_cache( + update_accumulator_refresh_cache( *networks.big.featureTransformer, rootPos, m_accumulators[0], caches.big); - update_accumulator_refresh_cache( + update_accumulator_refresh_cache( *networks.big.featureTransformer, rootPos, m_accumulators[0], caches.big); - update_accumulator_refresh_cache( + update_accumulator_refresh_cache( *networks.small.featureTransformer, rootPos, m_accumulators[0], caches.small); - update_accumulator_refresh_cache( + update_accumulator_refresh_cache( *networks.small.featureTransformer, rootPos, m_accumulators[0], caches.small); } @@ -112,24 +106,23 @@ void AccumulatorStack::pop() noexcept { m_current_idx--; } -template AccumulatorState::*accPtr> -void AccumulatorStack::evaluate(const Position& pos, - const FeatureTransformer& featureTransformer, - AccumulatorCaches::Cache& cache) noexcept { +template +void AccumulatorStack::evaluate(const Position& pos, + const FeatureTransformer& featureTransformer, + AccumulatorCaches::Cache& cache) noexcept { evaluate_side(pos, featureTransformer, cache); evaluate_side(pos, featureTransformer, cache); } -template AccumulatorState::*accPtr> -void AccumulatorStack::evaluate_side( - const Position& pos, - const FeatureTransformer& featureTransformer, - AccumulatorCaches::Cache& cache) noexcept { +template +void AccumulatorStack::evaluate_side(const Position& pos, + const FeatureTransformer& featureTransformer, + AccumulatorCaches::Cache& cache) noexcept { - const auto last_usable_accum = find_last_usable_accumulator(); + const auto last_usable_accum = find_last_usable_accumulator(); - if ((m_accumulators[last_usable_accum].*accPtr).computed[Perspective]) + if ((m_accumulators[last_usable_accum].template acc()).computed[Perspective]) forward_update_incremental(pos, featureTransformer, last_usable_accum); else @@ -141,12 +134,12 @@ void AccumulatorStack::evaluate_side( // Find the earliest usable accumulator, this can either be a computed accumulator or the accumulator // state just before a change that requires full refresh. -template AccumulatorState::*accPtr> +template std::size_t AccumulatorStack::find_last_usable_accumulator() const noexcept { for (std::size_t curr_idx = m_current_idx - 1; curr_idx > 0; curr_idx--) { - if ((m_accumulators[curr_idx].*accPtr).computed[Perspective]) + if ((m_accumulators[curr_idx].template acc()).computed[Perspective]) return curr_idx; if (FeatureSet::requires_refresh(m_accumulators[curr_idx].dirtyPiece, Perspective)) @@ -156,14 +149,14 @@ std::size_t AccumulatorStack::find_last_usable_accumulator() const noexcept { return 0; } -template AccumulatorState::*accPtr> +template void AccumulatorStack::forward_update_incremental( - const Position& pos, - const FeatureTransformer& featureTransformer, - const std::size_t begin) noexcept { + const Position& pos, + const FeatureTransformer& featureTransformer, + const std::size_t begin) noexcept { assert(begin < m_accumulators.size()); - assert((m_accumulators[begin].*accPtr).computed[Perspective]); + assert((m_accumulators[begin].acc()).computed[Perspective]); const Square ksq = pos.square(Perspective); @@ -171,18 +164,18 @@ void AccumulatorStack::forward_update_incremental( update_accumulator_incremental(featureTransformer, ksq, m_accumulators[next], m_accumulators[next - 1]); - assert((latest().*accPtr).computed[Perspective]); + assert((latest().acc()).computed[Perspective]); } -template AccumulatorState::*accPtr> +template void AccumulatorStack::backward_update_incremental( - const Position& pos, - const FeatureTransformer& featureTransformer, - const std::size_t end) noexcept { + const Position& pos, + const FeatureTransformer& featureTransformer, + const std::size_t end) noexcept { assert(end < m_accumulators.size()); assert(end < m_current_idx); - assert((latest().*accPtr).computed[Perspective]); + assert((latest().acc()).computed[Perspective]); const Square ksq = pos.square(Perspective); @@ -190,21 +183,17 @@ void AccumulatorStack::backward_update_incremental( update_accumulator_incremental( featureTransformer, ksq, m_accumulators[next], m_accumulators[next + 1]); - assert((m_accumulators[end].*accPtr).computed[Perspective]); + assert((m_accumulators[end].acc()).computed[Perspective]); } // Explicit template instantiations -template void -AccumulatorStack::evaluate( - const Position& pos, - const FeatureTransformer& - featureTransformer, +template void AccumulatorStack::evaluate( + const Position& pos, + const FeatureTransformer& featureTransformer, AccumulatorCaches::Cache& cache) noexcept; -template void -AccumulatorStack::evaluate( - const Position& pos, - const FeatureTransformer& - featureTransformer, +template void AccumulatorStack::evaluate( + const Position& pos, + const FeatureTransformer& featureTransformer, AccumulatorCaches::Cache& cache) noexcept; @@ -227,15 +216,15 @@ void fused_row_reduce(const ElementType* in, ElementType* out, const Ts* const.. vecIn[i], reinterpret_cast(rows)[i]...); } -template AccumulatorState::*accPtr> +template struct AccumulatorUpdateContext { - const FeatureTransformer& featureTransformer; - const AccumulatorState& from; - AccumulatorState& to; + const FeatureTransformer& featureTransformer; + const AccumulatorState& from; + AccumulatorState& to; - AccumulatorUpdateContext(const FeatureTransformer& ft, - const AccumulatorState& accF, - AccumulatorState& accT) noexcept : + AccumulatorUpdateContext(const FeatureTransformer& ft, + const AccumulatorState& accF, + AccumulatorState& accT) noexcept : featureTransformer{ft}, from{accF}, to{accT} {} @@ -252,41 +241,37 @@ struct AccumulatorUpdateContext { return &featureTransformer.psqtWeights[index * PSQTBuckets]; }; - fused_row_reduce((from.*accPtr).accumulation[Perspective], - (to.*accPtr).accumulation[Perspective], - to_weight_vector(indices)...); + fused_row_reduce( + (from.acc()).accumulation[Perspective], + (to.acc()).accumulation[Perspective], to_weight_vector(indices)...); fused_row_reduce( - (from.*accPtr).psqtAccumulation[Perspective], (to.*accPtr).psqtAccumulation[Perspective], - to_psqt_weight_vector(indices)...); + (from.acc()).psqtAccumulation[Perspective], + (to.acc()).psqtAccumulation[Perspective], to_psqt_weight_vector(indices)...); } }; -template AccumulatorState::*accPtr> -auto make_accumulator_update_context( - const FeatureTransformer& featureTransformer, - const AccumulatorState& accumulatorFrom, - AccumulatorState& accumulatorTo) noexcept { - return AccumulatorUpdateContext{ - featureTransformer, accumulatorFrom, accumulatorTo}; +template +auto make_accumulator_update_context(const FeatureTransformer& featureTransformer, + const AccumulatorState& accumulatorFrom, + AccumulatorState& accumulatorTo) noexcept { + return AccumulatorUpdateContext{featureTransformer, accumulatorFrom, + accumulatorTo}; } -template AccumulatorState::*accPtr> +template void update_accumulator_incremental( - const FeatureTransformer& featureTransformer, - const Square ksq, - AccumulatorState& target_state, - const AccumulatorState& computed) { + const FeatureTransformer& featureTransformer, + const Square ksq, + AccumulatorState& target_state, + const AccumulatorState& computed) { [[maybe_unused]] constexpr bool Forward = Direction == FORWARD; [[maybe_unused]] constexpr bool Backward = Direction == BACKWARD; assert(Forward != Backward); - assert((computed.*accPtr).computed[Perspective]); - assert(!(target_state.*accPtr).computed[Perspective]); + assert((computed.acc()).computed[Perspective]); + assert(!(target_state.acc()).computed[Perspective]); // The size must be enough to contain the largest possible update. // That might depend on the feature set and generally relies on the @@ -340,15 +325,14 @@ void update_accumulator_incremental( removed[1]); } - (target_state.*accPtr).computed[Perspective] = true; + (target_state.acc()).computed[Perspective] = true; } -template AccumulatorState::*accPtr> -void update_accumulator_refresh_cache( - const FeatureTransformer& featureTransformer, - const Position& pos, - AccumulatorState& accumulatorState, - AccumulatorCaches::Cache& cache) { +template +void update_accumulator_refresh_cache(const FeatureTransformer& featureTransformer, + const Position& pos, + AccumulatorState& accumulatorState, + AccumulatorCaches::Cache& cache) { using Tiling [[maybe_unused]] = SIMDTiling; const Square ksq = pos.square(Perspective); @@ -378,7 +362,7 @@ void update_accumulator_refresh_cache( } } - auto& accumulator = accumulatorState.*accPtr; + auto& accumulator = accumulatorState.acc(); accumulator.computed[Perspective] = true; #ifdef VECTOR diff --git a/src/nnue/nnue_accumulator.h b/src/nnue/nnue_accumulator.h index 362ea83e3..d83a5a446 100644 --- a/src/nnue/nnue_accumulator.h +++ b/src/nnue/nnue_accumulator.h @@ -46,10 +46,7 @@ struct Networks; template struct alignas(CacheLineSize) Accumulator; -struct AccumulatorState; - -template AccumulatorState::*accPtr> +template class FeatureTransformer; // Class that holds the result of affine transformation of input features @@ -121,6 +118,30 @@ struct AccumulatorState { Accumulator accumulatorSmall; DirtyPiece dirtyPiece; + template + auto& acc() noexcept { + static_assert(Size == TransformedFeatureDimensionsBig + || Size == TransformedFeatureDimensionsSmall, + "Invalid size for accumulator"); + + if constexpr (Size == TransformedFeatureDimensionsBig) + return accumulatorBig; + else if constexpr (Size == TransformedFeatureDimensionsSmall) + return accumulatorSmall; + } + + template + const auto& acc() const noexcept { + static_assert(Size == TransformedFeatureDimensionsBig + || Size == TransformedFeatureDimensionsSmall, + "Invalid size for accumulator"); + + if constexpr (Size == TransformedFeatureDimensionsBig) + return accumulatorBig; + else if constexpr (Size == TransformedFeatureDimensionsSmall) + return accumulatorSmall; + } + void reset(const DirtyPiece& dp) noexcept; }; @@ -138,41 +159,31 @@ class AccumulatorStack { void push(const DirtyPiece& dirtyPiece) noexcept; void pop() noexcept; - template AccumulatorState::*accPtr> - void evaluate(const Position& pos, - const FeatureTransformer& featureTransformer, - AccumulatorCaches::Cache& cache) noexcept; + template + void evaluate(const Position& pos, + const FeatureTransformer& featureTransformer, + AccumulatorCaches::Cache& cache) noexcept; private: [[nodiscard]] AccumulatorState& mut_latest() noexcept; - template AccumulatorState::*accPtr> - void evaluate_side(const Position& pos, - const FeatureTransformer& featureTransformer, - AccumulatorCaches::Cache& cache) noexcept; + template + void evaluate_side(const Position& pos, + const FeatureTransformer& featureTransformer, + AccumulatorCaches::Cache& cache) noexcept; - template AccumulatorState::*accPtr> + template [[nodiscard]] std::size_t find_last_usable_accumulator() const noexcept; - template AccumulatorState::*accPtr> - void - forward_update_incremental(const Position& pos, - const FeatureTransformer& featureTransformer, - const std::size_t begin) noexcept; + template + void forward_update_incremental(const Position& pos, + const FeatureTransformer& featureTransformer, + const std::size_t begin) noexcept; - template AccumulatorState::*accPtr> - void - backward_update_incremental(const Position& pos, - const FeatureTransformer& featureTransformer, - const std::size_t end) noexcept; + template + void backward_update_incremental(const Position& pos, + const FeatureTransformer& featureTransformer, + const std::size_t end) noexcept; std::vector m_accumulators; std::size_t m_current_idx; diff --git a/src/nnue/nnue_feature_transformer.h b/src/nnue/nnue_feature_transformer.h index 9dee29c19..d2abd40fa 100644 --- a/src/nnue/nnue_feature_transformer.h +++ b/src/nnue/nnue_feature_transformer.h @@ -294,8 +294,7 @@ class SIMDTiling { // Input feature converter -template AccumulatorState::*accPtr> +template class FeatureTransformer { // Number of output dimensions for one side @@ -400,12 +399,12 @@ class FeatureTransformer { const auto& accumulatorState = accumulatorStack.latest(); const Color perspectives[2] = {pos.side_to_move(), ~pos.side_to_move()}; - const auto& psqtAccumulation = (accumulatorState.*accPtr).psqtAccumulation; + const auto& psqtAccumulation = (accumulatorState.acc()).psqtAccumulation; const auto psqt = (psqtAccumulation[perspectives[0]][bucket] - psqtAccumulation[perspectives[1]][bucket]) / 2; - const auto& accumulation = (accumulatorState.*accPtr).accumulation; + const auto& accumulation = (accumulatorState.acc()).accumulation; for (IndexType p = 0; p < 2; ++p) { From 15f34560f2adf955cac7ae5a19d6c7ffdf36e4a3 Mon Sep 17 00:00:00 2001 From: Daniel Samek Date: Wed, 2 Apr 2025 18:40:56 +0200 Subject: [PATCH 02/11] Update AUTHORS closes https://github.com/official-stockfish/Stockfish/pull/5964 No functional change --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 092980fe5..dadff1422 100644 --- a/AUTHORS +++ b/AUTHORS @@ -57,8 +57,8 @@ Dale Weiler (graphitemaster) Daniel Axtens (daxtens) Daniel Dugovic (ddugovic) Daniel Monroe (Ergodice) +Daniel Samek (DanSamek) Dan Schmidt (dfannius) -DanSamek Dariusz Orzechowski (dorzechowski) David (dav1312) David Zar From fb6a3e04ec04a500d4b7c64158e5a74c2196e7ca Mon Sep 17 00:00:00 2001 From: Daniel Monroe Date: Thu, 27 Mar 2025 19:16:45 -0400 Subject: [PATCH 03/11] Simply use non_pawn_material rather than summing tuned terms Passed simplification STC LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 136576 W: 35285 L: 35175 D: 66116 Ptnml(0-2): 410, 16179, 34997, 16295, 407 https://tests.stockfishchess.org/tests/view/67e5dc736682f97da2178da6 Passed rebased simplification LTC LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 85482 W: 21812 L: 21658 D: 42012 Ptnml(0-2): 34, 9260, 24022, 9368, 57 https://tests.stockfishchess.org/tests/view/67e852cb31d7cf8afdc44966 closes https://github.com/official-stockfish/Stockfish/pull/5965 Bench: 2006483 --- src/search.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 291b99bd1..1c3622884 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -102,9 +102,7 @@ int risk_tolerance(const Position& pos, Value v) { return 644800 * x / ((x * x + 3 * y * y) * y); }; - int m = (67 * pos.count() + 182 * pos.count() + 182 * pos.count() - + 337 * pos.count() + 553 * pos.count()) - / 64; + int m = pos.count() + pos.non_pawn_material() / 300; // a and b are the crude approximation of the wdl model. // The win rate is: 1/(1+exp((a-v)/b)) From 1577fa04702b9a2a2c4ed9c4be0cfbae38b64cf0 Mon Sep 17 00:00:00 2001 From: mstembera Date: Wed, 2 Apr 2025 21:38:15 -0700 Subject: [PATCH 04/11] Simplify Forward and Backward Forward and Backward are not independent so simplify to a bool. Cleanup some MSVC warnings like "warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data" Other minor formatting stuff. This is a rebase of https://github.com/official-stockfish/Stockfish/pull/5912 closes https://github.com/official-stockfish/Stockfish/pull/5967 No functional change --- src/nnue/nnue_accumulator.cpp | 40 +++++++++++++---------------------- src/nnue/nnue_common.h | 5 ----- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/nnue/nnue_accumulator.cpp b/src/nnue/nnue_accumulator.cpp index 37af7a0fa..8b2585b91 100644 --- a/src/nnue/nnue_accumulator.cpp +++ b/src/nnue/nnue_accumulator.cpp @@ -29,7 +29,6 @@ #include "../types.h" #include "network.h" #include "nnue_architecture.h" -#include "nnue_common.h" #include "nnue_feature_transformer.h" namespace Stockfish::Eval::NNUE { @@ -48,9 +47,7 @@ namespace Stockfish::Eval::NNUE { namespace { -template +template void update_accumulator_incremental( const FeatureTransformer& featureTransformer, const Square ksq, @@ -161,8 +158,8 @@ void AccumulatorStack::forward_update_incremental( const Square ksq = pos.square(Perspective); for (std::size_t next = begin + 1; next < m_current_idx; next++) - update_accumulator_incremental(featureTransformer, ksq, m_accumulators[next], - m_accumulators[next - 1]); + update_accumulator_incremental( + featureTransformer, ksq, m_accumulators[next], m_accumulators[next - 1]); assert((latest().acc()).computed[Perspective]); } @@ -180,7 +177,7 @@ void AccumulatorStack::backward_update_incremental( const Square ksq = pos.square(Perspective); for (std::size_t next = m_current_idx - 2; next >= end; next--) - update_accumulator_incremental( + update_accumulator_incremental( featureTransformer, ksq, m_accumulators[next], m_accumulators[next + 1]); assert((m_accumulators[end].acc()).computed[Perspective]); @@ -259,16 +256,12 @@ auto make_accumulator_update_context(const FeatureTransformer& featu accumulatorTo}; } -template +template void update_accumulator_incremental( const FeatureTransformer& featureTransformer, const Square ksq, AccumulatorState& target_state, const AccumulatorState& computed) { - [[maybe_unused]] constexpr bool Forward = Direction == FORWARD; - [[maybe_unused]] constexpr bool Backward = Direction == BACKWARD; - - assert(Forward != Backward); assert((computed.acc()).computed[Perspective]); assert(!(target_state.acc()).computed[Perspective]); @@ -288,11 +281,8 @@ void update_accumulator_incremental( assert(added.size() == 1 || added.size() == 2); assert(removed.size() == 1 || removed.size() == 2); - - if (Forward) - assert(added.size() <= removed.size()); - else - assert(removed.size() <= added.size()); + assert((Forward && added.size() <= removed.size()) + || (!Forward && added.size() >= removed.size())); // Workaround compiler warning for uninitialized variables, replicated on // profile builds on windows with gcc 14.2.0. @@ -303,7 +293,7 @@ void update_accumulator_incremental( auto updateContext = make_accumulator_update_context(featureTransformer, computed, target_state); - if ((Forward && removed.size() == 1) || (Backward && added.size() == 1)) + if ((Forward && removed.size() == 1) || (!Forward && added.size() == 1)) { assert(added.size() == 1 && removed.size() == 1); updateContext.template apply(added[0], removed[0]); @@ -313,7 +303,7 @@ void update_accumulator_incremental( assert(removed.size() == 2); updateContext.template apply(added[0], removed[0], removed[1]); } - else if (Backward && removed.size() == 1) + else if (!Forward && removed.size() == 1) { assert(added.size() == 2); updateContext.template apply(added[0], added[1], removed[0]); @@ -380,7 +370,7 @@ void update_accumulator_refresh_cache(const FeatureTransformer& feat for (IndexType k = 0; k < Tiling::NumRegs; ++k) acc[k] = entryTile[k]; - std::size_t i = 0; + IndexType i = 0; for (; i < std::min(removed.size(), added.size()) - combineLast3; ++i) { IndexType indexR = removed[i]; @@ -460,10 +450,10 @@ void update_accumulator_refresh_cache(const FeatureTransformer& feat auto* entryTilePsqt = reinterpret_cast(&entry.psqtAccumulation[j * Tiling::PsqtTileHeight]); - for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k) + for (IndexType k = 0; k < Tiling::NumPsqtRegs; ++k) psqt[k] = entryTilePsqt[k]; - for (std::size_t i = 0; i < removed.size(); ++i) + for (IndexType i = 0; i < removed.size(); ++i) { IndexType index = removed[i]; const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight; @@ -473,7 +463,7 @@ void update_accumulator_refresh_cache(const FeatureTransformer& feat for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k) psqt[k] = vec_sub_psqt_32(psqt[k], columnPsqt[k]); } - for (std::size_t i = 0; i < added.size(); ++i) + for (IndexType i = 0; i < added.size(); ++i) { IndexType index = added[i]; const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight; @@ -484,9 +474,9 @@ void update_accumulator_refresh_cache(const FeatureTransformer& feat psqt[k] = vec_add_psqt_32(psqt[k], columnPsqt[k]); } - for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k) + for (IndexType k = 0; k < Tiling::NumPsqtRegs; ++k) vec_store_psqt(&entryTilePsqt[k], psqt[k]); - for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k) + for (IndexType k = 0; k < Tiling::NumPsqtRegs; ++k) vec_store_psqt(&accTilePsqt[k], psqt[k]); } diff --git a/src/nnue/nnue_common.h b/src/nnue/nnue_common.h index e6e3017d2..f21a8dec7 100644 --- a/src/nnue/nnue_common.h +++ b/src/nnue/nnue_common.h @@ -279,11 +279,6 @@ inline void write_leb_128(std::ostream& stream, const IntType* values, std::size flush(); } -enum IncUpdateDirection { - FORWARD, - BACKWARD -}; - } // namespace Stockfish::Eval::NNUE #endif // #ifndef NNUE_COMMON_H_INCLUDED From bb3eaf8defec018ae932ec24b6854966c8f83701 Mon Sep 17 00:00:00 2001 From: Disservin Date: Thu, 3 Apr 2025 20:10:17 +0200 Subject: [PATCH 05/11] Add cstddef header Fix missing header for std::size_t reported on discord. closes https://github.com/official-stockfish/Stockfish/pull/5968 No functional change --- src/types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types.h b/src/types.h index 5f9cb421e..d7f9dfb74 100644 --- a/src/types.h +++ b/src/types.h @@ -37,6 +37,7 @@ // | only in 64-bit mode and requires hardware with pext support. #include + #include #include #include From cf8b3637a0fe3a026a338cb9215283baffd3ded2 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Fri, 4 Apr 2025 03:58:02 +0300 Subject: [PATCH 06/11] Improve futility pruning Adding a small term to the futility calculation that depends on eval - beta. Refactored to a simpler form. Passed STC: LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 74176 W: 19323 L: 18954 D: 35899 Ptnml(0-2): 226, 8576, 19117, 8941, 228 https://tests.stockfishchess.org/tests/view/67e6b0946682f97da2178eaf Passed LTC: LLR: 2.96 (-2.94,2.94) <0.50,2.50> Total: 135090 W: 34499 L: 33983 D: 66608 Ptnml(0-2): 79, 14403, 38040, 14969, 54 https://tests.stockfishchess.org/tests/view/67e757cc6682f97da2178f62 closes https://github.com/official-stockfish/Stockfish/pull/5970 Bench: 1875196 --- src/search.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 1c3622884..7b8fbb144 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -855,7 +855,8 @@ Value Search::Worker::search( // The depth condition is important for mate finding. if (!ss->ttPv && depth < 14 && eval - futility_margin(depth, cutNode && !ss->ttHit, improving, opponentWorsening) - - (ss - 1)->statScore / 301 + 37 - std::abs(correctionValue) / 139878 + - (ss - 1)->statScore / 301 + 37 + ((eval - beta) / 8) + - std::abs(correctionValue) / 139878 >= beta && eval >= beta && (!ttData.move || ttCapture) && !is_loss(beta) && !is_win(eval)) return beta + (eval - beta) / 3; From 2af64d581b91ace5a299ebfadf4a9558aa637d02 Mon Sep 17 00:00:00 2001 From: AliceRoselia <63040919+AliceRoselia@users.noreply.github.com> Date: Fri, 4 Apr 2025 08:12:55 +0700 Subject: [PATCH 07/11] Update AUTHORS closes https://github.com/official-stockfish/Stockfish/pull/5972 No functional change --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index dadff1422..54c5f8a21 100644 --- a/AUTHORS +++ b/AUTHORS @@ -20,6 +20,7 @@ Alexander Kure Alexander Pagel (Lolligerhans) Alfredo Menezes (lonfom169) Ali AlZhrani (Cooffe) +AliceRoselia Andreas Jan van der Meulen (Andyson007) Andreas Matthies (Matthies) Andrei Vetrov (proukornew) From 8d2eef2b1e0075b70bf6afa74fddb01c4b5e48f1 Mon Sep 17 00:00:00 2001 From: mstembera Date: Thu, 3 Apr 2025 19:50:23 -0700 Subject: [PATCH 08/11] Fix fused() all controll paths should return a value. closes https://github.com/official-stockfish/Stockfish/pull/5973 No functional change --- src/nnue/nnue_feature_transformer.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/nnue/nnue_feature_transformer.h b/src/nnue/nnue_feature_transformer.h index d2abd40fa..b9b422a65 100644 --- a/src/nnue/nnue_feature_transformer.h +++ b/src/nnue/nnue_feature_transformer.h @@ -194,6 +194,10 @@ fused(const typename VecWrapper::type& in, const T& operand, const Ts&... operan return fused(VecWrapper::add(in, operand), operands...); case Sub : return fused(VecWrapper::sub(in, operand), operands...); + default : + static_assert(update_op == Add || update_op == Sub, + "Only Add and Sub are currently supported."); + return typename VecWrapper::type(); } } From 5f8e67a544e0427696e2e7f950f221ef0d1c6ed4 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Wed, 2 Apr 2025 19:43:55 +0300 Subject: [PATCH 09/11] Remove combineLast3 optimization Passed non-reg STC 1st: LLR: 2.96 (-2.94,2.94) <-1.75,0.25> Total: 67328 W: 17296 L: 17118 D: 32914 Ptnml(0-2): 158, 7095, 19011, 7211, 189 https://tests.stockfishchess.org/tests/view/67e6c2796682f97da2178ebe Passed non-reg STC 2nd: LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 92288 W: 23885 L: 23734 D: 44669 Ptnml(0-2): 213, 10039, 25518, 10132, 242 https://tests.stockfishchess.org/tests/view/67ed6a2d31d7cf8afdc45190 closes https://github.com/official-stockfish/Stockfish/pull/5975 Bench: 1875196 --- src/nnue/nnue_accumulator.cpp | 63 ++++++++--------------------------- 1 file changed, 13 insertions(+), 50 deletions(-) diff --git a/src/nnue/nnue_accumulator.cpp b/src/nnue/nnue_accumulator.cpp index 8b2585b91..2153cd4a6 100644 --- a/src/nnue/nnue_accumulator.cpp +++ b/src/nnue/nnue_accumulator.cpp @@ -356,8 +356,6 @@ void update_accumulator_refresh_cache(const FeatureTransformer& feat accumulator.computed[Perspective] = true; #ifdef VECTOR - const bool combineLast3 = - std::abs((int) removed.size() - (int) added.size()) == 1 && removed.size() + added.size() > 2; vec_t acc[Tiling::NumRegs]; psqt_vec_t psqt[Tiling::NumPsqtRegs]; @@ -371,7 +369,7 @@ void update_accumulator_refresh_cache(const FeatureTransformer& feat acc[k] = entryTile[k]; IndexType i = 0; - for (; i < std::min(removed.size(), added.size()) - combineLast3; ++i) + for (; i < std::min(removed.size(), added.size()); ++i) { IndexType indexR = removed[i]; const IndexType offsetR = Dimensions * indexR + j * Tiling::TileHeight; @@ -383,58 +381,23 @@ void update_accumulator_refresh_cache(const FeatureTransformer& feat for (IndexType k = 0; k < Tiling::NumRegs; ++k) acc[k] = fused(acc[k], columnA[k], columnR[k]); } - if (combineLast3) + for (; i < removed.size(); ++i) { - IndexType indexR = removed[i]; - const IndexType offsetR = Dimensions * indexR + j * Tiling::TileHeight; - auto* columnR = reinterpret_cast(&featureTransformer.weights[offsetR]); - IndexType indexA = added[i]; - const IndexType offsetA = Dimensions * indexA + j * Tiling::TileHeight; - auto* columnA = reinterpret_cast(&featureTransformer.weights[offsetA]); + IndexType index = removed[i]; + const IndexType offset = Dimensions * index + j * Tiling::TileHeight; + auto* column = reinterpret_cast(&featureTransformer.weights[offset]); - if (removed.size() > added.size()) - { - IndexType indexR2 = removed[i + 1]; - const IndexType offsetR2 = Dimensions * indexR2 + j * Tiling::TileHeight; - auto* columnR2 = - reinterpret_cast(&featureTransformer.weights[offsetR2]); - - for (IndexType k = 0; k < Tiling::NumRegs; ++k) - acc[k] = fused(acc[k], columnA[k], columnR[k], - columnR2[k]); - } - else - { - IndexType indexA2 = added[i + 1]; - const IndexType offsetA2 = Dimensions * indexA2 + j * Tiling::TileHeight; - auto* columnA2 = - reinterpret_cast(&featureTransformer.weights[offsetA2]); - - for (IndexType k = 0; k < Tiling::NumRegs; ++k) - acc[k] = fused(acc[k], columnA[k], columnA2[k], - columnR[k]); - } + for (IndexType k = 0; k < Tiling::NumRegs; ++k) + acc[k] = vec_sub_16(acc[k], column[k]); } - else + for (; i < added.size(); ++i) { - for (; i < removed.size(); ++i) - { - IndexType index = removed[i]; - const IndexType offset = Dimensions * index + j * Tiling::TileHeight; - auto* column = reinterpret_cast(&featureTransformer.weights[offset]); + IndexType index = added[i]; + const IndexType offset = Dimensions * index + j * Tiling::TileHeight; + auto* column = reinterpret_cast(&featureTransformer.weights[offset]); - for (IndexType k = 0; k < Tiling::NumRegs; ++k) - acc[k] = vec_sub_16(acc[k], column[k]); - } - for (; i < added.size(); ++i) - { - IndexType index = added[i]; - const IndexType offset = Dimensions * index + j * Tiling::TileHeight; - auto* column = reinterpret_cast(&featureTransformer.weights[offset]); - - for (IndexType k = 0; k < Tiling::NumRegs; ++k) - acc[k] = vec_add_16(acc[k], column[k]); - } + for (IndexType k = 0; k < Tiling::NumRegs; ++k) + acc[k] = vec_add_16(acc[k], column[k]); } for (IndexType k = 0; k < Tiling::NumRegs; k++) From 904a016396013cacdf36d9c7fe4c562a330b33b4 Mon Sep 17 00:00:00 2001 From: Daniel Monroe Date: Fri, 28 Mar 2025 12:38:59 -0400 Subject: [PATCH 10/11] Don't use 5th continuation history in move ordering Passed simplification STC LLR: 2.96 (-2.94,2.94) <-1.75,0.25> Total: 136960 W: 35374 L: 35262 D: 66324 Ptnml(0-2): 420, 16214, 35049, 16428, 369 https://tests.stockfishchess.org/tests/view/67e6d0ae6682f97da2178ee5 Passed simplification LTC LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 233016 W: 59063 L: 59059 D: 114894 Ptnml(0-2): 113, 25430, 65421, 25428, 116 https://tests.stockfishchess.org/tests/view/67e9f7fb31d7cf8afdc44ad4 closes https://github.com/official-stockfish/Stockfish/pull/5978 Bench: 1842721 --- src/movepick.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/movepick.cpp b/src/movepick.cpp index 6ee5fad7c..11317f113 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -162,7 +162,6 @@ void MovePicker::score() { m.value += (*continuationHistory[1])[pc][to]; m.value += (*continuationHistory[2])[pc][to]; m.value += (*continuationHistory[3])[pc][to]; - m.value += (*continuationHistory[4])[pc][to] / 3; m.value += (*continuationHistory[5])[pc][to]; // bonus for checks From 44efbaddea909e146c6c41afaf458da8c9e4b4e4 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Sat, 5 Apr 2025 14:23:33 +0300 Subject: [PATCH 11/11] Simplify bonusScale calculation Allowing this specific term to potentially become negative for low depth values is ok, because the overall `bonusScale` is explicitly ensured to be non-negative a few lines later: bonusScale = std::max(bonusScale, 0); Passed STC: LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 164928 W: 42446 L: 42368 D: 80114 Ptnml(0-2): 497, 19551, 42306, 19597, 513 https://tests.stockfishchess.org/tests/view/67debf0b8888403457d8736c Passed LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 234942 W: 59539 L: 59537 D: 115866 Ptnml(0-2): 113, 25639, 65964, 25643, 112 https://tests.stockfishchess.org/tests/view/67e2e1c48888403457d87768 closes https://github.com/official-stockfish/Stockfish/pull/5979 Bench: 1933843 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 7b8fbb144..7efd8499f 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1446,7 +1446,7 @@ moves_loop: // When in check, search starts here else if (!priorCapture && prevSq != SQ_NONE) { int bonusScale = - (std::clamp(80 * depth - 320, 0, 200) + 34 * !allNode + 164 * ((ss - 1)->moveCount > 8) + (std::min(78 * depth - 312, 194) + 34 * !allNode + 164 * ((ss - 1)->moveCount > 8) + 141 * (!ss->inCheck && bestValue <= ss->staticEval - 100) + 121 * (!(ss - 1)->inCheck && bestValue <= -(ss - 1)->staticEval - 75) + 86 * ((ss - 1)->isTTMove) + 86 * (ss->cutoffCnt <= 3)