From fb41f2953f453c4bbe03459f8a93c505ff76a2e8 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Tue, 23 Dec 2025 21:27:54 +0100 Subject: [PATCH 01/23] Remove low ply history for check evasions scoring Passed STC: LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 81888 W: 21336 L: 21166 D: 39386 Ptnml(0-2): 284, 9438, 21342, 9584, 296 https://tests.stockfishchess.org/tests/view/692ada47b23dfeae38cffce5 Passed LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 107328 W: 27534 L: 27404 D: 52390 Ptnml(0-2): 55, 11390, 30659, 11490, 70 https://tests.stockfishchess.org/tests/view/692d7a01b23dfeae38d011ab closes https://github.com/official-stockfish/Stockfish/pull/6467 Bench: 3006182 --- src/movepick.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/movepick.cpp b/src/movepick.cpp index 7de11fa1f..d20ab151e 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -184,11 +184,7 @@ ExtMove* MovePicker::score(MoveList& ml) { if (pos.capture_stage(m)) m.value = PieceValue[capturedPiece] + (1 << 28); else - { m.value = (*mainHistory)[us][m.raw()] + (*continuationHistory[0])[pc][to]; - if (ply < LOW_PLY_HISTORY_SIZE) - m.value += (*lowPlyHistory)[ply][m.raw()]; - } } } return it; From 1a67ccc72ef2e3c06e9c905a793a14416d53643f Mon Sep 17 00:00:00 2001 From: anematode Date: Tue, 23 Dec 2025 21:28:15 +0100 Subject: [PATCH 02/23] Share correction history between threads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We did quite a few tests because this is a pretty involved change with unknown scaling behavior, but results are decent. [STC 10+0.1 1th, non-regression](https://tests.stockfishchess.org/tests/live_elo/6941ce3b46f342e1ec210180) ``` LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 83200 W: 21615 L: 21452 D: 40133 Ptnml(0-2): 247, 9064, 22844, 9169, 276 ``` [STC 5+0.05 8th](https://tests.stockfishchess.org/tests/live_elo/693dc38346f342e1ec20f555) ``` LLR: 3.48 (-2.94,2.94) <0.00,2.00> Total: 58536 W: 15067 L: 14688 D: 28781 Ptnml(0-2): 87, 6474, 15781, 6825, 101 ``` [LTC 20+0.2 8th](https://tests.stockfishchess.org/tests/live_elo/693f2afb46f342e1ec20f847) ``` LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 27716 W: 7211 L: 6925 D: 13580 Ptnml(0-2): 8, 2674, 8207, 2962, 7 ``` [LTC 10+0.1 64th](https://tests.stockfishchess.org/tests/live_elo/694003aa46f342e1ec20fac4): ``` LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 16918 W: 4439 L: 4182 D: 8297 Ptnml(0-2): 3, 1493, 5213, 1744, 6 ``` [NUMA test, 5+0.05 256th](https://tests.stockfishchess.org/tests/view/6941ee4e46f342e1ec210203) ``` LLR: 2.95 (-2.94,2.94) <0.00,2.00> Total: 7124 W: 1910 L: 1678 D: 3536 Ptnml(0-2): 0, 560, 2211, 790, 1 ``` [LTC 60+0.6 64th](https://tests.stockfishchess.org/tests/live_elo/6940a85346f342e1ec20fcde): ``` LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 15504 W: 4045 L: 3826 D: 7633 Ptnml(0-2): 0, 1002, 5530, 1219, 1 ``` Bonus (courtesy of Viz): The 1 double kill in this last test was master blundering a cool mate in 3: https://lichess.org/jyNZuRl4 Basically the idea here is to share correction history between threads. That way, T1 can use the correction values produced by T2, which already searched positions with that pawn structure etc., so that T1 can search more efficiently. The table size per thread is about the same, so we shouldn't get a large increase in hash collisions; in fact, I'd expect a lower collision rate overall. Although I came up with and implemented the idea independently, [Caissa](https://github.com/Witek902/Caissa) was the first engine to implement corrhist sharing (and corrhist in the first place) – this idea is not completely novel. The table size is rounded to a power of two. In particular, it's `65536 * nextPowerOfTwo(threadCount)`. That way, the indexing operation becomes an AND of the key bits with a mask, rather than something more expensive (e.g., a `mul_hi64`-style approach or a modulo). The updates are racy, like the TT, but because `entry` is hoisted into a register, there's no risk of writing back a value that's out of the designated range `[-D, D]`. Various attempts at rewriting using atomics led to substantial slowdowns, so we begrudgingly ignored the functions in thread sanitizer, but at some point we'd like to make this better. We allocate one shared correction history per NUMA node, because the penalty associated with crossing nodes is substantial – I get a 40% hit with NPS=4 and 256 threads, which is intolerable. With separate tables per NUMA node I get a 6% penalty for nodes per second, which isn't ideal but apparently compensated for. closes https://github.com/official-stockfish/Stockfish/pull/6478 Bench: 2690604 Co-authored-by: Disservin --- src/engine.cpp | 3 +- src/engine.h | 3 + src/history.h | 140 ++++++++++++++++++++++++++++++++++++++--------- src/position.cpp | 14 ++++- src/position.h | 7 ++- src/search.cpp | 45 +++++++++------ src/search.h | 27 +++++---- src/thread.cpp | 44 +++++++++++++-- src/thread.h | 4 +- 9 files changed, 220 insertions(+), 67 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 9edff4864..40466c8f8 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -240,7 +240,8 @@ void Engine::set_numa_config_from_option(const std::string& o) { void Engine::resize_threads() { threads.wait_for_search_finished(); - threads.set(numaContext.get_numa_config(), {options, threads, tt, networks}, updateContext); + threads.set(numaContext.get_numa_config(), {options, threads, tt, sharedHists, networks}, + updateContext); // Reallocate the hash with the new threadpool size set_tt_size(options["Hash"]); diff --git a/src/engine.h b/src/engine.h index 7315b8881..6fd1ce040 100644 --- a/src/engine.h +++ b/src/engine.h @@ -22,12 +22,14 @@ #include #include #include +#include #include #include #include #include #include +#include "history.h" #include "nnue/network.h" #include "numa.h" #include "position.h" @@ -122,6 +124,7 @@ class Engine { Search::SearchManager::UpdateContext updateContext; std::function onVerifyNetworks; + std::map sharedHists; }; } // namespace Stockfish diff --git a/src/history.h b/src/history.h index 87004ead9..127fb9ef3 100644 --- a/src/history.h +++ b/src/history.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include // IWYU pragma: keep +#include "memory.h" #include "misc.h" #include "position.h" @@ -35,56 +37,54 @@ namespace Stockfish { constexpr int PAWN_HISTORY_SIZE = 8192; // has to be a power of 2 constexpr int UINT_16_HISTORY_SIZE = std::numeric_limits::max() + 1; +constexpr int CORRHIST_BASE_SIZE = UINT_16_HISTORY_SIZE; constexpr int CORRECTION_HISTORY_LIMIT = 1024; constexpr int LOW_PLY_HISTORY_SIZE = 5; static_assert((PAWN_HISTORY_SIZE & (PAWN_HISTORY_SIZE - 1)) == 0, "PAWN_HISTORY_SIZE has to be a power of 2"); -static_assert((UINT_16_HISTORY_SIZE & (UINT_16_HISTORY_SIZE - 1)) == 0, - "CORRECTION_HISTORY_SIZE has to be a power of 2"); +static_assert((CORRHIST_BASE_SIZE & (CORRHIST_BASE_SIZE - 1)) == 0, + "CORRHIST_BASE_SIZE has to be a power of 2"); inline int pawn_history_index(const Position& pos) { return pos.pawn_key() & (PAWN_HISTORY_SIZE - 1); } -inline uint16_t pawn_correction_history_index(const Position& pos) { - return uint16_t(pos.pawn_key()); -} - -inline uint16_t minor_piece_index(const Position& pos) { return uint16_t(pos.minor_piece_key()); } - -template -inline uint16_t non_pawn_index(const Position& pos) { - return uint16_t(pos.non_pawn_key(c)); -} - // StatsEntry is the container of various numerical statistics. We use a class // instead of a naked value to directly call history update operator<<() on // the entry. The first template parameter T is the base type of the array, // and the second template parameter D limits the range of updates in [-D, D] // when we update values with the << operator -template -class StatsEntry { - +template +struct StatsEntry { static_assert(std::is_arithmetic_v, "Not an arithmetic type"); - static_assert(D <= std::numeric_limits::max(), "D overflows T"); - T entry; + private: + std::conditional_t, T> entry; public: - StatsEntry& operator=(const T& v) { - entry = v; - return *this; + void operator=(const T& v) { + if constexpr (Atomic) + entry.store(v, std::memory_order_relaxed); + else + entry = v; + } + + operator T() const { + if constexpr (Atomic) + return entry.load(std::memory_order_relaxed); + else + return entry; } - operator const T&() const { return entry; } void operator<<(int bonus) { // Make sure that bonus is in range [-D, D] int clampedBonus = std::clamp(bonus, -D, D); - entry += clampedBonus - entry * std::abs(clampedBonus) / D; + T val = *this; + *this = val + clampedBonus - val * std::abs(clampedBonus) / D; - assert(std::abs(entry) <= D); + assert(std::abs(T(*this)) <= D); } }; @@ -96,6 +96,37 @@ enum StatsType { template using Stats = MultiArray, Sizes...>; +// DynStats is a dynamically sized array of Stats, used for thread-shared histories +// which should scale with the total number of threads. The SizeMultiplier gives +// the per-thread allocation count of T. +template +struct DynStats { + explicit DynStats(size_t s) { + size = s * SizeMultiplier; + data = make_unique_large_page(size); + } + // Sets all values in the range to 0 + void clear_range(size_t start, size_t end) { + assert(start < size); + assert(end <= size); + T* fill_start = &(*this)[start]; + memset(reinterpret_cast(fill_start), 0, sizeof(T) * (end - start)); + } + size_t get_size() const { return size; } + T& operator[](size_t index) { + assert(index < size); + return data.get()[index]; + } + const T& operator[](size_t index) const { + assert(index < size); + return data.get()[index]; + } + + private: + size_t size; + LargePagePtr data; +}; + // ButterflyHistory records how often quiet moves have been successful or unsuccessful // during the current search, and is used for reduction and move ordering decisions. // It uses 2 tables (one for each color) indexed by the move's from and to squares, @@ -132,11 +163,20 @@ enum CorrHistType { Continuation, // Combined history of move pairs }; +template +struct CorrectionBundle { + StatsEntry pawn; + StatsEntry minor; + StatsEntry nonPawnWhite; + StatsEntry nonPawnBlack; +}; + namespace Detail { template struct CorrHistTypedef { - using type = Stats; + using type = + DynStats, CORRHIST_BASE_SIZE>; }; template<> @@ -151,17 +191,63 @@ struct CorrHistTypedef { template<> struct CorrHistTypedef { - using type = - Stats; + using type = DynStats, + CORRHIST_BASE_SIZE>; }; } +using UnifiedCorrectionHistory = + DynStats, COLOR_NB>, + CORRHIST_BASE_SIZE>; + template using CorrectionHistory = typename Detail::CorrHistTypedef::type; using TTMoveHistory = StatsEntry; +// Set of histories shared between groups of threads. To avoid excessive +// cross-node data transfer, histories are shared only between threads +// on a given NUMA node. The passed size must be a power of two to make +// the indexing more efficient. +struct SharedHistories { + SharedHistories(size_t threadCount) : + correctionHistory(threadCount) { + assert((threadCount & (threadCount - 1)) == 0 && threadCount != 0); + sizeMinus1 = correctionHistory.get_size() - 1; + } + + size_t get_size() const { return sizeMinus1 + 1; } + + auto& pawn_correction_entry(const Position& pos) { + return correctionHistory[pos.pawn_key() & sizeMinus1]; + } + const auto& pawn_correction_entry(const Position& pos) const { + return correctionHistory[pos.pawn_key() & sizeMinus1]; + } + + auto& minor_piece_correction_entry(const Position& pos) { + return correctionHistory[pos.minor_piece_key() & sizeMinus1]; + } + const auto& minor_piece_correction_entry(const Position& pos) const { + return correctionHistory[pos.minor_piece_key() & sizeMinus1]; + } + + template + auto& nonpawn_correction_entry(const Position& pos) { + return correctionHistory[pos.non_pawn_key(c) & sizeMinus1]; + } + template + const auto& nonpawn_correction_entry(const Position& pos) const { + return correctionHistory[pos.non_pawn_key(c) & sizeMinus1]; + } + + UnifiedCorrectionHistory correctionHistory; + + private: + size_t sizeMinus1; +}; + } // namespace Stockfish #endif // #ifndef HISTORY_H_INCLUDED diff --git a/src/position.cpp b/src/position.cpp index a4286b86a..7377b2029 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -32,6 +32,7 @@ #include #include "bitboard.h" +#include "history.h" #include "misc.h" #include "movegen.h" #include "syzygy/tbprobe.h" @@ -692,13 +693,14 @@ bool Position::gives_check(Move m) const { // to a StateInfo object. The move is assumed to be legal. Pseudo-legal // moves should be filtered out before this function is called. // If a pointer to the TT table is passed, the entry for the new position -// will be prefetched +// will be prefetched, and likewise for shared history. void Position::do_move(Move m, StateInfo& newSt, bool givesCheck, DirtyPiece& dp, DirtyThreats& dts, - const TranspositionTable* tt = nullptr) { + const TranspositionTable* tt = nullptr, + const SharedHistories* history = nullptr) { assert(m.is_ok()); assert(&newSt != st); @@ -880,6 +882,14 @@ void Position::do_move(Move m, if (tt && !checkEP) prefetch(tt->first_entry(adjust_key50(k))); + if (history) + { + prefetch(&history->pawn_correction_entry(*this)); + prefetch(&history->minor_piece_correction_entry(*this)); + prefetch(&history->nonpawn_correction_entry(*this)); + prefetch(&history->nonpawn_correction_entry(*this)); + } + // Set capture piece st->capturedPiece = captured; diff --git a/src/position.h b/src/position.h index e5d3f6d28..e49e10f96 100644 --- a/src/position.h +++ b/src/position.h @@ -33,6 +33,7 @@ namespace Stockfish { class TranspositionTable; +struct SharedHistories; // StateInfo struct stores information needed to restore a Position object to // its previous state when we retract a move. Whenever a move is made on the @@ -69,7 +70,6 @@ struct StateInfo { // elements are not invalidated upon list resizing. using StateListPtr = std::unique_ptr>; - // Position class stores information regarding the board representation as // pieces, side to move, hash keys, castling info, etc. Important methods are // do_move() and undo_move(), used by the search to update node info when @@ -140,7 +140,8 @@ class Position { bool givesCheck, DirtyPiece& dp, DirtyThreats& dts, - const TranspositionTable* tt); + const TranspositionTable* tt, + const SharedHistories* worker); void undo_move(Move m); void do_null_move(StateInfo& newSt, const TranspositionTable& tt); void undo_null_move(); @@ -403,7 +404,7 @@ inline void Position::swap_piece(Square s, Piece pc, DirtyThreats* const dts) { inline void Position::do_move(Move m, StateInfo& newSt, const TranspositionTable* tt = nullptr) { new (&scratch_dts) DirtyThreats; - do_move(m, newSt, gives_check(m), scratch_dp, scratch_dts, tt); + do_move(m, newSt, gives_check(m), scratch_dp, scratch_dts, tt, nullptr); } inline StateInfo* Position::state() const { return st; } diff --git a/src/search.cpp b/src/search.cpp index adb7985d2..7c08bb0fa 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -77,16 +77,17 @@ using SearchedList = ValueList; // optimized for require verifications at longer time controls int correction_value(const Worker& w, const Position& pos, const Stack* const ss) { - const Color us = pos.side_to_move(); - const auto m = (ss - 1)->currentMove; - const auto pcv = w.pawnCorrectionHistory[pawn_correction_history_index(pos)][us]; - const auto micv = w.minorPieceCorrectionHistory[minor_piece_index(pos)][us]; - const auto wnpcv = w.nonPawnCorrectionHistory[non_pawn_index(pos)][WHITE][us]; - const auto bnpcv = w.nonPawnCorrectionHistory[non_pawn_index(pos)][BLACK][us]; - const auto cntcv = + const Color us = pos.side_to_move(); + const auto m = (ss - 1)->currentMove; + const auto& shared = w.sharedHistory; + const int pcv = shared.pawn_correction_entry(pos).at(us).pawn; + const int micv = shared.minor_piece_correction_entry(pos).at(us).minor; + const int wnpcv = shared.nonpawn_correction_entry(pos).at(us).nonPawnWhite; + const int bnpcv = shared.nonpawn_correction_entry(pos).at(us).nonPawnBlack; + const int cntcv = m.is_ok() ? (*(ss - 2)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()] + (*(ss - 4)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()] - : 8; + : 8; return 10347 * pcv + 8821 * micv + 11168 * (wnpcv + bnpcv) + 7841 * cntcv; } @@ -105,13 +106,12 @@ void update_correction_history(const Position& pos, const Color us = pos.side_to_move(); constexpr int nonPawnWeight = 178; + auto& shared = workerThread.sharedHistory; - workerThread.pawnCorrectionHistory[pawn_correction_history_index(pos)][us] << bonus; - workerThread.minorPieceCorrectionHistory[minor_piece_index(pos)][us] << bonus * 156 / 128; - workerThread.nonPawnCorrectionHistory[non_pawn_index(pos)][WHITE][us] - << bonus * nonPawnWeight / 128; - workerThread.nonPawnCorrectionHistory[non_pawn_index(pos)][BLACK][us] - << bonus * nonPawnWeight / 128; + shared.pawn_correction_entry(pos).at(us).pawn << bonus; + shared.minor_piece_correction_entry(pos).at(us).minor << bonus * 156 / 128; + shared.nonpawn_correction_entry(pos).at(us).nonPawnWhite << bonus * nonPawnWeight / 128; + shared.nonpawn_correction_entry(pos).at(us).nonPawnBlack << bonus * nonPawnWeight / 128; if (m.is_ok()) { @@ -155,9 +155,14 @@ bool is_shuffling(Move move, Stack* const ss, const Position& pos) { Search::Worker::Worker(SharedState& sharedState, std::unique_ptr sm, size_t threadId, + size_t numaThreadId, + size_t numaTotalThreads, NumaReplicatedAccessToken token) : // Unpack the SharedState struct into member variables + sharedHistory(sharedState.sharedHistories.at(token.get_numa_index())), threadIdx(threadId), + numaThreadIdx(numaThreadId), + numaTotal(numaTotalThreads), numaAccessToken(token), manager(std::move(sm)), options(sharedState.options), @@ -544,7 +549,7 @@ void Search::Worker::do_move( nodes.store(nodes.load(std::memory_order_relaxed) + 1, std::memory_order_relaxed); auto [dirtyPiece, dirtyThreats] = accumulatorStack.push(); - pos.do_move(move, st, givesCheck, dirtyPiece, dirtyThreats, &tt); + pos.do_move(move, st, givesCheck, dirtyPiece, dirtyThreats, &tt, &sharedHistory); if (ss != nullptr) { @@ -576,9 +581,13 @@ void Search::Worker::clear() { mainHistory.fill(68); captureHistory.fill(-689); pawnHistory.fill(-1238); - pawnCorrectionHistory.fill(5); - minorPieceCorrectionHistory.fill(0); - nonPawnCorrectionHistory.fill(0); + + // Each thread is responsible for clearing their part of shared history + size_t len = sharedHistory.get_size() / numaTotal; + size_t start = numaThreadIdx * len; + size_t end = std::min(start + len, sharedHistory.get_size()); + + sharedHistory.correctionHistory.clear_range(start, end); ttMoveHistory = 0; diff --git a/src/search.h b/src/search.h index f3d99d415..9644f6aa5 100644 --- a/src/search.h +++ b/src/search.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -136,15 +137,18 @@ struct SharedState { SharedState(const OptionsMap& optionsMap, ThreadPool& threadPool, TranspositionTable& transpositionTable, + std::map& sharedHists, const LazyNumaReplicatedSystemWide& nets) : options(optionsMap), threads(threadPool), tt(transpositionTable), + sharedHistories(sharedHists), networks(nets) {} const OptionsMap& options; ThreadPool& threads; TranspositionTable& tt; + std::map& sharedHistories; const LazyNumaReplicatedSystemWide& networks; }; @@ -258,13 +262,17 @@ class NullSearchManager: public ISearchManager { void check_time(Search::Worker&) override {} }; - // Search::Worker is the class that does the actual search. // It is instantiated once per thread, and it is responsible for keeping track // of the search history, and storing data required for the search. class Worker { public: - Worker(SharedState&, std::unique_ptr, size_t, NumaReplicatedAccessToken); + Worker(SharedState&, + std::unique_ptr, + size_t, + size_t, + size_t, + NumaReplicatedAccessToken); // Called at instantiation to initialize reductions tables. // Reset histories, usually before a new game. @@ -282,16 +290,13 @@ class Worker { ButterflyHistory mainHistory; LowPlyHistory lowPlyHistory; - CapturePieceToHistory captureHistory; - ContinuationHistory continuationHistory[2][2]; - PawnHistory pawnHistory; - - CorrectionHistory pawnCorrectionHistory; - CorrectionHistory minorPieceCorrectionHistory; - CorrectionHistory nonPawnCorrectionHistory; + CapturePieceToHistory captureHistory; + ContinuationHistory continuationHistory[2][2]; + PawnHistory pawnHistory; CorrectionHistory continuationCorrectionHistory; - TTMoveHistory ttMoveHistory; + TTMoveHistory ttMoveHistory; + SharedHistories& sharedHistory; private: void iterative_deepening(); @@ -338,7 +343,7 @@ class Worker { Depth rootDepth, completedDepth; Value rootDelta; - size_t threadIdx; + size_t threadIdx, numaThreadIdx, numaTotal; NumaReplicatedAccessToken numaAccessToken; // Reductions lookup table initialized at startup diff --git a/src/thread.cpp b/src/thread.cpp index 58840a874..eaf1d09bd 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -21,11 +21,14 @@ #include #include #include +#include #include #include #include #include +#include "bitboard.h" +#include "history.h" #include "memory.h" #include "movegen.h" #include "search.h" @@ -42,8 +45,12 @@ namespace Stockfish { Thread::Thread(Search::SharedState& sharedState, std::unique_ptr sm, size_t n, + size_t numaN, + size_t totalNumaCount, OptionalThreadToNumaNodeBinder binder) : idx(n), + idxInNuma(numaN), + totalNuma(totalNumaCount), nthreads(sharedState.options["Threads"]), stdThread(&Thread::idle_loop, this) { @@ -54,8 +61,8 @@ Thread::Thread(Search::SharedState& sharedState, // the Worker allocation. Ideally we would also allocate the SearchManager // here, but that's minor. this->numaAccessToken = binder(); - this->worker = make_unique_large_page(sharedState, std::move(sm), n, - this->numaAccessToken); + this->worker = make_unique_large_page( + sharedState, std::move(sm), n, idxInNuma, totalNuma, this->numaAccessToken); }); wait_for_search_finished(); @@ -134,6 +141,8 @@ Search::SearchManager* ThreadPool::main_manager() { return main_thread()->worker uint64_t ThreadPool::nodes_searched() const { return accumulate(&Search::Worker::nodes); } uint64_t ThreadPool::tb_hits() const { return accumulate(&Search::Worker::tbHits); } +static size_t next_power_of_two(uint64_t count) { return count > 1 ? (2ULL << msb(count - 1)) : 1; } + // Creates/destroys threads to match the requested number. // Created and launched threads will immediately go to sleep in idle_loop. // Upon resizing, threads are recreated to allow for binding if necessary. @@ -172,10 +181,36 @@ void ThreadPool::set(const NumaConfig& numaConfig, return true; }(); + std::map counts; boundThreadToNumaNode = doBindThreads ? numaConfig.distribute_threads_among_numa_nodes(requested) : std::vector{}; + if (boundThreadToNumaNode.empty()) + counts[0] = requested; // Pretend all threads are part of numa node 0 + else + { + for (size_t i = 0; i < boundThreadToNumaNode.size(); ++i) + counts[boundThreadToNumaNode[i]]++; + } + + sharedState.sharedHistories.clear(); + for (auto pair : counts) + { + NumaIndex numaIndex = pair.first; + uint64_t count = pair.second; + auto f = [&]() { + sharedState.sharedHistories.try_emplace(numaIndex, next_power_of_two(count)); + }; + if (doBindThreads) + numaConfig.execute_on_numa_node(numaIndex, f); + else + f(); + } + + auto threadsPerNode = counts; + counts.clear(); + while (threads.size() < requested) { const size_t threadId = threads.size(); @@ -191,8 +226,9 @@ void ThreadPool::set(const NumaConfig& numaConfig, auto binder = doBindThreads ? OptionalThreadToNumaNodeBinder(numaConfig, numaId) : OptionalThreadToNumaNodeBinder(numaId); - threads.emplace_back( - std::make_unique(sharedState, std::move(manager), threadId, binder)); + threads.emplace_back(std::make_unique(sharedState, std::move(manager), threadId, + counts[numaId]++, threadsPerNode[numaId], + binder)); } clear(); diff --git a/src/thread.h b/src/thread.h index 79376b10a..2368c3069 100644 --- a/src/thread.h +++ b/src/thread.h @@ -76,6 +76,8 @@ class Thread { Thread(Search::SharedState&, std::unique_ptr, size_t, + size_t, + size_t, OptionalThreadToNumaNodeBinder); virtual ~Thread(); @@ -100,7 +102,7 @@ class Thread { private: std::mutex mutex; std::condition_variable cv; - size_t idx, nthreads; + size_t idx, idxInNuma, totalNuma, nthreads; bool exit = false, searching = true; // Set before starting std::thread NativeThread stdThread; NumaReplicatedAccessToken numaAccessToken; From 447f66acac30f5f56c4cfbea3dcc2f90504f77f7 Mon Sep 17 00:00:00 2001 From: Michael Chaly Date: Tue, 23 Dec 2025 21:28:51 +0100 Subject: [PATCH 03/23] Less penalty for quiet late moves that didn't beat the best move. This moves since they are late in move ordering probably already have pretty bad stats anyway. Passed STC: https://tests.stockfishchess.org/tests/view/6943bcd546f342e1ec210e25 LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 96704 W: 25206 L: 24798 D: 46700 Ptnml(0-2): 357, 11244, 24767, 11602, 382 Passed LTC: https://tests.stockfishchess.org/tests/view/6946a8723c8768ca450722f0 LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 89814 W: 23193 L: 22770 D: 43851 Ptnml(0-2): 53, 9532, 25321, 9941, 60 bench 2717363 closes https://github.com/official-stockfish/Stockfish/pull/6485 Bench: 2791988 --- src/search.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 7c08bb0fa..377b96343 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1831,9 +1831,16 @@ void update_all_stats(const Position& pos, { update_quiet_histories(pos, ss, workerThread, bestMove, bonus * 910 / 1024); + int i = 0; // Decrease stats for all non-best quiet moves for (Move move : quietsSearched) - update_quiet_histories(pos, ss, workerThread, move, -malus * 1085 / 1024); + { + i++; + int actualMalus = malus * 1085 / 1024; + if (i > 5) + actualMalus -= actualMalus * (i - 5) / i; + update_quiet_histories(pos, ss, workerThread, move, -actualMalus); + } } else { From 4d4c6ebd0255f29a45fb5e071fc7471ab0adf316 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Tue, 23 Dec 2025 21:29:16 +0100 Subject: [PATCH 04/23] Simplify doDeeperSearch formula Passed STC: LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 211776 W: 54939 L: 54911 D: 101926 Ptnml(0-2): 714, 24971, 54484, 25011, 708 https://tests.stockfishchess.org/tests/view/6938971875b70713ef796b70 Passed LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 216774 W: 55346 L: 55326 D: 106102 Ptnml(0-2): 105, 23599, 60980, 23577, 126 https://tests.stockfishchess.org/tests/view/693fc91f46f342e1ec20f9f6 closes https://github.com/official-stockfish/Stockfish/pull/6486 Bench: 3267755 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 377b96343..9c52592e0 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1241,7 +1241,7 @@ moves_loop: // When in check, search starts here { // Adjust full-depth search based on LMR results - if the result was // good enough search deeper, if it was bad enough search shallower. - const bool doDeeperSearch = d < newDepth && value > (bestValue + 43 + 2 * newDepth); + const bool doDeeperSearch = d < newDepth && value > (bestValue + newDepth + 44); const bool doShallowerSearch = value < bestValue + 9; newDepth += doDeeperSearch - doShallowerSearch; From 73b3b1859518e88c9c292d2efbd7debe57d7351d Mon Sep 17 00:00:00 2001 From: Disservin Date: Tue, 23 Dec 2025 21:30:16 +0100 Subject: [PATCH 05/23] Init threat offsets at compile time Init threat offsets at compile time. Avoid another global init function call. Passed STC Non-Regression: https://tests.stockfishchess.org/tests/view/694971a83c8768ca4507275c LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 43296 W: 11284 L: 11077 D: 20935 Ptnml(0-2): 152, 4611, 11924, 4800, 161 closes https://github.com/official-stockfish/Stockfish/pull/6487 No functional change --- src/bitboard.cpp | 48 +------ src/bitboard.h | 218 ++++++++++++++++++++--------- src/main.cpp | 2 - src/nnue/features/full_threats.cpp | 196 ++++++++++++++++++-------- src/nnue/features/full_threats.h | 1 - src/syzygy/tbprobe.cpp | 1 + 6 files changed, 293 insertions(+), 173 deletions(-) diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 6c97d7863..350e56c92 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -32,7 +32,6 @@ uint8_t SquareDistance[SQUARE_NB][SQUARE_NB]; Bitboard LineBB[SQUARE_NB][SQUARE_NB]; Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; Bitboard RayPassBB[SQUARE_NB][SQUARE_NB]; -Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; alignas(64) Magic Magics[SQUARE_NB][2]; @@ -42,13 +41,6 @@ Bitboard RookTable[0x19000]; // To store rook attacks Bitboard BishopTable[0x1480]; // To store bishop attacks void init_magics(PieceType pt, Bitboard table[], Magic magics[][2]); - -// Returns the bitboard of target square for the given step -// from the given square. If the step is off the board, returns empty bitboard. -Bitboard safe_destination(Square s, int step) { - Square to = Square(s + step); - return is_ok(to) && distance(s, to) <= 2 ? square_bb(to) : Bitboard(0); -} } // Returns an ASCII representation of a bitboard suitable @@ -86,18 +78,6 @@ void Bitboards::init() { for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) { - PseudoAttacks[WHITE][s1] = pawn_attacks_bb(square_bb(s1)); - PseudoAttacks[BLACK][s1] = pawn_attacks_bb(square_bb(s1)); - - for (int step : {-9, -8, -7, -1, 1, 7, 8, 9}) - PseudoAttacks[KING][s1] |= safe_destination(s1, step); - - for (int step : {-17, -15, -10, -6, 6, 10, 15, 17}) - PseudoAttacks[KNIGHT][s1] |= safe_destination(s1, step); - - PseudoAttacks[QUEEN][s1] = PseudoAttacks[BISHOP][s1] = attacks_bb(s1, 0); - PseudoAttacks[QUEEN][s1] |= PseudoAttacks[ROOK][s1] = attacks_bb(s1, 0); - for (PieceType pt : {BISHOP, ROOK}) for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2) { @@ -115,30 +95,6 @@ void Bitboards::init() { } namespace { - -Bitboard sliding_attack(PieceType pt, Square sq, Bitboard occupied) { - - Bitboard attacks = 0; - Direction RookDirections[4] = {NORTH, SOUTH, EAST, WEST}; - Direction BishopDirections[4] = {NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST}; - - for (Direction d : (pt == ROOK ? RookDirections : BishopDirections)) - { - Square s = sq; - while (safe_destination(s, d)) - { - attacks |= (s += d); - if (occupied & s) - { - break; - } - } - } - - return attacks; -} - - // Computes all rook and bishop attacks at startup. Magic // bitboards are used to look up attacks of sliding pieces. As a reference see // https://www.chessprogramming.org/Magic_Bitboards. In particular, here we use @@ -167,7 +123,7 @@ void init_magics(PieceType pt, Bitboard table[], Magic magics[][2]) { // the number of 1s of the mask. Hence we deduce the size of the shift to // apply to the 64 or 32 bits word to get the index. Magic& m = magics[s][pt - BISHOP]; - m.mask = sliding_attack(pt, s, 0) & ~edges; + m.mask = Bitboards::sliding_attack(pt, s, 0) & ~edges; #ifndef USE_PEXT m.shift = (Is64Bit ? 64 : 32) - popcount(m.mask); #endif @@ -184,7 +140,7 @@ void init_magics(PieceType pt, Bitboard table[], Magic magics[][2]) { #ifndef USE_PEXT occupancy[size] = b; #endif - reference[size] = sliding_attack(pt, s, b); + reference[size] = Bitboards::sliding_attack(pt, s, b); if (HasPext) m.attacks[pext(b, m.mask)] = reference[size]; diff --git a/src/bitboard.h b/src/bitboard.h index 1cd717b8f..1da11d45c 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include "types.h" @@ -62,8 +64,6 @@ extern uint8_t SquareDistance[SQUARE_NB][SQUARE_NB]; extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; extern Bitboard LineBB[SQUARE_NB][SQUARE_NB]; extern Bitboard RayPassBB[SQUARE_NB][SQUARE_NB]; -extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; - // Magic holds all magic bitboards relevant data for a single square struct Magic { @@ -203,69 +203,12 @@ inline int distance(Square x, Square y) { inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); } -// Returns the pseudo attacks of the given piece type -// assuming an empty board. -template -inline Bitboard attacks_bb(Square s, Color c = COLOR_NB) { - assert((Pt != PAWN || c < COLOR_NB) && (is_ok(s))); - return Pt == PAWN ? PseudoAttacks[c][s] : PseudoAttacks[Pt][s]; -} - - -// Returns the attacks by the given piece -// assuming the board is occupied according to the passed Bitboard. -// Sliding piece attacks do not continue passed an occupied square. -template -inline Bitboard attacks_bb(Square s, Bitboard occupied) { - - assert((Pt != PAWN) && (is_ok(s))); - - switch (Pt) - { - case BISHOP : - case ROOK : - return Magics[s][Pt - BISHOP].attacks_bb(occupied); - case QUEEN : - return attacks_bb(s, occupied) | attacks_bb(s, occupied); - default : - return PseudoAttacks[Pt][s]; - } -} - -// Returns the attacks by the given piece -// assuming the board is occupied according to the passed Bitboard. -// Sliding piece attacks do not continue passed an occupied square. -inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) { - - assert((pt != PAWN) && (is_ok(s))); - - switch (pt) - { - case BISHOP : - return attacks_bb(s, occupied); - case ROOK : - return attacks_bb(s, occupied); - case QUEEN : - return attacks_bb(s, occupied) | attacks_bb(s, occupied); - default : - return PseudoAttacks[pt][s]; - } -} - -inline Bitboard attacks_bb(Piece pc, Square s) { - if (type_of(pc) == PAWN) - return PseudoAttacks[color_of(pc)][s]; - - return PseudoAttacks[type_of(pc)][s]; -} - - -inline Bitboard attacks_bb(Piece pc, Square s, Bitboard occupied) { - if (type_of(pc) == PAWN) - return PseudoAttacks[color_of(pc)][s]; - - return attacks_bb(type_of(pc), s, occupied); +constexpr int constexpr_popcount(Bitboard b) { + b = b - ((b >> 1) & 0x5555555555555555ULL); + b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL); + b = (b + (b >> 4)) & 0x0F0F0F0F0F0F0F0FULL; + return static_cast((b * 0x0101010101010101ULL) >> 56); } // Counts the number of non-zero bits in a bitboard. @@ -373,6 +316,153 @@ inline Square pop_lsb(Bitboard& b) { return s; } +namespace Bitboards { +// Returns the bitboard of target square for the given step +// from the given square. If the step is off the board, returns empty bitboard. +constexpr Bitboard safe_destination(Square s, int step) { + constexpr auto abs = [](int v) { return v < 0 ? -v : v; }; + Square to = Square(s + step); + return is_ok(to) && abs(file_of(s) - file_of(to)) <= 2 ? square_bb(to) : Bitboard(0); +} + +constexpr Bitboard sliding_attack(PieceType pt, Square sq, Bitboard occupied) { + Bitboard attacks = 0; + Direction RookDirections[4] = {NORTH, SOUTH, EAST, WEST}; + Direction BishopDirections[4] = {NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST}; + + for (Direction d : (pt == ROOK ? RookDirections : BishopDirections)) + { + Square s = sq; + while (safe_destination(s, d)) + { + attacks |= (s += d); + if (occupied & s) + { + break; + } + } + } + + return attacks; +} + +constexpr Bitboard knight_attack(Square sq) { + Bitboard b = {}; + for (int step : {-17, -15, -10, -6, 6, 10, 15, 17}) + b |= safe_destination(sq, step); + return b; +} + +constexpr Bitboard king_attack(Square sq) { + Bitboard b = {}; + for (int step : {-9, -8, -7, -1, 1, 7, 8, 9}) + b |= safe_destination(sq, step); + return b; +} + +constexpr Bitboard pseudo_attacks(PieceType pt, Square sq) { + switch (pt) + { + case PieceType::ROOK : + case PieceType::BISHOP : + return sliding_attack(pt, sq, 0); + case PieceType::QUEEN : + return sliding_attack(PieceType::ROOK, sq, 0) | sliding_attack(PieceType::BISHOP, sq, 0); + case PieceType::KNIGHT : + return knight_attack(sq); + case PieceType::KING : + return king_attack(sq); + default : + assert(false); + return 0; + } +} + +} + +inline constexpr auto PseudoAttacks = []() constexpr { + std::array, PIECE_TYPE_NB> attacks{}; + + for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) + { + attacks[WHITE][s1] = pawn_attacks_bb(square_bb(s1)); + attacks[BLACK][s1] = pawn_attacks_bb(square_bb(s1)); + + attacks[KING][s1] = Bitboards::pseudo_attacks(KING, s1); + attacks[KNIGHT][s1] = Bitboards::pseudo_attacks(KNIGHT, s1); + attacks[QUEEN][s1] = attacks[BISHOP][s1] = Bitboards::pseudo_attacks(BISHOP, s1); + attacks[QUEEN][s1] |= attacks[ROOK][s1] = Bitboards::pseudo_attacks(ROOK, s1); + } + + return attacks; +}(); + + +// Returns the pseudo attacks of the given piece type +// assuming an empty board. +template +inline Bitboard attacks_bb(Square s, Color c = COLOR_NB) { + + assert((Pt != PAWN || c < COLOR_NB) && (is_ok(s))); + return Pt == PAWN ? PseudoAttacks[c][s] : PseudoAttacks[Pt][s]; +} + + +// Returns the attacks by the given piece +// assuming the board is occupied according to the passed Bitboard. +// Sliding piece attacks do not continue passed an occupied square. +template +inline Bitboard attacks_bb(Square s, Bitboard occupied) { + + assert((Pt != PAWN) && (is_ok(s))); + + switch (Pt) + { + case BISHOP : + case ROOK : + return Magics[s][Pt - BISHOP].attacks_bb(occupied); + case QUEEN : + return attacks_bb(s, occupied) | attacks_bb(s, occupied); + default : + return PseudoAttacks[Pt][s]; + } +} + +// Returns the attacks by the given piece +// assuming the board is occupied according to the passed Bitboard. +// Sliding piece attacks do not continue passed an occupied square. +inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) { + + assert((pt != PAWN) && (is_ok(s))); + + switch (pt) + { + case BISHOP : + return attacks_bb(s, occupied); + case ROOK : + return attacks_bb(s, occupied); + case QUEEN : + return attacks_bb(s, occupied) | attacks_bb(s, occupied); + default : + return PseudoAttacks[pt][s]; + } +} + +inline Bitboard attacks_bb(Piece pc, Square s) { + if (type_of(pc) == PAWN) + return PseudoAttacks[color_of(pc)][s]; + + return PseudoAttacks[type_of(pc)][s]; +} + + +inline Bitboard attacks_bb(Piece pc, Square s, Bitboard occupied) { + if (type_of(pc) == PAWN) + return PseudoAttacks[color_of(pc)][s]; + + return attacks_bb(type_of(pc), s, occupied); +} + } // namespace Stockfish #endif // #ifndef BITBOARD_H_INCLUDED diff --git a/src/main.cpp b/src/main.cpp index 6ab3507f3..107b5e43d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,6 @@ #include "bitboard.h" #include "misc.h" -#include "nnue/features/full_threats.h" #include "position.h" #include "tune.h" #include "uci.h" @@ -33,7 +32,6 @@ int main(int argc, char* argv[]) { Bitboards::init(); Position::init(); - Eval::NNUE::Features::init_threat_offsets(); auto uci = std::make_unique(argc, argv); diff --git a/src/nnue/features/full_threats.cpp b/src/nnue/features/full_threats.cpp index 645bb7090..63b7f8e13 100644 --- a/src/nnue/features/full_threats.cpp +++ b/src/nnue/features/full_threats.cpp @@ -21,7 +21,9 @@ #include "full_threats.h" #include +#include #include +#include #include "../../bitboard.h" #include "../../misc.h" @@ -31,26 +33,28 @@ namespace Stockfish::Eval::NNUE::Features { -// Lookup array for indexing threats -IndexType offsets[PIECE_NB][SQUARE_NB]; - struct HelperOffsets { int cumulativePieceOffset, cumulativeOffset; }; -std::array helper_offsets; // Information on a particular pair of pieces and whether they should be excluded struct PiecePairData { // Layout: bits 8..31 are the index contribution of this piece pair, bits 0 and 1 are exclusion info uint32_t data; - PiecePairData() {} - PiecePairData(bool excluded_pair, bool semi_excluded_pair, IndexType feature_index_base) { - data = - excluded_pair << 1 | (semi_excluded_pair && !excluded_pair) | feature_index_base << 8; - } + + constexpr PiecePairData() : + data(0) {} + + constexpr PiecePairData(bool excluded_pair, + bool semi_excluded_pair, + IndexType feature_index_base) : + data((uint32_t(excluded_pair) << 1) | (uint32_t(semi_excluded_pair && !excluded_pair)) + | (uint32_t(feature_index_base) << 8)) {} + // lsb: excluded if from < to; 2nd lsb: always excluded - uint8_t excluded_pair_info() const { return (uint8_t) data; } - IndexType feature_index_base() const { return data >> 8; } + constexpr uint8_t excluded_pair_info() const { return static_cast(data); } + + constexpr IndexType feature_index_base() const { return static_cast(data >> 8); } }; constexpr std::array AllPieces = { @@ -58,12 +62,119 @@ constexpr std::array AllPieces = { B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING, }; -// The final index is calculated from summing data found in these two LUTs, as well -// as offsets[attacker][from] -PiecePairData index_lut1[PIECE_NB][PIECE_NB]; // [attacker][attacked] -uint8_t index_lut2[PIECE_NB][SQUARE_NB][SQUARE_NB]; // [attacker][from][to] +template +constexpr auto make_piece_indices_type() { + static_assert(PT != PieceType::PAWN); + + std::array, SQUARE_NB> out{}; + + for (int from = 0; from < SQUARE_NB; ++from) + { + Bitboard attacks = PseudoAttacks[PT][Square(from)]; + + for (int to = 0; to < SQUARE_NB; ++to) + { + out[from][to] = constexpr_popcount(((1ULL << to) - 1) & attacks); + } + } + + return out; +} + +template +constexpr auto make_piece_indices_piece() { + static_assert(type_of(P) == PieceType::PAWN); + + std::array, SQUARE_NB> out{}; + + constexpr Color C = color_of(P); + + for (int from = 0; from < SQUARE_NB; ++from) + { + Bitboard attacks = PseudoAttacks[C][from]; + + for (int to = 0; to < SQUARE_NB; ++to) + { + out[from][to] = constexpr_popcount(((1ULL << to) - 1) & attacks); + } + } + + return out; +} + +constexpr auto index_lut2_array() { + constexpr auto KNIGHT_ATTACKS = make_piece_indices_type(); + constexpr auto BISHOP_ATTACKS = make_piece_indices_type(); + constexpr auto ROOK_ATTACKS = make_piece_indices_type(); + constexpr auto QUEEN_ATTACKS = make_piece_indices_type(); + constexpr auto KING_ATTACKS = make_piece_indices_type(); + + std::array, SQUARE_NB>, PIECE_NB> indices{}; + + indices[W_PAWN] = make_piece_indices_piece(); + indices[B_PAWN] = make_piece_indices_piece(); + + indices[W_KNIGHT] = KNIGHT_ATTACKS; + indices[B_KNIGHT] = KNIGHT_ATTACKS; + + indices[W_BISHOP] = BISHOP_ATTACKS; + indices[B_BISHOP] = BISHOP_ATTACKS; + + indices[W_ROOK] = ROOK_ATTACKS; + indices[B_ROOK] = ROOK_ATTACKS; + + indices[W_QUEEN] = QUEEN_ATTACKS; + indices[B_QUEEN] = QUEEN_ATTACKS; + + indices[W_KING] = KING_ATTACKS; + indices[B_KING] = KING_ATTACKS; + + return indices; +} + +constexpr auto init_threat_offsets() { + std::array indices{}; + std::array, PIECE_NB> offsets{}; + + int cumulativeOffset = 0; + for (Piece piece : AllPieces) + { + int pieceIdx = piece; + int cumulativePieceOffset = 0; + + for (Square from = SQ_A1; from <= SQ_H8; ++from) + { + offsets[pieceIdx][from] = cumulativePieceOffset; + + if (type_of(piece) != PAWN) + { + Bitboard attacks = PseudoAttacks[type_of(piece)][from]; + cumulativePieceOffset += constexpr_popcount(attacks); + } + + else if (from >= SQ_A2 && from <= SQ_H7) + { + Bitboard attacks = (pieceIdx < 8) ? pawn_attacks_bb(square_bb(from)) + : pawn_attacks_bb(square_bb(from)); + cumulativePieceOffset += constexpr_popcount(attacks); + } + } + + indices[pieceIdx] = {cumulativePieceOffset, cumulativeOffset}; + + cumulativeOffset += numValidTargets[pieceIdx] * cumulativePieceOffset; + } + + return std::pair{indices, offsets}; +} + +constexpr auto helper_offsets = init_threat_offsets().first; +// Lookup array for indexing threats +constexpr auto offsets = init_threat_offsets().second; + +constexpr auto init_index_luts() { + std::array, PIECE_NB> indices{}; -static void init_index_luts() { for (Piece attacker : AllPieces) { for (Piece attacked : AllPieces) @@ -78,56 +189,21 @@ static void init_index_luts() { + (color_of(attacked) * (numValidTargets[attacker] / 2) + map) * helper_offsets[attacker].cumulativePieceOffset; - bool excluded = map < 0; - index_lut1[attacker][attacked] = PiecePairData(excluded, semi_excluded, feature); + bool excluded = map < 0; + indices[attacker][attacked] = PiecePairData(excluded, semi_excluded, feature); } } - for (Piece attacker : AllPieces) - { - for (int from = 0; from < SQUARE_NB; ++from) - { - for (int to = 0; to < SQUARE_NB; ++to) - { - Bitboard attacks = attacks_bb(attacker, Square(from)); - index_lut2[attacker][from][to] = popcount((square_bb(Square(to)) - 1) & attacks); - } - } - } + return indices; } -void init_threat_offsets() { - int cumulativeOffset = 0; - for (Piece piece : AllPieces) - { - int pieceIdx = piece; - int cumulativePieceOffset = 0; +// The final index is calculated from summing data found in these two LUTs, as well +// as offsets[attacker][from] - for (Square from = SQ_A1; from <= SQ_H8; ++from) - { - offsets[pieceIdx][from] = cumulativePieceOffset; - - if (type_of(piece) != PAWN) - { - Bitboard attacks = attacks_bb(piece, from, 0ULL); - cumulativePieceOffset += popcount(attacks); - } - - else if (from >= SQ_A2 && from <= SQ_H7) - { - Bitboard attacks = (pieceIdx < 8) ? pawn_attacks_bb(square_bb(from)) - : pawn_attacks_bb(square_bb(from)); - cumulativePieceOffset += popcount(attacks); - } - } - - helper_offsets[pieceIdx] = {cumulativePieceOffset, cumulativeOffset}; - - cumulativeOffset += numValidTargets[pieceIdx] * cumulativePieceOffset; - } - - init_index_luts(); -} +// [attacker][attacked] +constexpr auto index_lut1 = init_index_luts(); +// [attacker][from][to] +constexpr auto index_lut2 = index_lut2_array(); // Index of a feature for a given king position and another piece on some square inline sf_always_inline IndexType FullThreats::make_index( diff --git a/src/nnue/features/full_threats.h b/src/nnue/features/full_threats.h index 177e9fabe..e4fa3331b 100644 --- a/src/nnue/features/full_threats.h +++ b/src/nnue/features/full_threats.h @@ -32,7 +32,6 @@ namespace Stockfish::Eval::NNUE::Features { static constexpr int numValidTargets[PIECE_NB] = {0, 6, 12, 10, 10, 12, 8, 0, 0, 6, 12, 10, 10, 12, 8, 0}; -void init_threat_offsets(); class FullThreats { public: diff --git a/src/syzygy/tbprobe.cpp b/src/syzygy/tbprobe.cpp index e3f7c0a18..c371259d6 100644 --- a/src/syzygy/tbprobe.cpp +++ b/src/syzygy/tbprobe.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "../bitboard.h" #include "../misc.h" From c475024be75c1d239b6410aa8ec3122fb5b4260c Mon Sep 17 00:00:00 2001 From: Taras Vuk <117687515+TarasVuk@users.noreply.github.com> Date: Tue, 23 Dec 2025 21:31:48 +0100 Subject: [PATCH 06/23] Incorporate statscore into history bonus Passed STC: LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 80128 W: 20879 L: 20498 D: 38751 Ptnml(0-2): 274, 9318, 20496, 9705, 271 https://tests.stockfishchess.org/tests/view/6945d11f3c8768ca45072218 Passed LTC: LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 134298 W: 34497 L: 33983 D: 65818 Ptnml(0-2): 81, 14334, 37812, 14834, 88 https://tests.stockfishchess.org/tests/view/6947bf033c8768ca45072491 closes https://github.com/official-stockfish/Stockfish/pull/6488 Bench: 2325401 --- src/search.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 9c52592e0..c42fcd4ad 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1824,7 +1824,8 @@ void update_all_stats(const Position& pos, Piece movedPiece = pos.moved_piece(bestMove); PieceType capturedPiece; - int bonus = std::min(116 * depth - 81, 1515) + 347 * (bestMove == ttMove); + int bonus = + std::min(116 * depth - 81, 1515) + 347 * (bestMove == ttMove) + (ss - 1)->statScore / 32; int malus = std::min(848 * depth - 207, 2446) - 17 * moveCount; if (!pos.capture_stage(bestMove)) From cd3a8373243d145291abe9e546fd0396fc0e73fd Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Sun, 28 Dec 2025 14:48:56 +0100 Subject: [PATCH 07/23] Refine reduction logic based on next-ply cutoff count Passed STC: LLR: 2.95 (-2.94,2.94) <0.00,2.00> Total: 38208 W: 10076 L: 9754 D: 18378 Ptnml(0-2): 139, 4390, 9742, 4676, 157 https://tests.stockfishchess.org/tests/view/6945bb6446f342e1ec211d93 Passed LTC: LLR: 2.95 (-2.94,2.94) <0.50,2.50> Total: 64086 W: 16529 L: 16157 D: 31400 Ptnml(0-2): 34, 6808, 17990, 7174, 37 https://tests.stockfishchess.org/tests/view/69479d303c8768ca45072446 closes https://github.com/official-stockfish/Stockfish/pull/6489 Bench: 2442415 --- src/search.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index c42fcd4ad..8ac58fbab 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1203,8 +1203,9 @@ moves_loop: // When in check, search starts here r += 1119; // Increase reduction if next ply has a lot of fail high - if ((ss + 1)->cutoffCnt > 2) - r += 991 + allNode * 923; + if ((ss + 1)->cutoffCnt > 1) + r += 120 + 1024 * ((ss + 1)->cutoffCnt > 2) + 100 * ((ss + 1)->cutoffCnt > 3) + + 1024 * allNode; // For first picked move (ttMove) reduce reduction if (move == ttData.move) From 9d69577e1937aa532a832040c1a4616a4971c508 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Sun, 28 Dec 2025 14:50:12 +0100 Subject: [PATCH 08/23] Removing redundant parentheses closes https://github.com/official-stockfish/Stockfish/pull/6490 No functional change --- src/evaluate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index d20843e85..e7133f2df 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -42,8 +42,8 @@ namespace Stockfish { // an approximation of the material advantage on the board in terms of pawns. int Eval::simple_eval(const Position& pos) { Color c = pos.side_to_move(); - return PawnValue * (pos.count(c) - pos.count(~c)) - + (pos.non_pawn_material(c) - pos.non_pawn_material(~c)); + return PawnValue * (pos.count(c) - pos.count(~c)) + pos.non_pawn_material(c) + - pos.non_pawn_material(~c); } bool Eval::use_smallnet(const Position& pos) { return std::abs(simple_eval(pos)) > 962; } From 06819ad54c728aa873098e29094f22236a8bb3a6 Mon Sep 17 00:00:00 2001 From: Joost VandeVondele Date: Sun, 28 Dec 2025 14:51:09 +0100 Subject: [PATCH 09/23] Update Top CPU Contributors update to current closes https://github.com/official-stockfish/Stockfish/pull/6491 No functional change --- Top CPU Contributors.txt | 227 +++++++++++++++++++++++---------------- 1 file changed, 132 insertions(+), 95 deletions(-) diff --git a/Top CPU Contributors.txt b/Top CPU Contributors.txt index 4e598ecfc..f8134a199 100644 --- a/Top CPU Contributors.txt +++ b/Top CPU Contributors.txt @@ -1,89 +1,101 @@ -Contributors to Fishtest with >10,000 CPU hours, as of 2025-03-22. +Contributors to Fishtest with >10,000 CPU hours, as of 2025-12-24. Thank you! Username CPU Hours Games played ------------------------------------------------------------------ -noobpwnftw 41712226 3294628533 -vdv 28993864 954145232 -technologov 24984442 1115931964 -linrock 11463033 741692823 +noobpwnftw 42692720 3385202467 +vdv 39922218 1277282126 +technologov 26354561 1163905856 +linrock 12002255 785641643 +olafm 3030005 197722318 mlang 3026000 200065824 -okrout 2726068 248285678 -olafm 2420096 161297116 -pemo 1838361 62294199 -TueRens 1804847 80170868 +okrout 3020471 268364402 +pemo 2009761 66178221 +TueRens 1956328 83294326 +sebastronomy 1806628 73868874 dew 1689162 100033738 -sebastronomy 1655637 67294942 -grandphish2 1474752 92156319 -JojoM 1130625 73666098 -rpngn 973590 59996557 -oz 921203 60370346 +grandphish2 1479778 92306101 +JojoM 1130646 73666860 +rpngn 1081976 65292619 +oz 1029329 69522328 +gvreuls 844572 59249068 tvijlbrief 796125 51897690 -gvreuls 792215 55184194 mibere 703840 46867607 -leszek 599745 44681421 +leszek 609538 45301765 cw 519602 34988289 fastgm 503862 30260818 -CSU_Dynasty 474794 31654170 -maximmasiutin 441753 28129452 -robal 437950 28869118 -ctoks 435150 28542141 +robal 503208 32703510 +maximmasiutin 500174 30818270 +CSU_Dynasty 481663 31916842 +ctoks 435431 28551199 crunchy 427414 27371625 bcross 415724 29061187 mgrabiak 380202 27586936 +tolkki963 358623 26373242 velislav 342588 22140902 ncfish1 329039 20624527 Fisherman 327231 21829379 -Sylvain27 317021 11494912 +Fifis 323909 16200123 +Sylvain27 320732 11671388 marrco 310446 19587107 +Calis007 310201 18969692 +Viren6 297938 5847458 Dantist 296386 18031762 -Fifis 289595 14969251 -tolkki963 286043 23596996 -Calis007 272677 17281620 +naclosagc 296040 13865010 +anematode 293146 3918134 +maposora 278093 20454200 +javran 271465 20506096 cody 258835 13301710 nordlandia 249322 16420192 -javran 212141 16507618 +Goatminola 218812 21411814 +Torom 211061 7238522 glinscott 208125 13277240 drabel 204167 13930674 +Wencey 203584 9943614 mhoram 202894 12601997 +sschnee 201756 12874780 bking_US 198894 11876016 -Wencey 198537 9606420 +Mineta 195312 10337614 Thanar 179852 12365359 -sschnee 170521 10891112 -armo9494 168141 11177514 +armo9494 169747 11254404 +amicic 161636 11290899 DesolatedDodo 160605 10392474 +markkulix 158320 13538874 spams 157128 10319326 -maposora 155839 13963260 sqrt2 147963 9724586 -vdbergh 140514 9242985 +vdbergh 141201 9308647 jcAEie 140086 10603658 CoffeeOne 137100 5024116 malala 136182 8002293 -Goatminola 134893 11640524 xoto 133759 9159372 -markkulix 132104 11000548 -naclosagc 131472 4660806 -Dubslow 129685 8527664 +Dubslow 130795 8609646 +zeryl 129154 7911565 davar 129023 8376525 DMBK 122960 8980062 +cuistot 122470 8393996 +megaman7de 122254 8066174 dsmith 122059 7570238 Wolfgang 120919 8619168 CypressChess 120902 8683904 -amicic 119661 7938029 -cuistot 116864 7828864 sterni1971 113754 6054022 +Spprtr 113356 8129809 Data 113305 8220352 BrunoBanani 112960 7436849 -megaman7de 109139 7360928 skiminki 107583 7218170 -zeryl 104523 6618969 +MediumBerry5575 103884 7830022 MaZePallas 102823 6633619 +YvesKn 102213 5098076 sunu 100167 7040199 -thirdlife 99178 2246544 +thirdlife 99182 2246960 ElbertoOne 99028 7023771 +TechiePirate 98957 1249064 +DeepnessFulled 97313 5083358 TataneSan 97257 4239502 romangol 95662 7784954 bigpen0r 94825 6529241 +jojo2357 94358 7635486 +malfoy 92712 3392874 +voidedstarlight 92582 2342038 brabos 92118 6186135 Maxim 90818 3283364 psk 89957 5984901 @@ -92,26 +104,26 @@ jromang 87260 5988073 racerschmacer 85805 6122790 Vizvezdenec 83761 5344740 0x3C33 82614 5271253 -Spprtr 82103 5663635 +MarcusTullius 82359 5335665 BRAVONE 81239 5054681 -MarcusTullius 78930 5189659 -Mineta 78731 4947996 -Torom 77978 2651656 +rn 78566 6000852 nssy 76497 5259388 woutboat 76379 6031688 teddybaer 75125 5407666 Pking_cda 73776 5293873 -Viren6 73664 1356502 yurikvelo 73611 5046822 +Zirie 71260 4602355 Bobo1239 70579 4794999 solarlight 70517 5028306 dv8silencer 70287 3883992 +0x539 67147 2918044 manap 66273 4121774 tinker 64333 4268790 +CounterFlow 63914 3775062 +mecevdimitar 62493 3508750 +DanielMiao1 62188 1335664 qurashee 61208 3429862 -DanielMiao1 60181 1317252 AGI 58316 4336328 -jojo2357 57435 4944212 robnjr 57262 4053117 Freja 56938 3733019 MaxKlaxxMiner 56879 3423958 @@ -120,44 +132,52 @@ rkl 55132 4164467 jmdana 54988 4041917 notchris 53936 4184018 renouve 53811 3501516 -CounterFlow 52536 3203740 +jibarbosa 53504 5110028 +somethingintheshadows 52333 4344808 finfish 51360 3370515 eva42 51272 3599691 eastorwest 51117 3454811 +sylvek 50391 3765170 rap 49985 3219146 pb00067 49733 3298934 GPUex 48686 3684998 OuaisBla 48626 3445134 +lemtea 48563 1672454 ronaldjerum 47654 3240695 +abdicj 46740 2709482 biffhero 46564 3111352 -oryx 46141 3583236 -jibarbosa 45890 4541218 -DeepnessFulled 45734 3944282 -abdicj 45577 2631772 +oryx 46422 3607582 VoyagerOne 45476 3452465 -mecevdimitar 44240 2584396 +rdp65536 43948 2881890 speedycpu 43842 3003273 jbwiebe 43305 2805433 gopeto 43046 2821514 -YvesKn 42628 2177630 Antihistamine 41788 2761312 mhunt 41735 2691355 -somethingintheshadows 41502 3330418 +WoodMan777 40858 3491196 +Epic29 40771 4067404 +drauh 40419 1634770 homyur 39893 2850481 gri 39871 2515779 vidar808 39774 1656372 +Gaster319 38994 3477702 Garf 37741 2999686 SC 37299 2731694 -Gaster319 37229 3289674 +ZacHFX 36533 2553282 csnodgrass 36207 2688994 -ZacHFX 35528 2486328 -icewulf 34782 2415146 +icewulf 34935 2421834 strelock 34716 2074055 +Jopo12321 33921 2531448 +xuhdev 33798 3295210 +csnodgra 33780 1446866 EthanOConnor 33370 2090311 slakovv 32915 2021889 -shawnxu 32144 2814668 +IslandLambda 32667 1659344 +Kataiser 32477 2688862 +shawnxu 32330 2830036 +srowen 32248 1791136 +qgluca 31941 2491622 Gelma 31771 1551204 -srowen 31181 1732120 kdave 31157 2198362 manapbk 30987 1810399 votoanthuan 30691 2460856 @@ -168,15 +188,26 @@ spcc 29925 1901692 hyperbolic.tom 29840 2017394 chuckstablers 29659 2093438 Pyafue 29650 1902349 -WoodMan777 29300 2579864 +Flopzee 29388 1899905 +hoching 29054 2067144 belzedar94 28846 1811530 +wizardassassin 28007 2318204 +purpletree 27892 2061966 +Kyrega 27674 963872 +joendter 27193 1781570 +Danielv123 27132 1043614 chriswk 26902 1868317 xwziegtm 26897 2124586 -Jopo12321 26818 1816482 +spotscene 26877 2139674 achambord 26582 1767323 +shreven 26448 1703328 Patrick_G 26276 1801617 yorkman 26193 1992080 -Ulysses 25517 1711634 +ols 26173 1443517 +wer 26136 793146 +Skiff84 26083 1135002 +RudyMars 25980 2211364 +Ulysses 25544 1714542 SFTUser 25182 1675689 nabildanial 25068 1531665 Sharaf_DG 24765 1786697 @@ -184,30 +215,28 @@ rodneyc 24376 1416402 jsys14 24297 1721230 AndreasKrug 24235 1934711 agg177 23890 1395014 +Disservin 23768 1934576 Ente 23752 1678188 JanErik 23408 1703875 Isidor 23388 1680691 Norabor 23371 1603244 Nullvalue 23155 2022752 fishtester 23115 1581502 -wizardassassin 23073 1789536 -Skiff84 22984 1053680 cisco2015 22920 1763301 -ols 22914 1322047 Hjax 22561 1566151 -Zirie 22542 1472937 +gerbil 22435 1679842 +Serpensin 22396 1861156 team-oh 22272 1636708 mkstockfishtester 22253 2029566 Roady 22220 1465606 +tsim67 22077 1353048 MazeOfGalious 21978 1629593 sg4032 21950 1643373 -tsim67 21939 1343944 +sev 21791 1983016 ianh2105 21725 1632562 -Serpensin 21704 1809188 xor12 21628 1680365 dex 21612 1467203 nesoneg 21494 1463031 -IslandLambda 21468 1239756 user213718 21454 1404128 sphinx 21211 1384728 qoo_charly_cai 21136 1514927 @@ -215,22 +244,20 @@ jjoshua2 21001 1423089 Zake9298 20938 1565848 horst.prack 20878 1465656 0xB00B1ES 20590 1208666 +t3hf1sht3ster 20544 673134 Dinde 20459 1292774 -t3hf1sht3ster 20456 670646 j3corre 20405 941444 -0x539 20332 1039516 Adrian.Schmidt123 20316 1281436 -malfoy 20313 1350694 -purpletree 20019 1461026 wei 19973 1745989 teenychess 19819 1762006 +RickGroszkiewicz 19749 1913986 rstoesser 19569 1293588 eudhan 19274 1283717 nalanzeyu 19211 396674 vulcan 18871 1729392 Karpovbot 18766 1053178 +Farseer 18536 1078326 jundery 18445 1115855 -Farseer 18281 1074642 sebv15 18267 1262588 whelanh 17887 347974 ville 17883 1384026 @@ -239,84 +266,94 @@ purplefishies 17595 1092533 dju 17414 981289 iisiraider 17275 1049015 Karby 17177 1030688 +fogleman 17134 815562 +zhujianzhao 17111 1666972 DragonLord 17014 1162790 -pirt 16991 1274215 +pirt 16993 1274363 redstone59 16842 1461780 Alb11747 16787 1213990 Naven94 16414 951718 scuzzi 16155 995347 IgorLeMasson 16064 1147232 +micpilar 15866 1399266 ako027ako 15671 1173203 -xuhdev 15516 1528278 infinigon 15285 965966 +fishtrawler 15205 1436165 Nikolay.IT 15154 1068349 Andrew Grant 15114 895539 OssumOpossum 14857 1007129 LunaticBFF57 14525 1190310 +YELNAMRON 14480 1141420 enedene 14476 905279 -YELNAMRON 14475 1141330 -RickGroszkiewicz 14272 1385984 -joendter 14269 982014 +MooTheCow 14459 1023868 +BestBoyBerlin 14353 1365584 bpfliegel 14233 882523 mpx86 14019 759568 jpulman 13982 870599 getraideBFF 13871 1172846 crocogoat 13817 1119086 Nesa92 13806 1116101 -joster 13710 946160 +joster 13717 946960 mbeier 13650 1044928 Pablohn26 13552 1088532 wxt9861 13550 1312306 +biniek 13469 930029 Dark_wizzie 13422 1007152 +Jackfish 13422 914984 +Hongildong 13297 699288 Rudolphous 13244 883140 -Jackfish 13177 894206 -MooTheCow 13091 892304 +Phoenix17 13032 1124066 Machariel 13010 863104 mabichito 12903 749391 +FormazChar 12899 980413 thijsk 12886 722107 AdrianSA 12860 804972 -Flopzee 12698 894821 -szczur90 12684 977536 -Kyrega 12661 456438 +szczur90 12720 979324 mschmidt 12644 863193 korposzczur 12606 838168 fatmurphy 12547 853210 -Oakwen 12532 855759 +Oakwen 12537 856257 SapphireBrand 12416 969604 +Snuuka 12392 509082 deflectooor 12386 579392 modolief 12386 896470 ckaz 12273 754644 -Hongildong 12201 648712 pgontarz 12151 848794 dbernier 12103 860824 -FormazChar 12051 913497 -shreven 12044 884734 rensonthemove 11999 971993 stocky 11954 699440 +ali-al-zhrani 11887 836126 3cho 11842 1036786 +Craftyawesome 11736 832254 +dragon123118 11578 1044142 ImperiumAeternum 11482 979142 +lvdv 11475 594400 infinity 11470 727027 +kusihe 11468 468450 +vaskoul 11446 976902 aga 11412 695127 Def9Infinity 11408 700682 torbjo 11395 729145 Thomas A. Anderson 11372 732094 savage84 11358 670860 d64 11263 789184 -ali-al-zhrani 11245 779246 -vaskoul 11144 953906 +Poly 11172 455568 +enizor 11140 630194 snicolet 11106 869170 dapper 11032 771402 Ethnikoi 10993 945906 -Snuuka 10938 435504 Karmatron 10871 678306 -gerbil 10871 1005842 +zarthus 10773 1034536 OliverClarke 10696 942654 +Omed 10680 669816 +cyberthink 10647 936538 basepi 10637 744851 michaelrpg 10624 748179 Cubox 10621 826448 -dragon123118 10421 936506 +GBx3TV 10499 343266 +Styx 10450 867836 OIVAS7572 10420 995586 -GBx3TV 10388 339952 Garruk 10365 706465 dzjp 10343 732529 +Lorenz 10311 886308 borinot 10026 902130 From 1047f844d13ba890463c0eaf337b4fef613c2725 Mon Sep 17 00:00:00 2001 From: Daniel Monroe Date: Sun, 28 Dec 2025 14:52:56 +0100 Subject: [PATCH 10/23] Simplify doDeeperSearch Passed simplification STC LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 92096 W: 23888 L: 23728 D: 44480 Ptnml(0-2): 336, 10796, 23608, 10988, 320 https://tests.stockfishchess.org/tests/view/694b6b9d572093c1986d6ae0 Passed simplification LTC LLR: 2.96 (-2.94,2.94) <-1.75,0.25> Total: 50064 W: 12789 L: 12598 D: 24677 Ptnml(0-2): 24, 5350, 14103, 5521, 34 https://tests.stockfishchess.org/tests/view/694d49aa572093c1986d7021 closes https://github.com/official-stockfish/Stockfish/pull/6493 Bench: 2494221 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 8ac58fbab..41bbcd6d3 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1242,7 +1242,7 @@ moves_loop: // When in check, search starts here { // Adjust full-depth search based on LMR results - if the result was // good enough search deeper, if it was bad enough search shallower. - const bool doDeeperSearch = d < newDepth && value > (bestValue + newDepth + 44); + const bool doDeeperSearch = d < newDepth && value > bestValue + 50; const bool doShallowerSearch = value < bestValue + 9; newDepth += doDeeperSearch - doShallowerSearch; From b2e60960b39d7191105193d5ff8b7482dbcbf351 Mon Sep 17 00:00:00 2001 From: KazApps Date: Sun, 28 Dec 2025 14:54:37 +0100 Subject: [PATCH 11/23] Fix nonPawnKey Fix incorrect nonPawnKey update Passed non-reg SMP STC: ``` LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 139424 W: 35792 L: 35690 D: 67942 Ptnml(0-2): 197, 15783, 37665, 15855, 212 ``` https://tests.stockfishchess.org/tests/view/694b7b7e572093c1986d6b0d Passed non-reg SMP LTC: ``` LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 88880 W: 22863 L: 22718 D: 43299 Ptnml(0-2): 16, 8947, 26401, 9028, 48 ``` https://tests.stockfishchess.org/tests/view/694d2ceb572093c1986d6fc8 fixes https://github.com/official-stockfish/Stockfish/issues/6492 closes https://github.com/official-stockfish/Stockfish/pull/6494 Bench: 2475788 --- src/position.cpp | 1 + src/search.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/position.cpp b/src/position.cpp index 7377b2029..cfbb85e84 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -855,6 +855,7 @@ void Position::do_move(Move m, k ^= Zobrist::psq[promotion][to]; st->materialKey ^= Zobrist::psq[promotion][8 + pieceCount[promotion] - 1] ^ Zobrist::psq[pc][8 + pieceCount[pc]]; + st->nonPawnKey[us] ^= Zobrist::psq[promotion][to]; if (promotionType <= BISHOP) st->minorPieceKey ^= Zobrist::psq[promotion][to]; diff --git a/src/search.cpp b/src/search.cpp index 41bbcd6d3..86b69db57 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -89,7 +89,7 @@ int correction_value(const Worker& w, const Position& pos, const Stack* const ss + (*(ss - 4)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()] : 8; - return 10347 * pcv + 8821 * micv + 11168 * (wnpcv + bnpcv) + 7841 * cntcv; + return 10347 * pcv + 8821 * micv + 11665 * (wnpcv + bnpcv) + 7841 * cntcv; } // Add correctionHistory value to raw staticEval and guarantee evaluation From 1780c1fd6e1e63a852e5b901656ed6d76188b726 Mon Sep 17 00:00:00 2001 From: Stefan Geschwentner Date: Sun, 28 Dec 2025 14:54:57 +0100 Subject: [PATCH 12/23] For expected ALL nodes scale up reduction with depth dependent factor. Passed STC: LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 141120 W: 36860 L: 36390 D: 67870 Ptnml(0-2): 470, 16441, 36314, 16819, 516 https://tests.stockfishchess.org/tests/view/694978e93c8768ca45072763 Passed LTC: LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 66576 W: 17078 L: 16700 D: 32798 Ptnml(0-2): 45, 7093, 18628, 7483, 39 https://tests.stockfishchess.org/tests/view/694bb608572093c1986d6ba6 closes https://github.com/official-stockfish/Stockfish/pull/6496 Bench: 2503391 --- src/search.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/search.cpp b/src/search.cpp index 86b69db57..95dd97196 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1222,6 +1222,10 @@ moves_loop: // When in check, search starts here // Decrease/increase reduction for moves with a good/bad history r -= ss->statScore * 850 / 8192; + // Scale up reductions for expected ALL nodes + if (allNode) + r += r / (depth + 1); + // Step 17. Late moves reduction / extension (LMR) if (depth >= 2 && moveCount > 1) { From 969285fa5dff3c8367784758627cde732a886727 Mon Sep 17 00:00:00 2001 From: anematode Date: Sun, 28 Dec 2025 14:56:46 +0100 Subject: [PATCH 13/23] Shared pawn history MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Passed STC SMP](https://tests.stockfishchess.org/tests/view/694e506c572093c1986d7276): ``` LLR: 2.97 (-2.94,2.94) <0.00,2.00> Total: 14992 W: 3924 L: 3653 D: 7415 Ptnml(0-2): 20, 1547, 4090, 1820, 19 ``` [Passed LTC SMP](https://tests.stockfishchess.org/tests/live_elo/694ead61572093c1986d7365): ``` LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 41146 W: 10654 L: 10342 D: 20150 Ptnml(0-2): 17, 3999, 12225, 4319, 13 ``` [Passed a sanity check STC SMP post-refactoring](https://tests.stockfishchess.org/tests/view/69503997572093c1986d763a): ``` LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 46728 W: 12178 L: 11863 D: 22687 Ptnml(0-2): 82, 5093, 12685, 5436, 68 ``` (The large gain of the first STC was probably a fluke, and this result is more reasonable!) After shared correction history, Viz suggested we try sharing other histories, especially `pawnHistory`. As far as we're aware, sharing history besides correction history (like Caissa does) is novel. The implementation follows the same pattern as shared correction history – the size of the history table is scaled with `next_power_of_two(threadsInNumaNode)` and the entry is prefetched in `do_move`. A bit of refactoring was done to accommodate this new history. Note that we prefetch `&history->pawn_entry(*this)[pc][to]` rather than `&history->pawn_entry(*this)` because unlike the other entries, each entry contains multiple cache lines. closes https://github.com/official-stockfish/Stockfish/pull/6498 Bench: 2503391 Co-authored-by: Michael Chaly --- src/history.h | 50 +++++++++++++++++++++++++++++++++--------------- src/movepick.cpp | 6 +++--- src/movepick.h | 4 ++-- src/position.cpp | 1 + src/search.cpp | 21 ++++++++------------ src/search.h | 1 - 6 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/history.h b/src/history.h index 127fb9ef3..9811d0397 100644 --- a/src/history.h +++ b/src/history.h @@ -35,22 +35,18 @@ namespace Stockfish { -constexpr int PAWN_HISTORY_SIZE = 8192; // has to be a power of 2 +constexpr int PAWN_HISTORY_BASE_SIZE = 8192; // has to be a power of 2 constexpr int UINT_16_HISTORY_SIZE = std::numeric_limits::max() + 1; constexpr int CORRHIST_BASE_SIZE = UINT_16_HISTORY_SIZE; constexpr int CORRECTION_HISTORY_LIMIT = 1024; constexpr int LOW_PLY_HISTORY_SIZE = 5; -static_assert((PAWN_HISTORY_SIZE & (PAWN_HISTORY_SIZE - 1)) == 0, - "PAWN_HISTORY_SIZE has to be a power of 2"); +static_assert((PAWN_HISTORY_BASE_SIZE & (PAWN_HISTORY_BASE_SIZE - 1)) == 0, + "PAWN_HISTORY_BASE_SIZE has to be a power of 2"); static_assert((CORRHIST_BASE_SIZE & (CORRHIST_BASE_SIZE - 1)) == 0, "CORRHIST_BASE_SIZE has to be a power of 2"); -inline int pawn_history_index(const Position& pos) { - return pos.pawn_key() & (PAWN_HISTORY_SIZE - 1); -} - // StatsEntry is the container of various numerical statistics. We use a class // instead of a naked value to directly call history update operator<<() on // the entry. The first template parameter T is the base type of the array, @@ -96,6 +92,9 @@ enum StatsType { template using Stats = MultiArray, Sizes...>; +template +using AtomicStats = MultiArray, Sizes...>; + // DynStats is a dynamically sized array of Stats, used for thread-shared histories // which should scale with the total number of threads. The SizeMultiplier gives // the per-thread allocation count of T. @@ -106,11 +105,13 @@ struct DynStats { data = make_unique_large_page(size); } // Sets all values in the range to 0 - void clear_range(size_t start, size_t end) { + void clear_range(int value, size_t threadIdx) { + size_t start = threadIdx * SizeMultiplier; assert(start < size); - assert(end <= size); - T* fill_start = &(*this)[start]; - memset(reinterpret_cast(fill_start), 0, sizeof(T) * (end - start)); + size_t end = std::min(start + SizeMultiplier, size); + + while (start < end) + data[start++].fill(value); } size_t get_size() const { return size; } T& operator[](size_t index) { @@ -149,7 +150,8 @@ using PieceToHistory = Stats; using ContinuationHistory = MultiArray; // PawnHistory is addressed by the pawn structure and a move's [piece][to] -using PawnHistory = Stats; +using PawnHistory = + DynStats, PAWN_HISTORY_BASE_SIZE>; // Correction histories record differences between the static evaluation of // positions and their search score. It is used to improve the static evaluation @@ -169,6 +171,13 @@ struct CorrectionBundle { StatsEntry minor; StatsEntry nonPawnWhite; StatsEntry nonPawnBlack; + + void operator=(T val) { + pawn = val; + minor = val; + nonPawnWhite = val; + nonPawnBlack = val; + } }; namespace Detail { @@ -212,13 +221,22 @@ using TTMoveHistory = StatsEntry; // the indexing more efficient. struct SharedHistories { SharedHistories(size_t threadCount) : - correctionHistory(threadCount) { + correctionHistory(threadCount), + pawnHistory(threadCount) { assert((threadCount & (threadCount - 1)) == 0 && threadCount != 0); - sizeMinus1 = correctionHistory.get_size() - 1; + sizeMinus1 = correctionHistory.get_size() - 1; + pawnHistSizeMinus1 = pawnHistory.get_size() - 1; } size_t get_size() const { return sizeMinus1 + 1; } + auto& pawn_entry(const Position& pos) { + return pawnHistory[pos.pawn_key() & pawnHistSizeMinus1]; + } + const auto& pawn_entry(const Position& pos) const { + return pawnHistory[pos.pawn_key() & pawnHistSizeMinus1]; + } + auto& pawn_correction_entry(const Position& pos) { return correctionHistory[pos.pawn_key() & sizeMinus1]; } @@ -243,9 +261,11 @@ struct SharedHistories { } UnifiedCorrectionHistory correctionHistory; + PawnHistory pawnHistory; + private: - size_t sizeMinus1; + size_t sizeMinus1, pawnHistSizeMinus1; }; } // namespace Stockfish diff --git a/src/movepick.cpp b/src/movepick.cpp index d20ab151e..15f64d1cb 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -87,14 +87,14 @@ MovePicker::MovePicker(const Position& p, const LowPlyHistory* lph, const CapturePieceToHistory* cph, const PieceToHistory** ch, - const PawnHistory* ph, + const SharedHistories* sh, int pl) : pos(p), mainHistory(mh), lowPlyHistory(lph), captureHistory(cph), continuationHistory(ch), - pawnHistory(ph), + sharedHistory(sh), ttMove(ttm), depth(d), ply(pl) { @@ -159,7 +159,7 @@ ExtMove* MovePicker::score(MoveList& ml) { { // histories m.value = 2 * (*mainHistory)[us][m.raw()]; - m.value += 2 * (*pawnHistory)[pawn_history_index(pos)][pc][to]; + m.value += 2 * sharedHistory->pawn_entry(pos)[pc][to]; m.value += (*continuationHistory[0])[pc][to]; m.value += (*continuationHistory[1])[pc][to]; m.value += (*continuationHistory[2])[pc][to]; diff --git a/src/movepick.h b/src/movepick.h index 5b3190594..b1e041c17 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -45,7 +45,7 @@ class MovePicker { const LowPlyHistory*, const CapturePieceToHistory*, const PieceToHistory**, - const PawnHistory*, + const SharedHistories*, int); MovePicker(const Position&, Move, int, const CapturePieceToHistory*); Move next_move(); @@ -64,7 +64,7 @@ class MovePicker { const LowPlyHistory* lowPlyHistory; const CapturePieceToHistory* captureHistory; const PieceToHistory** continuationHistory; - const PawnHistory* pawnHistory; + const SharedHistories* sharedHistory; Move ttMove; ExtMove * cur, *endCur, *endBadCaptures, *endCaptures, *endGenerated; int stage; diff --git a/src/position.cpp b/src/position.cpp index cfbb85e84..f32530fdd 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -885,6 +885,7 @@ void Position::do_move(Move m, if (history) { + prefetch(&history->pawn_entry(*this)[pc][to]); prefetch(&history->pawn_correction_entry(*this)); prefetch(&history->minor_piece_correction_entry(*this)); prefetch(&history->nonpawn_correction_entry(*this)); diff --git a/src/search.cpp b/src/search.cpp index 95dd97196..87a96cab8 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -580,14 +580,10 @@ void Search::Worker::undo_null_move(Position& pos) { pos.undo_null_move(); } void Search::Worker::clear() { mainHistory.fill(68); captureHistory.fill(-689); - pawnHistory.fill(-1238); // Each thread is responsible for clearing their part of shared history - size_t len = sharedHistory.get_size() / numaTotal; - size_t start = numaThreadIdx * len; - size_t end = std::min(start + len, sharedHistory.get_size()); - - sharedHistory.correctionHistory.clear_range(start, end); + sharedHistory.correctionHistory.clear_range(0, numaThreadIdx); + sharedHistory.pawnHistory.clear_range(-1238, numaThreadIdx); ttMoveHistory = 0; @@ -861,7 +857,7 @@ Value Search::Worker::search( mainHistory[~us][((ss - 1)->currentMove).raw()] << evalDiff * 9; if (!ttHit && type_of(pos.piece_on(prevSq)) != PAWN && ((ss - 1)->currentMove).type_of() != PROMOTION) - pawnHistory[pawn_history_index(pos)][pos.piece_on(prevSq)][prevSq] << evalDiff * 13; + sharedHistory.pawn_entry(pos)[pos.piece_on(prevSq)][prevSq] << evalDiff * 13; } @@ -992,7 +988,7 @@ moves_loop: // When in check, search starts here MovePicker mp(pos, ttData.move, depth, &mainHistory, &lowPlyHistory, &captureHistory, contHist, - &pawnHistory, ss->ply); + &sharedHistory, ss->ply); value = bestValue; @@ -1081,7 +1077,7 @@ moves_loop: // When in check, search starts here { int history = (*contHist[0])[movedPiece][move.to_sq()] + (*contHist[1])[movedPiece][move.to_sq()] - + pawnHistory[pawn_history_index(pos)][movedPiece][move.to_sq()]; + + sharedHistory.pawn_entry(pos)[movedPiece][move.to_sq()]; // Continuation history based pruning if (history < -4083 * depth) @@ -1439,7 +1435,7 @@ moves_loop: // When in check, search starts here mainHistory[~us][((ss - 1)->currentMove).raw()] << scaledBonus * 243 / 32768; if (type_of(pos.piece_on(prevSq)) != PAWN && ((ss - 1)->currentMove).type_of() != PROMOTION) - pawnHistory[pawn_history_index(pos)][pos.piece_on(prevSq)][prevSq] + sharedHistory.pawn_entry(pos)[pos.piece_on(prevSq)][prevSq] << scaledBonus * 1160 / 32768; } @@ -1611,7 +1607,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) // the moves. We presently use two stages of move generator in quiescence search: // captures, or evasions only when in check. MovePicker mp(pos, ttData.move, DEPTH_QS, &mainHistory, &lowPlyHistory, &captureHistory, - contHist, &pawnHistory, ss->ply); + contHist, &sharedHistory, ss->ply); // Step 5. Loop through all pseudo-legal moves until no moves remain or a beta // cutoff occurs. @@ -1900,8 +1896,7 @@ void update_quiet_histories( update_continuation_histories(ss, pos.moved_piece(move), move.to_sq(), bonus * 896 / 1024); - int pIndex = pawn_history_index(pos); - workerThread.pawnHistory[pIndex][pos.moved_piece(move)][move.to_sq()] + workerThread.sharedHistory.pawn_entry(pos)[pos.moved_piece(move)][move.to_sq()] << bonus * (bonus > 0 ? 905 : 505) / 1024; } diff --git a/src/search.h b/src/search.h index 9644f6aa5..eb4dda77c 100644 --- a/src/search.h +++ b/src/search.h @@ -292,7 +292,6 @@ class Worker { CapturePieceToHistory captureHistory; ContinuationHistory continuationHistory[2][2]; - PawnHistory pawnHistory; CorrectionHistory continuationCorrectionHistory; TTMoveHistory ttMoveHistory; From 44d5467bbe06789e8a3cbaee87e699e033b3081a Mon Sep 17 00:00:00 2001 From: Timothy Herchen Date: Sun, 28 Dec 2025 14:57:28 +0100 Subject: [PATCH 14/23] Remove -Wstack-usage on (apple) clang Clang pretends to be GCC, but is enraged by `-Wstack-usage`: closes https://github.com/official-stockfish/Stockfish/pull/6499 No functional change --- src/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index cc85ac78e..bf3fbe80f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -436,7 +436,7 @@ endif ifeq ($(COMP),gcc) comp=gcc CXX=g++ - CXXFLAGS += -pedantic -Wextra -Wshadow -Wmissing-declarations -Wstack-usage=128000 + CXXFLAGS += -pedantic -Wextra -Wshadow -Wmissing-declarations ifeq ($(arch),$(filter $(arch),armv7 armv8 riscv64)) ifeq ($(OS),Android) @@ -607,6 +607,8 @@ ifeq ($(COMP),gcc) ifneq ($(gccisclang),) profile_make = clang-profile-make profile_use = clang-profile-use + else + CXXFLAGS += -Wstack-usage=128000 endif endif From e0fb783c30f86d9ff01328b14fefded21492677e Mon Sep 17 00:00:00 2001 From: Joost VandeVondele Date: Wed, 31 Dec 2025 15:55:00 +0100 Subject: [PATCH 15/23] Fix incorrect initialization Fixes https://github.com/official-stockfish/Stockfish/issues/6505 Missing initialization seemingly resulting in side effects, as discussed in the issue. Credit to Sopel for spotting the bug. PR used as a testcase for CoPilot, doing the right thing https://github.com/official-stockfish/Stockfish/pull/6478#discussion_r2655467218 closes https://github.com/official-stockfish/Stockfish/pull/6511 No functional change --- src/history.h | 6 +++--- src/search.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/history.h b/src/history.h index 9811d0397..3aa9ef623 100644 --- a/src/history.h +++ b/src/history.h @@ -105,10 +105,10 @@ struct DynStats { data = make_unique_large_page(size); } // Sets all values in the range to 0 - void clear_range(int value, size_t threadIdx) { - size_t start = threadIdx * SizeMultiplier; + void clear_range(int value, size_t threadIdx, size_t numaTotal) { + size_t start = uint64_t(threadIdx) * size / numaTotal; assert(start < size); - size_t end = std::min(start + SizeMultiplier, size); + size_t end = threadIdx + 1 == numaTotal ? size : uint64_t(threadIdx + 1) * size / numaTotal; while (start < end) data[start++].fill(value); diff --git a/src/search.cpp b/src/search.cpp index 87a96cab8..c1a7d5880 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -582,8 +582,8 @@ void Search::Worker::clear() { captureHistory.fill(-689); // Each thread is responsible for clearing their part of shared history - sharedHistory.correctionHistory.clear_range(0, numaThreadIdx); - sharedHistory.pawnHistory.clear_range(-1238, numaThreadIdx); + sharedHistory.correctionHistory.clear_range(0, numaThreadIdx, numaTotal); + sharedHistory.pawnHistory.clear_range(-1238, numaThreadIdx, numaTotal); ttMoveHistory = 0; From 145369149620591f7205faaa7f5ee44bdd5ce15e Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Wed, 31 Dec 2025 11:20:25 +0100 Subject: [PATCH 16/23] Fix feature check Use _POSIX_C_SOURCE to check for PTHREAD_MUTEX_ROBUST support. The latter is a enum, not a defined variable. closes https://github.com/official-stockfish/Stockfish/pull/6510 No functional change --- src/shm_linux.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shm_linux.h b/src/shm_linux.h index a8b5404b2..52abe8ec4 100644 --- a/src/shm_linux.h +++ b/src/shm_linux.h @@ -502,7 +502,7 @@ class SharedMemory: public detail::SharedMemoryBase { return false; bool success = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) == 0; -#ifdef PTHREAD_MUTEX_ROBUST +#if _POSIX_C_SOURCE >= 200809L if (success) success = pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST) == 0; #endif @@ -524,7 +524,7 @@ class SharedMemory: public detail::SharedMemoryBase { if (rc == 0) return true; -#ifdef PTHREAD_MUTEX_ROBUST +#if _POSIX_C_SOURCE >= 200809L if (rc == EOWNERDEAD) { if (pthread_mutex_consistent(&header_ptr_->mutex) == 0) From ced9f69834378f88efbf196d05666fb058fc4b00 Mon Sep 17 00:00:00 2001 From: Michael Chaly Date: Mon, 29 Dec 2025 10:47:40 +0300 Subject: [PATCH 17/23] Adjust main history with every new root position this patch dampens down main history to 3/4 of it value for all possible moves at the start of ID loop, making it partially refresh with every new root position. Passed STC: https://tests.stockfishchess.org/tests/view/694e33ff572093c1986d7234 LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 115520 W: 30164 L: 29735 D: 55621 Ptnml(0-2): 395, 13192, 30192, 13551, 430 Passed LTC: https://tests.stockfishchess.org/tests/view/6950cbe6572093c1986d816c LLR: 2.95 (-2.94,2.94) <0.50,2.50> Total: 63672 W: 16480 L: 16114 D: 31078 Ptnml(0-2): 46, 6524, 18329, 6892, 45 closes https://github.com/official-stockfish/Stockfish/pull/6504 bench 2710946 --- src/search.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index c1a7d5880..05f9b47fa 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -65,6 +65,7 @@ using namespace Search; namespace { constexpr int SEARCHEDLIST_CAPACITY = 32; +constexpr int mainHistoryDefault = 68; using SearchedList = ValueList; // (*Scalers): @@ -312,6 +313,10 @@ void Search::Worker::iterative_deepening() { lowPlyHistory.fill(97); + for (Color c: {WHITE, BLACK}) + for (int i = 0; i < UINT_16_HISTORY_SIZE; i++) + mainHistory[c][i] = (mainHistory[c][i] - mainHistoryDefault) * 3 / 4 + mainHistoryDefault; + // Iterative deepening loop until requested to stop or the target depth is reached while (++rootDepth < MAX_PLY && !threads.stop && !(limits.depth && mainThread && rootDepth > limits.depth)) @@ -578,7 +583,7 @@ void Search::Worker::undo_null_move(Position& pos) { pos.undo_null_move(); } // Reset histories, usually before a new game void Search::Worker::clear() { - mainHistory.fill(68); + mainHistory.fill(mainHistoryDefault); captureHistory.fill(-689); // Each thread is responsible for clearing their part of shared history From aeb3bf33a9bbf6dd662e9e570accf56c57eafbd7 Mon Sep 17 00:00:00 2001 From: anematode Date: Wed, 31 Dec 2025 17:44:43 -0800 Subject: [PATCH 18/23] port get_changed_pieces to ARM NEON passed STC: LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 71968 W: 18833 L: 18489 D: 34646 Ptnml(0-2): 192, 7310, 20643, 7640, 199 https://tests.stockfishchess.org/tests/view/69509e5c572093c1986d7a0a closes https://github.com/official-stockfish/Stockfish/pull/6512 No functional change --- src/nnue/nnue_accumulator.cpp | 12 ++++++++++++ src/search.cpp | 7 ++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/nnue/nnue_accumulator.cpp b/src/nnue/nnue_accumulator.cpp index 763fb7a5e..338d291e8 100644 --- a/src/nnue/nnue_accumulator.cpp +++ b/src/nnue/nnue_accumulator.cpp @@ -645,6 +645,18 @@ Bitboard get_changed_pieces(const std::array& oldPieces, sameBB |= static_cast(equalMask) << i; } return ~sameBB; +#elif defined(USE_NEON) + uint8x16x4_t old_v = vld4q_u8(reinterpret_cast(oldPieces.data())); + uint8x16x4_t new_v = vld4q_u8(reinterpret_cast(newPieces.data())); + auto cmp = [=](const int i) { return vceqq_u8(old_v.val[i], new_v.val[i]); }; + + uint8x16_t cmp0_1 = vsriq_n_u8(cmp(1), cmp(0), 1); + uint8x16_t cmp2_3 = vsriq_n_u8(cmp(3), cmp(2), 1); + uint8x16_t merged = vsriq_n_u8(cmp2_3, cmp0_1, 2); + merged = vsriq_n_u8(merged, merged, 4); + uint8x8_t sameBB = vshrn_n_u16(vreinterpretq_u16_u8(merged), 4); + + return ~vget_lane_u64(vreinterpret_u64_u8(sameBB), 0); #else Bitboard changed = 0; diff --git a/src/search.cpp b/src/search.cpp index 05f9b47fa..a880a741f 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -65,7 +65,7 @@ using namespace Search; namespace { constexpr int SEARCHEDLIST_CAPACITY = 32; -constexpr int mainHistoryDefault = 68; +constexpr int mainHistoryDefault = 68; using SearchedList = ValueList; // (*Scalers): @@ -313,9 +313,10 @@ void Search::Worker::iterative_deepening() { lowPlyHistory.fill(97); - for (Color c: {WHITE, BLACK}) + for (Color c : {WHITE, BLACK}) for (int i = 0; i < UINT_16_HISTORY_SIZE; i++) - mainHistory[c][i] = (mainHistory[c][i] - mainHistoryDefault) * 3 / 4 + mainHistoryDefault; + mainHistory[c][i] = + (mainHistory[c][i] - mainHistoryDefault) * 3 / 4 + mainHistoryDefault; // Iterative deepening loop until requested to stop or the target depth is reached while (++rootDepth < MAX_PLY && !threads.stop From 0317c6ccec12b15a80b8fbe98637c6f5a747f240 Mon Sep 17 00:00:00 2001 From: ppigazzini Date: Sun, 28 Dec 2025 14:10:23 +0100 Subject: [PATCH 19/23] build: rename WINE_PATH to RUN_PREFIX for wrapper execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WINE_PATH started as a Wine-specific knob, but it’s now used more generally as a command prefix to run the built engine under wrappers like Intel SDE, qemu-user, etc. - Add RUN_PREFIX as the supported “run wrapper/prefix” variable in Makefile - Set WINE_PATH as a deprecated alias - Update CI and scripts to use RUN_PREFIX closes https://github.com/official-stockfish/Stockfish/pull/6500 No functional change --- .github/workflows/arm_compilation.yml | 4 ++-- .github/workflows/compilation.yml | 4 ++-- src/Makefile | 21 ++++++++++++++++++--- tests/signature.sh | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/.github/workflows/arm_compilation.yml b/.github/workflows/arm_compilation.yml index 781bd8070..86d222182 100644 --- a/.github/workflows/arm_compilation.yml +++ b/.github/workflows/arm_compilation.yml @@ -80,9 +80,9 @@ jobs: export LDFLAGS="-static -Wno-unused-command-line-argument" fi make clean - make -j4 profile-build ARCH=$BINARY COMP=$COMP WINE_PATH=$EMU + make -j4 profile-build ARCH=$BINARY COMP=$COMP RUN_PREFIX=$EMU make strip ARCH=$BINARY COMP=$COMP - WINE_PATH=$EMU ../tests/signature.sh $benchref + RUN_PREFIX=$EMU ../tests/signature.sh $benchref mv ./stockfish$EXT ../stockfish-android-$BINARY$EXT - name: Remove non src files diff --git a/.github/workflows/compilation.yml b/.github/workflows/compilation.yml index 7805b24d6..473665ec2 100644 --- a/.github/workflows/compilation.yml +++ b/.github/workflows/compilation.yml @@ -76,9 +76,9 @@ jobs: - name: Compile ${{ matrix.config.binaries }} build run: | make clean - make -j4 profile-build ARCH=$BINARY COMP=$COMP WINE_PATH="$SDE" + make -j4 profile-build ARCH=$BINARY COMP=$COMP RUN_PREFIX="$SDE" make strip ARCH=$BINARY COMP=$COMP - WINE_PATH="$SDE" ../tests/signature.sh $benchref + RUN_PREFIX="$SDE" ../tests/signature.sh $benchref mv ./stockfish$EXT ../stockfish-$NAME-$BINARY$EXT - name: Remove non src files diff --git a/src/Makefile b/src/Makefile index bf3fbe80f..fa6297936 100644 --- a/src/Makefile +++ b/src/Makefile @@ -25,6 +25,21 @@ ifeq ($(KERNEL),Linux) OS := $(shell uname -o) endif +### Command prefix to run the built executable (e.g. wine, sde, qemu) +### Backward compatible alias: WINE_PATH (deprecated) +ifneq ($(strip $(WINE_PATH)),) +ifeq ($(strip $(RUN_PREFIX)),) +RUN_PREFIX := $(WINE_PATH) +endif +ifeq ($(MAKELEVEL),0) +ifneq ($(strip $(RUN_PREFIX)),$(strip $(WINE_PATH))) +$(warning *** Both RUN_PREFIX and WINE_PATH are set; ignoring WINE_PATH. ***) +else +$(warning *** WINE_PATH is deprecated; use RUN_PREFIX instead. ***) +endif +endif +endif + ### Target Windows OS ifeq ($(OS),Windows_NT) ifneq ($(COMP),ndk) @@ -32,8 +47,8 @@ ifeq ($(OS),Windows_NT) endif else ifeq ($(COMP),mingw) target_windows = yes - ifeq ($(WINE_PATH),) - WINE_PATH := $(shell which wine) + ifeq ($(RUN_PREFIX),) + RUN_PREFIX := $(shell which wine) endif endif @@ -49,7 +64,7 @@ PREFIX = /usr/local BINDIR = $(PREFIX)/bin ### Built-in benchmark for pgo-builds -PGOBENCH = $(WINE_PATH) ./$(EXE) bench +PGOBENCH = $(RUN_PREFIX) ./$(EXE) bench ### Source and object files SRCS = benchmark.cpp bitboard.cpp evaluate.cpp main.cpp \ diff --git a/tests/signature.sh b/tests/signature.sh index 0f6dd7585..ef781a0f4 100755 --- a/tests/signature.sh +++ b/tests/signature.sh @@ -18,7 +18,7 @@ error() trap 'error ${LINENO}' ERR # obtain -eval "$WINE_PATH ./stockfish bench" > "$STDOUT_FILE" 2> "$STDERR_FILE" || error ${LINENO} +eval "$RUN_PREFIX ./stockfish bench" > "$STDOUT_FILE" 2> "$STDERR_FILE" || error ${LINENO} signature=$(grep "Nodes searched : " "$STDERR_FILE" | awk '{print $4}') rm -f "$STDOUT_FILE" "$STDERR_FILE" From 593eeaf24c062482db095b331f10147e105524be Mon Sep 17 00:00:00 2001 From: anematode Date: Sun, 28 Dec 2025 12:18:33 -0800 Subject: [PATCH 20/23] simplify find_nnz a bit This code path is never taken for vector sizes >= 512, so we can simplify it. closes https://github.com/official-stockfish/Stockfish/pull/6501 No functional change --- .../layers/affine_transform_sparse_input.h | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/nnue/layers/affine_transform_sparse_input.h b/src/nnue/layers/affine_transform_sparse_input.h index 85c0dbfec..789ee454e 100644 --- a/src/nnue/layers/affine_transform_sparse_input.h +++ b/src/nnue/layers/affine_transform_sparse_input.h @@ -138,11 +138,12 @@ void find_nnz(const std::int32_t* RESTRICT input, using namespace SIMD; constexpr IndexType InputSimdWidth = sizeof(vec_uint_t) / sizeof(std::int32_t); - // Inputs are processed InputSimdWidth at a time and outputs are processed 8 at a time so we process in chunks of max(InputSimdWidth, 8) - constexpr IndexType ChunkSize = std::max(InputSimdWidth, 8); - constexpr IndexType NumChunks = InputDimensions / ChunkSize; - constexpr IndexType InputsPerChunk = ChunkSize / InputSimdWidth; - constexpr IndexType OutputsPerChunk = ChunkSize / 8; + // Outputs are processed 8 elements at a time, even if the SIMD width is narrower + constexpr IndexType ChunkSize = 8; + constexpr IndexType NumChunks = InputDimensions / ChunkSize; + constexpr IndexType InputsPerChunk = ChunkSize / InputSimdWidth; + + static_assert(InputsPerChunk > 0 && "SIMD width too wide"); const auto inputVector = reinterpret_cast(input); IndexType count = 0; @@ -157,15 +158,11 @@ void find_nnz(const std::int32_t* RESTRICT input, const vec_uint_t inputChunk = inputVector[i * InputsPerChunk + j]; nnz |= unsigned(vec_nnz(inputChunk)) << (j * InputSimdWidth); } - for (IndexType j = 0; j < OutputsPerChunk; ++j) - { - const unsigned lookup = (nnz >> (j * 8)) & 0xFF; - const vec128_t offsets = - vec128_load(reinterpret_cast(&Lookup.offset_indices[lookup])); - vec128_storeu(reinterpret_cast(out + count), vec128_add(base, offsets)); - count += popcount(lookup); - base = vec128_add(base, increment); - } + const vec128_t offsets = + vec128_load(reinterpret_cast(&Lookup.offset_indices[nnz])); + vec128_storeu(reinterpret_cast(out + count), vec128_add(base, offsets)); + count += popcount(nnz); + base = vec128_add(base, increment); } count_out = count; #endif From 5b9259e51fbf0231d2d97039f43590ff47a9d481 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Mon, 29 Dec 2025 00:51:10 +0300 Subject: [PATCH 21/23] Replacing nested loops with a single range-based for loop closes https://github.com/official-stockfish/Stockfish/pull/6503 No functional change --- src/nnue/nnue_feature_transformer.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/nnue/nnue_feature_transformer.h b/src/nnue/nnue_feature_transformer.h index ce23bdf0e..98b031f6b 100644 --- a/src/nnue/nnue_feature_transformer.h +++ b/src/nnue/nnue_feature_transformer.h @@ -145,15 +145,10 @@ class FeatureTransformer { } inline void scale_weights(bool read) { - for (IndexType j = 0; j < InputDimensions; ++j) - { - WeightType* w = &weights[j * HalfDimensions]; - for (IndexType i = 0; i < HalfDimensions; ++i) - w[i] = read ? w[i] * 2 : w[i] / 2; - } - - for (IndexType i = 0; i < HalfDimensions; ++i) - biases[i] = read ? biases[i] * 2 : biases[i] / 2; + for (auto& w : weights) + w = read ? w * 2 : w / 2; + for (auto& b : biases) + b = read ? b * 2 : b / 2; } // Read network parameters From 8815d1ef02038e5f60b974b2d24c380bbd6ba4d8 Mon Sep 17 00:00:00 2001 From: mstembera <5421953+mstembera@users.noreply.github.com> Date: Tue, 30 Dec 2025 20:45:32 -0800 Subject: [PATCH 22/23] Minor cleanup in full_threats.cpp closes https://github.com/official-stockfish/Stockfish/pull/6509 No functional change --- src/nnue/features/full_threats.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nnue/features/full_threats.cpp b/src/nnue/features/full_threats.cpp index 63b7f8e13..9006d851b 100644 --- a/src/nnue/features/full_threats.cpp +++ b/src/nnue/features/full_threats.cpp @@ -68,11 +68,11 @@ constexpr auto make_piece_indices_type() { std::array, SQUARE_NB> out{}; - for (int from = 0; from < SQUARE_NB; ++from) + for (Square from = SQ_A1; from <= SQ_H8; ++from) { - Bitboard attacks = PseudoAttacks[PT][Square(from)]; + Bitboard attacks = PseudoAttacks[PT][from]; - for (int to = 0; to < SQUARE_NB; ++to) + for (Square to = SQ_A1; to <= SQ_H8; ++to) { out[from][to] = constexpr_popcount(((1ULL << to) - 1) & attacks); } @@ -89,11 +89,11 @@ constexpr auto make_piece_indices_piece() { constexpr Color C = color_of(P); - for (int from = 0; from < SQUARE_NB; ++from) + for (Square from = SQ_A1; from <= SQ_H8; ++from) { Bitboard attacks = PseudoAttacks[C][from]; - for (int to = 0; to < SQUARE_NB; ++to) + for (Square to = SQ_A1; to <= SQ_H8; ++to) { out[from][to] = constexpr_popcount(((1ULL << to) - 1) & attacks); } @@ -323,11 +323,11 @@ void FullThreats::append_changed_indices(Color perspective, { if (first) { - fusedData->dp2removedOriginBoard |= square_bb(to); + fusedData->dp2removedOriginBoard |= to; continue; } } - else if (fusedData->dp2removedOriginBoard & square_bb(to)) + else if (fusedData->dp2removedOriginBoard & to) continue; } @@ -337,11 +337,11 @@ void FullThreats::append_changed_indices(Color perspective, { if (first) { - fusedData->dp2removedTargetBoard |= square_bb(from); + fusedData->dp2removedTargetBoard |= from; continue; } } - else if (fusedData->dp2removedTargetBoard & square_bb(from)) + else if (fusedData->dp2removedTargetBoard & from) continue; } } From 28844fc6975b002150190464914e5b340a2c9209 Mon Sep 17 00:00:00 2001 From: Joost VandeVondele Date: Thu, 1 Jan 2026 15:17:27 +0100 Subject: [PATCH 23/23] Update of the year Happy New Year! closes https://github.com/official-stockfish/Stockfish/pull/6514 No functional change --- src/Makefile | 2 +- src/benchmark.cpp | 2 +- src/benchmark.h | 2 +- src/bitboard.cpp | 2 +- src/bitboard.h | 2 +- src/engine.cpp | 2 +- src/engine.h | 2 +- src/evaluate.cpp | 2 +- src/evaluate.h | 2 +- src/history.h | 2 +- src/main.cpp | 2 +- src/memory.cpp | 2 +- src/memory.h | 2 +- src/misc.cpp | 2 +- src/misc.h | 2 +- src/movegen.cpp | 2 +- src/movegen.h | 2 +- src/movepick.cpp | 2 +- src/movepick.h | 2 +- src/nnue/features/full_threats.cpp | 2 +- src/nnue/features/full_threats.h | 2 +- src/nnue/features/half_ka_v2_hm.cpp | 2 +- src/nnue/features/half_ka_v2_hm.h | 2 +- src/nnue/layers/affine_transform.h | 2 +- src/nnue/layers/affine_transform_sparse_input.h | 2 +- src/nnue/layers/clipped_relu.h | 2 +- src/nnue/layers/sqr_clipped_relu.h | 2 +- src/nnue/network.cpp | 2 +- src/nnue/network.h | 2 +- src/nnue/nnue_accumulator.cpp | 2 +- src/nnue/nnue_accumulator.h | 2 +- src/nnue/nnue_architecture.h | 2 +- src/nnue/nnue_common.h | 2 +- src/nnue/nnue_feature_transformer.h | 2 +- src/nnue/nnue_misc.cpp | 2 +- src/nnue/nnue_misc.h | 2 +- src/nnue/simd.h | 2 +- src/numa.h | 2 +- src/perft.h | 2 +- src/position.cpp | 2 +- src/position.h | 2 +- src/score.cpp | 2 +- src/score.h | 2 +- src/search.cpp | 2 +- src/search.h | 2 +- src/shm.h | 2 +- src/shm_linux.h | 2 +- src/syzygy/tbprobe.cpp | 2 +- src/syzygy/tbprobe.h | 2 +- src/thread.cpp | 2 +- src/thread.h | 2 +- src/thread_win32_osx.h | 2 +- src/timeman.cpp | 2 +- src/timeman.h | 2 +- src/tt.cpp | 2 +- src/tt.h | 2 +- src/tune.cpp | 2 +- src/tune.h | 2 +- src/types.h | 2 +- src/uci.cpp | 2 +- src/uci.h | 2 +- src/ucioption.cpp | 2 +- src/ucioption.h | 2 +- 63 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/Makefile b/src/Makefile index fa6297936..dcd3f1fea 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ # Stockfish, a UCI chess playing engine derived from Glaurung 2.1 -# Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) +# Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) # # Stockfish is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/benchmark.cpp b/src/benchmark.cpp index 039e384c9..4e266db89 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/benchmark.h b/src/benchmark.h index d6bdc275d..a6606e78c 100644 --- a/src/benchmark.h +++ b/src/benchmark.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 350e56c92..4decb8d66 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/bitboard.h b/src/bitboard.h index 1da11d45c..f97ff3219 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/engine.cpp b/src/engine.cpp index 40466c8f8..355103c7b 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/engine.h b/src/engine.h index 6fd1ce040..10c92d759 100644 --- a/src/engine.h +++ b/src/engine.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/evaluate.cpp b/src/evaluate.cpp index e7133f2df..745bd3e4d 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/evaluate.h b/src/evaluate.h index 8ed2eb994..b4f54a381 100644 --- a/src/evaluate.h +++ b/src/evaluate.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/history.h b/src/history.h index 3aa9ef623..c98a7ee22 100644 --- a/src/history.h +++ b/src/history.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/main.cpp b/src/main.cpp index 107b5e43d..9a7376efb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/memory.cpp b/src/memory.cpp index f4aa8fc26..94a599399 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/memory.h b/src/memory.h index dad07df1d..c307a1317 100644 --- a/src/memory.h +++ b/src/memory.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/misc.cpp b/src/misc.cpp index 886544b6c..3ddae503c 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/misc.h b/src/misc.h index c9951e555..f1016b496 100644 --- a/src/misc.h +++ b/src/misc.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/movegen.cpp b/src/movegen.cpp index 697a83cdf..d22faad25 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/movegen.h b/src/movegen.h index 287fd8927..7f209f92a 100644 --- a/src/movegen.h +++ b/src/movegen.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/movepick.cpp b/src/movepick.cpp index 15f64d1cb..415d252f3 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/movepick.h b/src/movepick.h index b1e041c17..08bd9a539 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/features/full_threats.cpp b/src/nnue/features/full_threats.cpp index 9006d851b..4e3ba81cf 100644 --- a/src/nnue/features/full_threats.cpp +++ b/src/nnue/features/full_threats.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/features/full_threats.h b/src/nnue/features/full_threats.h index e4fa3331b..5b2582954 100644 --- a/src/nnue/features/full_threats.h +++ b/src/nnue/features/full_threats.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish 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 diff --git a/src/nnue/features/half_ka_v2_hm.cpp b/src/nnue/features/half_ka_v2_hm.cpp index 56779ddce..a82e89de4 100644 --- a/src/nnue/features/half_ka_v2_hm.cpp +++ b/src/nnue/features/half_ka_v2_hm.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/features/half_ka_v2_hm.h b/src/nnue/features/half_ka_v2_hm.h index c58a3246b..49b0a87a4 100644 --- a/src/nnue/features/half_ka_v2_hm.h +++ b/src/nnue/features/half_ka_v2_hm.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/layers/affine_transform.h b/src/nnue/layers/affine_transform.h index 7ead09327..a3d072f67 100644 --- a/src/nnue/layers/affine_transform.h +++ b/src/nnue/layers/affine_transform.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/layers/affine_transform_sparse_input.h b/src/nnue/layers/affine_transform_sparse_input.h index 789ee454e..5e0551f69 100644 --- a/src/nnue/layers/affine_transform_sparse_input.h +++ b/src/nnue/layers/affine_transform_sparse_input.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/layers/clipped_relu.h b/src/nnue/layers/clipped_relu.h index a8679d14d..7284c1033 100644 --- a/src/nnue/layers/clipped_relu.h +++ b/src/nnue/layers/clipped_relu.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/layers/sqr_clipped_relu.h b/src/nnue/layers/sqr_clipped_relu.h index 4218c0fe2..53412d014 100644 --- a/src/nnue/layers/sqr_clipped_relu.h +++ b/src/nnue/layers/sqr_clipped_relu.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/network.cpp b/src/nnue/network.cpp index a4d464df0..d1f2b14c3 100644 --- a/src/nnue/network.cpp +++ b/src/nnue/network.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/network.h b/src/nnue/network.h index ba8f469f7..d0e3218ca 100644 --- a/src/nnue/network.h +++ b/src/nnue/network.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/nnue_accumulator.cpp b/src/nnue/nnue_accumulator.cpp index 338d291e8..16af8d5f6 100644 --- a/src/nnue/nnue_accumulator.cpp +++ b/src/nnue/nnue_accumulator.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/nnue_accumulator.h b/src/nnue/nnue_accumulator.h index 1ccab5f2f..438074f43 100644 --- a/src/nnue/nnue_accumulator.h +++ b/src/nnue/nnue_accumulator.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/nnue_architecture.h b/src/nnue/nnue_architecture.h index 5093abdd7..71fce9bd5 100644 --- a/src/nnue/nnue_architecture.h +++ b/src/nnue/nnue_architecture.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/nnue_common.h b/src/nnue/nnue_common.h index 8a877ae2b..febe7ca70 100644 --- a/src/nnue/nnue_common.h +++ b/src/nnue/nnue_common.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/nnue_feature_transformer.h b/src/nnue/nnue_feature_transformer.h index 98b031f6b..99cda2a69 100644 --- a/src/nnue/nnue_feature_transformer.h +++ b/src/nnue/nnue_feature_transformer.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/nnue_misc.cpp b/src/nnue/nnue_misc.cpp index 220140e5e..66a6764a3 100644 --- a/src/nnue/nnue_misc.cpp +++ b/src/nnue/nnue_misc.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/nnue_misc.h b/src/nnue/nnue_misc.h index 7ecfd58a2..ecece5589 100644 --- a/src/nnue/nnue_misc.h +++ b/src/nnue/nnue_misc.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/nnue/simd.h b/src/nnue/simd.h index 6160221b9..25891163e 100644 --- a/src/nnue/simd.h +++ b/src/nnue/simd.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/numa.h b/src/numa.h index 76d265af2..99169c211 100644 --- a/src/numa.h +++ b/src/numa.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/perft.h b/src/perft.h index e249a8e49..24d125cbf 100644 --- a/src/perft.h +++ b/src/perft.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/position.cpp b/src/position.cpp index f32530fdd..d8b02e8ab 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/position.h b/src/position.h index e49e10f96..a136c0729 100644 --- a/src/position.h +++ b/src/position.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/score.cpp b/src/score.cpp index 561bc23c4..ea62577b9 100644 --- a/src/score.cpp +++ b/src/score.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/score.h b/src/score.h index eda90af35..cf89d3cdd 100644 --- a/src/score.h +++ b/src/score.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/search.cpp b/src/search.cpp index a880a741f..afdda262c 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/search.h b/src/search.h index eb4dda77c..202f7c8db 100644 --- a/src/search.h +++ b/src/search.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/shm.h b/src/shm.h index b870afc24..9bf13f234 100644 --- a/src/shm.h +++ b/src/shm.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/shm_linux.h b/src/shm_linux.h index 52abe8ec4..1e344e93f 100644 --- a/src/shm_linux.h +++ b/src/shm_linux.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/syzygy/tbprobe.cpp b/src/syzygy/tbprobe.cpp index c371259d6..8db007194 100644 --- a/src/syzygy/tbprobe.cpp +++ b/src/syzygy/tbprobe.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/syzygy/tbprobe.h b/src/syzygy/tbprobe.h index 4a6c3b763..7b60d6e20 100644 --- a/src/syzygy/tbprobe.h +++ b/src/syzygy/tbprobe.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/thread.cpp b/src/thread.cpp index eaf1d09bd..c485697da 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/thread.h b/src/thread.h index 2368c3069..f97e2b3f8 100644 --- a/src/thread.h +++ b/src/thread.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/thread_win32_osx.h b/src/thread_win32_osx.h index fb4b2ec97..5a8d43a2e 100644 --- a/src/thread_win32_osx.h +++ b/src/thread_win32_osx.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/timeman.cpp b/src/timeman.cpp index e82a1f6bf..4e98081bc 100644 --- a/src/timeman.cpp +++ b/src/timeman.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/timeman.h b/src/timeman.h index a2d1a4364..e72cc102a 100644 --- a/src/timeman.h +++ b/src/timeman.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/tt.cpp b/src/tt.cpp index d7f7dbdef..ef602809f 100644 --- a/src/tt.cpp +++ b/src/tt.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/tt.h b/src/tt.h index 26b63c1ad..38f6c8f4f 100644 --- a/src/tt.h +++ b/src/tt.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/tune.cpp b/src/tune.cpp index f53a0eb52..f930c267e 100644 --- a/src/tune.cpp +++ b/src/tune.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/tune.h b/src/tune.h index d3c9ebaa3..4ce6e759f 100644 --- a/src/tune.h +++ b/src/tune.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/types.h b/src/types.h index 1bb8bd3cc..b5a0498a8 100644 --- a/src/types.h +++ b/src/types.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/uci.cpp b/src/uci.cpp index be7de97d7..139d97b60 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/uci.h b/src/uci.h index 1686b3a72..c9b594393 100644 --- a/src/uci.h +++ b/src/uci.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/ucioption.cpp b/src/ucioption.cpp index ff6235695..8db796749 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/ucioption.h b/src/ucioption.h index 0c957fda1..4f6d7541c 100644 --- a/src/ucioption.h +++ b/src/ucioption.h @@ -1,6 +1,6 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 - Copyright (C) 2004-2025 The Stockfish developers (see AUTHORS file) + Copyright (C) 2004-2026 The Stockfish developers (see AUTHORS file) Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by