Skip to content

Commit

Permalink
Merge with latest Stockfish development branch (last revision: 9927)
Browse files Browse the repository at this point in the history
  • Loading branch information
khalid-a-omar committed Oct 1, 2023
1 parent 9ba0d72 commit 8c9a9be
Show file tree
Hide file tree
Showing 15 changed files with 62 additions and 65 deletions.
10 changes: 5 additions & 5 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -708,24 +708,24 @@ ifeq ($(pext),yes)
endif
endif

### 3.7.1 Try to include git commit sha for versioning
### 3.8.1 Try to include git commit sha for versioning
GIT_SHA = $(shell git rev-parse HEAD 2>/dev/null | cut -c 1-8)
ifneq ($(GIT_SHA), )
CXXFLAGS += -DGIT_SHA=$(GIT_SHA)
endif

### 3.7.2 Try to include git commit date for versioning
### 3.8.2 Try to include git commit date for versioning
GIT_DATE = $(shell git show -s --date=format:'%Y%m%d' --format=%cd HEAD 2>/dev/null)
ifneq ($(GIT_DATE), )
CXXFLAGS += -DGIT_DATE=$(GIT_DATE)
endif

### 3.7.3 Try to include architecture
### 3.8.3 Try to include architecture
ifneq ($(ARCH), )
CXXFLAGS += -DARCH=$(ARCH)
endif

### 3.8 Link Time Optimization
### 3.9 Link Time Optimization
### This is a mix of compile and link time options because the lto link phase
### needs access to the optimization flags.
ifeq ($(optimize),yes)
Expand Down Expand Up @@ -760,7 +760,7 @@ ifeq ($(debug), no)
endif
endif

### 3.9 Android 5 can only run position independent executables. Note that this
### 3.10 Android 5 can only run position independent executables. Note that this
### breaks Android 4.0 and earlier.
ifeq ($(OS), Android)
CXXFLAGS += -fPIE
Expand Down
2 changes: 1 addition & 1 deletion src/bitboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ template<> inline int distance<Square>(Square x, Square y) { return SquareDistan

inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); }

/// attacks_bb(Square) returns the pseudo attacks of the give piece type
/// attacks_bb(Square) returns the pseudo attacks of the given piece type
/// assuming an empty board.

template<PieceType Pt>
Expand Down
2 changes: 1 addition & 1 deletion src/evaluate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ Value Eval::evaluate(const Position& pos) {

int npm = pos.non_pawn_material() / 64;
v = ( nnue * (915 + npm + 9 * pos.count<PAWN>())
+ optimism * (154 + npm + pos.count<PAWN>())) / 1024;
+ optimism * (154 + npm )) / 1024;
}

// Damp down the evaluation linearly when shuffling
Expand Down
2 changes: 1 addition & 1 deletion src/evaluate.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace Eval {
// The default net name MUST follow the format nn-[SHA256 first 12 digits].nnue
// for the build process (profile-build and fishtest) to work. Do not change the
// name of the macro, as it is used in the Makefile.
#define EvalFileDefaultName "nn-ac1dbea57aa3.nnue"
#define EvalFileDefaultName "nn-0000000000a0.nnue"

namespace NNUE {

Expand Down
5 changes: 3 additions & 2 deletions src/movegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ inline bool operator<(const ExtMove& f, const ExtMove& s) {
template<GenType>
ExtMove* generate(const Position& pos, ExtMove* moveList);

/// The MoveList struct is a simple wrapper around generate(). It sometimes comes
/// in handy to use this class instead of the low level generate() function.
/// The MoveList struct wraps the generate() function and returns a convenient
/// list of moves. Using MoveList is sometimes preferable to directly calling
/// the lower level generate() function.
template<GenType T>
struct MoveList {

Expand Down
8 changes: 4 additions & 4 deletions src/movepick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ namespace {
} // namespace


/// Constructors of the MovePicker class. As arguments we pass information
/// to help it to return the (presumably) good moves first, to decide which
/// Constructors of the MovePicker class. As arguments, we pass information
/// to help it return the (presumably) good moves first, to decide which
/// moves to return (in the quiescence search, for instance, we only want to
/// search captures, promotions, and some checks) and how important good move
/// ordering is at the current node.
/// search captures, promotions, and some checks) and how important a good
/// move ordering is at the current node.

/// MovePicker constructor for the main search
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh,
Expand Down
4 changes: 2 additions & 2 deletions src/movepick.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <cstdint>
#include <cstdlib>
#include <limits>
#include <type_traits>
#include <type_traits> // IWYU pragma: keep

#include "movegen.h"
#include "types.h"
Expand Down Expand Up @@ -70,7 +70,7 @@ struct Stats : public std::array<Stats<T, D, Sizes...>, Size>
void fill(const T& v) {

// For standard-layout 'this' points to first struct member
assert(std::is_standard_layout<stats>::value);
assert(std::is_standard_layout_v<stats>);

using entry = StatsEntry<T, D>;
entry* p = reinterpret_cast<entry*>(this);
Expand Down
4 changes: 2 additions & 2 deletions src/nnue/nnue_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ namespace Polyfish::Eval::NNUE {
else
{
std::uint8_t u[sizeof(IntType)];
typename std::make_unsigned<IntType>::type v = 0;
std::make_unsigned_t<IntType> v = 0;

stream.read(reinterpret_cast<char*>(u), sizeof(IntType));
for (std::size_t i = 0; i < sizeof(IntType); ++i)
Expand All @@ -128,7 +128,7 @@ namespace Polyfish::Eval::NNUE {
else
{
std::uint8_t u[sizeof(IntType)];
typename std::make_unsigned<IntType>::type v = value;
std::make_unsigned_t<IntType> v = value;

std::size_t i = 0;
// if constexpr to silence the warning about shift by 8
Expand Down
37 changes: 16 additions & 21 deletions src/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,9 @@ std::ostream& operator<<(std::ostream& os, const Position& pos) {
}


// Marcel van Kervinck's cuckoo algorithm for fast detection of "upcoming repetition"
// situations. Description of the algorithm in the following paper:
// Implements Marcel van Kervinck's cuckoo algorithm to detect repetition of positions
// for 3-fold repetition draws. The algorithm uses two hash tables with Zobrist hashes to
// allow fast detection of recurring positions. For details see:
// http://web.archive.org/web/20201107002606/https://marcelk.net/2013-04-06/paper/upcoming-rep-v2.pdf

// First and second hash functions for indexing the cuckoo tables
Expand Down Expand Up @@ -549,7 +550,7 @@ bool Position::legal(Move m) const {


/// Position::pseudo_legal() takes a random move and tests whether the move is
/// pseudo legal. It is used to validate moves from TT that can be corrupted
/// pseudo-legal. It is used to validate moves from TT that can be corrupted
/// due to SMP concurrent access or hash position key aliasing.

bool Position::pseudo_legal(const Move m) const {
Expand All @@ -565,7 +566,7 @@ bool Position::pseudo_legal(const Move m) const {
return checkers() ? MoveList< EVASIONS>(*this).contains(m)
: MoveList<NON_EVASIONS>(*this).contains(m);

// Is not a promotion, so promotion piece must be empty
// Is not a promotion, so the promotion piece must be empty
assert(promotion_type(m) - KNIGHT == NO_PIECE_TYPE);

// If the 'from' square is not occupied by a piece belonging to the side to
Expand Down Expand Up @@ -603,15 +604,15 @@ bool Position::pseudo_legal(const Move m) const {
{
if (type_of(pc) != KING)
{
// Double check? In this case a king move is required
// Double check? In this case, a king move is required
if (more_than_one(checkers()))
return false;

// Our move must be a blocking interposition or a capture of the checking piece
if (!(between_bb(square<KING>(us), lsb(checkers())) & to))
return false;
}
// In case of king moves under check we have to remove king so as to catch
// In case of king moves under check we have to remove the king so as to catch
// invalid moves like b1a1 when opposite queen is on c1.
else if (attackers_to(to, pieces() ^ from) & pieces(~us))
return false;
Expand Down Expand Up @@ -1041,7 +1042,7 @@ Key Position::key_after(Move m) const {
/// SEE value of move is greater or equal to the given threshold. We'll use an
/// algorithm similar to alpha-beta pruning with a null window.

bool Position::see_ge(Move m, Bitboard& occupied, Value threshold) const {
bool Position::see_ge(Move m, Value threshold) const {

assert(is_ok(m));

Expand All @@ -1060,7 +1061,7 @@ bool Position::see_ge(Move m, Bitboard& occupied, Value threshold) const {
return true;

assert(color_of(piece_on(from)) == sideToMove);
occupied = pieces() ^ from ^ to; // xoring to is important for pinned piece logic
Bitboard occupied = pieces() ^ from ^ to; // xoring to is important for pinned piece logic
Color stm = sideToMove;
Bitboard attackers = attackers_to(to, occupied);
Bitboard stmAttackers, bb;
Expand Down Expand Up @@ -1091,63 +1092,57 @@ bool Position::see_ge(Move m, Bitboard& occupied, Value threshold) const {
// the bitboard 'attackers' any X-ray attackers behind it.
if ((bb = stmAttackers & pieces(PAWN)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = PawnValue - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);

attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}

else if ((bb = stmAttackers & pieces(KNIGHT)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = KnightValue - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);
}

else if ((bb = stmAttackers & pieces(BISHOP)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = BishopValue - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);

attackers |= attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN);
}

else if ((bb = stmAttackers & pieces(ROOK)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = RookValue - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);

attackers |= attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN);
}

else if ((bb = stmAttackers & pieces(QUEEN)))
{
occupied ^= least_significant_square_bb(bb);
if ((swap = QueenValue - swap) < res)
break;
occupied ^= least_significant_square_bb(bb);

attackers |= (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
| (attacks_bb<ROOK >(to, occupied) & pieces(ROOK , QUEEN));
}

else // KING
// If we "capture" with the king but opponent still has attackers,
// If we "capture" with the king but the opponent still has attackers,
// reverse the result.
return (attackers & ~pieces(stm)) ? res ^ 1 : res;
}

return bool(res);
}

bool Position::see_ge(Move m, Value threshold) const {
Bitboard occupied;
return see_ge(m, occupied, threshold);
}


/// Position::is_draw() tests whether the position is drawn by 50-move rule
/// or by repetition. It does not detect stalemates.

Expand Down Expand Up @@ -1265,7 +1260,7 @@ void Position::flip() {


/// Position::pos_is_ok() performs some consistency checks for the
/// position object and raises an asserts if something wrong is detected.
/// position object and raise an assert if something wrong is detected.
/// This is meant to be helpful when debugging.

bool Position::pos_is_ok() const {
Expand Down
1 change: 0 additions & 1 deletion src/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ class Position {

// Static Exchange Evaluation
bool see_ge(Move m, Value threshold = VALUE_ZERO) const;
bool see_ge(Move m, Bitboard& occupied, Value threshold = VALUE_ZERO) const;

// Accessing hash keys
Key key() const;
Expand Down
28 changes: 15 additions & 13 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,12 @@ namespace {
return VALUE_DRAW - 1 + Value(thisThread->nodes & 0x2);
}

// Skill structure is used to implement strength limit. If we have an uci_elo then
// we convert it to a suitable fractional skill level using anchoring to CCRL Elo
// (goldfish 1.13 = 2000) and a fit through Ordo derived Elo for a match (TC 60+0.6)
// results spanning a wide range of k values.
// Skill structure is used to implement strength limit.
// If we have a UCI_Elo, we convert it to an appropriate skill level, anchored to the Stash engine.
// This method is based on a fit of the Elo results for games played between the master at various
// skill levels and various versions of the Stash engine, all ranked at CCRL.
// Skill 0 .. 19 now covers CCRL Blitz Elo from 1320 to 3190, approximately
// Reference: https://github.com/vondele/Stockfish/commit/a08b8d4e9711c20acedbfe17d618c3c384b339ec
struct Skill {
Skill(int skill_level, int uci_elo) {
if (uci_elo)
Expand Down Expand Up @@ -297,10 +299,9 @@ void MainThread::search() {

void Thread::search() {

// To allow access to (ss-7) up to (ss+2), the stack must be oversized.
// The former is needed to allow update_continuation_histories(ss-1, ...),
// which accesses its argument at ss-6, also near the root.
// The latter is needed for statScore and killer initialization.
// Allocate stack with extra size to allow access from (ss-7) to (ss+2)
// (ss-7) is needed for update_continuation_histories(ss-1, ...) which accesses (ss-6)
// (ss+2) is needed for initialization of statScore and killers
Stack stack[MAX_PLY+10], *ss = stack+7;
Move pv[MAX_PLY+1];
Value alpha, beta, delta;
Expand Down Expand Up @@ -387,7 +388,7 @@ void Thread::search() {
alpha = std::max(prev - delta,-VALUE_INFINITE);
beta = std::min(prev + delta, VALUE_INFINITE);

// Adjust optimism based on root move's previousScore
// Adjust optimism based on root move's previousScore (~4 Elo)
int opt = 109 * prev / (std::abs(prev) + 141);
optimism[ us] = Value(opt);
optimism[~us] = -optimism[us];
Expand Down Expand Up @@ -746,7 +747,7 @@ namespace {
}
else if (excludedMove)
{
// Providing the hint that this node's accumulator will be used often brings significant Elo gain (13 Elo)
// Providing the hint that this node's accumulator will be used often brings significant Elo gain (~13 Elo)
Eval::NNUE::hint_common_parent_position(pos);
eval = ss->staticEval;
}
Expand Down Expand Up @@ -787,7 +788,7 @@ namespace {
: (ss-4)->staticEval != VALUE_NONE ? ss->staticEval > (ss-4)->staticEval
: true;

// Step 7. Razoring (~1 Elo).
// Step 7. Razoring (~1 Elo)
// If eval is really low check with qsearch if it can exceed alpha, if it can't,
// return a fail low.
if (eval < alpha - 456 - 252 * depth * depth)
Expand All @@ -797,7 +798,7 @@ namespace {
return value;
}

// Step 8. Futility pruning: child node (~40 Elo).
// Step 8. Futility pruning: child node (~40 Elo)
// The depth condition is important for mate finding.
if ( !ss->ttPv
&& depth < 9
Expand Down Expand Up @@ -1451,6 +1452,7 @@ namespace {
Value bestValue, value, ttValue, futilityValue, futilityBase;
bool pvHit, givesCheck, capture;
int moveCount;
Color us = pos.side_to_move();

// Step 1. Initialize node
if (PvNode)
Expand Down Expand Up @@ -1561,7 +1563,7 @@ namespace {
moveCount++;

// Step 6. Pruning.
if (bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
if (bestValue > VALUE_TB_LOSS_IN_MAX_PLY && pos.non_pawn_material(us))
{
// Futility pruning and moveCount pruning (~10 Elo)
if ( !givesCheck
Expand Down
4 changes: 2 additions & 2 deletions src/syzygy/tbprobe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ constexpr Value WDL_to_value[] = {
template<typename T, int Half = sizeof(T) / 2, int End = sizeof(T) - 1>
inline void swap_endian(T& x)
{
static_assert(std::is_unsigned<T>::value, "Argument of swap_endian not unsigned");
static_assert(std::is_unsigned_v<T>, "Argument of swap_endian not unsigned");

uint8_t tmp, *c = (uint8_t*)&x;
for (int i = 0; i < Half; ++i)
Expand Down Expand Up @@ -332,7 +332,7 @@ struct PairsData {
// first access, when the corresponding file is memory mapped.
template<TBType Type>
struct TBTable {
using Ret = typename std::conditional<Type == WDL, WDLScore, int>::type;
using Ret = std::conditional_t<Type == WDL, WDLScore, int>;

static constexpr int Sides = Type == WDL ? 2 : 1;

Expand Down
Loading

0 comments on commit 8c9a9be

Please sign in to comment.