Merge branch 'master' into clusterMergeMaster3

This commit is contained in:
Joost VandeVondele
2019-01-09 21:52:30 +01:00
22 changed files with 181 additions and 165 deletions
+61 -41
View File
@@ -114,8 +114,8 @@ namespace {
Value value_from_tt(Value v, int ply);
void update_pv(Move* pv, Move move, Move* childPv);
void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
void update_quiet_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, int bonus);
void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCnt, int bonus);
void update_quiet_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietCount, int bonus);
void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCount, int bonus);
inline bool gives_check(const Position& pos, Move move) {
Color us = pos.side_to_move();
@@ -529,32 +529,32 @@ void Thread::search() {
if ( Limits.use_time_management()
&& !Threads.stop
&& !Threads.stopOnPonderhit)
{
double fallingEval = (306 + 119 * failedLow + 6 * (mainThread->previousScore - bestValue)) / 581.0;
fallingEval = std::max(0.5, std::min(1.5, fallingEval));
// If the bestMove is stable over several iterations, reduce time accordingly
timeReduction = 1.0;
for (int i : {3, 4, 5})
if (lastBestMoveDepth * i < completedDepth)
timeReduction *= 1.25;
// Use part of the gained time from a previous stable move for the current move
double bestMoveInstability = 1.0 + mainThread->bestMoveChanges;
bestMoveInstability *= std::pow(mainThread->previousTimeReduction, 0.528) / timeReduction;
// Stop the search if we have only one legal move, or if available time elapsed
if ( rootMoves.size() == 1
|| Time.elapsed() > Time.optimum() * bestMoveInstability * fallingEval)
{
double fallingEval = (306 + 119 * failedLow + 6 * (mainThread->previousScore - bestValue)) / 581.0;
fallingEval = std::max(0.5, std::min(1.5, fallingEval));
// If the bestMove is stable over several iterations, reduce time accordingly
timeReduction = 1.0;
for (int i : {3, 4, 5})
if (lastBestMoveDepth * i < completedDepth)
timeReduction *= 1.25;
// Use part of the gained time from a previous stable move for the current move
double bestMoveInstability = 1.0 + mainThread->bestMoveChanges;
bestMoveInstability *= std::pow(mainThread->previousTimeReduction, 0.528) / timeReduction;
// Stop the search if we have only one legal move, or if available time elapsed
if ( rootMoves.size() == 1
|| Time.elapsed() > Time.optimum() * bestMoveInstability * fallingEval)
{
// If we are allowed to ponder do not stop the search now but
// keep pondering until the GUI sends "ponderhit" or "stop".
if (Threads.ponder)
Threads.stopOnPonderhit = true;
else
Threads.stop = true;
}
// If we are allowed to ponder do not stop the search now but
// keep pondering until the GUI sends "ponderhit" or "stop".
if (Threads.ponder)
Threads.stopOnPonderhit = true;
else
Threads.stop = true;
}
}
}
if (!mainThread)
@@ -608,7 +608,7 @@ namespace {
Move ttMove, move, excludedMove, bestMove;
Depth extension, newDepth;
Value bestValue, value, ttValue, eval, maxValue, pureStaticEval;
bool ttHit, inCheck, givesCheck, improving;
bool ttHit, pvHit, inCheck, givesCheck, improving;
bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets, ttCapture, pvExact;
Piece movedPiece;
int moveCount, captureCount, quietCount;
@@ -674,6 +674,7 @@ namespace {
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
ttMove = rootNode ? thisThread->rootMoves[thisThread->pvIdx].pv[0]
: ttHit ? tte->move() : MOVE_NONE;
pvHit = ttHit ? tte->pv_hit() : false;
// At non-PV nodes we check for an early TT cutoff
if ( !PvNode
@@ -707,6 +708,11 @@ namespace {
return ttValue;
}
if ( depth > 6 * ONE_PLY
&& !excludedMove
&& PvNode)
pvHit = true;
// Step 5. Tablebases probe
if (!rootNode && TB::Cardinality)
{
@@ -741,7 +747,7 @@ namespace {
|| (b == BOUND_LOWER ? value >= beta : value <= alpha))
{
Cluster::save(thisThread, tte,
posKey, value_to_tt(value, ss->ply), b,
posKey, value_to_tt(value, ss->ply), pvHit, b,
std::min(DEPTH_MAX - ONE_PLY, depth + 6 * ONE_PLY),
MOVE_NONE, VALUE_NONE);
@@ -793,7 +799,7 @@ namespace {
ss->staticEval = eval = pureStaticEval = -(ss-1)->staticEval + 2 * Eval::Tempo;
Cluster::save(thisThread, tte,
posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE,
posKey, VALUE_NONE, pvHit, BOUND_NONE, DEPTH_NONE, MOVE_NONE,
pureStaticEval);
}
@@ -909,6 +915,7 @@ namespace {
tte = TT.probe(posKey, ttHit);
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
ttMove = ttHit ? tte->move() : MOVE_NONE;
pvHit = ttHit ? tte->pv_hit() : false;
}
moves_loop: // When in check, search starts from here
@@ -977,13 +984,21 @@ moves_loop: // When in check, search starts from here
&& tte->depth() >= depth - 3 * ONE_PLY
&& pos.legal(move))
{
Value reducedBeta = std::max(ttValue - 2 * depth / ONE_PLY, -VALUE_MATE);
Value singularBeta = std::max(ttValue - 2 * depth / ONE_PLY, -VALUE_MATE);
ss->excludedMove = move;
value = search<NonPV>(pos, ss, reducedBeta - 1, reducedBeta, depth / 2, cutNode);
value = search<NonPV>(pos, ss, singularBeta - 1, singularBeta, depth / 2, cutNode);
ss->excludedMove = MOVE_NONE;
if (value < reducedBeta)
if (value < singularBeta)
extension = ONE_PLY;
// Multi-cut pruning
// Our ttMove is assumed to fail high, and now we failed high also on a reduced
// search without the ttMove. So we assume this expected Cut-node is not singular,
// that is multiple moves fail high, and we can prune the whole subtree by returning
// the hard beta bound.
else if (cutNode && singularBeta > beta)
return beta;
}
else if ( givesCheck // Check extension (~2 Elo)
&& pos.see_ge(move))
@@ -1061,6 +1076,10 @@ moves_loop: // When in check, search starts from here
{
Depth r = reduction<PvNode>(improving, depth, moveCount);
// Decrease reduction if position is or has been on the PV
if (pvHit && !PvNode)
r -= ONE_PLY;
// Decrease reduction if opponent's move count is high (~10 Elo)
if ((ss-1)->moveCount > 15)
r -= ONE_PLY;
@@ -1244,7 +1263,7 @@ moves_loop: // When in check, search starts from here
if (!excludedMove)
Cluster::save(thisThread, tte,
posKey, value_to_tt(bestValue, ss->ply),
posKey, value_to_tt(bestValue, ss->ply), pvHit,
bestValue >= beta ? BOUND_LOWER :
PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
depth, bestMove, pureStaticEval);
@@ -1274,7 +1293,7 @@ moves_loop: // When in check, search starts from here
Move ttMove, move, bestMove;
Depth ttDepth;
Value bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha;
bool ttHit, inCheck, givesCheck, evasionPrunable;
bool ttHit, pvHit, inCheck, givesCheck, evasionPrunable;
int moveCount;
if (PvNode)
@@ -1308,6 +1327,7 @@ moves_loop: // When in check, search starts from here
tte = TT.probe(posKey, ttHit);
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
ttMove = ttHit ? tte->move() : MOVE_NONE;
pvHit = ttHit ? tte->pv_hit() : false;
if ( !PvNode
&& ttHit
@@ -1346,7 +1366,7 @@ moves_loop: // When in check, search starts from here
{
if (!ttHit)
Cluster::save(thisThread, tte,
posKey, value_to_tt(bestValue, ss->ply), BOUND_LOWER,
posKey, value_to_tt(bestValue, ss->ply), pvHit, BOUND_LOWER,
DEPTH_NONE, MOVE_NONE, ss->staticEval);
return bestValue;
@@ -1458,7 +1478,7 @@ moves_loop: // When in check, search starts from here
return mated_in(ss->ply); // Plies to mate from the root
Cluster::save(thisThread, tte,
posKey, value_to_tt(bestValue, ss->ply),
posKey, value_to_tt(bestValue, ss->ply), pvHit,
bestValue >= beta ? BOUND_LOWER :
PvNode && bestValue > oldAlpha ? BOUND_EXACT : BOUND_UPPER,
ttDepth, bestMove, ss->staticEval);
@@ -1518,7 +1538,7 @@ moves_loop: // When in check, search starts from here
// update_capture_stats() updates move sorting heuristics when a new capture best move is found
void update_capture_stats(const Position& pos, Move move,
Move* captures, int captureCnt, int bonus) {
Move* captures, int captureCount, int bonus) {
CapturePieceToHistory& captureHistory = pos.this_thread()->captureHistory;
Piece moved_piece = pos.moved_piece(move);
@@ -1528,7 +1548,7 @@ moves_loop: // When in check, search starts from here
captureHistory[moved_piece][to_sq(move)][captured] << bonus;
// Decrease all the other played capture moves
for (int i = 0; i < captureCnt; ++i)
for (int i = 0; i < captureCount; ++i)
{
moved_piece = pos.moved_piece(captures[i]);
captured = type_of(pos.piece_on(to_sq(captures[i])));
@@ -1540,7 +1560,7 @@ moves_loop: // When in check, search starts from here
// update_quiet_stats() updates move sorting heuristics when a new quiet best move is found
void update_quiet_stats(const Position& pos, Stack* ss, Move move,
Move* quiets, int quietsCnt, int bonus) {
Move* quiets, int quietCount, int bonus) {
if (ss->killers[0] != move)
{
@@ -1560,7 +1580,7 @@ moves_loop: // When in check, search starts from here
}
// Decrease all the other played quiet moves
for (int i = 0; i < quietsCnt; ++i)
for (int i = 0; i < quietCount; ++i)
{
thisThread->mainHistory[us][from_to(quiets[i])] << -bonus;
update_continuation_histories(ss, pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
@@ -1706,7 +1726,7 @@ bool RootMove::extract_ponder_from_tt(Position& pos) {
assert(pv.size() == 1);
if (!pv[0])
if (pv[0] == MOVE_NONE)
return false;
pos.do_move(pv[0], st);