mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
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:
committed by
Joost VandeVondele
parent
eca43a97ef
commit
48a9118251
@@ -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,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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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) {
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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> {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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");
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
@@ -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); }
|
||||||
|
|||||||
Reference in New Issue
Block a user