Minor cleanups June 2026

In the spirit of previous such PRs, this PR proposes a collection of nonfunctional changes.

I am happy to incorporate changes from other devs, and revert some of the proposed changes if the maintainers ask me to.

Apart from trivial changes, the proposed changes so far include:

* A requested edit to `AUTHORS` and a resorting of all entries, following DIN 5007 for the treatment of any special characters.
* Exclude the two recent integer type renaming commits from git blame.
* Tightening of some static asserts in `history.h` to avoid overflows. (Note that rounding errors for floating point types could lead to the assert in `operator<<` triggering at run-time.)
* Re-instate the 0.5s maximal thinking time in case of a single legal move and reword the comment to make it clear that it should not be tuned.
* ~~A small refactoring of the network loading code thanks to @dubslow.~~
* A refactoring of the "dtz is dtm" code, also thanks to @dubslow.

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

No functional change
This commit is contained in:
Robert Nurnberg
2026-07-10 20:12:38 +02:00
committed by Joost VandeVondele
parent eca43a97ef
commit 48a9118251
23 changed files with 87 additions and 182 deletions
+2 -3
View File
@@ -70,7 +70,7 @@ static void init_magics(Magic magics[][2]) {
// Sliding attacks within a rank, indexed by the slider's file and the
// 8-bit rank occupancy, yielding the 8-bit attack set on that rank
[[maybe_unused]] constexpr auto RankAttacks = []() {
constexpr auto RankAttacks = []() {
std::array<std::array<u8, 256>, FILE_NB> table{};
for (int file = 0; file < 8; ++file)
for (int occ = 0; occ < 256; ++occ)
@@ -117,8 +117,7 @@ void init_magics(PieceType pt, Bitboard table[], Magic magics[][2]) {
m.attacks = s == SQ_A1 ? table : magics[s - 1][pt - BISHOP].attacks + size;
size = 0;
Bitboard b = 0;
[[maybe_unused]] Bitboard prevSliding = -1;
Bitboard b = 0;
do
{
occupancy[size] = b;
+5 -5
View File
@@ -102,10 +102,10 @@ struct alignas(32) DualMagic {
//
// When using hyperbola quintessence, file, diagonal and antidiagonal attacks
// can use a byte reversal rather than a full bit reversal (because all squares
// reside in different bytes). Rank atttacks cannot. Thus, for rank attacks
// reside in different bytes). Rank attacks cannot. Thus, for rank attacks
// only, we use a compact lookup table indexed by the 8 bits of the rank's occupancy.
std::pair<Bitboard, Bitboard> both_attacks_bb(Bitboard occupied) const {
// Byteswap within 64-bit elements
// Byteswap within 128-bit elements
const auto bswap = [](__m256i v) {
return _mm256_shuffle_epi8(v, _mm256_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
@@ -270,7 +270,7 @@ inline Bitboard attacks_bb(Square s, Color c = COLOR_NB) {
// 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.
// Sliding piece attacks do not continue past an occupied square.
template<PieceType Pt>
inline Bitboard attacks_bb(Square s, Bitboard occupied) {
@@ -306,7 +306,7 @@ inline Bitboard attacks_bb(Square s, Bitboard occupied) {
// 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.
// Sliding piece attacks do not continue past an occupied square.
inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) {
assert(pt != PAWN && is_ok(s));
@@ -318,7 +318,7 @@ inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) {
case ROOK :
return attacks_bb<ROOK>(s, occupied);
case QUEEN :
return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied);
return attacks_bb<QUEEN>(s, occupied);
default :
return PseudoAttacks[pt][s];
}
+1 -1
View File
@@ -485,7 +485,7 @@ BenchmarkSetup setup_benchmark(std::istream& is) {
float totalTime = 0;
for (const auto& game : BenchmarkPositions)
for (usize i = 0; i < game.size(); ++i)
totalTime += float(getCorrectedTime(i + 1));
totalTime += float(getCorrectedTime(int(i + 1)));
float timeScaleFactor = static_cast<float>(desiredTimeS * 1000) / totalTime;
+1 -8
View File
@@ -23,7 +23,6 @@
namespace Stockfish {
u8 PopCnt16[1 << 16];
u8 SquareDistance[SQUARE_NB][SQUARE_NB];
// Returns an ASCII representation of a bitboard suitable
// to be printed to standard output. Useful for debugging.
@@ -46,16 +45,10 @@ std::string Bitboards::pretty(Bitboard b) {
return s;
}
// Initializes various bitboard tables. It is called at
// startup and relies on global objects to be already zero-initialized.
// Initializes the popcount table at startup.
void Bitboards::init() {
for (unsigned i = 0; i < (1 << 16); ++i)
PopCnt16[i] = u8(std::bitset<16>(i).count());
for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
SquareDistance[s1][s2] = std::max(distance<File>(s1, s2), distance<Rank>(s1, s2));
}
} // namespace Stockfish
-25
View File
@@ -21,9 +21,7 @@
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include "types.h"
@@ -66,7 +64,6 @@ constexpr Bitboard Rank7BB = Rank1BB << (8 * 6);
constexpr Bitboard Rank8BB = Rank1BB << (8 * 7);
extern u8 PopCnt16[1 << 16];
extern u8 SquareDistance[SQUARE_NB][SQUARE_NB];
constexpr Bitboard square_bb(Square s) {
assert(is_ok(s));
@@ -133,30 +130,8 @@ constexpr Bitboard pawn_single_push_bb(Color c, Bitboard b) {
return c == WHITE ? shift<NORTH>(b) : shift<SOUTH>(b);
}
// distance() functions return the distance between x and y, defined as the
// number of steps for a king in x to reach y.
template<typename T1 = Square>
inline int distance(Square x, Square y);
template<>
inline int distance<File>(Square x, Square y) {
return std::abs(file_of(x) - file_of(y));
}
template<>
inline int distance<Rank>(Square x, Square y) {
return std::abs(rank_of(x) - rank_of(y));
}
template<>
inline int distance<Square>(Square x, Square y) {
return SquareDistance[x][y];
}
inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); }
constexpr int constexpr_popcount(Bitboard b) {
b = b - ((b >> 1) & 0x5555555555555555ULL);
b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL);
+1 -1
View File
@@ -164,7 +164,7 @@ void Engine::search_clear() {
tt.clear(threads);
threads.clear();
// @TODO wont work with multiple instances
// TODO: does not work with multiple instances
Tablebases::init(options["SyzygyPath"]); // Free mapped files
}
+4 -1
View File
@@ -54,7 +54,10 @@ static_assert((CORRHIST_BASE_SIZE & (CORRHIST_BASE_SIZE - 1)) == 0,
// when we update values with the << operator
template<typename T, int D, bool Shared = false>
struct StatsEntry {
static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type");
static_assert(std::is_integral_v<T> && std::is_signed_v<T>, "Not a signed integer type");
static_assert(D > 0 && D <= std::numeric_limits<T>::max()
&& D <= std::numeric_limits<int>::max() / D,
"D can lead to overflows");
private:
std::conditional_t<Shared, RelaxedAtomic<T>, T> entry;
+1 -1
View File
@@ -190,7 +190,7 @@ MovePicker::MovePicker(const Position& p, Move ttm, int th, const CapturePieceTo
// Assigns a numerical value to each move in a list, used for sorting.
// Captures are ordered by Most Valuable Victim (MVV), preferring captures
// with a good history. Quiets moves are ordered using the history tables.
// with a good history. Quiet moves are ordered using the history tables.
template<GenType Type>
ExtMove* MovePicker::score(const MoveList<Type>& ml) {
+1 -1
View File
@@ -256,10 +256,10 @@ void FullThreats::append_active_indices(Color perspective, const Position& pos,
{
Piece attacker = make_piece(c, pt);
Bitboard bb = pos.pieces(c, pt);
Bitboard targets = pt == KNIGHT || pt == QUEEN ? queenTargets : minorSliderTargets;
while (bb)
{
Square from = pop_lsb(bb);
Bitboard targets = pt == KNIGHT || pt == QUEEN ? queenTargets : minorSliderTargets;
Bitboard attacks = Attacks::attacks_bb(pt, from, occupied) & targets;
while (attacks)
{
+1 -1
View File
@@ -109,7 +109,7 @@ class Network {
};
} // namespace Stockfish
} // namespace Stockfish::Eval::NNUE
template<>
struct std::hash<Stockfish::Eval::NNUE::Network> {
+2 -2
View File
@@ -73,8 +73,8 @@ struct NetworkArchitecture {
hashValue ^= TransformedFeatureDimensions * 2;
hashValue = decltype(fc_0)::get_hash_value(hashValue);
// TODO: considerincluding hash value of ac_sqr_0 in the overall hash value.
// For now omitted on purpose because hash value is not written by trainer yet
// TODO: consider including hash value of ac_sqr_0 in the overall hash value.
// For now omitted on purpose because hash value is not written by trainer (yet)
hashValue = decltype(ac_0)::get_hash_value(hashValue);
hashValue = decltype(fc_1)::get_hash_value(hashValue);
hashValue = decltype(ac_1)::get_hash_value(hashValue);
+1 -1
View File
@@ -252,7 +252,7 @@ class FeatureTransformer {
// means our pairwise product is zero. If we perform packus and
// remove the lower-side clip for the second element, then our
// product before packus will be negative, and is zeroed on pack.
// The two operation produce equivalent results, but the second
// The two operations produce equivalent results, but the second
// one (using packus) saves one max operation per pair.
// But here we run into a problem: mullo does not preserve the
+4 -3
View File
@@ -42,7 +42,7 @@ struct NNZInfo {
indices[i] = {0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23,
8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31};
for (u16& m : indices[i])
m += i * Dimensions / 8;
m += u16(i * Dimensions / 8);
}
return indices;
}();
@@ -85,9 +85,10 @@ struct NNZInfo {
count += popcount(nnzMask);
indices = _mm512_add_epi16(indices, increment);
#else
const __m512i increment = _mm512_set1_epi32(16);
for (auto neurons : {neurons1, neurons2})
{
const __m512i increment = _mm512_set1_epi32(16);
// Get a bitmask and gather non zero indices
const __mmask16 nnzMask = _mm512_test_epi32_mask(neurons, neurons);
const __m512i nnzV = _mm512_maskz_compress_epi32(nnzMask, indices);
@@ -162,6 +163,6 @@ struct NNZInfo {
NNZCursor make_cursor(bool perspective) { return {*this, perspective}; }
#endif
};
} // namespace Stockfish
} // namespace Stockfish::Eval::NNUE
#endif
+4 -63
View File
@@ -59,9 +59,7 @@ namespace Stockfish::Eval::NNUE::SIMD {
#ifdef USE_AVX512
using vec_t = __m512i;
using vec_i8_t = __m256i;
using vec128_t = __m128i;
using psqt_vec_t = __m256i;
using vec_uint_t = __m512i;
#define vec_load(a) _mm512_load_si512(a)
#define vec_store(a, b) _mm512_store_si512(a, b)
#define vec_convert_8_16(a) _mm512_cvtepi8_epi16(a)
@@ -81,24 +79,15 @@ using vec_uint_t = __m512i;
#define vec_sub_psqt_32(a, b) _mm256_sub_epi32(a, b)
#define vec_zero_psqt() _mm256_setzero_si256()
#ifdef USE_SSSE3
#define vec_nnz(a) _mm512_cmpgt_epi32_mask(a, _mm512_setzero_si512())
#endif
#define vec_nnz(a) _mm512_cmpgt_epi32_mask(a, _mm512_setzero_si512())
#define vec128_zero _mm_setzero_si128()
#define vec128_set_16(a) _mm_set1_epi16(a)
#define vec128_load(a) _mm_load_si128(a)
#define vec128_storeu(a, b) _mm_storeu_si128(a, b)
#define vec128_add(a, b) _mm_add_epi16(a, b)
#define NumRegistersSIMD 16
#define MaxChunkSize 64
#elif USE_AVX2
using vec_t = __m256i;
using vec_i8_t = __m128i;
using vec128_t = __m128i;
using psqt_vec_t = __m256i;
using vec_uint_t = __m256i;
#define vec_load(a) _mm256_load_si256(a)
#define vec_store(a, b) _mm256_store_si256(a, b)
#define vec_convert_8_16(a) _mm256_cvtepi8_epi16(a)
@@ -118,31 +107,16 @@ using vec_uint_t = __m256i;
#define vec_sub_psqt_32(a, b) _mm256_sub_epi32(a, b)
#define vec_zero_psqt() _mm256_setzero_si256()
#ifdef USE_SSSE3
#if defined(USE_VNNI) && !defined(USE_AVXVNNI)
#define vec_nnz(a) _mm256_cmpgt_epi32_mask(a, _mm256_setzero_si256())
#else
#define vec_nnz(a) \
_mm256_movemask_ps( \
_mm256_castsi256_ps(_mm256_cmpgt_epi32(a, _mm256_setzero_si256())))
#endif
#endif
#define vec128_zero _mm_setzero_si128()
#define vec128_set_16(a) _mm_set1_epi16(a)
#define vec128_load(a) _mm_load_si128(a)
#define vec128_storeu(a, b) _mm_storeu_si128(a, b)
#define vec128_add(a, b) _mm_add_epi16(a, b)
#define vec_nnz(a) \
_mm256_movemask_ps(_mm256_castsi256_ps(_mm256_cmpgt_epi32(a, _mm256_setzero_si256())))
#define NumRegistersSIMD 12
#define MaxChunkSize 32
#elif USE_SSE2
using vec_t = __m128i;
using vec_i8_t = u64; // for the correct size -- will be loaded into an xmm reg
using vec128_t = __m128i;
using vec_i8_t = u64;
using psqt_vec_t = __m128i;
using vec_uint_t = __m128i;
#define vec_load(a) (*(a))
#define vec_store(a, b) *(a) = (b)
#define vec_add_16(a, b) _mm_add_epi16(a, b)
@@ -186,12 +160,6 @@ inline __m128i vec_convert_8_16(u64 x) {
}
#endif
#define vec128_zero _mm_setzero_si128()
#define vec128_set_16(a) _mm_set1_epi16(a)
#define vec128_load(a) _mm_load_si128(a)
#define vec128_storeu(a, b) _mm_storeu_si128(a, b)
#define vec128_add(a, b) _mm_add_epi16(a, b)
#define NumRegistersSIMD (Is64Bit ? 12 : 6)
#define MaxChunkSize 16
@@ -205,8 +173,6 @@ using vec_i32x4_t __attribute__((may_alias)) = int32x4_t;
using vec_t __attribute__((may_alias)) = int16x8_t;
using vec_i8_t __attribute__((may_alias)) = int8x16_t;
using psqt_vec_t __attribute__((may_alias)) = int32x4_t;
using vec128_t __attribute__((may_alias)) = uint16x8_t;
using vec_uint_t __attribute__((may_alias)) = uint32x4_t;
#define vec_load(a) (*(a))
#define vec_store(a, b) *(a) = (b)
#define vec_add_16(a, b) vaddq_s16(a, b)
@@ -224,15 +190,6 @@ using vec_uint_t __attribute__((may_alias)) = uint32x4_t;
#define vec_sub_psqt_32(a, b) vsubq_s32(a, b)
#define vec_zero_psqt() psqt_vec_t{0}
static constexpr u32 Mask[4] = {1, 2, 4, 8};
#define vec_nnz(a) \
vaddvq_u32(vandq_u32(vtstq_u32((uint32x4_t) a, (uint32x4_t) a), vld1q_u32(Mask)))
#define vec128_zero vdupq_n_u16(0)
#define vec128_set_16(a) vdupq_n_u16(a)
#define vec128_load(a) vld1q_u16(reinterpret_cast<const u16*>(a))
#define vec128_storeu(a, b) vst1q_u16(reinterpret_cast<u16*>(a), b)
#define vec128_add(a, b) vaddq_u16(a, b)
#define NumRegistersSIMD 16
#define MaxChunkSize 16
@@ -245,9 +202,7 @@ inline int16x8_t vsubw_high_s8(int16x8_t a, int8x16_t b) { return vsubw_s8(a, vg
#elif USE_LASX
using vec_t = __m256i;
using vec_i8_t = __m128i;
using vec128_t = __m128i;
using psqt_vec_t = __m256i;
using vec_uint_t = __m256i;
inline __m256i lasx_load256(const __m256i* a) {
return __lasx_xvld(reinterpret_cast<const void*>(a), 0);
@@ -293,12 +248,6 @@ inline __m256i lasx_packus_32(__m256i a, __m256i b) {
#define vec_mulhi_8 __lasx_xvmuh_bu
#define vec_srli_8 __lasx_xvsrli_b
#define vec128_zero __lsx_vldi(0)
#define vec128_set_16(a) __lsx_vreplgr2vr_h(a)
#define vec128_load(a) (*(a))
#define vec128_storeu(a, b) *(a) = (b)
#define vec128_add(a, b) __lsx_vadd_h(a, b)
#define NumRegistersSIMD 24
#define MaxChunkSize 32
@@ -328,9 +277,7 @@ inline int lasx_vec_nnz(__m256i a) {
#elif USE_LSX
using vec_t = __m128i;
using vec_i8_t = u64;
using vec128_t = __m128i;
using psqt_vec_t = __m128i;
using vec_uint_t = __m128i;
inline __m128i lsx_packus_16(__m128i a, __m128i b) {
#if defined(__clang__) && defined(__has_builtin) && __has_builtin(__builtin_lsx_vssrani_bu_h)
@@ -381,12 +328,6 @@ inline __m128i vec_convert_8_16(u64 x) {
#define vec_mulhi_8 __lsx_vmuh_bu
#define vec_srli_8 __lsx_vsrli_b
#define vec128_zero __lsx_vldi(0)
#define vec128_set_16(a) __lsx_vreplgr2vr_h(a)
#define vec128_load(a) (*(a))
#define vec128_storeu(a, b) *(a) = (b)
#define vec128_add(a, b) __lsx_vadd_h(a, b)
#define NumRegistersSIMD 24
#define MaxChunkSize 16
+7 -13
View File
@@ -113,8 +113,8 @@ inline int H1(Key h) { return h & 0x1fff; }
inline int H2(Key h) { return (h >> 16) & 0x1fff; }
// Cuckoo tables with Zobrist hashes of valid reversible moves, and the moves themselves
std::array<Key, 8192> cuckoo;
std::array<Move, 8192> cuckooMove;
static std::array<Key, 8192> cuckoo;
static std::array<Move, 8192> cuckooMove;
// Initializes at startup the various arrays used to compute hash keys
void Position::init() {
@@ -305,7 +305,7 @@ Position::set(const string& fenStr, bool isChess960, StateInfo* si) {
// if an inner rook is associated with the castling right, the castling tag is
// replaced by the file letter of the involved rook, as for the Shredder-FEN.
//
// NOTE: Due to the prevalnce of incorrect (or missing) castling rights the
// NOTE: Due to the prevalence of incorrect (or missing) castling rights the
// validation is less strict. However, incorrect castling rights are still sanitized.
int num_castling_rights = 0;
for (;;)
@@ -421,7 +421,7 @@ Position::set(const string& fenStr, bool isChess960, StateInfo* si) {
ss >> std::skipws >> st->rule50 >> gamePly;
// Normally values larger than 99 would be pointless but we do support ignoring 50 move rule for TB purposes.
// Limit at 2**15 as it's used multiplicativly with position evaluation during search.
// Limit at 2**15 as it's used multiplicatively with position evaluation during search.
if (st->rule50 < 0 || st->rule50 > 32767)
return PositionSetError("Unsupported position. Rule50 counter out of range.");
@@ -1636,21 +1636,16 @@ bool Position::material_key_is_ok() const { return compute_material_key() == st-
// This is meant to be helpful when debugging.
bool Position::pos_is_ok() const {
constexpr bool Fast = false; // fast or full check?
if ((sideToMove != WHITE && sideToMove != BLACK) || piece_on(square<KING>(WHITE)) != W_KING
|| piece_on(square<KING>(BLACK)) != B_KING
|| (ep_square() != SQ_NONE && relative_rank(sideToMove, ep_square()) != RANK_6))
assert(0 && "pos_is_ok: Default");
if (Fast)
return true;
if (pieceCount[W_KING] != 1 || pieceCount[B_KING] != 1
if (count<KING>(WHITE) != 1 || count<KING>(BLACK) != 1
|| attackers_to_exist(square<KING>(~sideToMove), pieces(), sideToMove))
assert(0 && "pos_is_ok: Kings");
if ((pieces(PAWN) & (Rank1BB | Rank8BB)) || pieceCount[W_PAWN] > 8 || pieceCount[B_PAWN] > 8)
if ((pieces(PAWN) & (Rank1BB | Rank8BB)) || count<PAWN>(WHITE) > 8 || count<PAWN>(BLACK) > 8)
assert(0 && "pos_is_ok: Pawns");
@@ -1679,7 +1674,6 @@ bool Position::pos_is_ok() const {
if (p1 != p2 && (pieces(p1) & pieces(p2)))
assert(0 && "pos_is_ok: Bitboards");
for (Piece pc : Pieces)
if (pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc)))
|| pieceCount[pc] != std::count(board.begin(), board.end(), pc))
@@ -1691,7 +1685,7 @@ bool Position::pos_is_ok() const {
if (!can_castle(cr))
continue;
if (piece_on(castlingRookSquare[cr]) != make_piece(c, ROOK)
if (piece_on(castling_rook_square(cr)) != make_piece(c, ROOK)
|| castlingRightsMask[castlingRookSquare[cr]] != cr
|| (castlingRightsMask[square<KING>(c)] & cr) != cr)
assert(0 && "pos_is_ok: Castling");
+6
View File
@@ -177,6 +177,7 @@ class Position {
int rule50_count() const;
Value non_pawn_material(Color c) const;
Value non_pawn_material() const;
bool dtz_is_dtm() const; // Pawnless && (3-men || 4-men-minors-only)
// Position consistency check, for debugging
bool pos_is_ok() const;
@@ -344,6 +345,11 @@ inline int Position::rule50_count() const { return st->rule50; }
inline bool Position::is_chess960() const { return chess960; }
inline bool Position::dtz_is_dtm() const {
return !count<PAWN>()
&& (count<ALL_PIECES>() == 3 || (count<ALL_PIECES>() == 4 && !pieces(QUEEN, ROOK)));
}
inline bool Position::capture(Move m) const {
assert(m.is_ok());
+16 -15
View File
@@ -146,6 +146,8 @@ void update_all_stats(const Position& pos,
Move ttMove,
bool PvNode);
// Detect shuffling moves in order to limit search explosions
// Added in #6447 as non-regression, and so its parameters should not be tuned
bool is_shuffling(Move move, Stack* const ss, const Position& pos) {
if (pos.capture_stage(move) || pos.rule50_count() < 10)
return false;
@@ -249,9 +251,9 @@ void Search::Worker::start_searching() {
// Send PV info if it has changed since last output in iterative_deepening().
if (!uciPvSent || bestThread != this)
main_manager()->pv(*bestThread, threads, tt, bestThread->rootDepth);
main_manager()->output_pv(*bestThread, threads, tt, bestThread->rootDepth);
// In rare cases, pv() may change the ponder move through syzygy_extend_pv().
// In rare cases, output_pv() may change the ponder move through syzygy_extend_pv().
std::string ponder;
if (bestThread->rootMoves[0].pv.size() > 1)
ponder = UCIEngine::move(bestThread->rootMoves[0].pv[1], rootPos.is_chess960());
@@ -347,8 +349,7 @@ bool Search::Worker::iterative_deepening() {
rootMoves[i].previousScoreExact = i < multiPV;
}
usize pvFirst = 0;
pvLast = 0;
usize pvFirst = pvLast = 0;
if (!threads.increaseDepth)
searchAgainCounter++;
@@ -411,7 +412,7 @@ bool Search::Worker::iterative_deepening() {
// at nodes > 10M (rather than depth N, which can be reached quickly)
if (mainThread && multiPV == 1 && (bestValue <= alpha || bestValue >= beta)
&& nodes > NODES_LIMIT_OUTPUT)
main_manager()->pv(*this, threads, tt, rootDepth);
main_manager()->output_pv(*this, threads, tt, rootDepth);
// In case of failing low/high increase aspiration window and re-search,
// otherwise exit the loop.
@@ -491,7 +492,7 @@ bool Search::Worker::iterative_deepening() {
if (mainThread && !threads.stop && (pvIdx + 1 == multiPV || nodes > NODES_LIMIT_OUTPUT))
{
main_manager()->pv(*this, threads, tt, rootDepth);
main_manager()->output_pv(*this, threads, tt, rootDepth);
uciPvSent = (pvIdx + 1 == multiPV);
}
@@ -587,9 +588,9 @@ bool Search::Worker::iterative_deepening() {
double totalTime = mainThread->tm.optimum() * fallingEval * reduction
* bestMoveInstability * highBestMoveEffort;
// Cap used time in case of a single legal move for a better viewer experience
if (rootMoves.size() == 1)
totalTime = std::min(561.7, totalTime);
// Cap used time to 0.5s for a better viewer experience
totalTime = std::min(500.0, totalTime);
auto elapsedTime = elapsed();
@@ -700,7 +701,7 @@ void Search::Worker::clear() {
// Main search function for both PV and non-PV nodes
template<NodeType nodeType>
Value Search::Worker::search(
Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode) {
Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, const bool cutNode) {
constexpr bool PvNode = nodeType != NonPV;
constexpr bool rootNode = nodeType == Root;
@@ -1917,7 +1918,7 @@ void update_all_stats(const Position& pos,
if (!PvNode)
// Important: don't remove the cast to a 64-bit number else the multiplication
// can overflow on 32-bit platforms which would change the bench signature
bonus += bonus * u64(quietsSearched.size() + capturesSearched.size()) / 256;
bonus += int(bonus * u64(quietsSearched.size() + capturesSearched.size()) / 256);
if (!pos.capture_stage(bestMove))
{
@@ -2175,7 +2176,7 @@ void syzygy_extend_pv(const OptionsMap& options,
// Finding a draw in this function is an exceptional case, that cannot happen when rule50 is false or
// during engine game play, since we have a winning score, and play correctly
// with TB support. However, it can be that a position is draw due to the 50 move
// rule if it has been been reached on the board with a non-optimal 50 move counter
// rule if it has been reached on the board with a non-optimal 50 move counter
// (e.g. 8/8/6k1/3B4/3K4/4N3/8/8 w - - 54 106 ) which TB with dtz counter rounding
// cannot always correctly rank. See also
// https://github.com/official-stockfish/Stockfish/issues/5175#issuecomment-2058893495
@@ -2196,10 +2197,10 @@ void syzygy_extend_pv(const OptionsMap& options,
<< sync_endl;
}
void SearchManager::pv(Search::Worker& worker,
const ThreadPool& threads,
const TranspositionTable& tt,
Depth depth) {
void SearchManager::output_pv(Search::Worker& worker,
const ThreadPool& threads,
const TranspositionTable& tt,
Depth depth) {
const auto nodes = threads.nodes_searched();
auto& rootMoves = worker.rootMoves;
+6 -5
View File
@@ -282,10 +282,10 @@ class SearchManager: public ISearchManager {
void check_time(Search::Worker& worker) override;
void pv(Search::Worker& worker,
const ThreadPool& threads,
const TranspositionTable& tt,
Depth depth);
void output_pv(Search::Worker& worker,
const ThreadPool& threads,
const TranspositionTable& tt,
Depth depth);
Stockfish::TimeManagement tm;
double originalTimeAdjust;
@@ -353,7 +353,8 @@ class Worker {
// This is the main search function, for both PV and non-PV nodes
template<NodeType nodeType>
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode);
Value
search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, const bool cutNode);
// Quiescence search function, which is called by the main search
template<NodeType nodeType>
-5
View File
@@ -40,11 +40,6 @@
#include "shm_linux.h"
#endif
#if defined(__ANDROID__)
#include <limits.h>
#define SF_MAX_SEM_NAME_LEN NAME_MAX
#endif
#include "types.h"
#include "memory.h"
+2 -6
View File
@@ -1802,14 +1802,10 @@ Config Tablebases::rank_root_moves(const OptionsMap& options,
config.probeDepth = 0;
}
if (config.cardinality >= popcount(pos.pieces()) && !pos.can_castle(ANY_CASTLING))
if (config.cardinality >= pos.count<ALL_PIECES>() && !pos.can_castle(ANY_CASTLING))
{
// Use DTZ to rank the moves if checkmate is the only zeroing move
rankDTZ =
rankDTZ
|| (!pos.pieces(PAWN)
&& (popcount(pos.pieces()) == 3
|| (popcount(pos.pieces()) == 4 && !(pos.pieces(QUEEN) | pos.pieces(ROOK)))));
rankDTZ = rankDTZ || pos.dtz_is_dtm();
// Rank moves using DTZ tables, bail out if time_abort flags zeitnot
config.rootInTB =
+5 -9
View File
@@ -58,7 +58,7 @@
// _WIN32 Building on Windows (any)
// _WIN64 Building on Windows 64 bit
// Enforce minimum GCC version
// Enforce minimum GCC version
#if defined(__GNUC__) && !defined(__clang__) \
&& (__GNUC__ < 9 || (__GNUC__ == 9 && __GNUC_MINOR__ < 3))
#error "Stockfish requires GCC 9.3 or later for correct compilation"
@@ -190,6 +190,10 @@ constexpr bool is_mated(Value value) {
constexpr bool is_mate_or_mated(Value value) { return is_mate(value) || is_mated(value); }
constexpr Value mate_in(int ply) { return VALUE_MATE - ply; }
constexpr Value mated_in(int ply) { return -VALUE_MATE + ply; }
// In the code, we make the assumption that these values
// are such that non_pawn_material() can be used to uniquely
// identify the material on the board.
@@ -377,10 +381,6 @@ constexpr CastlingRights operator&(Color c, CastlingRights cr) {
return CastlingRights((c == WHITE ? WHITE_CASTLING : BLACK_CASTLING) & cr);
}
constexpr Value mate_in(int ply) { return VALUE_MATE - ply; }
constexpr Value mated_in(int ply) { return -VALUE_MATE + ply; }
constexpr Square make_square(File f, Rank r) { return Square((r << 3) + f); }
constexpr Piece make_piece(Color c, PieceType pt) { return Piece((c << 3) + pt); }
@@ -454,10 +454,6 @@ class Move {
return Square(data & 0x3F);
}
// Same as to_sq() but without assertion, for branchless code paths
// where the result is masked/ignored when move is not ok
constexpr Square to_sq_unchecked() const { return Square(data & 0x3F); }
constexpr MoveType type_of() const { return MoveType(data & (3 << 14)); }
constexpr PieceType promotion_type() const { return PieceType(((data >> 12) & 3) + KNIGHT); }