]> git.sesse.net Git - stockfish/commitdiff
Introduce Material Correction History
authorShawn Xu <xu107288696@gmail.com>
Sat, 24 Aug 2024 00:13:49 +0000 (17:13 -0700)
committerDisservin <disservin.social@gmail.com>
Mon, 9 Sep 2024 15:43:05 +0000 (17:43 +0200)
Idea from Caissa (https://github.com/Witek902/Caissa) chess engine.

Add a secondary correction history indexed by the material key of a position.
The material key is the zobrist hash representing the number of pieces left in a
position.

Passed STC:
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 189472 W: 49360 L: 48813 D: 91299
Ptnml(0-2): 666, 22453, 47953, 22996, 668
https://tests.stockfishchess.org/tests/view/66cbddafbf8c9d8780fda9f1

Passed LTC:
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 224190 W: 57022 L: 56312 D: 110856
Ptnml(0-2): 197, 24723, 61540, 25443, 192
https://tests.stockfishchess.org/tests/view/66cd529bbf8c9d8780fdab4c

closes https://github.com/official-stockfish/Stockfish/pull/5556

Bench: 1462697

src/movepick.h
src/search.cpp
src/search.h

index 61f6368e6d988faf39eb783484ba25f7e06025a6..651091b08290fd7e9efbfd1e092b58dd513b355c 100644 (file)
 
 namespace Stockfish {
 
-constexpr int PAWN_HISTORY_SIZE        = 512;    // has to be a power of 2
-constexpr int CORRECTION_HISTORY_SIZE  = 16384;  // 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 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 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((CORRECTION_HISTORY_SIZE & (CORRECTION_HISTORY_SIZE - 1)) == 0,
+static_assert((PAWN_CORRECTION_HISTORY_SIZE & (PAWN_CORRECTION_HISTORY_SIZE - 1)) == 0,
               "CORRECTION_HISTORY_SIZE has to be a power of 2");
 
 enum PawnHistoryType {
@@ -51,7 +52,11 @@ enum PawnHistoryType {
 
 template<PawnHistoryType T = Normal>
 inline int pawn_structure_index(const Position& pos) {
-    return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : CORRECTION_HISTORY_SIZE) - 1);
+    return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : PAWN_CORRECTION_HISTORY_SIZE) - 1);
+}
+
+inline int material_index(const Position& pos) {
+    return pos.material_key() & (MATERIAL_CORRECTION_HISTORY_SIZE - 1);
 }
 
 // StatsEntry stores the stat table value. It is usually a number but could
@@ -133,9 +138,18 @@ using ContinuationHistory = Stats<PieceToHistory, NOT_USED, PIECE_NB, SQUARE_NB>
 // PawnHistory is addressed by the pawn structure and a move's [piece][to]
 using PawnHistory = Stats<int16_t, 8192, PAWN_HISTORY_SIZE, PIECE_NB, SQUARE_NB>;
 
-// CorrectionHistory is addressed by color and pawn structure
-using CorrectionHistory =
-  Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, CORRECTION_HISTORY_SIZE>;
+
+// Correction histories record differences between the static evaluation of
+// positions and their search score. It is used to improve the static evaluation
+// used by some search heuristics.
+
+// PawnCorrectionHistory is addressed by color and pawn structure
+using PawnCorrectionHistory =
+  Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, PAWN_CORRECTION_HISTORY_SIZE>;
+
+// MaterialCorrectionHistory is addressed by color and material configuration
+using MaterialCorrectionHistory =
+  Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, MATERIAL_CORRECTION_HISTORY_SIZE>;
 
 // 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
index 9d950c0e7552804e02017a721e04b0c6bdb8de38..bc85a5c3e96f0737d5c27a2dc5d0b792cc85f7e7 100644 (file)
@@ -81,7 +81,10 @@ 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) {
-    auto cv = w.correctionHistory[pos.side_to_move()][pawn_structure_index<Correction>(pos)];
+    const auto pcv =
+      w.pawnCorrectionHistory[pos.side_to_move()][pawn_structure_index<Correction>(pos)];
+    const auto mcv = w.materialCorrectionHistory[pos.side_to_move()][material_index(pos)];
+    const auto cv  = (2 * pcv + mcv) / 3;
     v += 66 * cv / 512;
     return std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
 }
@@ -487,7 +490,8 @@ void Search::Worker::clear() {
     mainHistory.fill(0);
     captureHistory.fill(-700);
     pawnHistory.fill(-1188);
-    correctionHistory.fill(0);
+    pawnCorrectionHistory.fill(0);
+    materialCorrectionHistory.fill(0);
 
     for (bool inCheck : {false, true})
         for (StatsType c : {NoCaptures, Captures})
@@ -1390,7 +1394,8 @@ moves_loop:  // When in check, search starts here
     {
         auto bonus = std::clamp(int(bestValue - ss->staticEval) * depth / 8,
                                 -CORRECTION_HISTORY_LIMIT / 4, CORRECTION_HISTORY_LIMIT / 4);
-        thisThread->correctionHistory[us][pawn_structure_index<Correction>(pos)] << bonus;
+        thisThread->pawnCorrectionHistory[us][pawn_structure_index<Correction>(pos)] << bonus;
+        thisThread->materialCorrectionHistory[us][material_index(pos)] << bonus;
     }
 
     assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
index 0f635186a3b6a5dcd362443b2be9f025c6907f5e..c9fe9e184ac628905546f1f7baf33a0263719055 100644 (file)
@@ -277,11 +277,12 @@ class Worker {
     void ensure_network_replicated();
 
     // Public because they need to be updatable by the stats
-    ButterflyHistory      mainHistory;
-    CapturePieceToHistory captureHistory;
-    ContinuationHistory   continuationHistory[2][2];
-    PawnHistory           pawnHistory;
-    CorrectionHistory     correctionHistory;
+    ButterflyHistory          mainHistory;
+    CapturePieceToHistory     captureHistory;
+    ContinuationHistory       continuationHistory[2][2];
+    PawnHistory               pawnHistory;
+    PawnCorrectionHistory     pawnCorrectionHistory;
+    MaterialCorrectionHistory materialCorrectionHistory;
 
    private:
     void iterative_deepening();