From 86ceb98bafd359a15d22e47a13ea5524d65c3f74 Mon Sep 17 00:00:00 2001 From: PGG106 Date: Sun, 26 Jan 2025 05:56:46 +0100 Subject: [PATCH] Use LTC tuned values (88000 games) (#504) Passed STC: Elo | 7.41 +- 3.70 (95%) SPRT | 8.0+0.08s Threads=1 Hash=16MB LLR | 2.92 (-2.25, 2.89) [0.00, 3.00] Games | N: 9236 W: 2348 L: 2151 D: 4737 Penta | [26, 1038, 2311, 1199, 44] Passed LTC: Elo | 6.81 +- 3.45 (95%) SPRT | 40.0+0.40s Threads=1 Hash=64MB LLR | 2.90 (-2.25, 2.89) [0.00, 3.00] Games | N: 9486 W: 2270 L: 2084 D: 5132 Penta | [4, 1045, 2462, 1225, 7] Bench: 10727485 --- src/history.cpp | 2 +- src/init.cpp | 8 ++++---- src/search.cpp | 26 +++++++++++++------------ src/tune.h | 52 ++++++++++++++++++++++++++++++++++--------------- src/types.h | 2 +- src/uci.cpp | 2 +- 6 files changed, 57 insertions(+), 35 deletions(-) diff --git a/src/history.cpp b/src/history.cpp index 59841114..d9c77e43 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -12,7 +12,7 @@ GetScore: this is simply a getter for a specific entry of the history table */ int history_bonus(const int depth) { - return std::min(16 * depth * depth + 32 * depth + 16, 1200); + return std::min(16 * depth * depth + 32 * depth + 16, historyBonusMax()); } void updateHHScore(const Position* pos, SearchData* sd, const Move move, int bonus) { diff --git a/src/init.cpp b/src/init.cpp index 64df8c16..285df964 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -142,8 +142,8 @@ void InitReductions() { for (int i = 1; i < 64; i++) { for (int j = 1; j < 64; j++) { - reductions[0][i][j] = -0.25 + log(i) * log(j) / 2.25; - reductions[1][i][j] = +1.00 + log(i) * log(j) / 2.00; + reductions[0][i][j] = lmrNoisyBase() / 100.0 + log(i) * log(j) / (lmrNoisytDivisor() / 100.0); + reductions[1][i][j] = lmrQuietBase() / 100.0 + log(i) * log(j) / (lmrQuietDivisor() / 100.0); } } @@ -151,8 +151,8 @@ void InitReductions() { lmp_margin[depth][0] = 1.5 + 0.5 * std::pow(depth, 2.0); // Not improving lmp_margin[depth][1] = 3.0 + 1.0 * std::pow(depth, 2.0); // improving - see_margin[depth][1] = -80.0 * std::pow(depth, 1.0); // Quiet moves - see_margin[depth][0] = -30.0 * std::pow(depth, 2.0); // Non quiets + see_margin[depth][1] = seeQuietMargin() * std::pow(depth, 1.0); // Quiet moves + see_margin[depth][0] = seeNoisyMargin() * std::pow(depth, 2.0); // Non quiets } } diff --git a/src/search.cpp b/src/search.cpp index 464b14db..f270e8b5 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "bitboard.h" #include "move.h" #include "search.h" @@ -516,8 +517,8 @@ int Negamax(int alpha, int beta, int depth, const bool cutNode, ThreadData* td, if ( depth < 10 && abs(eval) < MATE_FOUND && (ttMove == NOMOVE || isTactical(ttMove)) - && eval - 91 * (depth - improving - canIIR) >= beta) - return eval - 91 * (depth - improving - canIIR); + && eval - rfpMargin() * (depth - improving - canIIR) >= beta) + return eval - rfpMargin() * (depth - improving - canIIR); // Null move pruning: If our position is so good that we can give the opponent a free move and still fail high, // return early. At higher depth we do a reduced search with null move pruning disabled (ie verification search) @@ -531,7 +532,7 @@ int Negamax(int alpha, int beta, int depth, const bool cutNode, ThreadData* td, && BoardHasNonPawns(pos, pos->side)) { ss->move = NOMOVE; - const int R = 4 + depth / 3 + std::min((eval - beta) / 200, 3); + const int R = 4 + depth / 3 + std::min((eval - beta) / nmpReductionEvalDivisor(), 3); ss->contHistEntry = &sd->contHist[PieceTo(NOMOVE)]; MakeNullMove(pos); @@ -562,7 +563,7 @@ int Negamax(int alpha, int beta, int depth, const bool cutNode, ThreadData* td, } } // Razoring - if (depth <= 5 && eval + 256 * depth < alpha) + if (depth <= 5 && eval + razoringCoeff() * depth < alpha) { const int razorScore = Quiescence(alpha, beta, td, ss); if (razorScore <= alpha) @@ -652,8 +653,9 @@ int Negamax(int alpha, int beta, int depth, const bool cutNode, ThreadData* td, if ( !rootNode && bestScore > -MATE_FOUND) { + const int reduction = reductions[isQuiet][std::min(depth, 63)][std::min(totalMoves, 63)]; // lmrDepth is the current depth minus the reduction the move would undergo in lmr, this is helpful because it helps us discriminate the bad moves with more accuracy - const int lmrDepth = std::max(0, depth - reductions[isQuiet][std::min(depth, 63)][std::min(totalMoves, 63)] + moveHistory / 8192); + const int lmrDepth = std::max(0, depth - reduction + moveHistory / lmrDepthDivisor()); if (!skipQuiets) { @@ -665,13 +667,13 @@ int Negamax(int alpha, int beta, int depth, const bool cutNode, ThreadData* td, // Futility pruning: if the static eval is so low that even after adding a bonus we are still under alpha we can stop trying quiet moves if (!inCheck && lmrDepth < 11 - && ss->staticEval + 250 + 150 * lmrDepth <= alpha) { + && ss->staticEval + futilityCoeff0() + futilityCoeff1() * lmrDepth <= alpha) { skipQuiets = true; } } - + int see_margin = isQuiet ? seeQuietMargin() * lmrDepth : seeNoisyMargin() * lmrDepth * lmrDepth; // See pruning: prune all the moves that have a SEE score that is lower than our threshold - if (!SEE(pos, move, see_margin[std::min(lmrDepth, 63)][isQuiet])) + if (!SEE(pos, move, see_margin)) continue; } @@ -762,7 +764,7 @@ int Negamax(int alpha, int beta, int depth, const bool cutNode, ThreadData* td, depthReduction -= 1; // Decrease the reduction for moves that have a good history score and increase it for moves with a bad score - depthReduction -= moveHistory / 8192; + depthReduction -= moveHistory / historyQuietLmrDivisor(); } else { // Fuck @@ -770,7 +772,7 @@ int Negamax(int alpha, int beta, int depth, const bool cutNode, ThreadData* td, depthReduction += 2; // Decrease the reduction for moves that have a good history score and increase it for moves with a bad score - depthReduction -= moveHistory / 6144; + depthReduction -= moveHistory / historyNoisyLmrDivisor(); } // adjust the reduction so that we can't drop into Qsearch and to prevent extensions @@ -784,7 +786,7 @@ int Negamax(int alpha, int beta, int depth, const bool cutNode, ThreadData* td, if (score > alpha && newDepth > reducedDepth) { // Based on the value returned by our reduced search see if we should search deeper or shallower, // this is an exact yoink of what SF does and frankly i don't care lmao - const bool doDeeperSearch = score > (bestScore + 53 + 2 * newDepth); + const bool doDeeperSearch = score > (bestScore + doDeeperBaseMargin() + 2 * newDepth); const bool doShallowerSearch = score < (bestScore + newDepth); newDepth += doDeeperSearch - doShallowerSearch; if (newDepth > reducedDepth) @@ -977,7 +979,7 @@ int Quiescence(int alpha, int beta, ThreadData* td, SearchStack* ss) { // Futility pruning. If static eval is far below alpha, only search moves that win material. if ( bestScore > -MATE_FOUND && !inCheck) { - const int futilityBase = ss->staticEval + 192; + const int futilityBase = ss->staticEval + qsBaseFutility(); if (futilityBase <= alpha && !SEE(pos, move, 1)) { bestScore = std::max(futilityBase, bestScore); continue; diff --git a/src/tune.h b/src/tune.h index ed786fdf..f0b6f1b2 100644 --- a/src/tune.h +++ b/src/tune.h @@ -88,26 +88,46 @@ inline bool updateTuneVariable(std::string tune_variable_name, int value) // TM STUFF // SOFT/HARD bounds -TUNE_PARAM(baseMultiplier, 54, 20, 150, 7, 0.002) -TUNE_PARAM(incMultiplier, 85, 50, 150, 5, 0.002) -TUNE_PARAM(maxBoundMultiplier, 76, 50, 90, 2, 0.002) -TUNE_PARAM(optTimeMultiplier, 76, 50, 90, 2, 0.002) -TUNE_PARAM(maxTimeMultiplier, 304, 100, 500, 20, 0.002) +TUNE_PARAM(baseMultiplier, 59, 20, 150, 7, 0.002) +TUNE_PARAM(incMultiplier, 84, 50, 150, 5, 0.002) +TUNE_PARAM(maxBoundMultiplier, 73, 50, 90, 2, 0.002) +TUNE_PARAM(optTimeMultiplier, 79, 50, 90, 2, 0.002) +TUNE_PARAM(maxTimeMultiplier, 284, 100, 500, 20, 0.002) // Bestmove stability -TUNE_PARAM(bmScale1, 243, 50, 300, 10, 0.002) -TUNE_PARAM(bmScale2, 135, 50, 200, 10, 0.002) -TUNE_PARAM(bmScale3, 109, 50, 150, 6, 0.002) -TUNE_PARAM(bmScale4, 88, 40, 110, 5, 0.002) -TUNE_PARAM(bmScale5, 68, 35, 100, 5, 0.002) +TUNE_PARAM(bmScale1, 247, 50, 300, 10, 0.002) +TUNE_PARAM(bmScale2, 147, 50, 200, 10, 0.002) +TUNE_PARAM(bmScale3, 116, 50, 150, 6, 0.002) +TUNE_PARAM(bmScale4, 90, 40, 110, 5, 0.002) +TUNE_PARAM(bmScale5, 65, 35, 100, 5, 0.002) // Eval stability -TUNE_PARAM(evalScale1, 125, 90, 160, 4, 0.002) -TUNE_PARAM(evalScale2, 115, 80, 150, 4, 0.002) -TUNE_PARAM(evalScale3, 100, 80, 150, 4, 0.002) -TUNE_PARAM(evalScale4, 94, 60, 130, 4, 0.002) -TUNE_PARAM(evalScale5, 88, 40, 110, 4, 0.002) +TUNE_PARAM(evalScale1, 120, 90, 160, 4, 0.002) +TUNE_PARAM(evalScale2, 118, 80, 150, 4, 0.002) +TUNE_PARAM(evalScale3, 103, 80, 150, 4, 0.002) +TUNE_PARAM(evalScale4, 100, 60, 130, 4, 0.002) +TUNE_PARAM(evalScale5, 83, 40, 110, 4, 0.002) // Node Tm TUNE_PARAM(nodeTmBase, 152, 100, 300, 10, 0.002) -TUNE_PARAM(nodeTmMultiplier, 174, 80, 250, 8, 0.002) +TUNE_PARAM(nodeTmMultiplier, 183, 80, 250, 8, 0.002) + + +// Search +TUNE_PARAM(rfpMargin, 79, 40, 200, 10, 0.002) +TUNE_PARAM(nmpReductionEvalDivisor, 195, 100, 400, 20, 0.002) +TUNE_PARAM(razoringCoeff, 243, 100, 400, 20, 0.002) +TUNE_PARAM(historyQuietLmrDivisor, 8177, 1, 16383, 100, 0.002) +TUNE_PARAM(historyNoisyLmrDivisor, 5941, 1, 16383, 100, 0.002) +TUNE_PARAM(doDeeperBaseMargin, 117, 1, 200, 20, 0.002) +TUNE_PARAM(qsBaseFutility, 295, -500, 500, 25, 0.002) +TUNE_PARAM(historyBonusMax, 1286, 1, 4096, 256, 0.002) +TUNE_PARAM(lmrQuietBase, 106, 40, 150, 7, 0.002) +TUNE_PARAM(lmrQuietDivisor, 229, 150, 500, 15, 0.002) +TUNE_PARAM(lmrNoisyBase, -27, -70, 100, 7, 0.002) +TUNE_PARAM(lmrNoisytDivisor, 234, 150, 500, 15, 0.002) +TUNE_PARAM(seeQuietMargin, -93, -150, -20, 5, 0.002) +TUNE_PARAM(seeNoisyMargin, -34, -100, -1, 3, 0.002) +TUNE_PARAM(futilityCoeff0, 242, 40, 300, 10, 0.002) +TUNE_PARAM(futilityCoeff1, 137, 40, 200, 10, 0.002) +TUNE_PARAM(lmrDepthDivisor, 8135, 1, 16383, 100, 0.002) diff --git a/src/types.h b/src/types.h index df3ac7c3..5645858c 100644 --- a/src/types.h +++ b/src/types.h @@ -4,7 +4,7 @@ // include the tune stuff here to give it global visibility #include "tune.h" -#define NAME "Alexandria-7.1.8" +#define NAME "Alexandria-7.1.9" inline int reductions[2][64][64]; inline int lmp_margin[64][2]; diff --git a/src/uci.cpp b/src/uci.cpp index 57f4d80f..249b760f 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -336,7 +336,7 @@ void UciLoop(int argc, char** argv) { #ifdef TUNE // spsa info dump for (const auto ¶m: tunables()) { - std::cout << param << std::endl; + std::cout << "option name " << param.name << " type spin default " << param.defaultValue <<" min " <