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 | |
| 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')
| -rw-r--r-- | src/GNUmakefile | 21 | ||||
| -rwxr-xr-x | src/chess.h | 90 | ||||
| -rw-r--r-- | src/root.c | 14 | ||||
| -rw-r--r-- | src/script.c | 122 | ||||
| -rw-r--r-- | src/search.c | 149 |
5 files changed, 8 insertions, 388 deletions
diff --git a/src/GNUmakefile b/src/GNUmakefile index 2cd1462..c625fa6 100644 --- a/src/GNUmakefile +++ b/src/GNUmakefile @@ -246,21 +246,12 @@ endif # u64JointExtraVerifyNullBailoutSignature), once WITH it for the # corrected rate. # 2026-10-03: PRUNE_VERIFY -- shadow verification for the DEEP PRUNE gate -# (ShouldLatePrune), the question JOINT_EXTRA_VERIFY structurally cannot -# answer: "this move was about to be skipped ENTIRELY -- would searching -# it have failed high?" AUDIT-ONLY by construction: the gate runs, its -# verdict is recorded, and the move is then searched anyway, so the -# measurement needs no bespoke shadow Search() call and has no -# null-move-bailout exposure. Costs counter increments plus one extra -# ShouldLatePrune evaluation per eligible move; never part of a normal -# build. Pair with SILENT_MISS_TRACE to get a PRUNEMISS line (FEN, move, -# alpha/beta, predicted FH, margin) for every miss found, for direct -# manual investigation -- SPEC.md's agreed design requirement that any -# wrong guess gets looked at and reasoned about, not just counted. -# Requires PERF_COUNTERS. -ifdef PRUNE_VERIFY -PROFILE += -DPRUNE_VERIFY -endif +# (ShouldLatePrune) was removed (2026-10-14): it never actually compiled +# (fVerifyFlagged/uVerifyBand/etc. were used in search.c but never +# declared -- PRUNE_VERIFY is never defined by any path in this file, so +# nothing ever caught it). Dead, broken code, not a working diagnostic; +# removed rather than fixed since reconstructing its intended semantics +# from scratch would be inventing behavior, not restoring it. # 2026-10-03: PRUNE_LIVE=<K> -- actually prune any gate-1-eligible move # whose 4D-table predicted FH% (Wilson upper bound, see data.c) is <= K diff --git a/src/chess.h b/src/chess.h index 36b90e3..ec912a2 100755 --- a/src/chess.h +++ b/src/chess.h @@ -1078,47 +1078,6 @@ MOVE_STACK; // to a formula that might grow later. #define NULL_R_BUCKETS (12) -// 2026-10-03: PRUNE_VERIFY (GNUmakefile) -- shadow verification for the -// DEEP PRUNE gate (ShouldLatePrune), answering a question the LMR-side -// JOINT_EXTRA_VERIFY cannot: "this move was about to be skipped -// ENTIRELY -- would searching it have failed high?" A reduction leaves a -// score behind that can be sanity-checked; a prune leaves nothing, so -// there is no signal at all unless we deliberately decline to prune and -// watch what the move does. -// -// Deliberately AUDIT-ONLY: the gate is evaluated, the verdict is -// recorded, and then the move is searched normally anyway. That means -// NO bespoke shadow Search() call is needed -- the move's own ordinary -// search answers "did it fail high", with the real move loop's -// re-search wrapper intact. That sidesteps the null-move-bailout -// fabrication (searchsup.c's Tord Romstad branch) that made -// JOINT_EXTRA_VERIFY's first numbers 80-99.8% measurement artifact and -// needed NEUTRALIZE_NULL_BAILOUT to fix. Nothing here fabricates a -// score, so nothing here can misread one. -// -// Known, accepted under-detection: an audited move is still subject to -// LMR, so a fail-high that only a FULL-depth search would have found -// can be missed. The existing re-search-on-fail-high path catches the -// common case, and JOINT_EXTRA_VERIFY measured the residual silent-miss -// rate at ~0.00056% once measured correctly -- negligible against the -// prune miss rates this is built to detect. -// -// Bands are the table's own predicted-FH value (thousandths of a -// percent, post-Wilson-re-bake so the value already encodes the cell's -// sample confidence -- see data.c's header). Indexed by band because -// the decision this validates is literally "prune if predicted <= K", -// so band-resolution answers "is the rule sound at threshold K" for -// every candidate K at once. Depth is carried alongside because the -// COST of a wrong prune scales with remaining depth even where the rate -// does not. -// Shipped depth dimension of g_uJointFHThousandths (data.c declares it -// as [12][11][11][16][11], including the 5th/improve axis; the 12 is -// _ShipDepthBucket's range). -#define SHIP_DEPTH_BUCKETS (12) -#define PRUNE_VERIFY_BANDS (8) -// band edges, predicted FH in thousandths of a percent: -// 0: ==0 1: 1 2: 2 3: 3-5 4: 6-10 5: 11-50 6: 51-500 7: >500 - // 2026-09-28: JOINT_EXTRA_VERIFY silent-miss calibration, bucketed by // how much remaining depth the FULLY-reduced (base + extra) search @@ -1274,47 +1233,6 @@ typedef struct _COUNTERS // clamped to NULL_R_BUCKETS - 1. UINT64 u64NullMoveTriesByR[NULL_R_BUCKETS]; UINT64 u64NullMoveSuccessByR[NULL_R_BUCKETS]; -#ifdef PRUNE_VERIFY - // [predicted-FH band][shipped depth bucket] -- see - // PRUNE_VERIFY_BANDS above. Tries = moves the deep-prune gate - // said to skip; FailHigh = how many of those then actually - // raised beta when searched anyway (a silent miss the gate - // would have caused). Margin = how far past beta it cleared, - // summed, so narrow-window boundary noise (JOINT_EXTRA_VERIFY's - // documented false-positive class: a score clearing a tight - // inherited PVS window proves only that, not that the move is - // good) can be separated from real misses post-hoc instead of - // hand-traced one at a time. - UINT64 u64PruneVerifyTries[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64PruneVerifyFailHigh[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64PruneVerifyMarginSum[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - // Volume-weighted sum of the PREDICTED rate over exactly the - // flagged population. The calibration check is measured-vs-this, - // NOT measured-vs-threshold: a threshold is a ceiling on what - // gets flagged, not the typical value of what actually does, and - // SPEC.md records getting that wrong once already. - UINT64 u64PruneVerifyPredSum[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - // Cost/benefit cross-tab for a DYNAMIC veto layered on the - // static gate, prunable bands only (predicted <= 10). Indexed - // [attempts band][own-FH-rate band] per searchsup.c's - // AttemptsBucket/RateBucket. Dyn = every flagged move; - // DynMiss = the subset that actually failed high. Together they - // give, for any candidate rule "refuse when attempts >= A and - // rate > B": how many REAL misses it catches, and how many - // sound prunes it costs. The second number is what matters -- - // the GetMoveFailHighPercentage veto was retired last time - // because it vetoed 70-80% of candidates for zero node savings. - UINT64 u64PruneVerifyDyn[8][8]; - UINT64 u64PruneVerifyDynMiss[8][8]; -#endif - - // above -- settles whether elevated per-move-identity rates - // (5-100 thousandths) are concentrated at low attempts - // (sampling noise around the real 0.400% population average) - // or spread across high attempts too (a real, well-evidenced - // elevated rate, which the sampling-noise theory would NOT - // predict). AttemptsBucket/RateBucket (searchsup.c) define - // the 8 bands each axis uses. #ifdef JOINT_EXTRA_VERIFY // Full-coverage shadow-search "silent miss" calibration -- see // GNUmakefile's JOINT_EXTRA_VERIFY comment. Tries = extra- @@ -2077,14 +1995,6 @@ typedef struct _GAME_OPTIONS UINT64 u64LMPPruned; UINT64 u64NullMoveTriesByR[NULL_R_BUCKETS]; UINT64 u64NullMoveSuccessByR[NULL_R_BUCKETS]; -#ifdef PRUNE_VERIFY - UINT64 u64PruneVerifyTries[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64PruneVerifyFailHigh[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64PruneVerifyMarginSum[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64PruneVerifyPredSum[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64PruneVerifyDyn[8][8]; - UINT64 u64PruneVerifyDynMiss[8][8]; -#endif #ifdef JOINT_EXTRA_VERIFY UINT64 u64JointExtraVerifyTries[JOINT_EXTRA_TIER_COUNT][POST_REDUCE_DEPTH_BUCKETS]; UINT64 u64JointExtraVerifySilentMiss[JOINT_EXTRA_TIER_COUNT][POST_REDUCE_DEPTH_BUCKETS]; @@ -1597,20 +1597,6 @@ Return value: sizeof(g_Options.u64NullMoveTriesByR)); memcpy(g_Options.u64NullMoveSuccessByR, ctx->sCounters.tree.u64NullMoveSuccessByR, sizeof(g_Options.u64NullMoveSuccessByR)); -#ifdef PRUNE_VERIFY - memcpy(g_Options.u64PruneVerifyTries, ctx->sCounters.tree.u64PruneVerifyTries, - sizeof(g_Options.u64PruneVerifyTries)); - memcpy(g_Options.u64PruneVerifyFailHigh, ctx->sCounters.tree.u64PruneVerifyFailHigh, - sizeof(g_Options.u64PruneVerifyFailHigh)); - memcpy(g_Options.u64PruneVerifyMarginSum, ctx->sCounters.tree.u64PruneVerifyMarginSum, - sizeof(g_Options.u64PruneVerifyMarginSum)); - memcpy(g_Options.u64PruneVerifyPredSum, ctx->sCounters.tree.u64PruneVerifyPredSum, - sizeof(g_Options.u64PruneVerifyPredSum)); - memcpy(g_Options.u64PruneVerifyDyn, ctx->sCounters.tree.u64PruneVerifyDyn, - sizeof(g_Options.u64PruneVerifyDyn)); - memcpy(g_Options.u64PruneVerifyDynMiss, ctx->sCounters.tree.u64PruneVerifyDynMiss, - sizeof(g_Options.u64PruneVerifyDynMiss)); -#endif #ifdef JOINT_EXTRA_VERIFY memcpy(g_Options.u64JointExtraVerifyTries, ctx->sCounters.tree.u64JointExtraVerifyTries, sizeof(g_Options.u64JointExtraVerifyTries)); diff --git a/src/script.c b/src/script.c index 219825c..7286d17 100644 --- a/src/script.c +++ b/src/script.c @@ -97,14 +97,6 @@ typedef struct _SUITE_COUNTERS UINT64 u64TotalJointExtraTries[JOINT_EXTRA_TIER_COUNT]; UINT64 u64TotalJointExtraResearch[JOINT_EXTRA_TIER_COUNT]; UINT64 u64TotalLMPPruned; -#ifdef PRUNE_VERIFY - UINT64 u64TotalPruneVerifyTries[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64TotalPruneVerifyFailHigh[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64TotalPruneVerifyMarginSum[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64TotalPruneVerifyPredSum[PRUNE_VERIFY_BANDS][SHIP_DEPTH_BUCKETS]; - UINT64 u64TotalPruneVerifyDyn[8][8]; - UINT64 u64TotalPruneVerifyDynMiss[8][8]; -#endif #ifdef JOINT_EXTRA_VERIFY UINT64 u64TotalJointExtraVerifyTries[JOINT_EXTRA_TIER_COUNT][POST_REDUCE_DEPTH_BUCKETS]; UINT64 u64TotalJointExtraVerifySilentMiss[JOINT_EXTRA_TIER_COUNT][POST_REDUCE_DEPTH_BUCKETS]; @@ -514,35 +506,6 @@ _ProcessSuiteLine(char *szLine, POSITION *pos) } g_SuiteCounters.u64TotalLMPPruned += g_Options.u64LMPPruned; - #ifdef PRUNE_VERIFY - { - ULONG w; - for (v = 0; v < PRUNE_VERIFY_BANDS; v++) - { - for (w = 0; w < SHIP_DEPTH_BUCKETS; w++) - { - g_SuiteCounters.u64TotalPruneVerifyTries[v][w] += - g_Options.u64PruneVerifyTries[v][w]; - g_SuiteCounters.u64TotalPruneVerifyFailHigh[v][w] += - g_Options.u64PruneVerifyFailHigh[v][w]; - g_SuiteCounters.u64TotalPruneVerifyMarginSum[v][w] += - g_Options.u64PruneVerifyMarginSum[v][w]; - g_SuiteCounters.u64TotalPruneVerifyPredSum[v][w] += - g_Options.u64PruneVerifyPredSum[v][w]; - } - } - for (v = 0; v < 8; v++) - { - for (w = 0; w < 8; w++) - { - g_SuiteCounters.u64TotalPruneVerifyDyn[v][w] += - g_Options.u64PruneVerifyDyn[v][w]; - g_SuiteCounters.u64TotalPruneVerifyDynMiss[v][w] += - g_Options.u64PruneVerifyDynMiss[v][w]; - } - } - } -#endif #ifdef JOINT_EXTRA_VERIFY { ULONG w; @@ -831,91 +794,6 @@ _PrintSuiteReport(double dSuiteStart) ((double)g_SuiteCounters.u64TotalJointExtraTries[v] + 1.0)), g_SuiteCounters.u64TotalJointExtraTries[v]); } -#ifdef PRUNE_VERIFY - // See chess.h's PRUNE_VERIFY comment. The calibration test is - // MEASURED vs PREDICTED on exactly the flagged population -- - // never measured-vs-threshold, which is a ceiling on what gets - // flagged rather than the typical value of what does (SPEC.md - // records getting that wrong once). A band whose measured rate - // tracks its predicted rate is a band the gate can be trusted - // in; one where measured >> predicted is model error localized - // there, which no amount of Wilson/sampling conservatism fixes. - { - static const char *szBand[PRUNE_VERIFY_BANDS] = - { "==0", "1", "2", "3-5", "6-10", "11-50", "51-500", ">500" }; - ULONG w; - Trace("\ndeep-prune shadow verification (AUDIT ONLY -- nothing " - "was actually pruned):\n"); - Trace(" predFH flagged actual-FH measured%% " - "predicted%% mean-margin\n"); - for (v = 0; v < PRUNE_VERIFY_BANDS; v++) - { - UINT64 u64T = 0, u64F = 0, u64M = 0, u64P = 0; - for (w = 0; w < SHIP_DEPTH_BUCKETS; w++) - { - u64T += g_SuiteCounters.u64TotalPruneVerifyTries[v][w]; - u64F += g_SuiteCounters.u64TotalPruneVerifyFailHigh[v][w]; - u64M += g_SuiteCounters.u64TotalPruneVerifyMarginSum[v][w]; - u64P += g_SuiteCounters.u64TotalPruneVerifyPredSum[v][w]; - } - if (0 == u64T) continue; - Trace(" %-8s %10" COMPILER_LONGLONG_UNSIGNED_FORMAT - " %10" COMPILER_LONGLONG_UNSIGNED_FORMAT - " %8.5f%% %8.5f%% %10.1f\n", - szBand[v], u64T, u64F, - 100.0 * (double)u64F / (double)u64T, - ((double)u64P / (double)u64T) / 1000.0, - u64F ? (double)u64M / (double)u64F : 0.0); - } - Trace(" (by remaining-depth bucket, flagged/actual-FH -- the COST " - "of a wrong\n prune scales with depth even where the RATE " - "does not)\n"); - for (w = 0; w < SHIP_DEPTH_BUCKETS; w++) - { - UINT64 u64T = 0, u64F = 0; - for (v = 0; v < PRUNE_VERIFY_BANDS; v++) - { - u64T += g_SuiteCounters.u64TotalPruneVerifyTries[v][w]; - u64F += g_SuiteCounters.u64TotalPruneVerifyFailHigh[v][w]; - } - if (0 == u64T) continue; - Trace(" depth bucket %2u: %10" COMPILER_LONGLONG_UNSIGNED_FORMAT - " / %" COMPILER_LONGLONG_UNSIGNED_FORMAT - " (%7.5f%%)\n", w, u64T, u64F, - 100.0 * (double)u64F / (double)u64T); - } - // Dynamic-veto cost/benefit, prunable bands only. For any - // rule "refuse when attempts >= A and rate > B", sum the - // Dyn cells it covers (sound prunes lost) against the - // DynMiss cells (real misses caught). - { - static const char *szA[8] = - { "0", "1", "2", "3-4", "5-9", "10-24", "25-99", "100+" }; - ULONG u; - Trace("\n dynamic signals over PRUNABLE-band candidates " - "(flagged / of-those-missed),\n rows = own-FH attempts, " - "cols = own-FH rate in thousandths of a percent:\n"); - Trace(" attempts 0 1-100 101-400 401-900 " - "901-1900 1901-4900 4901-9900 9901+\n"); - for (u = 0; u < 8; u++) - { - UINT64 u64RowT = 0; - for (v = 0; v < 8; v++) - u64RowT += g_SuiteCounters.u64TotalPruneVerifyDyn[u][v]; - if (0 == u64RowT) continue; - Trace(" %-8s", szA[u]); - for (v = 0; v < 8; v++) - { - Trace(" %7" COMPILER_LONGLONG_UNSIGNED_FORMAT - "/%-2" COMPILER_LONGLONG_UNSIGNED_FORMAT, - g_SuiteCounters.u64TotalPruneVerifyDyn[u][v], - g_SuiteCounters.u64TotalPruneVerifyDynMiss[u][v]); - } - Trace("\n"); - } - } - } -#endif Trace("\nlate-move pruning (overt skip, not reduction): %" COMPILER_LONGLONG_UNSIGNED_FORMAT " moves pruned\n", g_SuiteCounters.u64TotalLMPPruned); 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)); |
