diff options
| author | Scott Gasch <[email protected]> | 2026-10-15 16:26:09 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-10-15 16:26:09 -0700 |
| commit | 1ea81bae240912efb8cebabae35fe58bc5d12afb (patch) | |
| tree | e43b3bbb179601595a47f7c5c4661a297a8b4664 /src/board.c | |
| parent | 3d55dc94497661b1577109b42a94cc3dba1860fb (diff) | |
Wire NNUE eval into real search path; fix critical perf regression
Load-and-call infra: export_nnue_weights.py-produced weight files can
now be loaded at runtime (nnueeval.c's NnueLoadWeights, "nnue load"
command, --nnueweights CLI flag for scripted match-play), and the FC
head (NnueForward) runs the real forward pass against the live
accumulator.
Real integration: Eval() now short-circuits to NnueForward when
g_fUseNnueEval && g_fNnueWeightsLoaded, so ./typhoon can actually play
on the NNUE eval -- ./eval_tune/test_vs_head.sh works unmodified to
compare it against the old HCE. ReInitializeSearcherContext (root.c)
gained a defensive accumulator recompute hook covering setboard's
downstream effect on the next go/ponder; it only fires when both
kings are validly placed, since testrecogn.c's synthetic positions
don't always have one at the moment this is called.
Critical fix: the NNUE accumulator maintenance added to move.c's 8
primitives (and MakeMove/UnmakeMove's king-move backup/restore) was
running unconditionally, on the mistaken assumption this was cheap.
It cost ~50% of engine throughput even with NNUE off (673k nps
measured vs the expected 1.4-1.5M baseline). Gated all of it behind
g_fUseNnueEval; classic HCE is back to ~1.52M nps, NNUE eval runs at
a fair ~409k nps (expected for an unquantized float32 forward pass).
This gating also exposed that testnnue.c's TestNnueAccumulator never
set g_fUseNnueEval, so its own direct NnueAccumRecompute calls raced
ahead of now-gated-off incremental maintenance; fixed by having the
test set/restore the flag around its run.
board.c: added en passant legality check to IsBoardLegal (rank vs
side-to-move, origin-square occupancy) -- a real, previously-latent
bug surfaced while building the NNUE test fixtures, unrelated to
NNUE itself.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/board.c')
| -rw-r--r-- | src/board.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/src/board.c b/src/board.c index 80b5acb..d2d6c28 100644 --- a/src/board.c +++ b/src/board.c @@ -89,26 +89,31 @@ Return value: **/ { static char buf[MEDIUM_STRING_LEN_CHAR]; + char *pch = buf; + size_t cbLeft; COOR f, r; memset(buf, 0, sizeof(buf)); strcpy(buf, " 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07\n"); strcat(buf, " +---------------------------------------+\n"); + pch = buf + strlen(buf); for (r = 8; r >= 1; r--) { - sprintf(buf, "%s %u |", buf, r); + cbLeft = sizeof(buf) - (size_t)(pch - buf); + pch += snprintf(pch, cbLeft, " %u |", r); for (f = A; f <= H; f++) { + cbLeft = sizeof(buf) - (size_t)(pch - buf); if (IS_WHITE_SQUARE_FR(f, r)) { if (IS_EMPTY(pos->rgSquare[FILE_RANK_TO_COOR(f,r)].pPiece)) { - sprintf(buf, "%s%s", buf, " |"); + pch += snprintf(pch, cbLeft, "%s", " |"); } else { - sprintf(buf, "%s %2s |", buf, + pch += snprintf(pch, cbLeft, " %2s |", PieceAbbrev(pos->rgSquare[FILE_RANK_TO_COOR(f,r)].pPiece)); } } @@ -116,16 +121,17 @@ Return value: { if (IS_EMPTY(pos->rgSquare[FILE_RANK_TO_COOR(f,r)].pPiece)) { - sprintf(buf, "%s%s", buf, "::::|"); + pch += snprintf(pch, cbLeft, "%s", "::::|"); } else { - sprintf(buf, "%s:%2s:|", buf, + pch += snprintf(pch, cbLeft, ":%2s:|", PieceAbbrev(pos->rgSquare[FILE_RANK_TO_COOR(f,r)].pPiece)); } } } - sprintf(buf, "%s 0x%x0\n", buf, (8 - r)); + cbLeft = sizeof(buf) - (size_t)(pch - buf); + pch += snprintf(pch, cbLeft, " 0x%x0\n", (8 - r)); } strcat(buf, " +---------------------------------------+\n"); strcat(buf, " A B C D E F G H\n\n"); |
