From 56444ce1f7e2204d69c35f5826f74130adc77b2c Mon Sep 17 00:00:00 2001 From: peregrineshahin <41402573+peregrineshahin@users.noreply.github.com> Date: Fri, 20 Sep 2024 14:09:03 +0300 Subject: [PATCH 01/23] Push expected cutting late moves up in the move ordering. since the passing of the LMR verification is coming from a relatively late move this means we have wasted some time trying/picking other moves, and it would make sense to push it up in the move ordering for future positions not to be as late. Passed STC: https://tests.stockfishchess.org/tests/view/66f0f69186d5ee47d953b2aa LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 34144 W: 9024 L: 8709 D: 16411 Ptnml(0-2): 137, 3875, 8732, 4192, 136 Passed LTC: https://tests.stockfishchess.org/tests/view/66f1d84a86d5ee47d953b325 LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 62808 W: 16054 L: 15684 D: 31070 Ptnml(0-2): 24, 6725, 17555, 7057, 43 closes https://github.com/official-stockfish/Stockfish/pull/5608 bench: 1452807 --- src/search.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index d87a6b9a0..7d84bd388 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1201,8 +1201,8 @@ moves_loop: // When in check, search starts here value = -search(pos, ss + 1, -(alpha + 1), -alpha, newDepth, !cutNode); // Post LMR continuation history updates (~1 Elo) - int bonus = value >= beta ? stat_bonus(newDepth) : -stat_malus(newDepth); - + int bonus = value >= beta ? (1 + 2 * (moveCount > depth)) * stat_bonus(newDepth) + : -stat_malus(newDepth); update_continuation_histories(ss, movedPiece, move.to_sq(), bonus); } } From d6043970bd156b1d2ab6cb51e8d5cb0c6a40797c Mon Sep 17 00:00:00 2001 From: Shawn Xu Date: Tue, 17 Sep 2024 14:29:55 -0700 Subject: [PATCH 02/23] Make Correction History Size Uniform Passed Non-regression STC: LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 207232 W: 53834 L: 53802 D: 99596 Ptnml(0-2): 695, 24486, 53200, 24562, 673 https://tests.stockfishchess.org/tests/view/66e9f5a886d5ee47d953ada1 Passed Non-regression LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 99120 W: 25264 L: 25123 D: 48733 Ptnml(0-2): 66, 10803, 27675, 10956, 60 https://tests.stockfishchess.org/tests/view/66ed7ebc86d5ee47d953b056 Passed Non-regression LTC vs #5606: LLR: 2.96 (-2.94,2.94) <-1.75,0.25> Total: 208950 W: 53049 L: 53019 D: 102882 Ptnml(0-2): 111, 23232, 57760, 23260, 112 https://tests.stockfishchess.org/tests/view/66f1843886d5ee47d953b2f2 closes https://github.com/official-stockfish/Stockfish/pull/5609 bench 1575189 --- src/movepick.h | 32 ++++++++++++++------------------ src/search.cpp | 3 +-- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/movepick.h b/src/movepick.h index 13b9635bb..c5e565fe4 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -34,18 +34,14 @@ namespace Stockfish { -constexpr int PAWN_HISTORY_SIZE = 512; // has to be a power of 2 -constexpr int PAWN_CORRECTION_HISTORY_SIZE = 16384; // has to be a power of 2 -constexpr int MATERIAL_CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2 -constexpr int MAJOR_PIECE_CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2 -constexpr int MINOR_PIECE_CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2 -constexpr int NON_PAWN_CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2 -constexpr int CORRECTION_HISTORY_LIMIT = 1024; +constexpr int PAWN_HISTORY_SIZE = 512; // has to be a power of 2 +constexpr int CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2 +constexpr int CORRECTION_HISTORY_LIMIT = 1024; static_assert((PAWN_HISTORY_SIZE & (PAWN_HISTORY_SIZE - 1)) == 0, "PAWN_HISTORY_SIZE has to be a power of 2"); -static_assert((PAWN_CORRECTION_HISTORY_SIZE & (PAWN_CORRECTION_HISTORY_SIZE - 1)) == 0, +static_assert((CORRECTION_HISTORY_SIZE & (CORRECTION_HISTORY_SIZE - 1)) == 0, "CORRECTION_HISTORY_SIZE has to be a power of 2"); enum PawnHistoryType { @@ -55,24 +51,24 @@ enum PawnHistoryType { template inline int pawn_structure_index(const Position& pos) { - return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : PAWN_CORRECTION_HISTORY_SIZE) - 1); + return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : CORRECTION_HISTORY_SIZE) - 1); } inline int material_index(const Position& pos) { - return pos.material_key() & (MATERIAL_CORRECTION_HISTORY_SIZE - 1); + return pos.material_key() & (CORRECTION_HISTORY_SIZE - 1); } inline int major_piece_index(const Position& pos) { - return pos.major_piece_key() & (MAJOR_PIECE_CORRECTION_HISTORY_SIZE - 1); + return pos.major_piece_key() & (CORRECTION_HISTORY_SIZE - 1); } inline int minor_piece_index(const Position& pos) { - return pos.minor_piece_key() & (MINOR_PIECE_CORRECTION_HISTORY_SIZE - 1); + return pos.minor_piece_key() & (CORRECTION_HISTORY_SIZE - 1); } template inline int non_pawn_index(const Position& pos) { - return pos.non_pawn_key(c) & (NON_PAWN_CORRECTION_HISTORY_SIZE - 1); + return pos.non_pawn_key(c) & (CORRECTION_HISTORY_SIZE - 1); } // StatsEntry stores the stat table value. It is usually a number but could @@ -161,23 +157,23 @@ using PawnHistory = Stats // PawnCorrectionHistory is addressed by color and pawn structure using PawnCorrectionHistory = - Stats; + Stats; // MaterialCorrectionHistory is addressed by color and material configuration using MaterialCorrectionHistory = - Stats; + Stats; // MajorPieceCorrectionHistory is addressed by color and king/major piece (Queen, Rook) positions using MajorPieceCorrectionHistory = - Stats; + Stats; // MinorPieceCorrectionHistory is addressed by color and king/minor piece (Knight, Bishop) positions using MinorPieceCorrectionHistory = - Stats; + Stats; // NonPawnCorrectionHistory is addressed by color and non-pawn material positions using NonPawnCorrectionHistory = - Stats; + Stats; // The MovePicker class is used to pick one pseudo-legal move at a time from the // current position. The most important method is next_move(), which emits one diff --git a/src/search.cpp b/src/search.cpp index 7d84bd388..4d581a850 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -88,8 +88,7 @@ Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos) { const auto wnpcv = w.nonPawnCorrectionHistory[WHITE][us][non_pawn_index(pos)]; const auto bnpcv = w.nonPawnCorrectionHistory[BLACK][us][non_pawn_index(pos)]; const auto cv = - (99916 * pcv + 55067 * mcv + 55530 * macv + 95324 * micv + 105056 * (wnpcv + bnpcv)) - / 2097152; + (6245 * pcv + 3442 * mcv + 3471 * macv + 5958 * micv + 6566 * (wnpcv + bnpcv)) / 131072; v += cv; return std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1); } From c85f802185dd223bae1197269d17b9b1d5e935a0 Mon Sep 17 00:00:00 2001 From: Taras Vuk <117687515+TarasVuk@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:58:48 +0200 Subject: [PATCH 03/23] Tweak ttCapture reduction More reduction at shallow depth for quiet moves when ttMove is a capture. Passed STC: LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 365728 W: 95896 L: 95090 D: 174742 Ptnml(0-2): 1283, 43133, 93262, 43867, 1319 https://tests.stockfishchess.org/tests/view/66edd35986d5ee47d953b0d5 Passed LTC: LLR: 2.96 (-2.94,2.94) <0.50,2.50> Total: 200526 W: 51197 L: 50540 D: 98789 Ptnml(0-2): 119, 21952, 55462, 22613, 117 https://tests.stockfishchess.org/tests/view/66f405dc86d5ee47d953b460 closes https://github.com/official-stockfish/Stockfish/pull/5610 bench: 1269487 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 4d581a850..a206cddab 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1157,7 +1157,7 @@ moves_loop: // When in check, search starts here // Increase reduction if ttMove is a capture but the current move is not a capture (~3 Elo) if (ttCapture && !capture) - r++; + r += 1 + (depth < 8); // Increase reduction if next ply has a lot of fail high (~5 Elo) if ((ss + 1)->cutoffCnt > 3) From 2b9154882a0e924c28d4de7b98309d889334428c Mon Sep 17 00:00:00 2001 From: Linmiao Xu Date: Mon, 16 Sep 2024 01:49:04 -0400 Subject: [PATCH 04/23] Tweak 7 eval params Values found from 120k / 120k spsa games at 30+0.3 Passed STC: https://tests.stockfishchess.org/tests/view/66ecd7ce86d5ee47d953b003 LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 241312 W: 62994 L: 62373 D: 115945 Ptnml(0-2): 754, 28684, 61280, 29063, 875 Passed LTC: https://tests.stockfishchess.org/tests/view/66f1f3a286d5ee47d953b331 LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 304896 W: 77580 L: 76709 D: 150607 Ptnml(0-2): 198, 33413, 84360, 34274, 203 closes https://github.com/official-stockfish/Stockfish/pull/5611 bench 1173651 --- src/evaluate.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 221ccde8b..087765e36 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -77,11 +77,11 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, // Blend optimism and eval with nnue complexity int nnueComplexity = std::abs(psqt - positional); - optimism += optimism * nnueComplexity / (smallNet ? 433 : 453); - nnue -= nnue * nnueComplexity / (smallNet ? 18815 : 17864); + optimism += optimism * nnueComplexity / (smallNet ? 430 : 474); + nnue -= nnue * nnueComplexity / (smallNet ? 20233 : 17879); int material = (smallNet ? 553 : 532) * pos.count() + pos.non_pawn_material(); - v = (nnue * (73921 + material) + optimism * (8112 + material)) / (smallNet ? 68104 : 74715); + v = (nnue * (76898 + material) + optimism * (8112 + material)) / (smallNet ? 74411 : 76256); // Evaluation grain (to get more alpha-beta cuts) with randomization (for robustness) v = (v / 16) * 16 - 1 + (pos.key() & 0x2); From 0186904f53e6b9c90935cd8fe822da795ca9d333 Mon Sep 17 00:00:00 2001 From: Linmiao Xu Date: Sun, 29 Sep 2024 04:22:37 -0400 Subject: [PATCH 05/23] Remove evaluation grain Passed non-regression STC: https://tests.stockfishchess.org/tests/view/66fa345a86d5ee47d953b86e LLR: 2.96 (-2.94,2.94) <-1.75,0.25> Total: 39776 W: 10528 L: 10306 D: 18942 Ptnml(0-2): 134, 4674, 10063, 4870, 147 Passed non-regression LTC: https://tests.stockfishchess.org/tests/view/66facfb886d5ee47d953b8a8 LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 64230 W: 16484 L: 16305 D: 31441 Ptnml(0-2): 38, 7195, 17483, 7348, 51 closes https://github.com/official-stockfish/Stockfish/pull/5613 bench 1013135 --- src/evaluate.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 087765e36..b1c7283e3 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -83,9 +83,6 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, int material = (smallNet ? 553 : 532) * pos.count() + pos.non_pawn_material(); v = (nnue * (76898 + material) + optimism * (8112 + material)) / (smallNet ? 74411 : 76256); - // Evaluation grain (to get more alpha-beta cuts) with randomization (for robustness) - v = (v / 16) * 16 - 1 + (pos.key() & 0x2); - // Damp down the evaluation linearly when shuffling v -= v * pos.rule50_count() / 212; From 7ac745a736a37f69632d6612d422aa3127f85509 Mon Sep 17 00:00:00 2001 From: Michael Chaly Date: Wed, 2 Oct 2024 10:49:23 +0300 Subject: [PATCH 06/23] Refactor root history into low ply history This patch changes root history to low ply history - butterfly history for plies < 4. Doubles weight of this history for root, latter plies have lesser effect. Passed STC: https://tests.stockfishchess.org/tests/view/66f77d2386d5ee47d953b65d LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 180992 W: 47362 L: 46830 D: 86800 Ptnml(0-2): 554, 21499, 45928, 21891, 624 Passed LTC: https://tests.stockfishchess.org/tests/view/66fb557986d5ee47d953b8e5 LLR: 2.95 (-2.94,2.94) <0.50,2.50> Total: 42462 W: 11013 L: 10682 D: 20767 Ptnml(0-2): 33, 4518, 11795, 4855, 30 closes https://github.com/official-stockfish/Stockfish/pull/5614 Bench 1264335 --- src/movepick.cpp | 12 +++++----- src/movepick.h | 12 ++++++---- src/search.cpp | 62 +++++++++++++++++++----------------------------- src/search.h | 2 +- 4 files changed, 40 insertions(+), 48 deletions(-) diff --git a/src/movepick.cpp b/src/movepick.cpp index f4ef0e549..1d1aef0f3 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -82,20 +82,20 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh, - const ButterflyHistory* rh, + const LowPlyHistory* lph, const CapturePieceToHistory* cph, const PieceToHistory** ch, const PawnHistory* ph, - bool rn) : + int pl) : pos(p), mainHistory(mh), - rootHistory(rh), + lowPlyHistory(lph), captureHistory(cph), continuationHistory(ch), pawnHistory(ph), ttMove(ttm), depth(d), - rootNode(rn) { + ply(pl) { if (pos.checkers()) stage = EVASION_TT + !(ttm && pos.pseudo_legal(ttm)); @@ -179,8 +179,8 @@ void MovePicker::score() { : pt == ROOK && bool(to & threatenedByMinor) ? 24335 : 0); - if (rootNode) - m.value += 4 * (*rootHistory)[pos.side_to_move()][m.from_to()]; + if (ply < 4) + m.value += 8 * (*lowPlyHistory)[ply][m.from_to()] / (1 + 2 * ply); } else // Type == EVASIONS diff --git a/src/movepick.h b/src/movepick.h index c5e565fe4..8deefd140 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -135,6 +135,10 @@ enum StatsType { // see https://www.chessprogramming.org/Butterfly_Boards (~11 elo) using ButterflyHistory = Stats; +// LowPlyHistory is adressed by play and move's from and to squares, used +// to improve move ordering near the root +using LowPlyHistory = Stats; + // CapturePieceToHistory is addressed by a move's [piece][to][captured piece type] using CapturePieceToHistory = Stats; @@ -195,11 +199,11 @@ class MovePicker { Move, Depth, const ButterflyHistory*, - const ButterflyHistory*, + const LowPlyHistory*, const CapturePieceToHistory*, const PieceToHistory**, const PawnHistory*, - bool); + int); MovePicker(const Position&, Move, int, const CapturePieceToHistory*); Move next_move(bool skipQuiets = false); @@ -213,7 +217,7 @@ class MovePicker { const Position& pos; const ButterflyHistory* mainHistory; - const ButterflyHistory* rootHistory; + const LowPlyHistory* lowPlyHistory; const CapturePieceToHistory* captureHistory; const PieceToHistory** continuationHistory; const PawnHistory* pawnHistory; @@ -222,7 +226,7 @@ class MovePicker { int stage; int threshold; Depth depth; - bool rootNode; + int ply; ExtMove moves[MAX_MOVES]; }; diff --git a/src/search.cpp b/src/search.cpp index a206cddab..0ed7b6a76 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -105,21 +105,16 @@ Value value_to_tt(Value v, int ply); Value value_from_tt(Value v, int ply, int r50c); void update_pv(Move* pv, Move move, const Move* childPv); void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus); -void update_quiet_histories(const Position& pos, - Stack* ss, - Search::Worker& workerThread, - Move move, - int bonus, - bool rootNode); -void update_all_stats(const Position& pos, - Stack* ss, - Search::Worker& workerThread, - Move bestMove, - Square prevSq, - ValueList& quietsSearched, - ValueList& capturesSearched, - Depth depth, - bool rootNode); +void update_quiet_histories( + const Position& pos, Stack* ss, Search::Worker& workerThread, Move move, int bonus); +void update_all_stats(const Position& pos, + Stack* ss, + Search::Worker& workerThread, + Move bestMove, + Square prevSq, + ValueList& quietsSearched, + ValueList& capturesSearched, + Depth depth); } // namespace @@ -273,7 +268,7 @@ void Search::Worker::iterative_deepening() { int searchAgainCounter = 0; - rootHistory.fill(0); + lowPlyHistory.fill(0); // Iterative deepening loop until requested to stop or the target depth is reached while (++rootDepth < MAX_PLY && !threads.stop @@ -499,7 +494,7 @@ void Search::Worker::iterative_deepening() { // Reset histories, usually before a new game void Search::Worker::clear() { mainHistory.fill(0); - rootHistory.fill(0); + lowPlyHistory.fill(0); captureHistory.fill(-753); pawnHistory.fill(-1152); pawnCorrectionHistory.fill(0); @@ -638,7 +633,7 @@ Value Search::Worker::search( { // Bonus for a quiet ttMove that fails high (~2 Elo) if (!ttCapture) - update_quiet_histories(pos, ss, *this, ttData.move, stat_bonus(depth), rootNode); + update_quiet_histories(pos, ss, *this, ttData.move, stat_bonus(depth)); // Extra penalty for early quiet moves of // the previous ply (~1 Elo on STC, ~2 Elo on LTC) @@ -928,8 +923,8 @@ moves_loop: // When in check, search starts here (ss - 6)->continuationHistory}; - MovePicker mp(pos, ttData.move, depth, &thisThread->mainHistory, &thisThread->rootHistory, - &thisThread->captureHistory, contHist, &thisThread->pawnHistory, rootNode); + MovePicker mp(pos, ttData.move, depth, &thisThread->mainHistory, &thisThread->lowPlyHistory, + &thisThread->captureHistory, contHist, &thisThread->pawnHistory, ss->ply); value = bestValue; @@ -1355,8 +1350,7 @@ moves_loop: // When in check, search starts here // If there is a move that produces search value greater than alpha, // we update the stats of searched moves. else if (bestMove) - update_all_stats(pos, ss, *this, bestMove, prevSq, quietsSearched, capturesSearched, depth, - rootNode); + update_all_stats(pos, ss, *this, bestMove, prevSq, quietsSearched, capturesSearched, depth); // Bonus for prior countermove that caused the fail low else if (!priorCapture && prevSq != SQ_NONE) @@ -1557,9 +1551,8 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) // Initialize a MovePicker object for the current position, and prepare to search // 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, &thisThread->mainHistory, &thisThread->rootHistory, - &thisThread->captureHistory, contHist, &thisThread->pawnHistory, - nodeType == Root); + MovePicker mp(pos, ttData.move, DEPTH_QS, &thisThread->mainHistory, &thisThread->lowPlyHistory, + &thisThread->captureHistory, contHist, &thisThread->pawnHistory, ss->ply); // Step 5. Loop through all pseudo-legal moves until no moves remain or a beta // cutoff occurs. @@ -1768,8 +1761,7 @@ void update_all_stats(const Position& pos, Square prevSq, ValueList& quietsSearched, ValueList& capturesSearched, - Depth depth, - bool rootNode) { + Depth depth) { CapturePieceToHistory& captureHistory = workerThread.captureHistory; Piece moved_piece = pos.moved_piece(bestMove); @@ -1780,11 +1772,11 @@ void update_all_stats(const Position& pos, if (!pos.capture_stage(bestMove)) { - update_quiet_histories(pos, ss, workerThread, bestMove, quietMoveBonus, rootNode); + update_quiet_histories(pos, ss, workerThread, bestMove, quietMoveBonus); // Decrease stats for all non-best quiet moves for (Move move : quietsSearched) - update_quiet_histories(pos, ss, workerThread, move, -quietMoveMalus, rootNode); + update_quiet_histories(pos, ss, workerThread, move, -quietMoveMalus); } else { @@ -1826,17 +1818,13 @@ void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus) { // Updates move sorting heuristics -void update_quiet_histories(const Position& pos, - Stack* ss, - Search::Worker& workerThread, - Move move, - int bonus, - bool rootNode) { +void update_quiet_histories( + const Position& pos, Stack* ss, Search::Worker& workerThread, Move move, int bonus) { Color us = pos.side_to_move(); workerThread.mainHistory[us][move.from_to()] << bonus; - if (rootNode) - workerThread.rootHistory[us][move.from_to()] << bonus; + if (ss->ply < 4) + workerThread.lowPlyHistory[ss->ply][move.from_to()] << bonus; update_continuation_histories(ss, pos.moved_piece(move), move.to_sq(), bonus); diff --git a/src/search.h b/src/search.h index d7a909a82..0761328a7 100644 --- a/src/search.h +++ b/src/search.h @@ -278,7 +278,7 @@ class Worker { // Public because they need to be updatable by the stats ButterflyHistory mainHistory; - ButterflyHistory rootHistory; + LowPlyHistory lowPlyHistory; CapturePieceToHistory captureHistory; ContinuationHistory continuationHistory[2][2]; From 81c1d310844e7b41caeabda0d5351ae275d799db Mon Sep 17 00:00:00 2001 From: Taras Vuk <117687515+TarasVuk@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:55:59 +0200 Subject: [PATCH 07/23] Decrease probCutBeta based on opponentWorsening Passed STC: LLR: 2.97 (-2.94,2.94) <0.00,2.00> Total: 62112 W: 16305 L: 15947 D: 29860 Ptnml(0-2): 203, 7226, 15856, 7552, 219 https://tests.stockfishchess.org/tests/view/66f85fc986d5ee47d953b71e Passed LTC: LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 129552 W: 33223 L: 32710 D: 63619 Ptnml(0-2): 94, 14250, 35573, 14767, 92 https://tests.stockfishchess.org/tests/view/66f93fef86d5ee47d953b7d2 closes https://github.com/official-stockfish/Stockfish/pull/5615 bench: 1511354 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 0ed7b6a76..d79b452d9 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -840,7 +840,7 @@ Value Search::Worker::search( // Step 11. ProbCut (~10 Elo) // If we have a good enough capture (or queen promotion) and a reduced search // returns a value much above beta, we can (almost) safely prune the previous move. - probCutBeta = beta + 189 - 53 * improving; + probCutBeta = beta + 189 - 53 * improving - 30 * opponentWorsening; if (!PvNode && depth > 3 && std::abs(beta) < VALUE_TB_WIN_IN_MAX_PLY // If value from transposition table is lower than probCutBeta, don't attempt From 6592b13d56e43c247ac8b0d6f62564b2a4ca72a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Tutkun?= Date: Fri, 4 Oct 2024 17:46:47 +0300 Subject: [PATCH 08/23] Introduce Continuation Correction History Continuation correction history uses last 2 move to correct static eval. ContCorrHist first introduced by @martinnovaak in Motor(https://github.com/martinnovaak/motor/pull/162). Earlier ideas using last move to correct eval is introduced by @MinusKelvin in Ice4(https://github.com/MinusKelvin/ice4/commit/45daf7d9ea64ea4efaf0d2b4e99f53e12e08c838) Passed STC: LLR: 2.96 (-2.94,2.94) <0.00,2.00> Total: 310144 W: 81267 L: 80538 D: 148339 Ptnml(0-2): 1160, 36607, 78834, 37286, 1185 https://tests.stockfishchess.org/tests/view/66f96cbc86d5ee47d953b7f7 Passed LTC: LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 97470 W: 24892 L: 24447 D: 48131 Ptnml(0-2): 63, 10631, 26915, 11050, 76 https://tests.stockfishchess.org/tests/view/66fd59bc86d5ee47d953b9ea closes https://github.com/official-stockfish/Stockfish/pull/5617 Bench: 1143382 --- AUTHORS | 1 + src/movepick.h | 7 +++++++ src/search.cpp | 47 ++++++++++++++++++++++++++++++++++++----------- src/search.h | 36 +++++++++++++++++++----------------- 4 files changed, 63 insertions(+), 28 deletions(-) diff --git a/AUTHORS b/AUTHORS index c0a8beebc..725b35690 100644 --- a/AUTHORS +++ b/AUTHORS @@ -176,6 +176,7 @@ Ofek Shochat (OfekShochat, ghostway) Ondrej Mosnáček (WOnder93) Ondřej Mišina (AndrovT) Oskar Werkelin Ahlin +Ömer Faruk Tutkun (OmerFarukTutkun) Pablo Vazquez Panthee Pascal Romaret diff --git a/src/movepick.h b/src/movepick.h index 8deefd140..9a68aaa1d 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -145,6 +145,9 @@ using CapturePieceToHistory = Stats; +// PieceToCorrectionHistory is addressed by a move's [piece][to] +using PieceToCorrectionHistory = Stats; + // ContinuationHistory is the combined history of a given pair of moves, usually // the current one given a previous one. The nested history table is based on // PieceToHistory instead of ButterflyBoards. @@ -179,6 +182,10 @@ using MinorPieceCorrectionHistory = using NonPawnCorrectionHistory = Stats; +// ContinuationCorrectionHistory is the combined correction history of a given pair of moves +using ContinuationCorrectionHistory = + Stats; + // The MovePicker class is used to pick one pseudo-legal move at a time from the // current position. The most important method is next_move(), which emits one // new pseudo-legal move on every call, until there are no moves left, when diff --git a/src/search.cpp b/src/search.cpp index d79b452d9..c55118ece 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -79,16 +79,23 @@ constexpr int futility_move_count(bool improving, Depth depth) { // Add correctionHistory value to raw staticEval and guarantee evaluation // does not hit the tablebase range. -Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos) { +Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos, Stack* ss) { const Color us = pos.side_to_move(); + const auto m = (ss - 1)->currentMove; const auto pcv = w.pawnCorrectionHistory[us][pawn_structure_index(pos)]; const auto mcv = w.materialCorrectionHistory[us][material_index(pos)]; const auto macv = w.majorPieceCorrectionHistory[us][major_piece_index(pos)]; const auto micv = w.minorPieceCorrectionHistory[us][minor_piece_index(pos)]; const auto wnpcv = w.nonPawnCorrectionHistory[WHITE][us][non_pawn_index(pos)]; const auto bnpcv = w.nonPawnCorrectionHistory[BLACK][us][non_pawn_index(pos)]; - const auto cv = - (6245 * pcv + 3442 * mcv + 3471 * macv + 5958 * micv + 6566 * (wnpcv + bnpcv)) / 131072; + int cntcv = 1; + + if (m.is_ok()) + cntcv = int((*(ss - 2)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()]); + + const auto cv = + (5932 * pcv + 2994 * mcv + 3269 * macv + 5660 * micv + 6237 * (wnpcv + bnpcv) + cntcv * 5555) + / 131072; v += cv; return std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1); } @@ -240,7 +247,8 @@ void Search::Worker::iterative_deepening() { { (ss - i)->continuationHistory = &this->continuationHistory[0][0][NO_PIECE][0]; // Use as a sentinel - (ss - i)->staticEval = VALUE_NONE; + (ss - i)->continuationCorrectionHistory = &this->continuationCorrectionHistory[NO_PIECE][0]; + (ss - i)->staticEval = VALUE_NONE; } for (int i = 0; i <= MAX_PLY + 2; ++i) @@ -504,6 +512,10 @@ void Search::Worker::clear() { nonPawnCorrectionHistory[WHITE].fill(0); nonPawnCorrectionHistory[BLACK].fill(0); + for (auto& to : continuationCorrectionHistory) + for (auto& h : to) + h->fill(0); + for (bool inCheck : {false, true}) for (StatsType c : {NoCaptures, Captures}) for (auto& to : continuationHistory[inCheck][c]) @@ -727,7 +739,8 @@ Value Search::Worker::search( else if (PvNode) Eval::NNUE::hint_common_parent_position(pos, networks[numaAccessToken], refreshTable); - ss->staticEval = eval = to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos); + ss->staticEval = eval = + to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos, ss); // ttValue can be used as a better position evaluation (~7 Elo) if (ttData.value != VALUE_NONE @@ -738,7 +751,8 @@ Value Search::Worker::search( { unadjustedStaticEval = evaluate(networks[numaAccessToken], pos, refreshTable, thisThread->optimism[us]); - ss->staticEval = eval = to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos); + ss->staticEval = eval = + to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos, ss); // Static evaluation is saved as it was before adjustment by correction history ttWriter.write(posKey, VALUE_NONE, ss->ttPv, BOUND_NONE, DEPTH_UNSEARCHED, Move::none(), @@ -793,8 +807,9 @@ Value Search::Worker::search( // Null move dynamic reduction based on depth and eval Depth R = std::min(int(eval - beta) / 209, 6) + depth / 3 + 5; - ss->currentMove = Move::null(); - ss->continuationHistory = &thisThread->continuationHistory[0][0][NO_PIECE][0]; + ss->currentMove = Move::null(); + ss->continuationHistory = &thisThread->continuationHistory[0][0][NO_PIECE][0]; + ss->continuationCorrectionHistory = &thisThread->continuationCorrectionHistory[NO_PIECE][0]; pos.do_null_move(st, tt); @@ -876,6 +891,8 @@ Value Search::Worker::search( ss->currentMove = move; ss->continuationHistory = &this->continuationHistory[ss->inCheck][true][pos.moved_piece(move)][move.to_sq()]; + ss->continuationCorrectionHistory = + &this->continuationCorrectionHistory[pos.moved_piece(move)][move.to_sq()]; thisThread->nodes.fetch_add(1, std::memory_order_relaxed); pos.do_move(move, st); @@ -1124,7 +1141,8 @@ moves_loop: // When in check, search starts here ss->currentMove = move; ss->continuationHistory = &thisThread->continuationHistory[ss->inCheck][capture][movedPiece][move.to_sq()]; - + ss->continuationCorrectionHistory = + &thisThread->continuationCorrectionHistory[movedPiece][move.to_sq()]; uint64_t nodeCount = rootNode ? uint64_t(nodes) : 0; // Step 16. Make the move @@ -1401,6 +1419,8 @@ moves_loop: // When in check, search starts here && !(bestValue >= beta && bestValue <= ss->staticEval) && !(!bestMove && bestValue >= ss->staticEval)) { + const auto m = (ss - 1)->currentMove; + auto bonus = std::clamp(int(bestValue - ss->staticEval) * depth / 8, -CORRECTION_HISTORY_LIMIT / 4, CORRECTION_HISTORY_LIMIT / 4); thisThread->pawnCorrectionHistory[us][pawn_structure_index(pos)] @@ -1412,6 +1432,9 @@ moves_loop: // When in check, search starts here << bonus * 123 / 128; thisThread->nonPawnCorrectionHistory[BLACK][us][non_pawn_index(pos)] << bonus * 165 / 128; + + if (m.is_ok()) + (*(ss - 2)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()] << bonus; } assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); @@ -1507,7 +1530,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) unadjustedStaticEval = evaluate(networks[numaAccessToken], pos, refreshTable, thisThread->optimism[us]); ss->staticEval = bestValue = - to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos); + to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos, ss); // ttValue can be used as a better position evaluation (~13 Elo) if (std::abs(ttData.value) < VALUE_TB_WIN_IN_MAX_PLY @@ -1522,7 +1545,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) ? evaluate(networks[numaAccessToken], pos, refreshTable, thisThread->optimism[us]) : -(ss - 1)->staticEval; ss->staticEval = bestValue = - to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos); + to_corrected_static_eval(unadjustedStaticEval, *thisThread, pos, ss); } // Stand pat. Return immediately if static value is at least beta @@ -1619,6 +1642,8 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) ss->continuationHistory = &thisThread ->continuationHistory[ss->inCheck][capture][pos.moved_piece(move)][move.to_sq()]; + ss->continuationCorrectionHistory = + &thisThread->continuationCorrectionHistory[pos.moved_piece(move)][move.to_sq()]; // Step 7. Make and search the move thisThread->nodes.fetch_add(1, std::memory_order_relaxed); diff --git a/src/search.h b/src/search.h index 0761328a7..a407e1058 100644 --- a/src/search.h +++ b/src/search.h @@ -61,18 +61,19 @@ namespace Search { // shallower and deeper in the tree during the search. Each search thread has // its own array of Stack objects, indexed by the current ply. struct Stack { - Move* pv; - PieceToHistory* continuationHistory; - int ply; - Move currentMove; - Move excludedMove; - Value staticEval; - int statScore; - int moveCount; - bool inCheck; - bool ttPv; - bool ttHit; - int cutoffCnt; + Move* pv; + PieceToHistory* continuationHistory; + PieceToCorrectionHistory* continuationCorrectionHistory; + int ply; + Move currentMove; + Move excludedMove; + Value staticEval; + int statScore; + int moveCount; + bool inCheck; + bool ttPv; + bool ttHit; + int cutoffCnt; }; @@ -284,11 +285,12 @@ class Worker { ContinuationHistory continuationHistory[2][2]; PawnHistory pawnHistory; - PawnCorrectionHistory pawnCorrectionHistory; - MaterialCorrectionHistory materialCorrectionHistory; - MajorPieceCorrectionHistory majorPieceCorrectionHistory; - MinorPieceCorrectionHistory minorPieceCorrectionHistory; - NonPawnCorrectionHistory nonPawnCorrectionHistory[COLOR_NB]; + PawnCorrectionHistory pawnCorrectionHistory; + MaterialCorrectionHistory materialCorrectionHistory; + MajorPieceCorrectionHistory majorPieceCorrectionHistory; + MinorPieceCorrectionHistory minorPieceCorrectionHistory; + NonPawnCorrectionHistory nonPawnCorrectionHistory[COLOR_NB]; + ContinuationCorrectionHistory continuationCorrectionHistory; private: void iterative_deepening(); From e046c4ef0d743ce57c97c0d40f17610dc2ec3c56 Mon Sep 17 00:00:00 2001 From: Linmiao Xu Date: Mon, 30 Sep 2024 23:53:57 -0400 Subject: [PATCH 09/23] Simplify evaluation scaling Set digits in adjusted eval params all to 7. Passed non-regression STC: https://tests.stockfishchess.org/tests/view/66fc493d86d5ee47d953b94c LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 57696 W: 15098 L: 14898 D: 27700 Ptnml(0-2): 205, 6784, 14678, 6968, 213 Passed non-regression LTC: https://tests.stockfishchess.org/tests/view/66fd4b9386d5ee47d953b9d5 LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 93786 W: 23868 L: 23721 D: 46197 Ptnml(0-2): 55, 10322, 25993, 10467, 56 closes https://github.com/official-stockfish/Stockfish/pull/5618 Bench: 1277182 --- src/evaluate.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index b1c7283e3..802913a04 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -59,9 +59,7 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, assert(!pos.checkers()); - bool smallNet = use_smallnet(pos); - int v; - + bool smallNet = use_smallnet(pos); auto [psqt, positional] = smallNet ? networks.small.evaluate(pos, &caches.small) : networks.big.evaluate(pos, &caches.big); @@ -81,7 +79,7 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, nnue -= nnue * nnueComplexity / (smallNet ? 20233 : 17879); int material = (smallNet ? 553 : 532) * pos.count() + pos.non_pawn_material(); - v = (nnue * (76898 + material) + optimism * (8112 + material)) / (smallNet ? 74411 : 76256); + int v = (nnue * (77777 + material) + optimism * (7777 + material)) / 77777; // Damp down the evaluation linearly when shuffling v -= v * pos.rule50_count() / 212; From dce72913feec523f077db8e86cc5797286c6548d Mon Sep 17 00:00:00 2001 From: Disservin Date: Fri, 4 Oct 2024 19:36:02 +0200 Subject: [PATCH 10/23] Temporarily fix clang-format mismatch closes https://github.com/official-stockfish/Stockfish/pull/5620 No functional change --- src/uci.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/uci.cpp b/src/uci.cpp index cfb34db79..8388cad8c 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -431,6 +431,8 @@ void UCIEngine::benchmark(std::istream& args) { if (threadBinding.empty()) threadBinding = "none"; + // clang-format off + std::cerr << "===========================" << "\nVersion : " << engine_version_info() @@ -453,6 +455,8 @@ void UCIEngine::benchmark(std::istream& args) { << "\nTotal search time [s] : " << totalTime / 1000.0 << "\nNodes/second : " << 1000 * nodes / totalTime << std::endl; + // clang-format on + init_search_update_listeners(); } From 3348603770926e9865fc3f43baaaef8de99d3014 Mon Sep 17 00:00:00 2001 From: mstembera Date: Fri, 4 Oct 2024 10:39:51 -0700 Subject: [PATCH 11/23] Simplify previous #5608 https://github.com/official-stockfish/Stockfish/pull/5608 STC: https://tests.stockfishchess.org/tests/view/66fb1bab86d5ee47d953b8cc LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 25536 W: 6797 L: 6560 D: 12179 Ptnml(0-2): 93, 2953, 6460, 3148, 114 LTC https://tests.stockfishchess.org/tests/view/66fb690e86d5ee47d953b8eb LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 225114 W: 57200 L: 57188 D: 110726 Ptnml(0-2): 197, 25076, 61995, 25096, 193 closes https://github.com/official-stockfish/Stockfish/pull/5621 Bench: 1570076 --- src/search.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index c55118ece..34fb5a805 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1213,8 +1213,7 @@ moves_loop: // When in check, search starts here value = -search(pos, ss + 1, -(alpha + 1), -alpha, newDepth, !cutNode); // Post LMR continuation history updates (~1 Elo) - int bonus = value >= beta ? (1 + 2 * (moveCount > depth)) * stat_bonus(newDepth) - : -stat_malus(newDepth); + int bonus = value >= beta ? 3 * stat_bonus(newDepth) : -stat_malus(newDepth); update_continuation_histories(ss, movedPiece, move.to_sq(), bonus); } } From 9a21e3e9968ebdd36c24d9b2762646a76a4e448b Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Sat, 5 Oct 2024 13:52:24 +0300 Subject: [PATCH 12/23] Simplify bestvalue formula Passed STC: LLR: 2.97 (-2.94,2.94) <-1.75,0.25> Total: 163680 W: 42689 L: 42605 D: 78386 Ptnml(0-2): 619, 19555, 41386, 19683, 597 https://tests.stockfishchess.org/tests/view/66f9451386d5ee47d953b7d9 Passed LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 96498 W: 24582 L: 24438 D: 47478 Ptnml(0-2): 62, 10642, 26718, 10744, 83 https://tests.stockfishchess.org/tests/view/66fd765786d5ee47d953ba1c closes https://github.com/official-stockfish/Stockfish/pull/5622 Bench: 1309815 --- src/search.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 34fb5a805..5598b5ffb 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1610,11 +1610,11 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) continue; } - // if static exchange evaluation is low enough + // If static exchange evaluation is low enough // we can prune this move. (~2 Elo) if (!pos.see_ge(move, alpha - futilityBase)) { - bestValue = (futilityBase > alpha) ? alpha : std::max(bestValue, futilityBase); + bestValue = std::min(alpha, futilityBase); continue; } } From 76923bb6fef2982dbce201227f6a33788390ce35 Mon Sep 17 00:00:00 2001 From: mstembera Date: Sat, 5 Oct 2024 16:18:21 -0700 Subject: [PATCH 13/23] Optimize magics Reduce the size of the Magics table by half on modern cpu's and lay it out to match our access pattern. Namely we typically access the magics for the same square for both bishop and rook back to back so we want those to be in the same cache line. https://tests.stockfishchess.org/tests/view/6701c9b386d5ee47d953bcf4 LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 121664 W: 31931 L: 31497 D: 58236 Ptnml(0-2): 395, 13658, 32322, 14032, 425 A similar patch minus the size reduction finished yellow https://tests.stockfishchess.org/tests/view/6695f03f4ff211be9d4ec16c LLR: -2.94 (-2.94,2.94) <0.00,2.00> Total: 310688 W: 80940 L: 80746 D: 149002 Ptnml(0-2): 1119, 35032, 82846, 35230, 1117 closes https://github.com/official-stockfish/Stockfish/pull/5623 No functional change --- src/bitboard.cpp | 40 +++++++++++++++++++++++----------------- src/bitboard.h | 21 ++++++++++++--------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/bitboard.cpp b/src/bitboard.cpp index a8b4e5f44..deda6da2a 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -34,15 +34,14 @@ Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; Bitboard PawnAttacks[COLOR_NB][SQUARE_NB]; -Magic RookMagics[SQUARE_NB]; -Magic BishopMagics[SQUARE_NB]; +alignas(64) Magic Magics[SQUARE_NB][2]; namespace { Bitboard RookTable[0x19000]; // To store rook attacks Bitboard BishopTable[0x1480]; // To store bishop attacks -void init_magics(PieceType pt, Bitboard table[], Magic magics[]); +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. @@ -82,8 +81,8 @@ void Bitboards::init() { for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2) SquareDistance[s1][s2] = std::max(distance(s1, s2), distance(s1, s2)); - init_magics(ROOK, RookTable, RookMagics); - init_magics(BISHOP, BishopTable, BishopMagics); + init_magics(ROOK, RookTable, Magics); + init_magics(BISHOP, BishopTable, Magics); for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) { @@ -142,39 +141,47 @@ Bitboard sliding_attack(PieceType pt, Square sq, Bitboard occupied) { // 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 // the so called "fancy" approach. -void init_magics(PieceType pt, Bitboard table[], Magic magics[]) { +void init_magics(PieceType pt, Bitboard table[], Magic magics[][2]) { +#ifndef USE_PEXT // Optimal PRNG seeds to pick the correct magics in the shortest time int seeds[][RANK_NB] = {{8977, 44560, 54343, 38998, 5731, 95205, 104912, 17020}, {728, 10316, 55013, 32803, 12281, 15100, 16645, 255}}; - Bitboard occupancy[4096], reference[4096], edges, b; - int epoch[4096] = {}, cnt = 0, size = 0; + Bitboard occupancy[4096]; + int epoch[4096] = {}, cnt = 0; +#endif + Bitboard reference[4096]; + int size = 0; for (Square s = SQ_A1; s <= SQ_H8; ++s) { // Board edges are not considered in the relevant occupancies - edges = ((Rank1BB | Rank8BB) & ~rank_bb(s)) | ((FileABB | FileHBB) & ~file_bb(s)); + Bitboard edges = ((Rank1BB | Rank8BB) & ~rank_bb(s)) | ((FileABB | FileHBB) & ~file_bb(s)); // Given a square 's', the mask is the bitboard of sliding attacks from // 's' computed on an empty board. The index must be big enough to contain // all the attacks for each possible subset of the mask and so is 2 power // 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]; + Magic& m = magics[s][pt - BISHOP]; m.mask = sliding_attack(pt, s, 0) & ~edges; - m.shift = (Is64Bit ? 64 : 32) - popcount(m.mask); - +#ifndef USE_PEXT + m.shift = (Is64Bit ? 64 : 32) - popcount(m.mask); +#endif // Set the offset for the attacks table of the square. We have individual // table sizes for each square with "Fancy Magic Bitboards". - m.attacks = s == SQ_A1 ? table : magics[s - 1].attacks + size; + m.attacks = s == SQ_A1 ? table : magics[s - 1][pt - BISHOP].attacks + size; + size = 0; // Use Carry-Rippler trick to enumerate all subsets of masks[s] and // store the corresponding sliding attack bitboard in reference[]. - b = size = 0; + Bitboard b = 0; do { +#ifndef USE_PEXT occupancy[size] = b; +#endif reference[size] = sliding_attack(pt, s, b); if (HasPext) @@ -184,9 +191,7 @@ void init_magics(PieceType pt, Bitboard table[], Magic magics[]) { b = (b - m.mask) & m.mask; } while (b); - if (HasPext) - continue; - +#ifndef USE_PEXT PRNG rng(seeds[Is64Bit][rank_of(s)]); // Find a magic for square 's' picking up an (almost) random number @@ -215,6 +220,7 @@ void init_magics(PieceType pt, Bitboard table[], Magic magics[]) { break; } } +#endif } } } diff --git a/src/bitboard.h b/src/bitboard.h index cdff4c759..c4bf18b53 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -67,27 +67,31 @@ extern Bitboard PawnAttacks[COLOR_NB][SQUARE_NB]; // Magic holds all magic bitboards relevant data for a single square struct Magic { Bitboard mask; - Bitboard magic; Bitboard* attacks; - unsigned shift; +#ifndef USE_PEXT + Bitboard magic; + unsigned shift; +#endif // Compute the attack's index using the 'magic bitboards' approach unsigned index(Bitboard occupied) const { - if (HasPext) - return unsigned(pext(occupied, mask)); - +#ifdef USE_PEXT + return unsigned(pext(occupied, mask)); +#else if (Is64Bit) return unsigned(((occupied & mask) * magic) >> shift); unsigned lo = unsigned(occupied) & unsigned(mask); unsigned hi = unsigned(occupied >> 32) & unsigned(mask >> 32); return (lo * unsigned(magic) ^ hi * unsigned(magic >> 32)) >> shift; +#endif } + + Bitboard attacks_bb(Bitboard occupied) const { return attacks[index(occupied)]; } }; -extern Magic RookMagics[SQUARE_NB]; -extern Magic BishopMagics[SQUARE_NB]; +extern Magic Magics[SQUARE_NB][2]; constexpr Bitboard square_bb(Square s) { assert(is_ok(s)); @@ -229,9 +233,8 @@ inline Bitboard attacks_bb(Square s, Bitboard occupied) { switch (Pt) { case BISHOP : - return BishopMagics[s].attacks[BishopMagics[s].index(occupied)]; case ROOK : - return RookMagics[s].attacks[RookMagics[s].index(occupied)]; + return Magics[s][Pt - BISHOP].attacks_bb(occupied); case QUEEN : return attacks_bb(s, occupied) | attacks_bb(s, occupied); default : From d4358ddba7184aa7403d12397f2f49f5ea6364fd Mon Sep 17 00:00:00 2001 From: Mathias Parnaudeau Date: Sat, 5 Oct 2024 15:28:39 +0200 Subject: [PATCH 14/23] Add autodetection of ppc64 architectures That allows 'make -j profile-build' work on ppc64 architectures, setting the use of the appropriate SIMD extension, Altivec or VSX. For VSX, gcc allows to map SSE2 intrinsics and get benefit of the existing SIMD code. On PowerMac G5, using altivec provides a performance improvement of 30%. On Talos 2, using vsx provides a performance improvement of 120%. closes https://github.com/official-stockfish/Stockfish/pull/5624 No functional change --- AUTHORS | 1 + scripts/get_native_properties.sh | 18 ++++++++++++++ src/Makefile | 42 ++++++++++++++++++++++++++++++-- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 725b35690..31a64c17e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -143,6 +143,7 @@ Maciej Żenczykowski (zenczykowski) Malcolm Campbell (xoto10) Mark Tenzer (31m059) marotear +Mathias Parnaudeau (mparnaudeau) Matt Ginsberg (mattginsberg) Matthew Lai (matthewlai) Matthew Sullivan (Matt14916) diff --git a/scripts/get_native_properties.sh b/scripts/get_native_properties.sh index dfbfac0ea..ed5fc9af0 100755 --- a/scripts/get_native_properties.sh +++ b/scripts/get_native_properties.sh @@ -54,6 +54,20 @@ set_arch_x86_64() { fi } +set_arch_ppc_64() { + if $(grep -q -w "altivec" /proc/cpuinfo); then + power=$(grep -oP -m 1 'cpu\t+: POWER\K\d+' /proc/cpuinfo) + if [ "0$power" -gt 7 ]; then + # VSX started with POWER8 + true_arch='ppc-64-vsx' + else + true_arch='ppc-64-altivec' + fi + else + true_arch='ppc-64' + fi +} + # Check the system type uname_s=$(uname -s) uname_m=$(uname -m) @@ -87,6 +101,10 @@ case $uname_s in file_os='ubuntu' true_arch='x86-32' ;; + 'ppc64'*) + file_os='ubuntu' + set_arch_ppc_64 + ;; 'aarch64') file_os='android' true_arch='armv8' diff --git a/src/Makefile b/src/Makefile index 6cb778a68..15066781b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -98,6 +98,8 @@ VPATH = syzygy:nnue:nnue/features # avx512 = yes/no --- -mavx512bw --- Use Intel Advanced Vector Extensions 512 # vnni256 = yes/no --- -mavx256vnni --- Use Intel Vector Neural Network Instructions 512 with 256bit operands # vnni512 = yes/no --- -mavx512vnni --- Use Intel Vector Neural Network Instructions 512 +# altivec = yes/no --- -maltivec --- Use PowerPC Altivec SIMD extension +# vsx = yes/no --- -mvsx --- Use POWER VSX SIMD extension # neon = yes/no --- -DUSE_NEON --- Use ARM SIMD architecture # dotprod = yes/no --- -DUSE_NEON_DOTPROD --- Use ARM advanced SIMD Int8 dot product instructions # lsx = yes/no --- -mlsx --- Use Loongson SIMD eXtension @@ -126,7 +128,7 @@ endif ifeq ($(ARCH), $(filter $(ARCH), \ x86-64-vnni512 x86-64-vnni256 x86-64-avx512 x86-64-avxvnni x86-64-bmi2 \ x86-64-avx2 x86-64-sse41-popcnt x86-64-modern x86-64-ssse3 x86-64-sse3-popcnt \ - x86-64 x86-32-sse41-popcnt x86-32-sse2 x86-32 ppc-64 ppc-32 e2k \ + x86-64 x86-32-sse41-popcnt x86-32-sse2 x86-32 ppc-64 ppc-64-altivec ppc-64-vsx ppc-32 e2k \ armv7 armv7-neon armv8 armv8-dotprod apple-silicon general-64 general-32 riscv64 \ loongarch64 loongarch64-lsx loongarch64-lasx)) SUPPORTED_ARCH=true @@ -151,6 +153,8 @@ avxvnni = no avx512 = no vnni256 = no vnni512 = no +altivec = no +vsx = no neon = no dotprod = no arm_version = 0 @@ -360,6 +364,20 @@ ifeq ($(ARCH),ppc-64) prefetch = yes endif +ifeq ($(ARCH),ppc-64-altivec) + arch = ppc64 + popcnt = yes + prefetch = yes + altivec = yes +endif + +ifeq ($(ARCH),ppc-64-vsx) + arch = ppc64 + popcnt = yes + prefetch = yes + vsx = yes +endif + ifeq ($(findstring e2k,$(ARCH)),e2k) arch = e2k mmx = yes @@ -650,7 +668,7 @@ else endif ifeq ($(popcnt),yes) - ifeq ($(arch),$(filter $(arch),ppc64 armv7 armv8 arm64)) + ifeq ($(arch),$(filter $(arch),ppc64 ppc64-altivec ppc64-vsx armv7 armv8 arm64)) CXXFLAGS += -DUSE_POPCNT else CXXFLAGS += -msse3 -mpopcnt -DUSE_POPCNT @@ -720,6 +738,20 @@ ifeq ($(mmx),yes) endif endif +ifeq ($(altivec),yes) + CXXFLAGS += -maltivec + ifeq ($(COMP),gcc) + CXXFLAGS += -mabi=altivec + endif +endif + +ifeq ($(vsx),yes) + CXXFLAGS += -mvsx + ifeq ($(COMP),gcc) + CXXFLAGS += -DNO_WARN_X86_INTRINSICS -DUSE_SSE2 + endif +endif + ifeq ($(neon),yes) CXXFLAGS += -DUSE_NEON=$(arm_version) ifeq ($(KERNEL),Linux) @@ -852,6 +884,8 @@ help: @echo "x86-32-sse2 > x86 32-bit with sse2 support" @echo "x86-32 > x86 32-bit generic (with mmx compile support)" @echo "ppc-64 > PPC 64-bit" + @echo "ppc-64-altivec > PPC 64-bit with altivec support" + @echo "ppc-64-vsx > PPC 64-bit with vsx support" @echo "ppc-32 > PPC 32-bit" @echo "armv7 > ARMv7 32-bit" @echo "armv7-neon > ARMv7 32-bit with popcnt and neon" @@ -987,6 +1021,8 @@ config-sanity: net @echo "avx512: '$(avx512)'" @echo "vnni256: '$(vnni256)'" @echo "vnni512: '$(vnni512)'" + @echo "altivec: '$(altivec)'" + @echo "vsx: '$(vsx)'" @echo "neon: '$(neon)'" @echo "dotprod: '$(dotprod)'" @echo "arm_version: '$(arm_version)'" @@ -1020,6 +1056,8 @@ config-sanity: net @test "$(avx512)" = "yes" || test "$(avx512)" = "no" @test "$(vnni256)" = "yes" || test "$(vnni256)" = "no" @test "$(vnni512)" = "yes" || test "$(vnni512)" = "no" + @test "$(altivec)" = "yes" || test "$(altivec)" = "no" + @test "$(vsx)" = "yes" || test "$(vsx)" = "no" @test "$(neon)" = "yes" || test "$(neon)" = "no" @test "$(lsx)" = "yes" || test "$(lsx)" = "no" @test "$(lasx)" = "yes" || test "$(lasx)" = "no" From aaadbe0572e793cea9ebdf37e32c79235e4d573b Mon Sep 17 00:00:00 2001 From: Nonlinear2 <131959792+Nonlinear2@users.noreply.github.com> Date: Wed, 9 Oct 2024 20:00:19 +0200 Subject: [PATCH 15/23] Introduce mean squared score for delta adjustments This patch introduces the value `meanSquaredScore`, which makes the initial delta sensitive to unstable iterative deepening scores. Passed STC: https://tests.stockfishchess.org/tests/view/66fed74286d5ee47d953bb42 LLR: 2.98 (-2.94,2.94) <0.00,2.00> Total: 71104 W: 18635 L: 18262 D: 34207 Ptnml(0-2): 234, 8365, 17993, 8714, 246 Passed LTC: https://tests.stockfishchess.org/tests/view/6700088e86d5ee47d953bbe9 LLR: 2.95 (-2.94,2.94) <0.50,2.50> Total: 212544 W: 54238 L: 53560 D: 104746 Ptnml(0-2): 120, 23093, 59172, 23763, 124 closes https://github.com/official-stockfish/Stockfish/pull/5627 Bench: 1395505 --- src/search.cpp | 8 ++++++-- src/search.h | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 5598b5ffb..647bae764 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -312,8 +312,8 @@ void Search::Worker::iterative_deepening() { selDepth = 0; // Reset aspiration window starting size + delta = 5 + std::abs(rootMoves[pvIdx].meanSquaredScore) / 13797; Value avg = rootMoves[pvIdx].averageScore; - delta = 5 + avg * avg / 11797; alpha = std::max(avg - delta, -VALUE_INFINITE); beta = std::min(avg + delta, VALUE_INFINITE); @@ -1065,7 +1065,7 @@ moves_loop: // When in check, search starts here // (alpha, beta), then that move is singular and should be extended. To // verify this we do a reduced search on the position excluding the ttMove // and if the result is lower than ttValue minus a margin, then we will - // extend the ttMove. Recursive singular search is avoided. + // extend the ttMove. Recursive singular search is avoided. // Note: the depth margin and singularBeta margin are known for having // non-linear scaling. Their values are optimized to time controls of @@ -1265,6 +1265,10 @@ moves_loop: // When in check, search starts here rm.averageScore = rm.averageScore != -VALUE_INFINITE ? (value + rm.averageScore) / 2 : value; + rm.meanSquaredScore = rm.meanSquaredScore != -VALUE_INFINITE * VALUE_INFINITE + ? (value * std::abs(value) + rm.meanSquaredScore) / 2 + : value * std::abs(value); + // PV move or new best move? if (moveCount == 1 || value > alpha) { diff --git a/src/search.h b/src/search.h index a407e1058..2342d9e93 100644 --- a/src/search.h +++ b/src/search.h @@ -91,15 +91,16 @@ struct RootMove { return m.score != score ? m.score < score : m.previousScore < previousScore; } - uint64_t effort = 0; - Value score = -VALUE_INFINITE; - Value previousScore = -VALUE_INFINITE; - Value averageScore = -VALUE_INFINITE; - Value uciScore = -VALUE_INFINITE; - bool scoreLowerbound = false; - bool scoreUpperbound = false; - int selDepth = 0; - int tbRank = 0; + uint64_t effort = 0; + Value score = -VALUE_INFINITE; + Value previousScore = -VALUE_INFINITE; + Value averageScore = -VALUE_INFINITE; + Value meanSquaredScore = -VALUE_INFINITE * VALUE_INFINITE; + Value uciScore = -VALUE_INFINITE; + bool scoreLowerbound = false; + bool scoreUpperbound = false; + int selDepth = 0; + int tbRank = 0; Value tbScore; std::vector pv; }; From b261df970d5207069a06e89b48983aece1c60925 Mon Sep 17 00:00:00 2001 From: Shawn Xu Date: Wed, 9 Oct 2024 20:16:14 -0700 Subject: [PATCH 16/23] Fix majorPieceKey Updates Passed STC: LLR: 2.98 (-2.94,2.94) <0.00,2.00> Total: 476160 W: 124285 L: 123311 D: 228564 Ptnml(0-2): 1662, 56266, 121219, 57302, 1631 https://tests.stockfishchess.org/tests/view/66ea3dc186d5ee47d953ae07 Failed Yellow LTC: LLR: -2.94 (-2.94,2.94) <0.50,2.50> Total: 230634 W: 58525 L: 58295 D: 113814 Ptnml(0-2): 113, 25301, 64299, 25451, 153 https://tests.stockfishchess.org/tests/view/66f1825e86d5ee47d953b2ec Passed Non-regression LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 112344 W: 28590 L: 28462 D: 55292 Ptnml(0-2): 71, 12439, 31039, 12537, 86 https://tests.stockfishchess.org/tests/view/6707474486d5ee47d953bfe3 closes https://github.com/official-stockfish/Stockfish/pull/5629 Bench: 1283457 --- src/position.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/position.cpp b/src/position.cpp index f596b0153..bab7a1fca 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -759,7 +759,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { st->nonPawnMaterial[them] -= PieceValue[captured]; st->nonPawnKey[them] ^= Zobrist::psq[captured][capsq]; - if (type_of(pc) == QUEEN || type_of(pc) == ROOK) + if (type_of(captured) == QUEEN || type_of(captured) == ROOK) st->majorPieceKey ^= Zobrist::psq[captured][capsq]; else From 9766db8139ce8815110c15bdde8381d0564a63fa Mon Sep 17 00:00:00 2001 From: Michael Chaly Date: Sat, 12 Oct 2024 08:32:15 +0300 Subject: [PATCH 17/23] Make low ply history size fixed Size of low ply history should always be the same, so ensure it. closes https://github.com/official-stockfish/Stockfish/pull/5630 No functional change --- src/movepick.cpp | 2 +- src/movepick.h | 3 ++- src/search.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/movepick.cpp b/src/movepick.cpp index 1d1aef0f3..064951893 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -179,7 +179,7 @@ void MovePicker::score() { : pt == ROOK && bool(to & threatenedByMinor) ? 24335 : 0); - if (ply < 4) + if (ply < LOW_PLY_HISTORY_SIZE) m.value += 8 * (*lowPlyHistory)[ply][m.from_to()] / (1 + 2 * ply); } diff --git a/src/movepick.h b/src/movepick.h index 9a68aaa1d..5c312531e 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -37,6 +37,7 @@ namespace Stockfish { constexpr int PAWN_HISTORY_SIZE = 512; // has to be a power of 2 constexpr int CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2 constexpr int CORRECTION_HISTORY_LIMIT = 1024; +constexpr int LOW_PLY_HISTORY_SIZE = 4; static_assert((PAWN_HISTORY_SIZE & (PAWN_HISTORY_SIZE - 1)) == 0, "PAWN_HISTORY_SIZE has to be a power of 2"); @@ -137,7 +138,7 @@ using ButterflyHistory = Stats; +using LowPlyHistory = Stats; // CapturePieceToHistory is addressed by a move's [piece][to][captured piece type] using CapturePieceToHistory = Stats; diff --git a/src/search.cpp b/src/search.cpp index 647bae764..6e513b458 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1851,7 +1851,7 @@ void update_quiet_histories( Color us = pos.side_to_move(); workerThread.mainHistory[us][move.from_to()] << bonus; - if (ss->ply < 4) + if (ss->ply < LOW_PLY_HISTORY_SIZE) workerThread.lowPlyHistory[ss->ply][move.from_to()] << bonus; update_continuation_histories(ss, pos.moved_piece(move), move.to_sq(), bonus); From 656b2cb6459cf3c91f8d8ed6aa770026f77ee7b9 Mon Sep 17 00:00:00 2001 From: Linmiao Xu Date: Sun, 6 Oct 2024 20:11:19 -0400 Subject: [PATCH 18/23] Update default main net to nn-1cedc0ffeeee.nnue Created by setting output weights (256) and biases (8) of the previous main net nn-1111cefa1111.nnue to values found with spsa after 38k / 120k games at 120+1.2 using the same method as: https://github.com/official-stockfish/Stockfish/pull/5459 nn-1111cefa1111.nnue -> nn-1cedc0ffeeee.nnue # weights changed: 185 mean: 0.0703 +/- 2.53 min: -6 max: 6 Passed STC: https://tests.stockfishchess.org/tests/view/6703589b86d5ee47d953bda1 LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 101984 W: 26690 L: 26275 D: 49019 Ptnml(0-2): 375, 11944, 25926, 12385, 362 Passed LTC: https://tests.stockfishchess.org/tests/view/670542d286d5ee47d953befa LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 106224 W: 27079 L: 26618 D: 52527 Ptnml(0-2): 71, 11508, 29487, 11981, 65 closes https://github.com/official-stockfish/Stockfish/pull/5632 Bench: 1351413 --- src/evaluate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/evaluate.h b/src/evaluate.h index c9041efbf..9bd436b58 100644 --- a/src/evaluate.h +++ b/src/evaluate.h @@ -33,7 +33,7 @@ namespace Eval { // for the build process (profile-build and fishtest) to work. Do not change the // name of the macro or the location where this macro is defined, as it is used // in the Makefile/Fishtest. -#define EvalFileDefaultNameBig "nn-1111cefa1111.nnue" +#define EvalFileDefaultNameBig "nn-1cedc0ffeeee.nnue" #define EvalFileDefaultNameSmall "nn-37f18f62d772.nnue" namespace NNUE { From 2f3e6198e878818f9f90de8cb31e287de34bed0e Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Sun, 13 Oct 2024 13:59:20 +0300 Subject: [PATCH 19/23] Simplify optimism divisor. Passed STC: LLR: 2.97 (-2.94,2.94) <-1.75,0.25> Total: 139360 W: 36143 L: 36033 D: 67184 Ptnml(0-2): 436, 16456, 35778, 16582, 428 https://tests.stockfishchess.org/tests/view/66fc49c786d5ee47d953b94e Passed LTC: LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 257748 W: 65163 L: 65184 D: 127401 Ptnml(0-2): 173, 28471, 71611, 28442, 177 https://tests.stockfishchess.org/tests/view/66ff01ae86d5ee47d953bb54 Passed LTC against rebased version: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 53610 W: 13691 L: 13501 D: 26418 Ptnml(0-2): 52, 5942, 14605, 6176, 30 https://tests.stockfishchess.org/tests/view/670a9c5c86d5ee47d953c231 closes https://github.com/official-stockfish/Stockfish/pull/5633 Bench: 1282078 --- src/evaluate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 802913a04..7c7b54a4f 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -75,7 +75,7 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, // Blend optimism and eval with nnue complexity int nnueComplexity = std::abs(psqt - positional); - optimism += optimism * nnueComplexity / (smallNet ? 430 : 474); + optimism += optimism * nnueComplexity / 468; nnue -= nnue * nnueComplexity / (smallNet ? 20233 : 17879); int material = (smallNet ? 553 : 532) * pos.count() + pos.non_pawn_material(); From bf2a0d53925da1a0d58a91ef78d577a448eb4b5a Mon Sep 17 00:00:00 2001 From: Taras Vuk <117687515+TarasVuk@users.noreply.github.com> Date: Mon, 14 Oct 2024 21:30:18 +0200 Subject: [PATCH 20/23] Simplify internal iterative reductions Passed STC: LLR: 2.92 (-2.94,2.94) <-1.75,0.25> Total: 138656 W: 36182 L: 36074 D: 66400 Ptnml(0-2): 523, 16422, 35310, 16570, 503 https://tests.stockfishchess.org/tests/view/6702beb386d5ee47d953bd41 Passed LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 680844 W: 172021 L: 172480 D: 336343 Ptnml(0-2): 492, 76259, 187419, 75720, 532 https://tests.stockfishchess.org/tests/view/67042b1f86d5ee47d953be7c closes https://github.com/official-stockfish/Stockfish/pull/5634 Bench: 1169252 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 6e513b458..75a8c9633 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -850,7 +850,7 @@ Value Search::Worker::search( // For cutNodes, if depth is high enough, decrease depth by 2 if there is no ttMove, // or by 1 if there is a ttMove with an upper bound. if (cutNode && depth >= 7 && (!ttData.move || ttData.bound == BOUND_UPPER)) - depth -= 1 + !ttData.move; + depth -= 2; // Step 11. ProbCut (~10 Elo) // If we have a good enough capture (or queen promotion) and a reduced search From 7f386d109e1b38d530d98f81e7213a2f1b2090af Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Wed, 16 Oct 2024 03:06:58 +0300 Subject: [PATCH 21/23] Remove material corrHist Passed STC: LLR: 2.96 (-2.94,2.94) <-1.75,0.25> Total: 80832 W: 21150 L: 20975 D: 38707 Ptnml(0-2): 283, 9531, 20598, 9736, 268 https://tests.stockfishchess.org/tests/view/670302fe86d5ee47d953bd68 Passed LTC: LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 46008 W: 11621 L: 11423 D: 22964 Ptnml(0-2): 30, 5072, 12606, 5262, 34 https://tests.stockfishchess.org/tests/view/6704074686d5ee47d953be53 Passed LTC Rebased: LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 95814 W: 24340 L: 24195 D: 47279 Ptnml(0-2): 71, 10497, 26602, 10690, 47 https://tests.stockfishchess.org/tests/view/670ae1ac86d5ee47d953c262 closes https://github.com/official-stockfish/Stockfish/pull/5636 Bench: 1119774 --- src/movepick.h | 4 ---- src/search.cpp | 6 +----- src/search.h | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/movepick.h b/src/movepick.h index 5c312531e..6ad13397a 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -167,10 +167,6 @@ using PawnHistory = Stats using PawnCorrectionHistory = Stats; -// MaterialCorrectionHistory is addressed by color and material configuration -using MaterialCorrectionHistory = - Stats; - // MajorPieceCorrectionHistory is addressed by color and king/major piece (Queen, Rook) positions using MajorPieceCorrectionHistory = Stats; diff --git a/src/search.cpp b/src/search.cpp index 75a8c9633..568e147c8 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -83,7 +83,6 @@ Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos, St const Color us = pos.side_to_move(); const auto m = (ss - 1)->currentMove; const auto pcv = w.pawnCorrectionHistory[us][pawn_structure_index(pos)]; - const auto mcv = w.materialCorrectionHistory[us][material_index(pos)]; const auto macv = w.majorPieceCorrectionHistory[us][major_piece_index(pos)]; const auto micv = w.minorPieceCorrectionHistory[us][minor_piece_index(pos)]; const auto wnpcv = w.nonPawnCorrectionHistory[WHITE][us][non_pawn_index(pos)]; @@ -94,8 +93,7 @@ Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos, St cntcv = int((*(ss - 2)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()]); const auto cv = - (5932 * pcv + 2994 * mcv + 3269 * macv + 5660 * micv + 6237 * (wnpcv + bnpcv) + cntcv * 5555) - / 131072; + (5932 * pcv + 3269 * macv + 5660 * micv + 6666 * (wnpcv + bnpcv) + 5555 * cntcv) / 131072; v += cv; return std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1); } @@ -506,7 +504,6 @@ void Search::Worker::clear() { captureHistory.fill(-753); pawnHistory.fill(-1152); pawnCorrectionHistory.fill(0); - materialCorrectionHistory.fill(0); majorPieceCorrectionHistory.fill(0); minorPieceCorrectionHistory.fill(0); nonPawnCorrectionHistory[WHITE].fill(0); @@ -1428,7 +1425,6 @@ moves_loop: // When in check, search starts here -CORRECTION_HISTORY_LIMIT / 4, CORRECTION_HISTORY_LIMIT / 4); thisThread->pawnCorrectionHistory[us][pawn_structure_index(pos)] << bonus * 101 / 128; - thisThread->materialCorrectionHistory[us][material_index(pos)] << bonus * 99 / 128; thisThread->majorPieceCorrectionHistory[us][major_piece_index(pos)] << bonus * 157 / 128; thisThread->minorPieceCorrectionHistory[us][minor_piece_index(pos)] << bonus * 153 / 128; thisThread->nonPawnCorrectionHistory[WHITE][us][non_pawn_index(pos)] diff --git a/src/search.h b/src/search.h index 2342d9e93..b599da110 100644 --- a/src/search.h +++ b/src/search.h @@ -287,7 +287,6 @@ class Worker { PawnHistory pawnHistory; PawnCorrectionHistory pawnCorrectionHistory; - MaterialCorrectionHistory materialCorrectionHistory; MajorPieceCorrectionHistory majorPieceCorrectionHistory; MinorPieceCorrectionHistory minorPieceCorrectionHistory; NonPawnCorrectionHistory nonPawnCorrectionHistory[COLOR_NB]; From b325b2c348df02e415b6c78121e0502622d57f34 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Wed, 16 Oct 2024 13:14:13 +0300 Subject: [PATCH 22/23] Simplify bestValue formula Passed STC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 45888 W: 12051 L: 11841 D: 21996 Ptnml(0-2): 123, 5356, 11807, 5504, 154 https://tests.stockfishchess.org/tests/view/670bb89086d5ee47d953c2d8 Passed LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 51336 W: 13021 L: 12830 D: 25485 Ptnml(0-2): 34, 5594, 14227, 5773, 40 https://tests.stockfishchess.org/tests/view/670c587f86d5ee47d953c31b closes https://github.com/official-stockfish/Stockfish/pull/5637 Bench: 1192999 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 568e147c8..c398b7d25 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1551,7 +1551,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) if (bestValue >= beta) { if (std::abs(bestValue) < VALUE_TB_WIN_IN_MAX_PLY) - bestValue = (3 * bestValue + beta) / 4; + bestValue = (bestValue + beta) / 2; if (!ss->ttHit) ttWriter.write(posKey, value_to_tt(bestValue, ss->ply), false, BOUND_LOWER, DEPTH_UNSEARCHED, Move::none(), unadjustedStaticEval, From 2ce47573b4d3664dca4cbc4354c8c600540d16ad Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Wed, 16 Oct 2024 19:40:49 +0300 Subject: [PATCH 23/23] Remove -stat_malus(newDepth) Passed STC: LLR: 2.97 (-2.94,2.94) <-1.75,0.25> Total: 92544 W: 23940 L: 23778 D: 44826 Ptnml(0-2): 286, 10936, 23638, 11154, 258 https://tests.stockfishchess.org/tests/view/670c3d6986d5ee47d953c30b Passed LTC: LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 43164 W: 10986 L: 10786 D: 21392 Ptnml(0-2): 27, 4713, 11905, 4907, 30 https://tests.stockfishchess.org/tests/view/670eda3d86d5ee47d953c51d closes https://github.com/official-stockfish/Stockfish/pull/5639 Bench: 1281912 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index c398b7d25..c78acb6c4 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1210,7 +1210,7 @@ moves_loop: // When in check, search starts here value = -search(pos, ss + 1, -(alpha + 1), -alpha, newDepth, !cutNode); // Post LMR continuation history updates (~1 Elo) - int bonus = value >= beta ? 3 * stat_bonus(newDepth) : -stat_malus(newDepth); + int bonus = 2 * (value >= beta) * stat_bonus(newDepth); update_continuation_histories(ss, movedPiece, move.to_sq(), bonus); } }