Merge commit '44efbaddea909e146c6c41afaf458da8c9e4b4e4' into cluster

This is the last commit before there are more conflicts.
This commit is contained in:
Steinar H. Gunderson
2025-12-25 20:03:12 +01:00
10 changed files with 170 additions and 244 deletions
+2 -1
View File
@@ -20,6 +20,7 @@ Alexander Kure
Alexander Pagel (Lolligerhans) Alexander Pagel (Lolligerhans)
Alfredo Menezes (lonfom169) Alfredo Menezes (lonfom169)
Ali AlZhrani (Cooffe) Ali AlZhrani (Cooffe)
AliceRoselia
Andreas Jan van der Meulen (Andyson007) Andreas Jan van der Meulen (Andyson007)
Andreas Matthies (Matthies) Andreas Matthies (Matthies)
Andrei Vetrov (proukornew) Andrei Vetrov (proukornew)
@@ -57,8 +58,8 @@ Dale Weiler (graphitemaster)
Daniel Axtens (daxtens) Daniel Axtens (daxtens)
Daniel Dugovic (ddugovic) Daniel Dugovic (ddugovic)
Daniel Monroe (Ergodice) Daniel Monroe (Ergodice)
Daniel Samek (DanSamek)
Dan Schmidt (dfannius) Dan Schmidt (dfannius)
DanSamek
Dariusz Orzechowski (dorzechowski) Dariusz Orzechowski (dorzechowski)
David (dav1312) David (dav1312)
David Zar David Zar
-1
View File
@@ -162,7 +162,6 @@ void MovePicker::score() {
m.value += (*continuationHistory[1])[pc][to]; m.value += (*continuationHistory[1])[pc][to];
m.value += (*continuationHistory[2])[pc][to]; m.value += (*continuationHistory[2])[pc][to];
m.value += (*continuationHistory[3])[pc][to]; m.value += (*continuationHistory[3])[pc][to];
m.value += (*continuationHistory[4])[pc][to] / 3;
m.value += (*continuationHistory[5])[pc][to]; m.value += (*continuationHistory[5])[pc][to];
// bonus for checks // bonus for checks
+10 -12
View File
@@ -220,13 +220,13 @@ Network<Arch, Transformer>::evaluate(const Position& pos
#if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN) #if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN)
TransformedFeatureType TransformedFeatureType
transformedFeaturesUnaligned[FeatureTransformer<FTDimensions, nullptr>::BufferSize transformedFeaturesUnaligned[FeatureTransformer<FTDimensions>::BufferSize
+ alignment / sizeof(TransformedFeatureType)]; + alignment / sizeof(TransformedFeatureType)];
auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]); auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]);
#else #else
alignas(alignment) TransformedFeatureType alignas(alignment)
transformedFeatures[FeatureTransformer<FTDimensions, nullptr>::BufferSize]; TransformedFeatureType transformedFeatures[FeatureTransformer<FTDimensions>::BufferSize];
#endif #endif
ASSERT_ALIGNED(transformedFeatures, alignment); ASSERT_ALIGNED(transformedFeatures, alignment);
@@ -292,13 +292,13 @@ Network<Arch, Transformer>::trace_evaluate(const Position&
#if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN) #if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN)
TransformedFeatureType TransformedFeatureType
transformedFeaturesUnaligned[FeatureTransformer<FTDimensions, nullptr>::BufferSize transformedFeaturesUnaligned[FeatureTransformer<FTDimensions>::BufferSize
+ alignment / sizeof(TransformedFeatureType)]; + alignment / sizeof(TransformedFeatureType)];
auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]); auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]);
#else #else
alignas(alignment) TransformedFeatureType alignas(alignment)
transformedFeatures[FeatureTransformer<FTDimensions, nullptr>::BufferSize]; TransformedFeatureType transformedFeatures[FeatureTransformer<FTDimensions>::BufferSize];
#endif #endif
ASSERT_ALIGNED(transformedFeatures, alignment); ASSERT_ALIGNED(transformedFeatures, alignment);
@@ -454,12 +454,10 @@ bool Network<Arch, Transformer>::write_parameters(std::ostream& stream,
// Explicit template instantiations // Explicit template instantiations
template class Network< template class Network<NetworkArchitecture<TransformedFeatureDimensionsBig, L2Big, L3Big>,
NetworkArchitecture<TransformedFeatureDimensionsBig, L2Big, L3Big>, FeatureTransformer<TransformedFeatureDimensionsBig>>;
FeatureTransformer<TransformedFeatureDimensionsBig, &AccumulatorState::accumulatorBig>>;
template class Network< template class Network<NetworkArchitecture<TransformedFeatureDimensionsSmall, L2Small, L3Small>,
NetworkArchitecture<TransformedFeatureDimensionsSmall, L2Small, L3Small>, FeatureTransformer<TransformedFeatureDimensionsSmall>>;
FeatureTransformer<TransformedFeatureDimensionsSmall, &AccumulatorState::accumulatorSmall>>;
} // namespace Stockfish::Eval::NNUE } // namespace Stockfish::Eval::NNUE
+2 -4
View File
@@ -110,13 +110,11 @@ class Network {
}; };
// Definitions of the network types // Definitions of the network types
using SmallFeatureTransformer = using SmallFeatureTransformer = FeatureTransformer<TransformedFeatureDimensionsSmall>;
FeatureTransformer<TransformedFeatureDimensionsSmall, &AccumulatorState::accumulatorSmall>;
using SmallNetworkArchitecture = using SmallNetworkArchitecture =
NetworkArchitecture<TransformedFeatureDimensionsSmall, L2Small, L3Small>; NetworkArchitecture<TransformedFeatureDimensionsSmall, L2Small, L3Small>;
using BigFeatureTransformer = using BigFeatureTransformer = FeatureTransformer<TransformedFeatureDimensionsBig>;
FeatureTransformer<TransformedFeatureDimensionsBig, &AccumulatorState::accumulatorBig>;
using BigNetworkArchitecture = NetworkArchitecture<TransformedFeatureDimensionsBig, L2Big, L3Big>; using BigNetworkArchitecture = NetworkArchitecture<TransformedFeatureDimensionsBig, L2Big, L3Big>;
using NetworkBig = Network<BigNetworkArchitecture, BigFeatureTransformer>; using NetworkBig = Network<BigNetworkArchitecture, BigFeatureTransformer>;
+102 -181
View File
@@ -29,7 +29,6 @@
#include "../types.h" #include "../types.h"
#include "network.h" #include "network.h"
#include "nnue_architecture.h" #include "nnue_architecture.h"
#include "nnue_common.h"
#include "nnue_feature_transformer.h" #include "nnue_feature_transformer.h"
namespace Stockfish::Eval::NNUE { namespace Stockfish::Eval::NNUE {
@@ -48,24 +47,18 @@ namespace Stockfish::Eval::NNUE {
namespace { namespace {
template<Color Perspective, template<Color Perspective, bool Forward, IndexType TransformedFeatureDimensions>
IncUpdateDirection Direction = FORWARD,
IndexType TransformedFeatureDimensions,
Accumulator<TransformedFeatureDimensions> AccumulatorState::* accPtr>
void update_accumulator_incremental( void update_accumulator_incremental(
const FeatureTransformer<TransformedFeatureDimensions, accPtr>& featureTransformer, const FeatureTransformer<TransformedFeatureDimensions>& featureTransformer,
const Square ksq, const Square ksq,
AccumulatorState& target_state, AccumulatorState& target_state,
const AccumulatorState& computed); const AccumulatorState& computed);
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions, void update_accumulator_refresh_cache(const FeatureTransformer<Dimensions>& featureTransformer,
Accumulator<Dimensions> AccumulatorState::* accPtr> const Position& pos,
void update_accumulator_refresh_cache( AccumulatorState& accumulatorState,
const FeatureTransformer<Dimensions, accPtr>& featureTransformer, AccumulatorCaches::Cache<Dimensions>& cache);
const Position& pos,
AccumulatorState& accumulatorState,
AccumulatorCaches::Cache<Dimensions>& cache);
} }
@@ -88,18 +81,14 @@ void AccumulatorStack::reset(const Position& rootPos,
AccumulatorCaches& caches) noexcept { AccumulatorCaches& caches) noexcept {
m_current_idx = 1; m_current_idx = 1;
update_accumulator_refresh_cache<WHITE, TransformedFeatureDimensionsBig, update_accumulator_refresh_cache<WHITE, TransformedFeatureDimensionsBig>(
&AccumulatorState::accumulatorBig>(
*networks.big.featureTransformer, rootPos, m_accumulators[0], caches.big); *networks.big.featureTransformer, rootPos, m_accumulators[0], caches.big);
update_accumulator_refresh_cache<BLACK, TransformedFeatureDimensionsBig, update_accumulator_refresh_cache<BLACK, TransformedFeatureDimensionsBig>(
&AccumulatorState::accumulatorBig>(
*networks.big.featureTransformer, rootPos, m_accumulators[0], caches.big); *networks.big.featureTransformer, rootPos, m_accumulators[0], caches.big);
update_accumulator_refresh_cache<WHITE, TransformedFeatureDimensionsSmall, update_accumulator_refresh_cache<WHITE, TransformedFeatureDimensionsSmall>(
&AccumulatorState::accumulatorSmall>(
*networks.small.featureTransformer, rootPos, m_accumulators[0], caches.small); *networks.small.featureTransformer, rootPos, m_accumulators[0], caches.small);
update_accumulator_refresh_cache<BLACK, TransformedFeatureDimensionsSmall, update_accumulator_refresh_cache<BLACK, TransformedFeatureDimensionsSmall>(
&AccumulatorState::accumulatorSmall>(
*networks.small.featureTransformer, rootPos, m_accumulators[0], caches.small); *networks.small.featureTransformer, rootPos, m_accumulators[0], caches.small);
} }
@@ -114,26 +103,23 @@ void AccumulatorStack::pop() noexcept {
m_current_idx--; m_current_idx--;
} }
template<IndexType Dimensions, Accumulator<Dimensions> AccumulatorState::* accPtr> template<IndexType Dimensions>
void AccumulatorStack::evaluate(const Position& pos, void AccumulatorStack::evaluate(const Position& pos,
const FeatureTransformer<Dimensions, accPtr>& featureTransformer, const FeatureTransformer<Dimensions>& featureTransformer,
AccumulatorCaches::Cache<Dimensions>& cache) noexcept { AccumulatorCaches::Cache<Dimensions>& cache) noexcept {
evaluate_side<WHITE>(pos, featureTransformer, cache); evaluate_side<WHITE>(pos, featureTransformer, cache);
evaluate_side<BLACK>(pos, featureTransformer, cache); evaluate_side<BLACK>(pos, featureTransformer, cache);
} }
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions, void AccumulatorStack::evaluate_side(const Position& pos,
Accumulator<Dimensions> AccumulatorState::* accPtr> const FeatureTransformer<Dimensions>& featureTransformer,
void AccumulatorStack::evaluate_side( AccumulatorCaches::Cache<Dimensions>& cache) noexcept {
const Position& pos,
const FeatureTransformer<Dimensions, accPtr>& featureTransformer,
AccumulatorCaches::Cache<Dimensions>& cache) noexcept {
const auto last_usable_accum = find_last_usable_accumulator<Perspective, Dimensions, accPtr>(); const auto last_usable_accum = find_last_usable_accumulator<Perspective, Dimensions>();
if ((m_accumulators[last_usable_accum].*accPtr).computed[Perspective]) if ((m_accumulators[last_usable_accum].template acc<Dimensions>()).computed[Perspective])
forward_update_incremental<Perspective>(pos, featureTransformer, last_usable_accum); forward_update_incremental<Perspective>(pos, featureTransformer, last_usable_accum);
else else
@@ -145,14 +131,12 @@ void AccumulatorStack::evaluate_side(
// Find the earliest usable accumulator, this can either be a computed accumulator or the accumulator // Find the earliest usable accumulator, this can either be a computed accumulator or the accumulator
// state just before a change that requires full refresh. // state just before a change that requires full refresh.
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions,
Accumulator<Dimensions> AccumulatorState::* accPtr>
std::size_t AccumulatorStack::find_last_usable_accumulator() const noexcept { 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--) 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<Dimensions>()).computed[Perspective])
return curr_idx; return curr_idx;
if (FeatureSet::requires_refresh(m_accumulators[curr_idx].dirtyPiece, Perspective)) if (FeatureSet::requires_refresh(m_accumulators[curr_idx].dirtyPiece, Perspective))
@@ -162,59 +146,51 @@ std::size_t AccumulatorStack::find_last_usable_accumulator() const noexcept {
return 0; return 0;
} }
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions,
Accumulator<Dimensions> AccumulatorState::* accPtr>
void AccumulatorStack::forward_update_incremental( void AccumulatorStack::forward_update_incremental(
const Position& pos, const Position& pos,
const FeatureTransformer<Dimensions, accPtr>& featureTransformer, const FeatureTransformer<Dimensions>& featureTransformer,
const std::size_t begin) noexcept { const std::size_t begin) noexcept {
assert(begin < m_accumulators.size()); assert(begin < m_accumulators.size());
assert((m_accumulators[begin].*accPtr).computed[Perspective]); assert((m_accumulators[begin].acc<Dimensions>()).computed[Perspective]);
const Square ksq = pos.square<KING>(Perspective); const Square ksq = pos.square<KING>(Perspective);
for (std::size_t next = begin + 1; next < m_current_idx; next++) for (std::size_t next = begin + 1; next < m_current_idx; next++)
update_accumulator_incremental<Perspective>(featureTransformer, ksq, m_accumulators[next], update_accumulator_incremental<Perspective, true>(
m_accumulators[next - 1]); featureTransformer, ksq, m_accumulators[next], m_accumulators[next - 1]);
assert((latest().*accPtr).computed[Perspective]); assert((latest().acc<Dimensions>()).computed[Perspective]);
} }
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions,
Accumulator<Dimensions> AccumulatorState::* accPtr>
void AccumulatorStack::backward_update_incremental( void AccumulatorStack::backward_update_incremental(
const Position& pos, const Position& pos,
const FeatureTransformer<Dimensions, accPtr>& featureTransformer, const FeatureTransformer<Dimensions>& featureTransformer,
const std::size_t end) noexcept { const std::size_t end) noexcept {
assert(end < m_accumulators.size()); assert(end < m_accumulators.size());
assert(end < m_current_idx); assert(end < m_current_idx);
assert((latest().*accPtr).computed[Perspective]); assert((latest().acc<Dimensions>()).computed[Perspective]);
const Square ksq = pos.square<KING>(Perspective); const Square ksq = pos.square<KING>(Perspective);
for (std::size_t next = m_current_idx - 2; next >= end; next--) for (std::size_t next = m_current_idx - 2; next >= end; next--)
update_accumulator_incremental<Perspective, BACKWARD>( update_accumulator_incremental<Perspective, false>(
featureTransformer, ksq, m_accumulators[next], m_accumulators[next + 1]); featureTransformer, ksq, m_accumulators[next], m_accumulators[next + 1]);
assert((m_accumulators[end].*accPtr).computed[Perspective]); assert((m_accumulators[end].acc<Dimensions>()).computed[Perspective]);
} }
// Explicit template instantiations // Explicit template instantiations
template void template void AccumulatorStack::evaluate<TransformedFeatureDimensionsBig>(
AccumulatorStack::evaluate<TransformedFeatureDimensionsBig, &AccumulatorState::accumulatorBig>( const Position& pos,
const Position& pos, const FeatureTransformer<TransformedFeatureDimensionsBig>& featureTransformer,
const FeatureTransformer<TransformedFeatureDimensionsBig, &AccumulatorState::accumulatorBig>&
featureTransformer,
AccumulatorCaches::Cache<TransformedFeatureDimensionsBig>& cache) noexcept; AccumulatorCaches::Cache<TransformedFeatureDimensionsBig>& cache) noexcept;
template void template void AccumulatorStack::evaluate<TransformedFeatureDimensionsSmall>(
AccumulatorStack::evaluate<TransformedFeatureDimensionsSmall, &AccumulatorState::accumulatorSmall>( const Position& pos,
const Position& pos, const FeatureTransformer<TransformedFeatureDimensionsSmall>& featureTransformer,
const FeatureTransformer<TransformedFeatureDimensionsSmall, &AccumulatorState::accumulatorSmall>&
featureTransformer,
AccumulatorCaches::Cache<TransformedFeatureDimensionsSmall>& cache) noexcept; AccumulatorCaches::Cache<TransformedFeatureDimensionsSmall>& cache) noexcept;
@@ -237,17 +213,15 @@ void fused_row_reduce(const ElementType* in, ElementType* out, const Ts* const..
vecIn[i], reinterpret_cast<const typename VectorWrapper::type*>(rows)[i]...); vecIn[i], reinterpret_cast<const typename VectorWrapper::type*>(rows)[i]...);
} }
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions,
Accumulator<Dimensions> AccumulatorState::* accPtr>
struct AccumulatorUpdateContext { struct AccumulatorUpdateContext {
const FeatureTransformer<Dimensions, accPtr>& featureTransformer; const FeatureTransformer<Dimensions>& featureTransformer;
const AccumulatorState& from; const AccumulatorState& from;
AccumulatorState& to; AccumulatorState& to;
AccumulatorUpdateContext(const FeatureTransformer<Dimensions, accPtr>& ft, AccumulatorUpdateContext(const FeatureTransformer<Dimensions>& ft,
const AccumulatorState& accF, const AccumulatorState& accF,
AccumulatorState& accT) noexcept : AccumulatorState& accT) noexcept :
featureTransformer{ft}, featureTransformer{ft},
from{accF}, from{accF},
to{accT} {} to{accT} {}
@@ -264,43 +238,33 @@ struct AccumulatorUpdateContext {
return &featureTransformer.psqtWeights[index * PSQTBuckets]; return &featureTransformer.psqtWeights[index * PSQTBuckets];
}; };
fused_row_reduce<Vec16Wrapper, Dimensions, ops...>((from.*accPtr).accumulation[Perspective], fused_row_reduce<Vec16Wrapper, Dimensions, ops...>(
(to.*accPtr).accumulation[Perspective], (from.acc<Dimensions>()).accumulation[Perspective],
to_weight_vector(indices)...); (to.acc<Dimensions>()).accumulation[Perspective], to_weight_vector(indices)...);
fused_row_reduce<Vec32Wrapper, PSQTBuckets, ops...>( fused_row_reduce<Vec32Wrapper, PSQTBuckets, ops...>(
(from.*accPtr).psqtAccumulation[Perspective], (to.*accPtr).psqtAccumulation[Perspective], (from.acc<Dimensions>()).psqtAccumulation[Perspective],
to_psqt_weight_vector(indices)...); (to.acc<Dimensions>()).psqtAccumulation[Perspective], to_psqt_weight_vector(indices)...);
} }
}; };
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions, auto make_accumulator_update_context(const FeatureTransformer<Dimensions>& featureTransformer,
Accumulator<Dimensions> AccumulatorState::* accPtr> const AccumulatorState& accumulatorFrom,
auto make_accumulator_update_context( AccumulatorState& accumulatorTo) noexcept {
const FeatureTransformer<Dimensions, accPtr>& featureTransformer, return AccumulatorUpdateContext<Perspective, Dimensions>{featureTransformer, accumulatorFrom,
const AccumulatorState& accumulatorFrom, accumulatorTo};
AccumulatorState& accumulatorTo) noexcept {
return AccumulatorUpdateContext<Perspective, Dimensions, accPtr>{
featureTransformer, accumulatorFrom, accumulatorTo};
} }
template<Color Perspective, template<Color Perspective, bool Forward, IndexType TransformedFeatureDimensions>
IncUpdateDirection Direction,
IndexType TransformedFeatureDimensions,
Accumulator<TransformedFeatureDimensions> AccumulatorState::* accPtr>
void update_accumulator_incremental( void update_accumulator_incremental(
const FeatureTransformer<TransformedFeatureDimensions, accPtr>& featureTransformer, const FeatureTransformer<TransformedFeatureDimensions>& featureTransformer,
const Square ksq, const Square ksq,
AccumulatorState& target_state, AccumulatorState& target_state,
const AccumulatorState& computed) { const AccumulatorState& computed) {
[[maybe_unused]] constexpr bool Forward = Direction == FORWARD;
[[maybe_unused]] constexpr bool Backward = Direction == BACKWARD;
assert(Forward != Backward); assert((computed.acc<TransformedFeatureDimensions>()).computed[Perspective]);
assert(!(target_state.acc<TransformedFeatureDimensions>()).computed[Perspective]);
assert((computed.*accPtr).computed[Perspective]);
assert(!(target_state.*accPtr).computed[Perspective]);
// The size must be enough to contain the largest possible update. // The size must be enough to contain the largest possible update.
// That might depend on the feature set and generally relies on the // That might depend on the feature set and generally relies on the
@@ -317,11 +281,8 @@ void update_accumulator_incremental(
assert(added.size() == 1 || added.size() == 2); assert(added.size() == 1 || added.size() == 2);
assert(removed.size() == 1 || removed.size() == 2); assert(removed.size() == 1 || removed.size() == 2);
assert((Forward && added.size() <= removed.size())
if (Forward) || (!Forward && added.size() >= removed.size()));
assert(added.size() <= removed.size());
else
assert(removed.size() <= added.size());
// Workaround compiler warning for uninitialized variables, replicated on // Workaround compiler warning for uninitialized variables, replicated on
// profile builds on windows with gcc 14.2.0. // profile builds on windows with gcc 14.2.0.
@@ -332,7 +293,7 @@ void update_accumulator_incremental(
auto updateContext = auto updateContext =
make_accumulator_update_context<Perspective>(featureTransformer, computed, target_state); make_accumulator_update_context<Perspective>(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); assert(added.size() == 1 && removed.size() == 1);
updateContext.template apply<Add, Sub>(added[0], removed[0]); updateContext.template apply<Add, Sub>(added[0], removed[0]);
@@ -342,7 +303,7 @@ void update_accumulator_incremental(
assert(removed.size() == 2); assert(removed.size() == 2);
updateContext.template apply<Add, Sub, Sub>(added[0], removed[0], removed[1]); updateContext.template apply<Add, Sub, Sub>(added[0], removed[0], removed[1]);
} }
else if (Backward && removed.size() == 1) else if (!Forward && removed.size() == 1)
{ {
assert(added.size() == 2); assert(added.size() == 2);
updateContext.template apply<Add, Add, Sub>(added[0], added[1], removed[0]); updateContext.template apply<Add, Add, Sub>(added[0], added[1], removed[0]);
@@ -354,17 +315,14 @@ void update_accumulator_incremental(
removed[1]); removed[1]);
} }
(target_state.*accPtr).computed[Perspective] = true; (target_state.acc<TransformedFeatureDimensions>()).computed[Perspective] = true;
} }
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions, void update_accumulator_refresh_cache(const FeatureTransformer<Dimensions>& featureTransformer,
Accumulator<Dimensions> AccumulatorState::* accPtr> const Position& pos,
void update_accumulator_refresh_cache( AccumulatorState& accumulatorState,
const FeatureTransformer<Dimensions, accPtr>& featureTransformer, AccumulatorCaches::Cache<Dimensions>& cache) {
const Position& pos,
AccumulatorState& accumulatorState,
AccumulatorCaches::Cache<Dimensions>& cache) {
using Tiling [[maybe_unused]] = SIMDTiling<Dimensions, Dimensions>; using Tiling [[maybe_unused]] = SIMDTiling<Dimensions, Dimensions>;
const Square ksq = pos.square<KING>(Perspective); const Square ksq = pos.square<KING>(Perspective);
@@ -394,12 +352,10 @@ void update_accumulator_refresh_cache(
} }
} }
auto& accumulator = accumulatorState.*accPtr; auto& accumulator = accumulatorState.acc<Dimensions>();
accumulator.computed[Perspective] = true; accumulator.computed[Perspective] = true;
#ifdef VECTOR #ifdef VECTOR
const bool combineLast3 =
std::abs((int) removed.size() - (int) added.size()) == 1 && removed.size() + added.size() > 2;
vec_t acc[Tiling::NumRegs]; vec_t acc[Tiling::NumRegs];
psqt_vec_t psqt[Tiling::NumPsqtRegs]; psqt_vec_t psqt[Tiling::NumPsqtRegs];
@@ -412,8 +368,8 @@ void update_accumulator_refresh_cache(
for (IndexType k = 0; k < Tiling::NumRegs; ++k) for (IndexType k = 0; k < Tiling::NumRegs; ++k)
acc[k] = entryTile[k]; acc[k] = entryTile[k];
std::size_t i = 0; 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]; IndexType indexR = removed[i];
const IndexType offsetR = Dimensions * indexR + j * Tiling::TileHeight; const IndexType offsetR = Dimensions * indexR + j * Tiling::TileHeight;
@@ -425,58 +381,23 @@ void update_accumulator_refresh_cache(
for (IndexType k = 0; k < Tiling::NumRegs; ++k) for (IndexType k = 0; k < Tiling::NumRegs; ++k)
acc[k] = fused<Vec16Wrapper, Add, Sub>(acc[k], columnA[k], columnR[k]); acc[k] = fused<Vec16Wrapper, Add, Sub>(acc[k], columnA[k], columnR[k]);
} }
if (combineLast3) for (; i < removed.size(); ++i)
{ {
IndexType indexR = removed[i]; IndexType index = removed[i];
const IndexType offsetR = Dimensions * indexR + j * Tiling::TileHeight; const IndexType offset = Dimensions * index + j * Tiling::TileHeight;
auto* columnR = reinterpret_cast<const vec_t*>(&featureTransformer.weights[offsetR]); auto* column = reinterpret_cast<const vec_t*>(&featureTransformer.weights[offset]);
IndexType indexA = added[i];
const IndexType offsetA = Dimensions * indexA + j * Tiling::TileHeight;
auto* columnA = reinterpret_cast<const vec_t*>(&featureTransformer.weights[offsetA]);
if (removed.size() > added.size()) for (IndexType k = 0; k < Tiling::NumRegs; ++k)
{ acc[k] = vec_sub_16(acc[k], column[k]);
IndexType indexR2 = removed[i + 1];
const IndexType offsetR2 = Dimensions * indexR2 + j * Tiling::TileHeight;
auto* columnR2 =
reinterpret_cast<const vec_t*>(&featureTransformer.weights[offsetR2]);
for (IndexType k = 0; k < Tiling::NumRegs; ++k)
acc[k] = fused<Vec16Wrapper, Add, Sub, Sub>(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<const vec_t*>(&featureTransformer.weights[offsetA2]);
for (IndexType k = 0; k < Tiling::NumRegs; ++k)
acc[k] = fused<Vec16Wrapper, Add, Add, Sub>(acc[k], columnA[k], columnA2[k],
columnR[k]);
}
} }
else for (; i < added.size(); ++i)
{ {
for (; i < removed.size(); ++i) IndexType index = added[i];
{ const IndexType offset = Dimensions * index + j * Tiling::TileHeight;
IndexType index = removed[i]; auto* column = reinterpret_cast<const vec_t*>(&featureTransformer.weights[offset]);
const IndexType offset = Dimensions * index + j * Tiling::TileHeight;
auto* column = reinterpret_cast<const vec_t*>(&featureTransformer.weights[offset]);
for (IndexType k = 0; k < Tiling::NumRegs; ++k) for (IndexType k = 0; k < Tiling::NumRegs; ++k)
acc[k] = vec_sub_16(acc[k], column[k]); acc[k] = vec_add_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<const vec_t*>(&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++) for (IndexType k = 0; k < Tiling::NumRegs; k++)
@@ -492,10 +413,10 @@ void update_accumulator_refresh_cache(
auto* entryTilePsqt = auto* entryTilePsqt =
reinterpret_cast<psqt_vec_t*>(&entry.psqtAccumulation[j * Tiling::PsqtTileHeight]); reinterpret_cast<psqt_vec_t*>(&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]; 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]; IndexType index = removed[i];
const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight; const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
@@ -505,7 +426,7 @@ void update_accumulator_refresh_cache(
for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k) for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k)
psqt[k] = vec_sub_psqt_32(psqt[k], columnPsqt[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]; IndexType index = added[i];
const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight; const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
@@ -516,9 +437,9 @@ void update_accumulator_refresh_cache(
psqt[k] = vec_add_psqt_32(psqt[k], columnPsqt[k]); 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]); 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]); vec_store_psqt(&accTilePsqt[k], psqt[k]);
} }
+42 -31
View File
@@ -46,10 +46,7 @@ struct Networks;
template<IndexType Size> template<IndexType Size>
struct alignas(CacheLineSize) Accumulator; struct alignas(CacheLineSize) Accumulator;
struct AccumulatorState; template<IndexType TransformedFeatureDimensions>
template<IndexType TransformedFeatureDimensions,
Accumulator<TransformedFeatureDimensions> AccumulatorState::* accPtr>
class FeatureTransformer; class FeatureTransformer;
// Class that holds the result of affine transformation of input features // Class that holds the result of affine transformation of input features
@@ -121,6 +118,30 @@ struct AccumulatorState {
Accumulator<TransformedFeatureDimensionsSmall> accumulatorSmall; Accumulator<TransformedFeatureDimensionsSmall> accumulatorSmall;
DirtyPiece dirtyPiece; DirtyPiece dirtyPiece;
template<IndexType Size>
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<IndexType Size>
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; void reset(const DirtyPiece& dp) noexcept;
}; };
@@ -138,41 +159,31 @@ class AccumulatorStack {
void push(const DirtyPiece& dirtyPiece) noexcept; void push(const DirtyPiece& dirtyPiece) noexcept;
void pop() noexcept; void pop() noexcept;
template<IndexType Dimensions, Accumulator<Dimensions> AccumulatorState::* accPtr> template<IndexType Dimensions>
void evaluate(const Position& pos, void evaluate(const Position& pos,
const FeatureTransformer<Dimensions, accPtr>& featureTransformer, const FeatureTransformer<Dimensions>& featureTransformer,
AccumulatorCaches::Cache<Dimensions>& cache) noexcept; AccumulatorCaches::Cache<Dimensions>& cache) noexcept;
private: private:
[[nodiscard]] AccumulatorState& mut_latest() noexcept; [[nodiscard]] AccumulatorState& mut_latest() noexcept;
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions, void evaluate_side(const Position& pos,
Accumulator<Dimensions> AccumulatorState::* accPtr> const FeatureTransformer<Dimensions>& featureTransformer,
void evaluate_side(const Position& pos, AccumulatorCaches::Cache<Dimensions>& cache) noexcept;
const FeatureTransformer<Dimensions, accPtr>& featureTransformer,
AccumulatorCaches::Cache<Dimensions>& cache) noexcept;
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions,
Accumulator<Dimensions> AccumulatorState::* accPtr>
[[nodiscard]] std::size_t find_last_usable_accumulator() const noexcept; [[nodiscard]] std::size_t find_last_usable_accumulator() const noexcept;
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions, void forward_update_incremental(const Position& pos,
Accumulator<Dimensions> AccumulatorState::* accPtr> const FeatureTransformer<Dimensions>& featureTransformer,
void const std::size_t begin) noexcept;
forward_update_incremental(const Position& pos,
const FeatureTransformer<Dimensions, accPtr>& featureTransformer,
const std::size_t begin) noexcept;
template<Color Perspective, template<Color Perspective, IndexType Dimensions>
IndexType Dimensions, void backward_update_incremental(const Position& pos,
Accumulator<Dimensions> AccumulatorState::* accPtr> const FeatureTransformer<Dimensions>& featureTransformer,
void const std::size_t end) noexcept;
backward_update_incremental(const Position& pos,
const FeatureTransformer<Dimensions, accPtr>& featureTransformer,
const std::size_t end) noexcept;
std::vector<AccumulatorState> m_accumulators; std::vector<AccumulatorState> m_accumulators;
std::size_t m_current_idx; std::size_t m_current_idx;
-5
View File
@@ -279,11 +279,6 @@ inline void write_leb_128(std::ostream& stream, const IntType* values, std::size
flush(); flush();
} }
enum IncUpdateDirection {
FORWARD,
BACKWARD
};
} // namespace Stockfish::Eval::NNUE } // namespace Stockfish::Eval::NNUE
#endif // #ifndef NNUE_COMMON_H_INCLUDED #endif // #ifndef NNUE_COMMON_H_INCLUDED
+7 -4
View File
@@ -192,6 +192,10 @@ fused(const typename VecWrapper::type& in, const T& operand, const Ts&... operan
return fused<VecWrapper, ops...>(VecWrapper::add(in, operand), operands...); return fused<VecWrapper, ops...>(VecWrapper::add(in, operand), operands...);
case Sub : case Sub :
return fused<VecWrapper, ops...>(VecWrapper::sub(in, operand), operands...); return fused<VecWrapper, ops...>(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();
} }
} }
@@ -292,8 +296,7 @@ class SIMDTiling {
// Input feature converter // Input feature converter
template<IndexType TransformedFeatureDimensions, template<IndexType TransformedFeatureDimensions>
Accumulator<TransformedFeatureDimensions> AccumulatorState::* accPtr>
class FeatureTransformer { class FeatureTransformer {
// Number of output dimensions for one side // Number of output dimensions for one side
@@ -398,12 +401,12 @@ class FeatureTransformer {
const auto& accumulatorState = accumulatorStack.latest(); const auto& accumulatorState = accumulatorStack.latest();
const Color perspectives[2] = {pos.side_to_move(), ~pos.side_to_move()}; const Color perspectives[2] = {pos.side_to_move(), ~pos.side_to_move()};
const auto& psqtAccumulation = (accumulatorState.*accPtr).psqtAccumulation; const auto& psqtAccumulation = (accumulatorState.acc<HalfDimensions>()).psqtAccumulation;
const auto psqt = const auto psqt =
(psqtAccumulation[perspectives[0]][bucket] - psqtAccumulation[perspectives[1]][bucket]) (psqtAccumulation[perspectives[0]][bucket] - psqtAccumulation[perspectives[1]][bucket])
/ 2; / 2;
const auto& accumulation = (accumulatorState.*accPtr).accumulation; const auto& accumulation = (accumulatorState.acc<HalfDimensions>()).accumulation;
for (IndexType p = 0; p < 2; ++p) for (IndexType p = 0; p < 2; ++p)
{ {
+4 -5
View File
@@ -103,9 +103,7 @@ int risk_tolerance(const Position& pos, Value v) {
return 644800 * x / ((x * x + 3 * y * y) * y); return 644800 * x / ((x * x + 3 * y * y) * y);
}; };
int m = (67 * pos.count<PAWN>() + 182 * pos.count<KNIGHT>() + 182 * pos.count<BISHOP>() int m = pos.count<PAWN>() + pos.non_pawn_material() / 300;
+ 337 * pos.count<ROOK>() + 553 * pos.count<QUEEN>())
/ 64;
// a and b are the crude approximation of the wdl model. // a and b are the crude approximation of the wdl model.
// The win rate is: 1/(1+exp((a-v)/b)) // The win rate is: 1/(1+exp((a-v)/b))
@@ -907,7 +905,8 @@ Value Search::Worker::search(
// The depth condition is important for mate finding. // The depth condition is important for mate finding.
if (!ss->ttPv && depth < 14 if (!ss->ttPv && depth < 14
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving, opponentWorsening) && 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 >= beta
&& eval >= beta && (!ttData.move || ttCapture) && !is_loss(beta) && !is_win(eval)) && eval >= beta && (!ttData.move || ttCapture) && !is_loss(beta) && !is_win(eval))
return beta + (eval - beta) / 3; return beta + (eval - beta) / 3;
@@ -1498,7 +1497,7 @@ moves_loop: // When in check, search starts here
else if (!priorCapture && prevSq != SQ_NONE) else if (!priorCapture && prevSq != SQ_NONE)
{ {
int bonusScale = 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) + 141 * (!ss->inCheck && bestValue <= ss->staticEval - 100)
+ 121 * (!(ss - 1)->inCheck && bestValue <= -(ss - 1)->staticEval - 75) + 121 * (!(ss - 1)->inCheck && bestValue <= -(ss - 1)->staticEval - 75)
+ 86 * ((ss - 1)->isTTMove) + 86 * (ss->cutoffCnt <= 3) + 86 * ((ss - 1)->isTTMove) + 86 * (ss->cutoffCnt <= 3)
+1
View File
@@ -37,6 +37,7 @@
// | only in 64-bit mode and requires hardware with pext support. // | only in 64-bit mode and requires hardware with pext support.
#include <cassert> #include <cassert>
#include <cstddef>
#include <cstdint> #include <cstdint>
#include <type_traits> #include <type_traits>