summaryrefslogtreecommitdiff
path: root/src/evalhash.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-08-27 13:13:08 -0700
committerScott Gasch <[email protected]>2026-08-27 13:13:08 -0700
commit2c44820a5cd952f3596dc34095a653cf461daef7 (patch)
treeabed39ed47f1c7be4aae3689bec7dbb6b7bd55b9 /src/evalhash.c
parent489915f4c98c7aca3a63c0f35b83929e8331a597 (diff)
Remove ctx->uPositional and the EVAL_HASH subsystem; fix GetRoughEvalScore.
Finishes work left half-done in 7857096 ("Replace ctx->uPositional with a data-calibrated Eval() return value"): that commit added Eval()'s new piPositional out-param but never migrated GetRoughEvalScore onto it, so GetRoughEvalScore's mid/deep-tree fallback kept reading the old ctx->uPositional field -- a per-thread EWMA written only on full-eval calls and never touched by the (far more common) lazy-eval path, so it carried a stale value from whatever unrelated position last triggered a full eval, potentially many nodes/plies away. Combined with EVAL_HASH being long since disabled (its probe branch already dead), every GetRoughEvalScore call past ply 4 was effectively "material + garbage." Fixed by having GetRoughEvalScore just call Eval() directly -- its own lazy-exit machinery already is the cheap, calibrated estimate this function exists to provide, so there's no separate estimator to maintain. Removed ctx->uPositional entirely (struct field, its EWMA update in eval.c, both root.c init sites, split.c's cross-split propagation, testeval.c's reset) along with the entire EVAL_HASH subsystem (struct, table, Probe/StoreEvalHash, main.c's now-dead reporting branch, the GNUmakefile flag) -- confirmed unused elsewhere and explicitly being cut for good, not coming back in this form. Also fixed GetRoughEvalScore's prototype being wrongly declared inside #ifdef EVAL_HASH in chess.h even though the function itself is defined and called unconditionally -- this was the source of the recurring "call to undeclared function 'GetRoughEvalScore'" implicit-declaration warning seen throughout this session's builds. Separately, fixed QSearch to match its own documented intent: the en-prise/trapped-piece "don't let this side stand pat" check now only fires if the side hasn't already been allowed to stand pat earlier in this qsearch line (matching the comment above it, which already said this but the code never implemented it). Verified against baseline/typhoon_baseline (pristine, pre-session) on ecm_ringers.ep_ (4), ecm_hard_quick.ep_ (50-sample), and ecm_confident_quick.ep_ (40) at sn=5M, --cpus 1, book disabled: pristine baseline solves 3/50 on the hard sample; this commit solves 6/50, with the stand-pat fix and GetRoughEvalScore fix each contributing +1 independently confirmed. No regressions on the other two suites (4/4 and 40/40 unchanged throughout). Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YGSMkwjqiCk4XhbfN7ugD2
Diffstat (limited to 'src/evalhash.c')
-rw-r--r--src/evalhash.c173
1 files changed, 16 insertions, 157 deletions
diff --git a/src/evalhash.c b/src/evalhash.c
index fc29b88..4df6e23 100644
--- a/src/evalhash.c
+++ b/src/evalhash.c
@@ -8,7 +8,11 @@ Module Name:
Abstract:
- Evaluation score hashing code.
+ Rough (mid-tree) eval estimation. Used to hold the eval-score
+ hashing code (EVAL_HASH) too; that subsystem was cut for good
+ (measured as slow as or slower than just computing eval) and is
+ not coming back in this form, so this file is now just
+ GetRoughEvalScore().
Author:
@@ -20,8 +24,6 @@ Revision History:
#include "chess.h"
-extern ULONG g_uIterateDepth;
-
SCORE
GetRoughEvalScore(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
IN SCORE iAlpha,
@@ -34,23 +36,22 @@ Routine description:
This is meant to be the "one place" that code looks when it needs to
get an idea of the estimated evaluation of a position (in mid tree,
not at the leaves... at the leaves just call Eval directly).
-
- The thought is that:
-
- 1. The top of the tree (near the root) represents very few nodes
- which have big subtrees. Use the real Eval here.
-
- 2. Otherwise possibly probe the eval hash -- if there's a score in
- it then we can return quickly.
-
- 3. Otherwise do a (very) rough material estimate.
+
+ Just calls Eval() -- its own lazy-exit machinery already is the
+ cheap, calibrated estimate this function exists to provide, so
+ there's no separate "rough" estimator to maintain here. Used to
+ fall back to material + a stale ctx->uPositional EWMA left over
+ from whatever full eval last ran anywhere in the tree, fed by an
+ eval-hash probe (fUseHash); both are gone now (see the commit
+ removing ctx->uPositional and EVAL_HASH), and this is the direct
+ replacement.
Parameters:
IN OUT SEARCHER_THREAD_CONTEXT *ctx,
IN SCORE iAlpha,
IN SCORE iBeta,
- IN FLAG fUseHash
+ IN FLAG fUseHash : unused, kept for call-site compatibility
Return value:
@@ -58,148 +59,6 @@ Return value:
--*/
{
- POSITION *pos = &(ctx->sPosition);
- UINT64 u64Key;
- ULONG u;
-
- if (ctx->uPly <= 4)
- {
- return Eval(ctx, iAlpha, iBeta, NULL);
- }
-#ifdef EVAL_HASH
- else if ((fUseHash) || (ctx->uPly <= (g_uIterateDepth / 2)))
- {
- u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig);
- u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1);
- if (ctx->rgEvalHash[u].u64Key == u64Key)
- {
- switch(ctx->rgEvalHash[u].bvFlags)
- {
- case EVAL_HASH_EXACT:
- ctx->uPositional = ctx->rgEvalHash[u].uPositional;
- return(ctx->rgEvalHash[u].iEval);
- case EVAL_HASH_UPPER:
- if (ctx->rgEvalHash[u].iBound <= iAlpha)
- {
- return(ctx->rgEvalHash[u].iEval);
- }
- break;
- case EVAL_HASH_LOWER:
- if (ctx->rgEvalHash[u].iBound >= iBeta)
- {
- return(ctx->rgEvalHash[u].iEval);
- }
- break;
- }
- }
- }
-#else
- (void)u64Key;
- (void)u;
(void)fUseHash;
-#endif
- return(pos->iMaterialBalance[pos->uToMove] + ctx->uPositional);
-}
-
-#ifdef EVAL_HASH
-
-
-SCORE
-ProbeEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx, IN SCORE iAlpha, IN SCORE iBeta)
-/*++
-
-Routine description:
-
- Probe the eval hash; return a real score if there's a hit
- otherwise return INVALID_SCORE. An EXACT entry is always usable.
- An UPPER/LOWER entry (recorded from a lazy-eval early exit) is
- only usable if the bound it proved still resolves the caller's
- current alpha/beta window; otherwise it's treated as a miss and
- the caller must actually compute something.
-
-Parameters:
-
- IN OUT SEARCHER_THREAD_CONTEXT *ctx : note that in the case
- of a hit, *ctx is modified also.
- IN SCORE iAlpha, IN SCORE iBeta : caller's current window
-
-Return value:
-
- SCORE
-
---*/
-{
- POSITION *pos = &(ctx->sPosition);
- UINT64 u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig);
- ULONG u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1);
-
- if (ctx->rgEvalHash[u].u64Key == u64Key)
- {
- switch(ctx->rgEvalHash[u].bvFlags)
- {
- case EVAL_HASH_EXACT:
- ctx->uPositional = ctx->rgEvalHash[u].uPositional;
- pos->cTrapped[WHITE] = ctx->rgEvalHash[u].cTrapped[WHITE];
- pos->cTrapped[BLACK] = ctx->rgEvalHash[u].cTrapped[BLACK];
- return(ctx->rgEvalHash[u].iEval);
- case EVAL_HASH_UPPER:
- if (ctx->rgEvalHash[u].iBound <= iAlpha)
- {
- return(ctx->rgEvalHash[u].iEval);
- }
- break;
- case EVAL_HASH_LOWER:
- if (ctx->rgEvalHash[u].iBound >= iBeta)
- {
- return(ctx->rgEvalHash[u].iEval);
- }
- break;
- }
- }
- return(INVALID_SCORE);
-}
-
-void
-StoreEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
- IN SCORE iScore,
- IN SCORE iBound,
- IN UCHAR bvFlags)
-/*++
-
-Routine description:
-
- Store a score in the eval hash table (which is pointed to
- indirectly via ctx). bvFlags is EVAL_HASH_EXACT for a fully
- computed eval (iBound ignored) or EVAL_HASH_UPPER/EVAL_HASH_LOWER
- for a bound proven by a lazy-eval early exit (iScore is the
- uncorrected partial score that would be returned, iBound is the
- proven bound on the true eval).
-
-Parameters:
-
- SEARCHER_THREAD_CONTEXT *ctx,
- SCORE iScore,
- SCORE iBound,
- UCHAR bvFlags
-
-Return value:
-
- void
-
---*/
-{
- POSITION *pos = &(ctx->sPosition);
- UINT64 u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig);
- ULONG u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1);
- ctx->rgEvalHash[u].u64Key = u64Key;
- ctx->rgEvalHash[u].iEval = iScore;
- ctx->rgEvalHash[u].iBound = iBound;
- ctx->rgEvalHash[u].bvFlags = bvFlags;
- if (bvFlags == EVAL_HASH_EXACT)
- {
- ctx->rgEvalHash[u].uPositional = ctx->uPositional;
- ctx->rgEvalHash[u].cTrapped[WHITE] = pos->cTrapped[WHITE];
- ctx->rgEvalHash[u].cTrapped[BLACK] = pos->cTrapped[BLACK];
- }
+ return Eval(ctx, iAlpha, iBeta, NULL);
}
-#endif // EVAL_HASH