summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-10-14 12:16:43 -0700
committerScott Gasch <[email protected]>2026-10-14 12:16:43 -0700
commitac5cc078b71e94b21a8a843628045c745022aa75 (patch)
tree1633412357651cd94e34b50c74f23ff06608db7f
parent91f01c607338eabb10ae1f8c144be55071d174a5 (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]>
-rw-r--r--src/GNUmakefile21
-rwxr-xr-xsrc/chess.h90
-rw-r--r--src/root.c14
-rw-r--r--src/script.c122
-rw-r--r--src/search.c149
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];
diff --git a/src/root.c b/src/root.c
index 3ec1a9d..fda77d5 100644
--- a/src/root.c
+++ b/src/root.c
@@ -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));