diff options
| author | Scott Gasch <[email protected]> | 2026-10-24 09:07:03 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-10-24 09:07:03 -0700 |
| commit | 5f901d737b17c5f99b6e456d6c0c7d5e3c093dc4 (patch) | |
| tree | 6601dadbd36c8f45991c5dd821a3dbb2059baafe /src/docs/TREEDUMP_FORMAT.md | |
| parent | 69525eb2f42ea9cca8255f6cc3b85e6b1312fd05 (diff) | |
More aggressive move reductions; Wilson bound overrides static signal when available
SPRT playtest (2000 games, sd/depth matched): -535 =875 +590, score=0.514,
llr=+1.04 (floated around +1.0 the whole run, never went negative) toward
H1=+2.94. Not a confirmed win, but searches meaningfully deeper (avg depth
14.35 vs 13.50, EBF 3.131 vs 3.305) at no measurable strength cost -- worth
banking and continuing to accumulate games against.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/docs/TREEDUMP_FORMAT.md')
| -rw-r--r-- | src/docs/TREEDUMP_FORMAT.md | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/docs/TREEDUMP_FORMAT.md b/src/docs/TREEDUMP_FORMAT.md index ecc4325..47d1a82 100644 --- a/src/docs/TREEDUMP_FORMAT.md +++ b/src/docs/TREEDUMP_FORMAT.md @@ -66,6 +66,101 @@ redirecting from a real tty) never hits this, which is why it's easy to not reproduce it while debugging interactively and then hit it again the next time a script pipes input in. +**Future-work idea, not yet built**: a small purpose-written xboard<->UCI +driver (distinct from `stockfish_xboard`, which hardcodes +`/usr/local/bin/stockfish` via PolyGlot for `match_play.py`'s xboard-only +engine pool, not this instrumented source build) would let this +TREEDUMP-build Stockfish be driven with the same `--batch --command`-style +invocation already used for typhoon and Crafty, sidestepping the +stdin-race gotcha entirely rather than working around it with `sleep`. +Worth doing if this three-engine TREEDUMP comparison becomes a repeated +workflow rather than a one-off batch. + +## Building a third engine: Crafty + +Crafty (`~/programming/chess/crafty-25.2`) also speaks this format now +(added 2026-10-23), giving a third data point alongside typhoon and +Stockfish -- useful specifically because Crafty's HCE is much "dumber" +than typhoon's NNUE, so if Crafty's pruning/reduction magnitudes still +line up with Stockfish's despite the weaker eval, that's a stronger +signal that the magnitude is calibration-driven (an engine-independent +"right amount") rather than an artifact of how strong the eval backing +the search happens to be. + +Crafty compiles everything into one translation unit (`crafty.c` +`#include`s every other `.c` file), so the `TREEDUMP` instrumentation +lives directly in `search.c` (new `TDOpen`/`TDClose`/`TDMove`/`TDResult` +functions, prototyped in `chess.h` behind `#if defined(TREEDUMP)`) rather +than needing a new source file. `main.c` opens `treedump.log` at process +start and registers `TDClose` via `atexit()` so it's closed on every exit +path, not just a clean `quit`. + +Build (single-threaded, matching typhoon's and Stockfish's TREEDUMP +convention -- `search.c`'s path-reconstruction helper assumes Crafty's +single-TREE-struct-per-thread model, where `tree->curmv[1..ply]` holds +every move played so far in *this* recursion; that invariant only holds +cleanly with one thread): + +```sh +cd ~/programming/chess/crafty-25.2 +rm -f *.o crafty +gmake target=UNIX CC=clang opt='-DSYZYGY -DCPUS=1 -DTREEDUMP' \ + CFLAGS='-Wall -Wno-array-bounds -pipe -O3 -mpopcnt' \ + LDFLAGS='-lstdc++ -lm' crafty-make +``` + +(`-j` can be dropped or kept; `crafty.o` depends on `*.c *.h` as one +glob so there's no partial-rebuild hazard the way Stockfish's +`EXTRACXXFLAGS` has -- no `touch` trick needed here. Rebuild the normal +multi-threaded profile afterward the same way the other two engines' +TREEDUMP builds get reverted: `rm -f *.o crafty && gmake target=UNIX +CC=clang opt='-DSYZYGY -DTEST -DCPUS=4' CFLAGS='-Wall -Wno-array-bounds +-pipe -O3 -mpopcnt -pthread' LDFLAGS='-pthread -lstdc++ -lm' +crafty-make` -- note the `-pthread` CFLAGS/LDFLAGS are required once +`CPUS` > 1, the TREEDUMP/`CPUS=1` build doesn't need them.) + +Crafty speaks xboard natively (no PolyGlot/UCI adapter needed, unlike +driving it through `stockfish_xboard`-style tooling), so it can be +driven the same way as typhoon's own `--batch --command` invocations: + +```sh +(printf 'force\nsetboard <FEN>\nsd 6\ngo\nquit\n'; sleep 2) | ./crafty +``` + +Hold stdin open past the search the same way Stockfish needs (see the +gotcha below) -- not yet confirmed whether Crafty has the identical +race, but cheap to guard against unconditionally rather than +re-discover it. + +**Mapped `act=` values**: `FP-QUIET` (Crafty's `FP_margin[]` futility +check -- note this is a **raw-material** check, +`MaterialSTM(wtm) + FP_margin[depth] <= alpha`, not a full static-eval +call the way typhoon's/Stockfish's futility-flavored checks are, so +don't read "FP-QUIET volume" as directly comparable cost between +engines even where the tag matches), `LMP` (pure move-count/depth +threshold, no evidence gate at all -- matches the `search.c` comment +block this investigation started from), `NMP` (null-move probe, `r` +left `0.00` same convention as typhoon), `FULL`/`LMR`/`EXT` (the main +move loop, after Crafty's own `reduce`/`extend` locals are resolved). +Crafty has no ProbCut and no IID-as-a-traced-decision (IID's recursive +call reuses the *same* ply rather than descending one, so it doesn't fit +the path model and isn't traced). + +**A Crafty-specific wrinkle worth remembering when reading a diff**: +Crafty's own `search.c` comment on this block (the one this +investigation started from) says forward pruning here "simply avoid[s] +searching this move at all, and skip[s] to the next move" -- but +functionally this is a `break`, not a `continue`: once FP or LMP fires on +one move, every *remaining* move at that node is abandoned too, not just +the one move. typhoon's and Stockfish's LMP-equivalents are evaluated +move-by-move (a `continue`, not a `break`) -- a given late move being +pruned doesn't prevent trying a later move that might not be. Don't read +Crafty's `act=LMP`/`act=FP-QUIET` *count* at a node as "N moves pruned +out of the move list" the way you might for the other two engines; it +usually means "the move list ended early starting here," which has a +different effect on tree shape (and EBF) than an equal count of +individually-pruned moves scattered across a wider move list. + ## Why path-keyed, not node-numbered Internal node counters are meaningless across two different engines -- |
