summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-10-20 09:26:44 -0700
committerScott Gasch <[email protected]>2026-10-20 09:26:44 -0700
commitc8c6bbc2c1a103e5b07b079a0f8bdf66c7724d80 (patch)
treeb6c2137c9ac577fa83b1e948fa0311d53dfe445d /src/main.c
parent3b5d3677bb14ae14728a1c4b221176bb83667d92 (diff)
Wire NNUE eval into search, build the training pipeline, and add a fast
move/eval-agreement benchmark against Stockfish (tests/lop) Implements the architecture decisions in src/docs/NNUE.md: HalfKAv2_hm feature set, int16/int8 quantization, per-ply accumulator backup for king moves, and a lazy-eval-ready integration into search.c/eval.c. Adds the full annotate_pgns/ training pipeline (extraction, K-fit/ labeling, quiet filtering, tensor building, training, export) plus an end-to-end orchestrator (run_nnue_pipeline.py) and validation tooling (sanity_check_net.py, compare_vs_stockfish_net.py). Adds tests/lop: a 10k-position list-of-positions benchmark comparing engine eval rank and move choice against pre-computed Stockfish/lc0 references, much cheaper than a full self-play match for day-to-day progress checks. First sd10-matched self-play result against classic HCE: LLR +2.28 (H1=+2.94), -72=119+169 over 360 games, confirming the net is "smarter per node" at matched depth. A real-time (--st 4) match is currently weaker (candidate loses ~3 plies of depth to a ~3.3-3.7x nps gap against an unrecalibrated search), consistent with NNUE.md's adoption-criterion section -- pruning/reduction constants still need retuning for the new eval's score scale before a fair real-time comparison is possible. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
index 90301af..f822b7e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -305,6 +305,7 @@ Return value:
g_Options.uNumProcessors = 1;
g_Options.fStatusLine = TRUE;
g_Options.iResignThreshold = 0;
+ g_Options.dPostThrottleSec = 0.35;
g_Options.u64MaxNodeCount = 0ULL;
i = 1;
@@ -424,6 +425,53 @@ Return value:
}
if (fConsumedNextArg) i++;
}
+ else if ((!STRCMPI(pszArg, "--nnueprobeweights")) && fHaveVal)
+ {
+ // Same reasoning as --nnueweights above -- loads and
+ // enables the lazy-eval accumulator probe gate at startup
+ // for scripted match-play, where there's no interactive
+ // "nnue probeload"/"nnue lazyprobeon" command pair
+ // available. Does NOT imply --nnueweights -- pass both to
+ // get the full NNUE+lazy-gate configuration; this alone
+ // without NNUE eval enabled would load the probe but never
+ // reach the code path that consults it.
+ if (!NnueProbeLoadWeights(pszVal))
+ {
+ UtilPanic(INITIALIZATION_FAILURE,
+ (void *)"Bad NNUE probe weights file",
+ (void *)&(pszVal),
+ (void *)"probeload",
+ NULL,
+ __FILE__, __LINE__);
+ }
+ else
+ {
+ g_fUseNnueLazyProbe = TRUE;
+ Trace("Loaded NNUE probe weights \"%s\", lazy probe gate enabled.\n",
+ pszVal);
+ }
+ if (fConsumedNextArg) i++;
+ }
+ else if ((!STRCMPI(pszArg, "--nnuelazymargin")) && fHaveVal)
+ {
+ // Scripted-match-play equivalent of "nnue lazymargin <cp>"
+ // -- flat override for every material bucket's lazy-probe
+ // margin, see nnueeval.c/eval.c. 2026-10-16 looser-margin
+ // experiment.
+ g_iNnueLazyMarginOverride = atoi(pszVal);
+ Trace("NNUE lazy margin override set to %d cp.\n",
+ g_iNnueLazyMarginOverride);
+ if (fConsumedNextArg) i++;
+ }
+ else if ((!STRCMPI(pszArg, "--nnuesuperlazymargin")) && fHaveVal)
+ {
+ // Scripted equivalent of "nnue superlazyon <cp>".
+ g_iNnueSuperLazyMargin = (SCORE)atoi(pszVal);
+ g_fUseNnueSuperLazy = TRUE;
+ Trace("NNUE super-lazy pre-filter enabled, margin=%d cp.\n",
+ g_iNnueSuperLazyMargin);
+ if (fConsumedNextArg) i++;
+ }
else if ((!STRCMPI(pszArg, "--dnafile")) && fHaveVal)
{
if (!ReadEvalDNA(pszVal))