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
+5 -1
View File
@@ -4,4 +4,8 @@
# Post commit formatting fixes # Post commit formatting fixes
0fca5605fa2e5e7240fde5e1aae50952b2612231 0fca5605fa2e5e7240fde5e1aae50952b2612231
08ed4c90db31959521b7ef3186c026edd1e90307 08ed4c90db31959521b7ef3186c026edd1e90307
# Ignore commits related to integer type renamings
dd3e1c4a50fd358c8bf8051c9ef73219669ff6c0
6e4e03fd282d5e1cba514197bf1ef326c990f0d2
+12 -12
View File
@@ -12,8 +12,8 @@ Hisayori Noda (nodchip)
# All other authors of Stockfish code (in alphabetical order) # All other authors of Stockfish code (in alphabetical order)
87flowers 87flowers
Aditya (absimaldata) Aditya (absimaldata)
Adrian Ladoni (AdrianGHUB15)
Adrian Petrescu (apetresc) Adrian Petrescu (apetresc)
Adrian (AdrianGHUB15)
Ahmed Kerimov (wcdbmv) Ahmed Kerimov (wcdbmv)
Ajith Chandy Jose (ajithcj) Ajith Chandy Jose (ajithcj)
AK-Khan02 AK-Khan02
@@ -63,11 +63,11 @@ Cody Ho (aesrentai)
CSTENTOR CSTENTOR
Dale Weiler (graphitemaster) Dale Weiler (graphitemaster)
Dalton Hanaway (dhanaway) Dalton Hanaway (dhanaway)
Dan Schmidt (dfannius)
Daniel Axtens (daxtens) Daniel Axtens (daxtens)
Daniel Dugovic (ddugovic) Daniel Dugovic (ddugovic)
Daniel Monroe (daniel-monroe) Daniel Monroe (daniel-monroe)
Daniel Samek (DanSamek) Daniel Samek (DanSamek)
Dan Schmidt (dfannius)
Dariusz Orzechowski (dorzechowski) Dariusz Orzechowski (dorzechowski)
David (dav1312) David (dav1312)
David Zar David Zar
@@ -92,9 +92,9 @@ Fanael Linithien (Fanael)
fanon fanon
Fauzi Akram Dabat (fauzi2) Fauzi Akram Dabat (fauzi2)
Felix Wittmann Felix Wittmann
gamander
Gabriele Lombardo (gabe) Gabriele Lombardo (gabe)
Gahtan Nahdi Gahtan Nahdi
gamander
Gary Heckman (gheckman) Gary Heckman (gheckman)
George Sobala (gsobala) George Sobala (gsobala)
gguliash gguliash
@@ -105,8 +105,8 @@ Gontran Lemaire (gonlem)
Goodkov Vasiliy Aleksandrovich (goodkov) Goodkov Vasiliy Aleksandrovich (goodkov)
Gregor Cramer Gregor Cramer
GuardianRM GuardianRM
Guy Vreuls (gvreuls)
Günther Demetz (pb00067, pb00068) Günther Demetz (pb00067, pb00068)
Guy Vreuls (gvreuls)
Henri Wiechers Henri Wiechers
Hiraoka Takuya (HiraokaTakuya) Hiraoka Takuya (HiraokaTakuya)
homoSapiensSapiens homoSapiensSapiens
@@ -119,8 +119,8 @@ Jan Ondruš (hxim)
Jared Kish (Kurtbusch, kurt22i) Jared Kish (Kurtbusch, kurt22i)
Jarrod Torriero (DU-jdto) Jarrod Torriero (DU-jdto)
Jasper Shovelton (Beanie496) Jasper Shovelton (Beanie496)
Jean-Francois Romang (jromang)
Jean Gauthier (OuaisBla) Jean Gauthier (OuaisBla)
Jean-Francois Romang (jromang)
Jekaa Jekaa
Jerry Donald Watson (jerrydonaldwatson) Jerry Donald Watson (jerrydonaldwatson)
jjoshua2 jjoshua2
@@ -128,10 +128,10 @@ Jonathan Buladas Dumale (SFisGOD)
Jonathan Calovski (Mysseno) Jonathan Calovski (Mysseno)
Jonathan McDermid (jonathanmcdermid) Jonathan McDermid (jonathanmcdermid)
Joost VandeVondele (vondele) Joost VandeVondele (vondele)
Jörg Oster (joergoster)
Joseph Ellis (jhellis3) Joseph Ellis (jhellis3)
Joseph R. Prostko Joseph R. Prostko
Jost Triller (tsoj) Jost Triller (tsoj)
Jörg Oster (joergoster)
Julian Willemer (NightlyKing) Julian Willemer (NightlyKing)
jundery jundery
Justin Blanchard (UncombedCoconut) Justin Blanchard (UncombedCoconut)
@@ -189,8 +189,8 @@ Muzhen J (XInTheDark)
Mafanwei Mafanwei
Nathan Rugg (nmrugg) Nathan Rugg (nmrugg)
Nguyen Pham (nguyenpham) Nguyen Pham (nguyenpham)
Nicklas Persson (NicklasPersson)
Nick Pelling (nickpelling) Nick Pelling (nickpelling)
Nicklas Persson (NicklasPersson)
Nicolas Duhamel (nikloskoda) Nicolas Duhamel (nikloskoda)
Niklas Fiekas (niklasf) Niklas Fiekas (niklasf)
Nikolay Kostov (NikolayIT) Nikolay Kostov (NikolayIT)
@@ -198,11 +198,11 @@ Norman Schmidt (FireFather)
notruck notruck
Nour Berakdar (Nonlinear) Nour Berakdar (Nonlinear)
Ofek Shochat (OfekShochat, ghostway) Ofek Shochat (OfekShochat, ghostway)
Ondrej Mosnáček (WOnder93) Ömer Faruk Tutkun (OmerFarukTutkun)
Ondřej Mišina (AndrovT) Ondřej Mišina (AndrovT)
Ondrej Mosnáček (WOnder93)
Onur Zungur (zungur) Onur Zungur (zungur)
Oskar Werkelin Ahlin Oskar Werkelin Ahlin
Ömer Faruk Tutkun (OmerFarukTutkun)
Pablo Vazquez Pablo Vazquez
Panthee Panthee
Pascal Romaret Pascal Romaret
@@ -224,13 +224,13 @@ Richard Lloyd (Richard-Lloyd)
Robert Nürnberg (robertnurnberg) Robert Nürnberg (robertnurnberg)
Rodrigo Exterckötter Tjäder Rodrigo Exterckötter Tjäder
Rodrigo Roim (roim) Rodrigo Roim (roim)
Ronald de Man (syzygy1, syzygy)
Ron Britvich (Britvich) Ron Britvich (Britvich)
Ronald de Man (syzygy1, syzygy)
rqs rqs
Rui Coelho (ruicoelhopedro) Rui Coelho (ruicoelhopedro)
rustam-cpp rustam-cpp
Ryan Lefkowitz (rlefko)
Ryan Hirsch Ryan Hirsch
Ryan Lefkowitz (rlefko)
Ryan Schmitt Ryan Schmitt
Ryan Takker Ryan Takker
Sami Kiminki (skiminki) Sami Kiminki (skiminki)
@@ -262,9 +262,9 @@ Timothy Herchen (anematode)
Ting-Hsuan Huang (fffelix-huang) Ting-Hsuan Huang (fffelix-huang)
tobi437a tobi437a
Tobias Steinmann Tobias Steinmann
Tomasz Sobczyk (Sopel97)
Tom Truscott Tom Truscott
Tom Vijlbrief (tomtor) Tom Vijlbrief (tomtor)
Tomasz Sobczyk (Sopel97)
Tony Wang (TonyCongqianWang) Tony Wang (TonyCongqianWang)
Torsten Franz (torfranz, tfranzer) Torsten Franz (torfranz, tfranzer)
Torsten Hellwig (Torom) Torsten Hellwig (Torom)
+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 // 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 // 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{}; std::array<std::array<u8, 256>, FILE_NB> table{};
for (int file = 0; file < 8; ++file) for (int file = 0; file < 8; ++file)
for (int occ = 0; occ < 256; ++occ) 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; m.attacks = s == SQ_A1 ? table : magics[s - 1][pt - BISHOP].attacks + size;
size = 0; size = 0;
Bitboard b = 0; Bitboard b = 0;
[[maybe_unused]] Bitboard prevSliding = -1;
do do
{ {
occupancy[size] = b; occupancy[size] = b;
+5 -5
View File
@@ -102,10 +102,10 @@ struct alignas(32) DualMagic {
// //
// When using hyperbola quintessence, file, diagonal and antidiagonal attacks // When using hyperbola quintessence, file, diagonal and antidiagonal attacks
// can use a byte reversal rather than a full bit reversal (because all squares // 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. // 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 { 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) { 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, 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, 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 // Returns the attacks by the given piece
// assuming the board is occupied according to the passed Bitboard. // 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> template<PieceType Pt>
inline Bitboard attacks_bb(Square s, Bitboard occupied) { 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 // Returns the attacks by the given piece
// assuming the board is occupied according to the passed Bitboard. // 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) { inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) {
assert(pt != PAWN && is_ok(s)); assert(pt != PAWN && is_ok(s));
@@ -318,7 +318,7 @@ inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) {
case ROOK : case ROOK :
return attacks_bb<ROOK>(s, occupied); return attacks_bb<ROOK>(s, occupied);
case QUEEN : case QUEEN :
return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied); return attacks_bb<QUEEN>(s, occupied);
default : default :
return PseudoAttacks[pt][s]; return PseudoAttacks[pt][s];
} }
+1 -1
View File
@@ -485,7 +485,7 @@ BenchmarkSetup setup_benchmark(std::istream& is) {
float totalTime = 0; float totalTime = 0;
for (const auto& game : BenchmarkPositions) for (const auto& game : BenchmarkPositions)
for (usize i = 0; i < game.size(); ++i) 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; float timeScaleFactor = static_cast<float>(desiredTimeS * 1000) / totalTime;
+1 -8
View File
@@ -23,7 +23,6 @@
namespace Stockfish { namespace Stockfish {
u8 PopCnt16[1 << 16]; u8 PopCnt16[1 << 16];
u8 SquareDistance[SQUARE_NB][SQUARE_NB];
// Returns an ASCII representation of a bitboard suitable // Returns an ASCII representation of a bitboard suitable
// to be printed to standard output. Useful for debugging. // to be printed to standard output. Useful for debugging.
@@ -46,16 +45,10 @@ std::string Bitboards::pretty(Bitboard b) {
return s; return s;
} }
// Initializes various bitboard tables. It is called at // Initializes the popcount table at startup.
// startup and relies on global objects to be already zero-initialized.
void Bitboards::init() { void Bitboards::init() {
for (unsigned i = 0; i < (1 << 16); ++i) for (unsigned i = 0; i < (1 << 16); ++i)
PopCnt16[i] = u8(std::bitset<16>(i).count()); 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 } // namespace Stockfish
-25
View File
@@ -21,9 +21,7 @@
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cmath>
#include <cstring> #include <cstring>
#include <cstdlib>
#include <string> #include <string>
#include "types.h" #include "types.h"
@@ -66,7 +64,6 @@ constexpr Bitboard Rank7BB = Rank1BB << (8 * 6);
constexpr Bitboard Rank8BB = Rank1BB << (8 * 7); constexpr Bitboard Rank8BB = Rank1BB << (8 * 7);
extern u8 PopCnt16[1 << 16]; extern u8 PopCnt16[1 << 16];
extern u8 SquareDistance[SQUARE_NB][SQUARE_NB];
constexpr Bitboard square_bb(Square s) { constexpr Bitboard square_bb(Square s) {
assert(is_ok(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); 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)); } inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); }
constexpr int constexpr_popcount(Bitboard b) { constexpr int constexpr_popcount(Bitboard b) {
b = b - ((b >> 1) & 0x5555555555555555ULL); b = b - ((b >> 1) & 0x5555555555555555ULL);
b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL); b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL);
+1 -1
View File
@@ -164,7 +164,7 @@ void Engine::search_clear() {
tt.clear(threads); tt.clear(threads);
threads.clear(); threads.clear();
// @TODO wont work with multiple instances // TODO: does not work with multiple instances
Tablebases::init(options["SyzygyPath"]); // Free mapped files 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 // when we update values with the << operator
template<typename T, int D, bool Shared = false> template<typename T, int D, bool Shared = false>
struct StatsEntry { 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: private:
std::conditional_t<Shared, RelaxedAtomic<T>, T> entry; 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. // Assigns a numerical value to each move in a list, used for sorting.
// Captures are ordered by Most Valuable Victim (MVV), preferring captures // 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> template<GenType Type>
ExtMove* MovePicker::score(const MoveList<Type>& ml) { 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); Piece attacker = make_piece(c, pt);
Bitboard bb = pos.pieces(c, pt); Bitboard bb = pos.pieces(c, pt);
Bitboard targets = pt == KNIGHT || pt == QUEEN ? queenTargets : minorSliderTargets;
while (bb) while (bb)
{ {
Square from = pop_lsb(bb); Square from = pop_lsb(bb);
Bitboard targets = pt == KNIGHT || pt == QUEEN ? queenTargets : minorSliderTargets;
Bitboard attacks = Attacks::attacks_bb(pt, from, occupied) & targets; Bitboard attacks = Attacks::attacks_bb(pt, from, occupied) & targets;
while (attacks) while (attacks)
{ {
+1 -1
View File
@@ -109,7 +109,7 @@ class Network {
}; };
} // namespace Stockfish } // namespace Stockfish::Eval::NNUE
template<> template<>
struct std::hash<Stockfish::Eval::NNUE::Network> { struct std::hash<Stockfish::Eval::NNUE::Network> {
+2 -2
View File
@@ -73,8 +73,8 @@ struct NetworkArchitecture {
hashValue ^= TransformedFeatureDimensions * 2; hashValue ^= TransformedFeatureDimensions * 2;
hashValue = decltype(fc_0)::get_hash_value(hashValue); hashValue = decltype(fc_0)::get_hash_value(hashValue);
// TODO: considerincluding hash value of ac_sqr_0 in the overall hash value. // 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 // For now omitted on purpose because hash value is not written by trainer (yet)
hashValue = decltype(ac_0)::get_hash_value(hashValue); hashValue = decltype(ac_0)::get_hash_value(hashValue);
hashValue = decltype(fc_1)::get_hash_value(hashValue); hashValue = decltype(fc_1)::get_hash_value(hashValue);
hashValue = decltype(ac_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 // means our pairwise product is zero. If we perform packus and
// remove the lower-side clip for the second element, then our // remove the lower-side clip for the second element, then our
// product before packus will be negative, and is zeroed on pack. // 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. // one (using packus) saves one max operation per pair.
// But here we run into a problem: mullo does not preserve the // 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, 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}; 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31};
for (u16& m : indices[i]) for (u16& m : indices[i])
m += i * Dimensions / 8; m += u16(i * Dimensions / 8);
} }
return indices; return indices;
}(); }();
@@ -85,9 +85,10 @@ struct NNZInfo {
count += popcount(nnzMask); count += popcount(nnzMask);
indices = _mm512_add_epi16(indices, increment); indices = _mm512_add_epi16(indices, increment);
#else #else
const __m512i increment = _mm512_set1_epi32(16);
for (auto neurons : {neurons1, neurons2}) for (auto neurons : {neurons1, neurons2})
{ {
const __m512i increment = _mm512_set1_epi32(16);
// Get a bitmask and gather non zero indices // Get a bitmask and gather non zero indices
const __mmask16 nnzMask = _mm512_test_epi32_mask(neurons, neurons); const __mmask16 nnzMask = _mm512_test_epi32_mask(neurons, neurons);
const __m512i nnzV = _mm512_maskz_compress_epi32(nnzMask, indices); const __m512i nnzV = _mm512_maskz_compress_epi32(nnzMask, indices);
@@ -162,6 +163,6 @@ struct NNZInfo {
NNZCursor make_cursor(bool perspective) { return {*this, perspective}; } NNZCursor make_cursor(bool perspective) { return {*this, perspective}; }
#endif #endif
}; };
} // namespace Stockfish } // namespace Stockfish::Eval::NNUE
#endif #endif
+4 -63
View File
@@ -59,9 +59,7 @@ namespace Stockfish::Eval::NNUE::SIMD {
#ifdef USE_AVX512 #ifdef USE_AVX512
using vec_t = __m512i; using vec_t = __m512i;
using vec_i8_t = __m256i; using vec_i8_t = __m256i;
using vec128_t = __m128i;
using psqt_vec_t = __m256i; using psqt_vec_t = __m256i;
using vec_uint_t = __m512i;
#define vec_load(a) _mm512_load_si512(a) #define vec_load(a) _mm512_load_si512(a)
#define vec_store(a, b) _mm512_store_si512(a, b) #define vec_store(a, b) _mm512_store_si512(a, b)
#define vec_convert_8_16(a) _mm512_cvtepi8_epi16(a) #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_sub_psqt_32(a, b) _mm256_sub_epi32(a, b)
#define vec_zero_psqt() _mm256_setzero_si256() #define vec_zero_psqt() _mm256_setzero_si256()
#ifdef USE_SSSE3 #define vec_nnz(a) _mm512_cmpgt_epi32_mask(a, _mm512_setzero_si512())
#define vec_nnz(a) _mm512_cmpgt_epi32_mask(a, _mm512_setzero_si512())
#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 16 #define NumRegistersSIMD 16
#define MaxChunkSize 64 #define MaxChunkSize 64
#elif USE_AVX2 #elif USE_AVX2
using vec_t = __m256i; using vec_t = __m256i;
using vec_i8_t = __m128i; using vec_i8_t = __m128i;
using vec128_t = __m128i;
using psqt_vec_t = __m256i; using psqt_vec_t = __m256i;
using vec_uint_t = __m256i;
#define vec_load(a) _mm256_load_si256(a) #define vec_load(a) _mm256_load_si256(a)
#define vec_store(a, b) _mm256_store_si256(a, b) #define vec_store(a, b) _mm256_store_si256(a, b)
#define vec_convert_8_16(a) _mm256_cvtepi8_epi16(a) #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_sub_psqt_32(a, b) _mm256_sub_epi32(a, b)
#define vec_zero_psqt() _mm256_setzero_si256() #define vec_zero_psqt() _mm256_setzero_si256()
#ifdef USE_SSSE3 #define vec_nnz(a) \
#if defined(USE_VNNI) && !defined(USE_AVXVNNI) _mm256_movemask_ps(_mm256_castsi256_ps(_mm256_cmpgt_epi32(a, _mm256_setzero_si256())))
#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 NumRegistersSIMD 12 #define NumRegistersSIMD 12
#define MaxChunkSize 32 #define MaxChunkSize 32
#elif USE_SSE2 #elif USE_SSE2
using vec_t = __m128i; using vec_t = __m128i;
using vec_i8_t = u64; // for the correct size -- will be loaded into an xmm reg using vec_i8_t = u64;
using vec128_t = __m128i;
using psqt_vec_t = __m128i; using psqt_vec_t = __m128i;
using vec_uint_t = __m128i;
#define vec_load(a) (*(a)) #define vec_load(a) (*(a))
#define vec_store(a, b) *(a) = (b) #define vec_store(a, b) *(a) = (b)
#define vec_add_16(a, b) _mm_add_epi16(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 #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 NumRegistersSIMD (Is64Bit ? 12 : 6)
#define MaxChunkSize 16 #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_t __attribute__((may_alias)) = int16x8_t;
using vec_i8_t __attribute__((may_alias)) = int8x16_t; using vec_i8_t __attribute__((may_alias)) = int8x16_t;
using psqt_vec_t __attribute__((may_alias)) = int32x4_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_load(a) (*(a))
#define vec_store(a, b) *(a) = (b) #define vec_store(a, b) *(a) = (b)
#define vec_add_16(a, b) vaddq_s16(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_sub_psqt_32(a, b) vsubq_s32(a, b)
#define vec_zero_psqt() psqt_vec_t{0} #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 NumRegistersSIMD 16
#define MaxChunkSize 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 #elif USE_LASX
using vec_t = __m256i; using vec_t = __m256i;
using vec_i8_t = __m128i; using vec_i8_t = __m128i;
using vec128_t = __m128i;
using psqt_vec_t = __m256i; using psqt_vec_t = __m256i;
using vec_uint_t = __m256i;
inline __m256i lasx_load256(const __m256i* a) { inline __m256i lasx_load256(const __m256i* a) {
return __lasx_xvld(reinterpret_cast<const void*>(a), 0); 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_mulhi_8 __lasx_xvmuh_bu
#define vec_srli_8 __lasx_xvsrli_b #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 NumRegistersSIMD 24
#define MaxChunkSize 32 #define MaxChunkSize 32
@@ -328,9 +277,7 @@ inline int lasx_vec_nnz(__m256i a) {
#elif USE_LSX #elif USE_LSX
using vec_t = __m128i; using vec_t = __m128i;
using vec_i8_t = u64; using vec_i8_t = u64;
using vec128_t = __m128i;
using psqt_vec_t = __m128i; using psqt_vec_t = __m128i;
using vec_uint_t = __m128i;
inline __m128i lsx_packus_16(__m128i a, __m128i b) { inline __m128i lsx_packus_16(__m128i a, __m128i b) {
#if defined(__clang__) && defined(__has_builtin) && __has_builtin(__builtin_lsx_vssrani_bu_h) #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_mulhi_8 __lsx_vmuh_bu
#define vec_srli_8 __lsx_vsrli_b #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 NumRegistersSIMD 24
#define MaxChunkSize 16 #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; } inline int H2(Key h) { return (h >> 16) & 0x1fff; }
// Cuckoo tables with Zobrist hashes of valid reversible moves, and the moves themselves // Cuckoo tables with Zobrist hashes of valid reversible moves, and the moves themselves
std::array<Key, 8192> cuckoo; static std::array<Key, 8192> cuckoo;
std::array<Move, 8192> cuckooMove; static std::array<Move, 8192> cuckooMove;
// Initializes at startup the various arrays used to compute hash keys // Initializes at startup the various arrays used to compute hash keys
void Position::init() { 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 // 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. // 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. // validation is less strict. However, incorrect castling rights are still sanitized.
int num_castling_rights = 0; int num_castling_rights = 0;
for (;;) for (;;)
@@ -421,7 +421,7 @@ Position::set(const string& fenStr, bool isChess960, StateInfo* si) {
ss >> std::skipws >> st->rule50 >> gamePly; 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. // 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) if (st->rule50 < 0 || st->rule50 > 32767)
return PositionSetError("Unsupported position. Rule50 counter out of range."); 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. // This is meant to be helpful when debugging.
bool Position::pos_is_ok() const { 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 if ((sideToMove != WHITE && sideToMove != BLACK) || piece_on(square<KING>(WHITE)) != W_KING
|| piece_on(square<KING>(BLACK)) != B_KING || piece_on(square<KING>(BLACK)) != B_KING
|| (ep_square() != SQ_NONE && relative_rank(sideToMove, ep_square()) != RANK_6)) || (ep_square() != SQ_NONE && relative_rank(sideToMove, ep_square()) != RANK_6))
assert(0 && "pos_is_ok: Default"); assert(0 && "pos_is_ok: Default");
if (Fast) if (count<KING>(WHITE) != 1 || count<KING>(BLACK) != 1
return true;
if (pieceCount[W_KING] != 1 || pieceCount[B_KING] != 1
|| attackers_to_exist(square<KING>(~sideToMove), pieces(), sideToMove)) || attackers_to_exist(square<KING>(~sideToMove), pieces(), sideToMove))
assert(0 && "pos_is_ok: Kings"); 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"); assert(0 && "pos_is_ok: Pawns");
@@ -1679,7 +1674,6 @@ bool Position::pos_is_ok() const {
if (p1 != p2 && (pieces(p1) & pieces(p2))) if (p1 != p2 && (pieces(p1) & pieces(p2)))
assert(0 && "pos_is_ok: Bitboards"); assert(0 && "pos_is_ok: Bitboards");
for (Piece pc : Pieces) for (Piece pc : Pieces)
if (pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc))) if (pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc)))
|| pieceCount[pc] != std::count(board.begin(), board.end(), pc)) || pieceCount[pc] != std::count(board.begin(), board.end(), pc))
@@ -1691,7 +1685,7 @@ bool Position::pos_is_ok() const {
if (!can_castle(cr)) if (!can_castle(cr))
continue; 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[castlingRookSquare[cr]] != cr
|| (castlingRightsMask[square<KING>(c)] & cr) != cr) || (castlingRightsMask[square<KING>(c)] & cr) != cr)
assert(0 && "pos_is_ok: Castling"); assert(0 && "pos_is_ok: Castling");
+6
View File
@@ -177,6 +177,7 @@ class Position {
int rule50_count() const; int rule50_count() const;
Value non_pawn_material(Color c) const; Value non_pawn_material(Color c) const;
Value non_pawn_material() const; Value non_pawn_material() const;
bool dtz_is_dtm() const; // Pawnless && (3-men || 4-men-minors-only)
// Position consistency check, for debugging // Position consistency check, for debugging
bool pos_is_ok() const; 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::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 { inline bool Position::capture(Move m) const {
assert(m.is_ok()); assert(m.is_ok());
+16 -15
View File
@@ -146,6 +146,8 @@ void update_all_stats(const Position& pos,
Move ttMove, Move ttMove,
bool PvNode); 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) { bool is_shuffling(Move move, Stack* const ss, const Position& pos) {
if (pos.capture_stage(move) || pos.rule50_count() < 10) if (pos.capture_stage(move) || pos.rule50_count() < 10)
return false; return false;
@@ -249,9 +251,9 @@ void Search::Worker::start_searching() {
// Send PV info if it has changed since last output in iterative_deepening(). // Send PV info if it has changed since last output in iterative_deepening().
if (!uciPvSent || bestThread != this) 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; std::string ponder;
if (bestThread->rootMoves[0].pv.size() > 1) if (bestThread->rootMoves[0].pv.size() > 1)
ponder = UCIEngine::move(bestThread->rootMoves[0].pv[1], rootPos.is_chess960()); 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; rootMoves[i].previousScoreExact = i < multiPV;
} }
usize pvFirst = 0; usize pvFirst = pvLast = 0;
pvLast = 0;
if (!threads.increaseDepth) if (!threads.increaseDepth)
searchAgainCounter++; searchAgainCounter++;
@@ -411,7 +412,7 @@ bool Search::Worker::iterative_deepening() {
// at nodes > 10M (rather than depth N, which can be reached quickly) // at nodes > 10M (rather than depth N, which can be reached quickly)
if (mainThread && multiPV == 1 && (bestValue <= alpha || bestValue >= beta) if (mainThread && multiPV == 1 && (bestValue <= alpha || bestValue >= beta)
&& nodes > NODES_LIMIT_OUTPUT) && 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, // In case of failing low/high increase aspiration window and re-search,
// otherwise exit the loop. // otherwise exit the loop.
@@ -491,7 +492,7 @@ bool Search::Worker::iterative_deepening() {
if (mainThread && !threads.stop && (pvIdx + 1 == multiPV || nodes > NODES_LIMIT_OUTPUT)) 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); uciPvSent = (pvIdx + 1 == multiPV);
} }
@@ -587,9 +588,9 @@ bool Search::Worker::iterative_deepening() {
double totalTime = mainThread->tm.optimum() * fallingEval * reduction double totalTime = mainThread->tm.optimum() * fallingEval * reduction
* bestMoveInstability * highBestMoveEffort; * bestMoveInstability * highBestMoveEffort;
// Cap used time in case of a single legal move for a better viewer experience
if (rootMoves.size() == 1) 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(); auto elapsedTime = elapsed();
@@ -700,7 +701,7 @@ void Search::Worker::clear() {
// Main search function for both PV and non-PV nodes // Main search function for both PV and non-PV nodes
template<NodeType nodeType> template<NodeType nodeType>
Value Search::Worker::search( 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 PvNode = nodeType != NonPV;
constexpr bool rootNode = nodeType == Root; constexpr bool rootNode = nodeType == Root;
@@ -1917,7 +1918,7 @@ void update_all_stats(const Position& pos,
if (!PvNode) if (!PvNode)
// Important: don't remove the cast to a 64-bit number else the multiplication // 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 // 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)) 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 // 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 // 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 // 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 // (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 // cannot always correctly rank. See also
// https://github.com/official-stockfish/Stockfish/issues/5175#issuecomment-2058893495 // https://github.com/official-stockfish/Stockfish/issues/5175#issuecomment-2058893495
@@ -2196,10 +2197,10 @@ void syzygy_extend_pv(const OptionsMap& options,
<< sync_endl; << sync_endl;
} }
void SearchManager::pv(Search::Worker& worker, void SearchManager::output_pv(Search::Worker& worker,
const ThreadPool& threads, const ThreadPool& threads,
const TranspositionTable& tt, const TranspositionTable& tt,
Depth depth) { Depth depth) {
const auto nodes = threads.nodes_searched(); const auto nodes = threads.nodes_searched();
auto& rootMoves = worker.rootMoves; auto& rootMoves = worker.rootMoves;
+6 -5
View File
@@ -282,10 +282,10 @@ class SearchManager: public ISearchManager {
void check_time(Search::Worker& worker) override; void check_time(Search::Worker& worker) override;
void pv(Search::Worker& worker, void output_pv(Search::Worker& worker,
const ThreadPool& threads, const ThreadPool& threads,
const TranspositionTable& tt, const TranspositionTable& tt,
Depth depth); Depth depth);
Stockfish::TimeManagement tm; Stockfish::TimeManagement tm;
double originalTimeAdjust; double originalTimeAdjust;
@@ -353,7 +353,8 @@ class Worker {
// This is the main search function, for both PV and non-PV nodes // This is the main search function, for both PV and non-PV nodes
template<NodeType nodeType> 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 // Quiescence search function, which is called by the main search
template<NodeType nodeType> template<NodeType nodeType>
-5
View File
@@ -40,11 +40,6 @@
#include "shm_linux.h" #include "shm_linux.h"
#endif #endif
#if defined(__ANDROID__)
#include <limits.h>
#define SF_MAX_SEM_NAME_LEN NAME_MAX
#endif
#include "types.h" #include "types.h"
#include "memory.h" #include "memory.h"
+2 -6
View File
@@ -1802,14 +1802,10 @@ Config Tablebases::rank_root_moves(const OptionsMap& options,
config.probeDepth = 0; 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 // Use DTZ to rank the moves if checkmate is the only zeroing move
rankDTZ = rankDTZ = rankDTZ || pos.dtz_is_dtm();
rankDTZ
|| (!pos.pieces(PAWN)
&& (popcount(pos.pieces()) == 3
|| (popcount(pos.pieces()) == 4 && !(pos.pieces(QUEEN) | pos.pieces(ROOK)))));
// Rank moves using DTZ tables, bail out if time_abort flags zeitnot // Rank moves using DTZ tables, bail out if time_abort flags zeitnot
config.rootInTB = config.rootInTB =
+5 -9
View File
@@ -58,7 +58,7 @@
// _WIN32 Building on Windows (any) // _WIN32 Building on Windows (any)
// _WIN64 Building on Windows 64 bit // _WIN64 Building on Windows 64 bit
// Enforce minimum GCC version // Enforce minimum GCC version
#if defined(__GNUC__) && !defined(__clang__) \ #if defined(__GNUC__) && !defined(__clang__) \
&& (__GNUC__ < 9 || (__GNUC__ == 9 && __GNUC_MINOR__ < 3)) && (__GNUC__ < 9 || (__GNUC__ == 9 && __GNUC_MINOR__ < 3))
#error "Stockfish requires GCC 9.3 or later for correct compilation" #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 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 // In the code, we make the assumption that these values
// are such that non_pawn_material() can be used to uniquely // are such that non_pawn_material() can be used to uniquely
// identify the material on the board. // 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); 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 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); } constexpr Piece make_piece(Color c, PieceType pt) { return Piece((c << 3) + pt); }
@@ -454,10 +454,6 @@ class Move {
return Square(data & 0x3F); 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 MoveType type_of() const { return MoveType(data & (3 << 14)); }
constexpr PieceType promotion_type() const { return PieceType(((data >> 12) & 3) + KNIGHT); } constexpr PieceType promotion_type() const { return PieceType(((data >> 12) & 3) + KNIGHT); }