Merge commit '16fee2a7da25c6d0267930eb9677862cb1f009c7' into cluster

This is the last commit before there are more conflicts.
This commit is contained in:
Steinar H. Gunderson
2025-12-25 17:30:06 +01:00
5 changed files with 64 additions and 64 deletions
+3 -1
View File
@@ -216,7 +216,7 @@ Move MovePicker::select(Pred filter) {
// This is the most important method of the MovePicker class. We emit one
// new pseudo-legal move on every call until there are no more moves left,
// picking the move with the highest score from a list of generated moves.
Move MovePicker::next_move(bool skipQuiets) {
Move MovePicker::next_move() {
auto quiet_threshold = [](Depth d) { return -3560 * d; };
@@ -322,4 +322,6 @@ top:
return Move::none(); // Silence warning
}
void MovePicker::skip_quiet_moves() { skipQuiets = true; }
} // namespace Stockfish
+25 -20
View File
@@ -146,9 +146,6 @@ using CapturePieceToHistory = Stats<int16_t, 10692, PIECE_NB, SQUARE_NB, PIECE_T
// PieceToHistory is like ButterflyHistory but is addressed by a move's [piece][to]
using PieceToHistory = Stats<int16_t, 29952, PIECE_NB, SQUARE_NB>;
// PieceToCorrectionHistory is addressed by a move's [piece][to]
using PieceToCorrectionHistory = Stats<int16_t, CORRECTION_HISTORY_LIMIT, PIECE_NB, SQUARE_NB>;
// 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.
@@ -162,26 +159,32 @@ using PawnHistory = Stats<int16_t, 8192, PAWN_HISTORY_SIZE, PIECE_NB, SQUARE_NB>
// positions and their search score. It is used to improve the static evaluation
// used by some search heuristics.
// see https://www.chessprogramming.org/Static_Evaluation_Correction_History
enum CorrHistType {
Pawn, // By color and pawn structure
Major, // By color and positions of major pieces (Queen, Rook) and King
Minor, // By color and positions of minor pieces (Knight, Bishop) and King
NonPawn, // By color and non-pawn material positions
PieceTo, // By [piece][to] move
Continuation, // Combined history of move pairs
};
// PawnCorrectionHistory is addressed by color and pawn structure
using PawnCorrectionHistory =
Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, CORRECTION_HISTORY_SIZE>;
template<CorrHistType _>
struct CorrHistTypedef {
using type = Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, CORRECTION_HISTORY_SIZE>;
};
// MajorPieceCorrectionHistory is addressed by color and king/major piece (Queen, Rook) positions
using MajorPieceCorrectionHistory =
Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, CORRECTION_HISTORY_SIZE>;
template<>
struct CorrHistTypedef<PieceTo> {
using type = Stats<int16_t, CORRECTION_HISTORY_LIMIT, PIECE_NB, SQUARE_NB>;
};
// MinorPieceCorrectionHistory is addressed by color and king/minor piece (Knight, Bishop) positions
using MinorPieceCorrectionHistory =
Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, CORRECTION_HISTORY_SIZE>;
template<>
struct CorrHistTypedef<Continuation> {
using type = Stats<CorrHistTypedef<PieceTo>::type, NOT_USED, PIECE_NB, SQUARE_NB>;
};
// NonPawnCorrectionHistory is addressed by color and non-pawn material positions
using NonPawnCorrectionHistory =
Stats<int16_t, CORRECTION_HISTORY_LIMIT, COLOR_NB, CORRECTION_HISTORY_SIZE>;
// ContinuationCorrectionHistory is the combined correction history of a given pair of moves
using ContinuationCorrectionHistory =
Stats<PieceToCorrectionHistory, NOT_USED, PIECE_NB, SQUARE_NB>;
template<CorrHistType T>
using CorrectionHistory = typename CorrHistTypedef<T>::type;
// 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
@@ -209,7 +212,8 @@ class MovePicker {
const PawnHistory*,
int);
MovePicker(const Position&, Move, int, const CapturePieceToHistory*);
Move next_move(bool skipQuiets = false);
Move next_move();
void skip_quiet_moves();
private:
template<PickType T, typename Pred>
@@ -231,6 +235,7 @@ class MovePicker {
int threshold;
Depth depth;
int ply;
bool skipQuiets = false;
ExtMove moves[MAX_MOVES];
};
+14 -14
View File
@@ -491,9 +491,9 @@ void Search::Worker::iterative_deepening() {
{
int nodesEffort = rootMoves[0].effort * 100 / std::max(size_t(1), size_t(nodes));
double fallingEval = (1067 + 223 * (mainThread->bestPreviousAverageScore - bestValue)
+ 97 * (mainThread->iterValue[iterIdx] - bestValue))
/ 10000.0;
double fallingEval = (11 + 2 * (mainThread->bestPreviousAverageScore - bestValue)
+ (mainThread->iterValue[iterIdx] - bestValue))
/ 100.0;
fallingEval = std::clamp(fallingEval, 0.580, 1.667);
// If the bestMove is stable over several iterations, reduce time accordingly
@@ -993,12 +993,11 @@ moves_loop: // When in check, search starts here
value = bestValue;
int moveCount = 0;
bool moveCountPruning = false;
int moveCount = 0;
// Step 13. Loop through all pseudo-legal moves until no moves remain
// or a beta cutoff occurs.
while ((move = mp.next_move(moveCountPruning)) != Move::none())
while ((move = mp.next_move()) != Move::none())
{
assert(move.is_ok());
@@ -1044,7 +1043,8 @@ moves_loop: // When in check, search starts here
if (!rootNode && pos.non_pawn_material(us) && bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
{
// Skip quiet moves if movecount exceeds our FutilityMoveCount threshold (~8 Elo)
moveCountPruning = moveCount >= futility_move_count(improving, depth);
if (moveCount >= futility_move_count(improving, depth))
mp.skip_quiet_moves();
// Reduced depth of the next LMR search
int lmrDepth = newDepth - r;
@@ -1845,35 +1845,35 @@ void update_all_stats(const Position& pos,
Piece moved_piece = pos.moved_piece(bestMove);
PieceType captured;
int quietMoveBonus = stat_bonus(depth);
int quietMoveMalus = stat_malus(depth);
int bonus = stat_bonus(depth);
int malus = stat_malus(depth);
if (!pos.capture_stage(bestMove))
{
update_quiet_histories(pos, ss, workerThread, bestMove, quietMoveBonus);
update_quiet_histories(pos, ss, workerThread, bestMove, bonus);
// Decrease stats for all non-best quiet moves
for (Move move : quietsSearched)
update_quiet_histories(pos, ss, workerThread, move, -quietMoveMalus);
update_quiet_histories(pos, ss, workerThread, move, -malus);
}
else
{
// Increase stats for the best move in case it was a capture move
captured = type_of(pos.piece_on(bestMove.to_sq()));
captureHistory[moved_piece][bestMove.to_sq()][captured] << quietMoveBonus;
captureHistory[moved_piece][bestMove.to_sq()][captured] << bonus;
}
// Extra penalty for a quiet early move that was not a TT move in
// previous ply when it gets refuted.
if (prevSq != SQ_NONE && ((ss - 1)->moveCount == 1 + (ss - 1)->ttHit) && !pos.captured_piece())
update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq, -quietMoveMalus);
update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq, -malus);
// Decrease stats for all non-best capture moves
for (Move move : capturesSearched)
{
moved_piece = pos.moved_piece(move);
captured = type_of(pos.piece_on(move.to_sq()));
captureHistory[moved_piece][move.to_sq()][captured] << -quietMoveMalus;
captureHistory[moved_piece][move.to_sq()][captured] << -malus;
}
}
+18 -18
View File
@@ -63,19 +63,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;
PieceToCorrectionHistory* continuationCorrectionHistory;
int ply;
Move currentMove;
Move excludedMove;
Value staticEval;
int statScore;
int moveCount;
bool inCheck;
bool ttPv;
bool ttHit;
int cutoffCnt;
Move* pv;
PieceToHistory* continuationHistory;
CorrectionHistory<PieceTo>* continuationCorrectionHistory;
int ply;
Move currentMove;
Move excludedMove;
Value staticEval;
int statScore;
int moveCount;
bool inCheck;
bool ttPv;
bool ttHit;
int cutoffCnt;
};
@@ -298,11 +298,11 @@ class Worker {
ContinuationHistory continuationHistory[2][2];
PawnHistory pawnHistory;
PawnCorrectionHistory pawnCorrectionHistory;
MajorPieceCorrectionHistory majorPieceCorrectionHistory;
MinorPieceCorrectionHistory minorPieceCorrectionHistory;
NonPawnCorrectionHistory nonPawnCorrectionHistory[COLOR_NB];
ContinuationCorrectionHistory continuationCorrectionHistory;
CorrectionHistory<Pawn> pawnCorrectionHistory;
CorrectionHistory<Major> majorPieceCorrectionHistory;
CorrectionHistory<Minor> minorPieceCorrectionHistory;
CorrectionHistory<NonPawn> nonPawnCorrectionHistory[COLOR_NB];
CorrectionHistory<Continuation> continuationCorrectionHistory;
#ifdef USE_MPI
struct {
+4 -11
View File
@@ -194,19 +194,12 @@ void TranspositionTable::clear(ThreadPool& threads) {
// occupation during a search. The hash is x permill full, as per UCI protocol.
// Only counts entries which match the current generation.
int TranspositionTable::hashfull(int maxAge) const {
int cnt = 0;
int maxAgeInternal = maxAge << GENERATION_BITS;
int cnt = 0;
for (int i = 0; i < 1000; ++i)
for (int j = 0; j < ClusterSize; ++j)
{
if (table[i].entry[j].is_occupied())
{
int age = (generation8 >> GENERATION_BITS)
- ((table[i].entry[j].genBound8 & GENERATION_MASK) >> GENERATION_BITS);
if (age < 0)
age += 1 << (8 - GENERATION_BITS);
cnt += age <= maxAge;
}
}
cnt += table[i].entry[j].is_occupied()
&& table[i].entry[j].relative_age(generation8) <= maxAgeInternal;
return cnt / ClusterSize;
}