1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-29 16:23:09 +00:00

Tune Search Parameters

Parameters Tune, adding also another tunable parameter (npmDiv) to be
variable for different nets (bignet, smallnet, psqtOnly smallnet). P.s:
The changed values are only the parameters where there is agreement
among the different time controls, so in other words, the tunings are
telling us that changing these specific values to this specific
direction is good in all time controls, so there shouldn't be a high
risk of regressing at longer time controls.

Passed STC:
LLR: 2.97 (-2.94,2.94) <0.00,2.00>
Total: 39552 W: 10329 L: 9999 D: 19224
Ptnml(0-2): 156, 4592, 9989, 4844, 195
https://tests.stockfishchess.org/tests/view/661be9a0bd68065432a088c0

Passed LTC:
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 56394 W: 14439 L: 14078 D: 27877
Ptnml(0-2): 30, 6152, 15480, 6497, 38
https://tests.stockfishchess.org/tests/view/661c746296961e72eb565406

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

Bench: 1836777
This commit is contained in:
FauziAkram 2024-04-22 14:34:22 +03:00 committed by Disservin
parent ddd250b9d6
commit fcba524793
3 changed files with 35 additions and 35 deletions

View file

@ -58,14 +58,14 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, const Position& pos,
Value nnue = smallNet ? networks.small.evaluate(pos, true, &nnueComplexity, psqtOnly) Value nnue = smallNet ? networks.small.evaluate(pos, true, &nnueComplexity, psqtOnly)
: networks.big.evaluate(pos, true, &nnueComplexity, false); : networks.big.evaluate(pos, true, &nnueComplexity, false);
const auto adjustEval = [&](int optDiv, int nnueDiv, int pawnCountConstant, int pawnCountMul, const auto adjustEval = [&](int optDiv, int nnueDiv, int npmDiv, int pawnCountConstant,
int npmConstant, int evalDiv, int shufflingConstant, int pawnCountMul, int npmConstant, int evalDiv,
int shufflingDiv) { int shufflingConstant, int shufflingDiv) {
// Blend optimism and eval with nnue complexity and material imbalance // Blend optimism and eval with nnue complexity and material imbalance
optimism += optimism * (nnueComplexity + std::abs(simpleEval - nnue)) / optDiv; optimism += optimism * (nnueComplexity + std::abs(simpleEval - nnue)) / optDiv;
nnue -= nnue * (nnueComplexity * 5 / 3) / nnueDiv; nnue -= nnue * (nnueComplexity * 5 / 3) / nnueDiv;
int npm = pos.non_pawn_material() / 64; int npm = pos.non_pawn_material() / npmDiv;
v = (nnue * (npm + pawnCountConstant + pawnCountMul * pos.count<PAWN>()) v = (nnue * (npm + pawnCountConstant + pawnCountMul * pos.count<PAWN>())
+ optimism * (npmConstant + npm)) + optimism * (npmConstant + npm))
/ evalDiv; / evalDiv;
@ -76,11 +76,11 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, const Position& pos,
}; };
if (!smallNet) if (!smallNet)
adjustEval(513, 32395, 919, 11, 145, 1036, 178, 204); adjustEval(524, 32395, 66, 942, 11, 139, 1058, 178, 204);
else if (psqtOnly) else if (psqtOnly)
adjustEval(517, 32857, 908, 7, 155, 1019, 224, 238); adjustEval(517, 32857, 65, 908, 7, 155, 1006, 224, 238);
else else
adjustEval(499, 32793, 903, 9, 147, 1067, 208, 211); adjustEval(515, 32793, 63, 944, 9, 140, 1067, 206, 206);
// Guarantee evaluation does not hit the tablebase range // Guarantee evaluation does not hit the tablebase range
v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1); v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);

View file

@ -190,8 +190,8 @@ void MovePicker::score() {
m.value += bool(pos.check_squares(pt) & to) * 16384; m.value += bool(pos.check_squares(pt) & to) * 16384;
// bonus for escaping from capture // bonus for escaping from capture
m.value += threatenedPieces & from ? (pt == QUEEN && !(to & threatenedByRook) ? 51000 m.value += threatenedPieces & from ? (pt == QUEEN && !(to & threatenedByRook) ? 51700
: pt == ROOK && !(to & threatenedByMinor) ? 24950 : pt == ROOK && !(to & threatenedByMinor) ? 25600
: !(to & threatenedByPawn) ? 14450 : !(to & threatenedByPawn) ? 14450
: 0) : 0)
: 0; : 0;
@ -200,7 +200,7 @@ void MovePicker::score() {
m.value -= !(threatenedPieces & from) m.value -= !(threatenedPieces & from)
? (pt == QUEEN ? bool(to & threatenedByRook) * 48150 ? (pt == QUEEN ? bool(to & threatenedByRook) * 48150
+ bool(to & threatenedByMinor) * 10650 + bool(to & threatenedByMinor) * 10650
: pt == ROOK ? bool(to & threatenedByMinor) * 24500 : pt == ROOK ? bool(to & threatenedByMinor) * 24335
: pt != PAWN ? bool(to & threatenedByPawn) * 14950 : pt != PAWN ? bool(to & threatenedByPawn) * 14950
: 0) : 0)
: 0; : 0;
@ -241,7 +241,7 @@ Move MovePicker::select(Pred filter) {
// moves left, picking the move with the highest score from a list of generated moves. // moves left, picking the move with the highest score from a list of generated moves.
Move MovePicker::next_move(bool skipQuiets) { Move MovePicker::next_move(bool skipQuiets) {
auto quiet_threshold = [](Depth d) { return -3550 * d; }; auto quiet_threshold = [](Depth d) { return -3560 * d; };
top: top:
switch (stage) switch (stage)
@ -310,7 +310,7 @@ top:
return *cur != refutations[0] && *cur != refutations[1] && *cur != refutations[2]; return *cur != refutations[0] && *cur != refutations[1] && *cur != refutations[2];
})) }))
{ {
if ((cur - 1)->value > -8000 || (cur - 1)->value <= quiet_threshold(depth)) if ((cur - 1)->value > -7998 || (cur - 1)->value <= quiet_threshold(depth))
return *(cur - 1); return *(cur - 1);
// Remaining quiets are bad // Remaining quiets are bad

View file

@ -57,9 +57,9 @@ static constexpr double EvalLevel[10] = {1.043, 1.017, 0.952, 1.009, 0.971,
// Futility margin // Futility margin
Value futility_margin(Depth d, bool noTtCutNode, bool improving, bool oppWorsening) { Value futility_margin(Depth d, bool noTtCutNode, bool improving, bool oppWorsening) {
Value futilityMult = 118 - 44 * noTtCutNode; Value futilityMult = 118 - 45 * noTtCutNode;
Value improvingDeduction = 52 * improving * futilityMult / 32; Value improvingDeduction = 52 * improving * futilityMult / 32;
Value worseningDeduction = (310 + 48 * improving) * oppWorsening * futilityMult / 1024; Value worseningDeduction = (316 + 48 * improving) * oppWorsening * futilityMult / 1024;
return futilityMult * d - improvingDeduction - worseningDeduction; return futilityMult * d - improvingDeduction - worseningDeduction;
} }
@ -76,10 +76,10 @@ Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos) {
} }
// History and stats update bonus, based on depth // History and stats update bonus, based on depth
int stat_bonus(Depth d) { return std::clamp(211 * d - 315, 0, 1291); } int stat_bonus(Depth d) { return std::clamp(214 * d - 318, 16, 1304); }
// History and stats update malus, based on depth // History and stats update malus, based on depth
int stat_malus(Depth d) { return (d < 4 ? 572 * d - 285 : 1372); } int stat_malus(Depth d) { return (d < 4 ? 572 * d - 284 : 1355); }
// Add a small random component to draw evaluations to avoid 3-fold blindness // Add a small random component to draw evaluations to avoid 3-fold blindness
Value value_draw(size_t nodes) { return VALUE_DRAW - 1 + Value(nodes & 0x2); } Value value_draw(size_t nodes) { return VALUE_DRAW - 1 + Value(nodes & 0x2); }
@ -303,12 +303,12 @@ void Search::Worker::iterative_deepening() {
// Reset aspiration window starting size // Reset aspiration window starting size
Value avg = rootMoves[pvIdx].averageScore; Value avg = rootMoves[pvIdx].averageScore;
delta = 11 + avg * avg / 11254; delta = 10 + avg * avg / 11480;
alpha = std::max(avg - delta, -VALUE_INFINITE); alpha = std::max(avg - delta, -VALUE_INFINITE);
beta = std::min(avg + delta, VALUE_INFINITE); beta = std::min(avg + delta, VALUE_INFINITE);
// Adjust optimism based on root move's averageScore (~4 Elo) // Adjust optimism based on root move's averageScore (~4 Elo)
optimism[us] = 125 * avg / (std::abs(avg) + 91); optimism[us] = 122 * avg / (std::abs(avg) + 92);
optimism[~us] = -optimism[us]; optimism[~us] = -optimism[us];
// Start with a small aspiration window and, in the case of a fail // Start with a small aspiration window and, in the case of a fail
@ -752,7 +752,7 @@ Value Search::Worker::search(
// If eval is really low check with qsearch if it can exceed alpha, if it can't, // If eval is really low check with qsearch if it can exceed alpha, if it can't,
// return a fail low. // return a fail low.
// Adjust razor margin according to cutoffCnt. (~1 Elo) // Adjust razor margin according to cutoffCnt. (~1 Elo)
if (eval < alpha - 471 - (276 - 148 * ((ss + 1)->cutoffCnt > 3)) * depth * depth) if (eval < alpha - 471 - (275 - 148 * ((ss + 1)->cutoffCnt > 3)) * depth * depth)
{ {
value = qsearch<NonPV>(pos, ss, alpha - 1, alpha); value = qsearch<NonPV>(pos, ss, alpha - 1, alpha);
if (value < alpha) if (value < alpha)
@ -763,14 +763,14 @@ Value Search::Worker::search(
// The depth condition is important for mate finding. // The depth condition is important for mate finding.
if (!ss->ttPv && depth < 12 if (!ss->ttPv && depth < 12
&& eval - futility_margin(depth, cutNode && !ss->ttHit, improving, opponentWorsening) && eval - futility_margin(depth, cutNode && !ss->ttHit, improving, opponentWorsening)
- (ss - 1)->statScore / 284 - (ss - 1)->statScore / 286
>= beta >= beta
&& eval >= beta && eval < VALUE_TB_WIN_IN_MAX_PLY && (!ttMove || ttCapture)) && eval >= beta && eval < VALUE_TB_WIN_IN_MAX_PLY && (!ttMove || ttCapture))
return beta > VALUE_TB_LOSS_IN_MAX_PLY ? (eval + beta) / 2 : eval; return beta > VALUE_TB_LOSS_IN_MAX_PLY ? (eval + beta) / 2 : eval;
// Step 9. Null move search with verification search (~35 Elo) // Step 9. Null move search with verification search (~35 Elo)
if (!PvNode && (ss - 1)->currentMove != Move::null() && (ss - 1)->statScore < 18001 if (!PvNode && (ss - 1)->currentMove != Move::null() && (ss - 1)->statScore < 18001
&& eval >= beta && ss->staticEval >= beta - 21 * depth + 315 && !excludedMove && eval >= beta && ss->staticEval >= beta - 21 * depth + 312 && !excludedMove
&& pos.non_pawn_material(us) && ss->ply >= thisThread->nmpMinPly && pos.non_pawn_material(us) && ss->ply >= thisThread->nmpMinPly
&& beta > VALUE_TB_LOSS_IN_MAX_PLY) && beta > VALUE_TB_LOSS_IN_MAX_PLY)
{ {
@ -881,7 +881,7 @@ Value Search::Worker::search(
moves_loop: // When in check, search starts here moves_loop: // When in check, search starts here
// Step 12. A small Probcut idea, when we are in check (~4 Elo) // Step 12. A small Probcut idea, when we are in check (~4 Elo)
probCutBeta = beta + 436; probCutBeta = beta + 452;
if (ss->inCheck && !PvNode && ttCapture && (tte->bound() & BOUND_LOWER) if (ss->inCheck && !PvNode && ttCapture && (tte->bound() & BOUND_LOWER)
&& tte->depth() >= depth - 4 && ttValue >= probCutBeta && tte->depth() >= depth - 4 && ttValue >= probCutBeta
&& std::abs(ttValue) < VALUE_TB_WIN_IN_MAX_PLY && std::abs(beta) < VALUE_TB_WIN_IN_MAX_PLY) && std::abs(ttValue) < VALUE_TB_WIN_IN_MAX_PLY && std::abs(beta) < VALUE_TB_WIN_IN_MAX_PLY)
@ -964,7 +964,7 @@ moves_loop: // When in check, search starts here
{ {
Piece capturedPiece = pos.piece_on(move.to_sq()); Piece capturedPiece = pos.piece_on(move.to_sq());
Value futilityValue = Value futilityValue =
ss->staticEval + 288 + 277 * lmrDepth + PieceValue[capturedPiece] ss->staticEval + 285 + 277 * lmrDepth + PieceValue[capturedPiece]
+ thisThread->captureHistory[movedPiece][move.to_sq()][type_of(capturedPiece)] + thisThread->captureHistory[movedPiece][move.to_sq()][type_of(capturedPiece)]
/ 7; / 7;
if (futilityValue <= alpha) if (futilityValue <= alpha)
@ -972,7 +972,7 @@ moves_loop: // When in check, search starts here
} }
// SEE based pruning for captures and checks (~11 Elo) // SEE based pruning for captures and checks (~11 Elo)
if (!pos.see_ge(move, -199 * depth)) if (!pos.see_ge(move, -203 * depth))
continue; continue;
} }
else else
@ -992,10 +992,10 @@ moves_loop: // When in check, search starts here
lmrDepth += history / 5285; lmrDepth += history / 5285;
Value futilityValue = Value futilityValue =
ss->staticEval + (bestValue < ss->staticEval - 54 ? 128 : 58) + 131 * lmrDepth; ss->staticEval + (bestValue < ss->staticEval - 54 ? 128 : 57) + 131 * lmrDepth;
// Futility pruning: parent node (~13 Elo) // Futility pruning: parent node (~13 Elo)
if (!ss->inCheck && lmrDepth < 15 && futilityValue <= alpha) if (!ss->inCheck && lmrDepth < 14 && futilityValue <= alpha)
{ {
if (bestValue <= futilityValue && std::abs(bestValue) < VALUE_TB_WIN_IN_MAX_PLY if (bestValue <= futilityValue && std::abs(bestValue) < VALUE_TB_WIN_IN_MAX_PLY
&& futilityValue < VALUE_TB_WIN_IN_MAX_PLY) && futilityValue < VALUE_TB_WIN_IN_MAX_PLY)
@ -1006,7 +1006,7 @@ moves_loop: // When in check, search starts here
lmrDepth = std::max(lmrDepth, 0); lmrDepth = std::max(lmrDepth, 0);
// Prune moves with negative SEE (~4 Elo) // Prune moves with negative SEE (~4 Elo)
if (!pos.see_ge(move, -26 * lmrDepth * lmrDepth)) if (!pos.see_ge(move, -27 * lmrDepth * lmrDepth))
continue; continue;
} }
} }
@ -1026,11 +1026,11 @@ moves_loop: // When in check, search starts here
// so changing them requires tests at these types of time controls. // so changing them requires tests at these types of time controls.
// Recursive singular search is avoided. // Recursive singular search is avoided.
if (!rootNode && move == ttMove && !excludedMove if (!rootNode && move == ttMove && !excludedMove
&& depth >= 4 - (thisThread->completedDepth > 32) + ss->ttPv && depth >= 4 - (thisThread->completedDepth > 33) + ss->ttPv
&& std::abs(ttValue) < VALUE_TB_WIN_IN_MAX_PLY && (tte->bound() & BOUND_LOWER) && std::abs(ttValue) < VALUE_TB_WIN_IN_MAX_PLY && (tte->bound() & BOUND_LOWER)
&& tte->depth() >= depth - 3) && tte->depth() >= depth - 3)
{ {
Value singularBeta = ttValue - (64 + 59 * (ss->ttPv && !PvNode)) * depth / 64; Value singularBeta = ttValue - (65 + 59 * (ss->ttPv && !PvNode)) * depth / 63;
Depth singularDepth = newDepth / 2; Depth singularDepth = newDepth / 2;
ss->excludedMove = move; ss->excludedMove = move;
@ -1134,10 +1134,10 @@ moves_loop: // When in check, search starts here
ss->statScore = 2 * thisThread->mainHistory[us][move.from_to()] ss->statScore = 2 * thisThread->mainHistory[us][move.from_to()]
+ (*contHist[0])[movedPiece][move.to_sq()] + (*contHist[0])[movedPiece][move.to_sq()]
+ (*contHist[1])[movedPiece][move.to_sq()] + (*contHist[1])[movedPiece][move.to_sq()]
+ (*contHist[3])[movedPiece][move.to_sq()] - 5007; + (*contHist[3])[movedPiece][move.to_sq()] - 5024;
// Decrease/increase reduction for moves with a good/bad history (~8 Elo) // Decrease/increase reduction for moves with a good/bad history (~8 Elo)
r -= ss->statScore / 12901; r -= ss->statScore / 13182;
// Step 17. Late moves reduction / extension (LMR, ~117 Elo) // Step 17. Late moves reduction / extension (LMR, ~117 Elo)
if (depth >= 2 && moveCount > 1 + rootNode) if (depth >= 2 && moveCount > 1 + rootNode)
@ -1274,7 +1274,7 @@ moves_loop: // When in check, search starts here
else else
{ {
// Reduce other moves if we have found at least one score improvement (~2 Elo) // Reduce other moves if we have found at least one score improvement (~2 Elo)
if (depth > 2 && depth < 12 && beta < 13132 && value > -13295) if (depth > 2 && depth < 12 && beta < 13546 && value > -13478)
depth -= 2; depth -= 2;
assert(depth > 0); assert(depth > 0);
@ -1319,7 +1319,7 @@ moves_loop: // When in check, search starts here
{ {
int bonus = (depth > 5) + (PvNode || cutNode) + ((ss - 1)->statScore < -14761) int bonus = (depth > 5) + (PvNode || cutNode) + ((ss - 1)->statScore < -14761)
+ ((ss - 1)->moveCount > 11) + ((ss - 1)->moveCount > 11)
+ (!ss->inCheck && bestValue <= ss->staticEval - 144); + (!ss->inCheck && bestValue <= ss->staticEval - 142);
update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq, update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq,
stat_bonus(depth) * bonus); stat_bonus(depth) * bonus);
thisThread->mainHistory[~us][((ss - 1)->currentMove).from_to()] thisThread->mainHistory[~us][((ss - 1)->currentMove).from_to()]
@ -1477,7 +1477,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,
if (bestValue > alpha) if (bestValue > alpha)
alpha = bestValue; alpha = bestValue;
futilityBase = ss->staticEval + 246; futilityBase = ss->staticEval + 250;
} }
const PieceToHistory* contHist[] = {(ss - 1)->continuationHistory, const PieceToHistory* contHist[] = {(ss - 1)->continuationHistory,
@ -1625,7 +1625,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,
Depth Search::Worker::reduction(bool i, Depth d, int mn, int delta) { Depth Search::Worker::reduction(bool i, Depth d, int mn, int delta) {
int reductionScale = reductions[d] * reductions[mn]; int reductionScale = reductions[d] * reductions[mn];
return (reductionScale + 1123 - delta * 832 / rootDelta) / 1024 + (!i && reductionScale > 1025); return (reductionScale + 1150 - delta * 832 / rootDelta) / 1024 + (!i && reductionScale > 1025);
} }
TimePoint Search::Worker::elapsed() const { TimePoint Search::Worker::elapsed() const {