summaryrefslogtreecommitdiff
path: root/src/root.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-10-23 13:19:17 -0700
committerScott Gasch <[email protected]>2026-10-23 13:19:17 -0700
commit69525eb2f42ea9cca8255f6cc3b85e6b1312fd05 (patch)
treed78420b6c45d584a3f09b4dcbaf4f1edb36e8d5d /src/root.c
parent6b883e83935f5e8110788565cfcb77cd6fbf8950 (diff)
NNUE search integration: FH% tables, NODE_TYPE refinement, TREEDUMP rewrite
- data.c/chess.h: widen the joint FH% table's late axis 16->17, dedicating the new bucket 0 to a whole-node ("will something here fail high at all") sample rather than sharing it with the first-leftover-move curve. Add an NNUE-eval counterpart table (g_uJointFHThousandths_NNUE) and an NNUE counterpart of the beta-side table, selected at runtime based on whether NNUE eval is active. - search.c/searchsup.c: add _RefineNodeTypeGuess, which uses the FH% tables (via g_NodeTypeGuessTable) to refine a node's NODE_TYPE guess instead of the old heuristic; thread uParentMoveFHEstimate through PLY_INFO so a node can see its parent's prediction for the move that led to it. - generate.c: initialize sKillers[2]/[3].uBonus unconditionally (an uninitialized-stack read caught by valgrind under LTO; harmless today but a real bug). - dumptree.c/chess.h/GNUmakefile: replace the long-dead DUMP_TREE XML tree dump (written for a GUI this project no longer has) with TREEDUMP, a flat, path-keyed move/result trace meant to diff against an identically-instrumented Stockfish build -- see docs/TREEDUMP_FORMAT.md. - docs/DEEPER_PRUNING.md: notes on closing the search-efficiency gap vs Stockfish. - crafty_egtb/stockfish_xboard/typhoon_nnue: wrapper scripts so match_play.py's Engine class can drive Crafty, Stockfish (via PolyGlot), and an NNUE-enabled typhoon the same way it drives HCE typhoon. - tests/lop: rename lop.txt -> lop.ep_; update compare_lop.cpp. - annotate_pgns: add aggregate_marginsafety.py, dedup_pgn.py, fit_lazy_probe.py; update annotate.py/run_nnue_pipeline.py for the NNUE training pipeline. - .gitignore: ignore compile_commands.json (clangd build DB) and eval.nnue (a symlink into the untracked head_reference/ comparison baseline), neither of which belongs in the repo. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/root.c')
-rw-r--r--src/root.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/root.c b/src/root.c
index 140c662..693fb1e 100644
--- a/src/root.c
+++ b/src/root.c
@@ -957,6 +957,21 @@ Return value:
// TODO: Fancy recap shit here?
//
+ // RootSearch has its own move loop here, separate from
+ // searchsup.c's SearchOneMove (which stashes this on
+ // every OTHER recursion into Search() -- see chess.h's
+ // PLY_INFO.uParentMoveFHEstimate comment). Without this,
+ // a root child's ply slot reads whatever was last left in
+ // it, caught by valgrind as a real uninitialised-value
+ // read inside search.c's _RefineNodeTypeGuess. Root tries
+ // every legal move in full, not a leftover-ordered
+ // subset, so there is no real per-move FH% prediction to
+ // report here -- MOVE_FH_ESTIMATE_NO_DATA ("unknown"), not
+ // MOVE_FH_ESTIMATE_NONLEFTOVER (which would falsely claim
+ // high confidence).
+ ctx->sPlyInfo[ctx->uPly].uParentMoveFHEstimate =
+ MOVE_FH_ESTIMATE_NO_DATA;
+
uNextDepth = uDepth - ONE_PLY;
if (IS_CHECKING_MOVE(mv))
{
@@ -988,6 +1003,12 @@ Return value:
}
}
ctx->sSearchFlags.fVerifyNullmove = FALSE;
+ TDMove(ctx, uDepth, iAlpha, iBeta,
+ (1 == uNumLegalMoves) ? "FIRST" :
+ (IS_CAPTURE_OR_PROMOTION(mv) ? "CAP" : "QUIET"),
+ "FULL", 0.0,
+ (double)(uNextDepth - (uDepth - ONE_PLY)) / ONE_PLY,
+ iScore, FALSE);
UnmakeMove(ctx, mv);
if (WE_SHOULD_STOP_SEARCHING)
{
@@ -1095,6 +1116,10 @@ Return value:
}
end:
+ if ((INVALID_SCORE != iBestScore) && !WE_SHOULD_STOP_SEARCHING)
+ {
+ TDResult(ctx, uDepth, iInitialAlpha, iBeta, pi->iEval, iBestScore);
+ }
return(iBestScore);
}