diff options
| author | Scott Gasch <[email protected]> | 2026-10-25 09:55:30 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-10-25 09:55:30 -0700 |
| commit | 874ef0478078ef4eb436af7d2b68a353f61f4d70 (patch) | |
| tree | e9954c289393c64d88402beff04637b52732ca73 /src/split.c | |
| parent | 5f901d737b17c5f99b6e456d6c0c7d5e3c093dc4 (diff) | |
Learned FH% logistic-regression model (alpha full, beta whole-node-only)
Replaces the data.c histogram tables (g_uJointFHThousandths/
g_uBetaFHThousandths and their _NNUE counterparts) with two quantized
logistic regressions as the default FH%-prediction mechanism under
FH_USE_REGRESSION_MODEL=1, trained against real collected search data
(fhcollect.c) per docs/REGRESSION.md.
Alpha side is a full per-move regression, validated against the old
table (0.119pp weighted mean deviation across 10,684 matched cells).
Beta side is whole-node-only (matching the old table's own scope --
no functionality lost), refit on the NO_MOVE population after an
earlier mixed-tier fit saturated and over-pruned; its skip threshold
(FH_BETA_SKIP_THRESHOLD=99000) was confirmed by direct self-play
sweeps, not just ECM solve-count intuition (see docs/REGRESSION.md's
"Category A vs B" discussion).
Gated by an overnight SPRT match (regression vs HEAD tables, same
NNUE eval, sd8): at 4120 games, llr=+2.53 (never dipped negative,
peaked +2.8), score=0.517, candidate reaching comparable depth at
higher nps/ebf than head. Did not cross the H1=+2.94 SPRT bound, but
the trend across the full run is unambiguous and the marginal value of
waiting out the remaining games was judged not worth it.
The data.c tables are left in place as the inactive #else branch of
FH_USE_REGRESSION_MODEL for now; a follow-up commit will flip the
build default and remove them once this commit's head_reference
baseline and ECM numbers are recorded.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/split.c')
| -rw-r--r-- | src/split.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/split.c b/src/split.c index 66f44a3..063f183 100644 --- a/src/split.c +++ b/src/split.c @@ -1194,6 +1194,13 @@ Return value: #ifdef TEST_NULL UINT64 uNullCalibFirstMoveNodeCostUnused; #endif +#ifdef FH_REGRESSION_COLLECTION + // The MP split path is deliberately uninstrumented (collection + // runs at --cpus 1, see docs/REGRESSION.md) -- this sink + // exists only so this call site's argument list matches + // SearchOneMove's prototype. + SCORE iFhCollectMoveValueUnused; +#endif uDepth = uOrigDepth; ASSERT(ctx->uPly == g_SplitInfo[u].uSplitPly); @@ -1285,6 +1292,18 @@ Return value: uRawImproveB, g_SplitInfo[u].bbMinorAttacksSnapshot, g_SplitInfo[u].bbRookAttacksSnapshot, +#ifdef FH_USE_REGRESSION_MODEL + // Same "deliberately + // uninstrumented" pattern as + // the FH_REGRESSION_COLLECTION + // param below -- no node-level + // precompute is threaded + // through the split machinery, + // so this always falls back to + // the no-data sentinel on a + // helper thread's move. + (FHM_NODE_BASE)FHM_MATE_GATED, +#endif #ifdef MOVE_ORDERING_EVIDENCE_COLLECTION FALSE, // fThisMoveIsCountermoveMatch 0, // uCMEvidenceBucket @@ -1303,6 +1322,9 @@ Return value: , &uThisMoveNumBucketUnused , &uThisMoveDepthBucketUnused #endif +#ifdef FH_REGRESSION_COLLECTION + , &iFhCollectMoveValueUnused +#endif ); ASSERT(PositionsAreEquivalent(&ctx->sPosition, &board)); |
