diff options
| author | Scott Gasch <[email protected]> | 2026-10-14 12:16:43 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-10-14 12:16:43 -0700 |
| commit | ac5cc078b71e94b21a8a843628045c745022aa75 (patch) | |
| tree | 1633412357651cd94e34b50c74f23ff06608db7f /src/search.c | |
| parent | 91f01c607338eabb10ae1f8c144be55071d174a5 (diff) | |
Remove PRUNE_VERIFY entirely -- never compiled in its current form
PRUNE_VERIFY (shadow verification for ShouldLatePrune's deep-prune
gate) is dead code that has apparently never been built successfully:
search.c's #if defined(PERF_COUNTERS) && defined(PRUNE_VERIFY) block
reads fVerifyFlagged/uVerifyBand/uVerifyDepthB/uVerifyAttB/
uVerifyRateB/uVerifyPred, none of which are declared or assigned
anywhere in the file. Confirmed by compiling search.c with
-DPRUNE_VERIFY directly: 7 "use of undeclared identifier" errors.
Since GNUmakefile never defines PRUNE_VERIFY on any path (it's
opt-in only, ifdef PRUNE_VERIFY / PROFILE += -DPRUNE_VERIFY), nothing
has ever caught this.
Removed rather than fixed: reconstructing fVerifyFlagged/uVerifyBand/
etc.'s intended semantics from scratch would be inventing behavior,
not restoring it -- there's no prior working version to recover.
Removed: the broken block in search.c's move loop; its two
PRUNE_VERIFY-exclusive helper functions (PruneVerifyBand,
PvAttBucket/PvRateBucket -- careful to keep ShipDepthBucketPublic/
JOINT_TABLE_SENTINEL_PUBLIC/ShipLateBucketPublic/PruneVerifyPredict,
which PRUNE_LIVE also uses via its PruneLivePredict alias, simplifying
that block's guard from "(PERF_COUNTERS && PRUNE_VERIFY) || PRUNE_LIVE"
to just "PRUNE_LIVE"); the COUNTERS and g_Options struct fields in
chess.h (u64PruneVerifyTries/FailHigh/MarginSum/PredSum/Dyn/DynMiss)
and PRUNE_VERIFY_BANDS/SHIP_DEPTH_BUCKETS (the latter was only ever
used by PRUNE_VERIFY code); root.c's dead counter copies; script.c's
report-printing block and SHIP_DEPTH_BUCKETS-sized suite-total fields;
GNUmakefile's flag wiring (left a comment explaining the removal).
Found while scoping the PRUNE_LIVE guard above: PRUNE_LIVE is ALSO
currently broken (separate, pre-existing, unrelated bug) --
PruneVerifyPredict (search.c) returns g_uJointFHThousandths[...]'s
element type as ULONG, but that array is declared USHORT in data.c,
producing an "incompatible pointer to integer conversion" error under
-DPRUNE_LIVE=<K>. Confirmed pre-existing (reproduces identically with
this commit reverted). Not fixed here -- out of scope, nobody's asked
to touch PRUNE_LIVE, flagging for awareness only.
Verified: standard profile (GENETIC=1 PERF_COUNTERS=1 MP=1 SIXTYFOUR=1)
builds clean, precommit_check.sh passes (TEST=1 self-test + DEBUG
smoke test). PRUNE_LIVE's build was already broken before this commit
and remains identically broken after (confirmed via git stash).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/search.c')
| -rw-r--r-- | src/search.c | 149 |
1 files changed, 2 insertions, 147 deletions
diff --git a/src/search.c b/src/search.c index d0d67b9..7c623fe 100644 --- a/src/search.c +++ b/src/search.c @@ -108,30 +108,10 @@ extern FLAG g_fCanSplit[MAX_PLY_PER_SEARCH]; // from here unchanged in behavior, just by their new (un-underscored) // public names. -#if (defined(PERF_COUNTERS) && defined(PRUNE_VERIFY)) || defined(PRUNE_LIVE) -// Band a deep-prune candidate by the predicted FH% the decision was -// made on (thousandths of a percent; post-Wilson-re-bake that value -// already encodes the cell's own sample confidence -- data.c header). -// Banding by the decision variable is what lets one run answer "is -// 'prune if predicted <= K' sound" for every candidate K at once. -#if defined(PERF_COUNTERS) && defined(PRUNE_VERIFY) -static ULONG -PruneVerifyBand(ULONG uPredicted) -{ - if (uPredicted == 0) return 0; - if (uPredicted == 1) return 1; - if (uPredicted == 2) return 2; - if (uPredicted <= 5) return 3; - if (uPredicted <= 10) return 4; - if (uPredicted <= 50) return 5; - if (uPredicted <= 500) return 6; - return 7; -} -#endif - +#ifdef PRUNE_LIVE // Mirror of searchsup.c's file-static _ShipDepthBucket. Duplicated // rather than exported because this is calibration-only code that -// should leave no trace in a normal build; if PRUNE_VERIFY ever +// should leave no trace in a normal build; if PRUNE_LIVE ever // graduates to something permanent, hoist the real one into chess.h // instead of keeping two copies. static ULONG @@ -157,35 +137,6 @@ ShipLateBucketPublic(ULONG uRawLateBucket) // below -- no local mirror, unlike ShipDepthBucketPublic/ // ShipLateBucketPublic above, which really do need file-local // standalone copies (see that function's own note on why). -// Local mirrors of searchsup.c's file-static AttemptsBucket/RateBucket -// (calibration-only; see ShipDepthBucketPublic's note on duplication). -#if defined(PERF_COUNTERS) && defined(PRUNE_VERIFY) -static ULONG -PvAttBucket(ULONG uAttempts) -{ - if (0 == uAttempts) return 0; - if (1 == uAttempts) return 1; - if (2 == uAttempts) return 2; - if (uAttempts <= 4) return 3; - if (uAttempts <= 9) return 4; - if (uAttempts <= 24) return 5; - if (uAttempts <= 99) return 6; - return 7; -} - -static ULONG -PvRateBucket(ULONG uPct) -{ - if (0 == uPct) return 0; - if (uPct <= 100) return 1; - if (uPct <= 400) return 2; - if (uPct <= 900) return 3; - if (uPct <= 1900) return 4; - if (uPct <= 4900) return 5; - if (uPct <= 9900) return 6; - return 7; -} -#endif #define PRUNE_LIVE_SENTINEL JOINT_TABLE_SENTINEL_PUBLIC #define PruneLivePredict PruneVerifyPredict @@ -1573,102 +1524,6 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, } } #endif -#if defined(PERF_COUNTERS) && defined(PRUNE_VERIFY) - // The audited move has now had its ordinary search. If - // it failed high, the deep-prune gate would have thrown - // away a move that actually raised beta -- a silent - // miss, attributed to the band/depth the decision was - // made in. The margin is accumulated so that - // boundary-noise clears (a score that only just beats a - // tight inherited PVS window, JOINT_EXTRA_VERIFY's - // documented false-positive class) can be separated - // from real misses afterwards rather than hand-traced. - if (TRUE == fVerifyFlagged) - { - if (iScore >= iBeta) - { - INC(ctx->sCounters.tree.u64PruneVerifyFailHigh - [uVerifyBand][uVerifyDepthB]); - if (uVerifyBand <= 4) - { - INC(ctx->sCounters.tree.u64PruneVerifyDynMiss - [uVerifyAttB][uVerifyRateB]); - } - ctx->sCounters.tree.u64PruneVerifyMarginSum - [uVerifyBand][uVerifyDepthB] += - (UINT64)(iScore - iBeta); -#ifdef SILENT_MISS_TRACE - // pos is the POST-move position here (UnmakeMove - // has not run yet) -- same convention as the - // JOINT_EXTRA_VERIFY trace above. - // 2026-10-03: log the DYNAMIC signals alongside - // the static prediction, so a real miss can be - // interrogated for "what would have saved us, and - // at what threshold". Motivated by the band-0 - // miss at - // 6k1/p4p1p/3p2q1/2p1rP2/2P3p1/P7/1P1Qn1PK/3R1R2, - // Qg6 -- a move whose queen only LOOKS hung - // (White is losing too badly to take it; best - // line grabs the e2 knight and White is -14 at - // depth 19), i.e. a genuine structural - // mispredict of the dumbness axis, which no - // amount of sampling conservatism in the static - // table can catch. - // - // fhpct/fhatt: this exact move identity's own - // observed rate and sample count - // (GetMoveFailHighPctThousandths) -- answers - // "what GetMoveFailHigh threshold would have - // vetoed this". - // cm: countermove-table level -- 0 none, 1 slot - // 0 match, 2 slot 1 match, against the move - // played two plies back (the index - // generate.c's _ScoreAllMoves uses). - // hist/cont: accumulated history and - // continuation-history evidence for this - // [piece][to]. - // killer: 1 if this ply's killer, 2 if ply-3's. - { - ULONG uDynAtt = 0; - ULONG uDynPct = GetMoveFailHighPctThousandths(mv, &uDynAtt); - ULONG uCmLevel = 0; - ULONG uHist = g_HistoryCounters[mv.pMoved][mv.cTo]; - ULONG uKiller = 0; - - if (ctx->uPly >= 2) - { - MOVE mvPrev = ctx->sPlyInfo[ctx->uPly - 2].mv; - if (0 != mvPrev.uMove) - { - ULONG uCi = MOVE_TO_INDEX(mvPrev); - if (IS_SAME_MOVE(mv, ctx->mvCounter[uCi][0])) uCmLevel = 1; - else if (IS_SAME_MOVE(mv, ctx->mvCounter[uCi][1])) uCmLevel = 2; - } - } - if (IS_SAME_MOVE(mv, ctx->mvKiller[ctx->uPly-1][0]) || - IS_SAME_MOVE(mv, ctx->mvKiller[ctx->uPly-1][1])) - { - uKiller = 1; - } - else if ((ctx->uPly >= 3) && - (IS_SAME_MOVE(mv, ctx->mvKiller[ctx->uPly-3][0]) || - IS_SAME_MOVE(mv, ctx->mvKiller[ctx->uPly-3][1]))) - { - uKiller = 2; - } - Trace("PRUNEMISS pred=%u band=%u depthb=%u " - "alpha=%d beta=%d score=%d margin=%d " - "fhpct=%u fhatt=%u cm=%u hist=%u killer=%u " - "mv=%s postfen=%s\n", - uVerifyPred, uVerifyBand, uVerifyDepthB, - iAlpha, iBeta, iScore, (iScore - iBeta), - uDynPct, uDynAtt, uCmLevel, uHist, uKiller, - MoveToIcs(mv), PositionToFen(pos)); - } -#endif - } - } -#endif UnmakeMove(ctx, mv); pf->iCumulativeExtend -= iExtend; ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); |
