| Age | Commit message (Collapse) | Author |
|
Board-representation migration section 6: a GNUmakefile build flag
(-DGETATTACKS_BITBOARD) makes chess.h's GetAttacks macro resolve to
_GetAttacksBB instead of the real asm implementation (or SlowGetAttacks
under CROUTINES) -- a three-way choice at the same spot the existing
CROUTINES switch already lived. _GetAttacksBB is now reachable from
every real call site (generate.c's check-detection call, see.c's
SEE(), searchsup.c), not just the test/bench harness.
Found and fixed while verifying this: testsee.c's TestGetAttacks and
its benchmark call the identifier GetAttacks meaning "the real
asm/CROUTINES baseline" -- once the macro could resolve to
_GetAttacksBB, those calls would silently compare the new
implementation against itself, turning both the correctness sweep and
the benchmark into false-positive no-ops. Fixed with a local #undef
GetAttacks right after #include "chess.h" in testsee.c, so the harness
always validates against the true baseline regardless of which
implementation is live in production.
Verified: gmake TEST=1 GETATTACKS_BITBOARD=1 passes (self-test suite,
corrected benchmark still reporting real asm vs. _GetAttacksBB
correctly, and a real Search() call exercising _GetAttacksBB live).
precommit_check.sh GETATTACKS_BITBOARD=1 clean for both the TEST=1
self-test and DEBUG=1 smoke test. Default (no flag) build confirmed
unaffected -- GetAttacks still resolves to the real asm function.
See board_representation/MIGRATION.md section 6 for the full writeup.
Sections 4/5/7's remaining items (curated-suite sd10 comparison,
match_play.py gate) are now unblocked but not yet run.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Jntky4yGUTyQVaGCXms4F2
|
|
Drafted after GetAttacks's migration landed, to evaluate extending the
same bbPieces/bbPawns/ray-table substrate to generate.c's seven
piece-type move generators. Kept as a separate document from
MIGRATION.md rather than a new section there, same reasoning as
dropping CountKingSafetyDefects from that plan: this is a
substantially bigger, higher-risk surface (7 functions, ~3400 lines,
no existing reference implementation to diff against, and the
pseudo-legal over-generation contract is load-bearing -- a bitboard
rewrite that accidentally becomes more legal-aware is a silent
behavior change, not a free improvement).
Covers: per-function rollout plan (knight/king first as
lowest-risk/best-precedented, rook/bishop as the real segment-marking
design work, queen mechanical once those land, pawns last and
possibly not worth it), a stronger correctness gate than GetAttacks
had (perft node-count matching against externally-known-correct
numbers, not just internal self-consistency), and a confirmed (not
just flagged) scope gap: _GenerateEscapes, the in-check move
generation path, has its own independent mailbox implementation and
is not covered by the seven piece-type functions this plan targets.
No code changes -- planning only.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Jntky4yGUTyQVaGCXms4F2
|
|
Descope CountKingSafetyDefects entirely, per discussion after landing
GetAttacks's half of section 3: the two functions no longer share
enough to justify one plan. CountKingSafetyDefects (eval.c:2325) turns
out to do no ray-walk/blocker check at all -- it's an unblocked
CHECK_VECTOR proximity heuristic, not a true attack query -- so
_WhoAttacksSquareBB's blocker-aware result isn't a value-identical
drop-in for it; making it bitboard-backed would be a real behavior
change (needing eval re-tuning/re-gating), not a reimplementation, and
a materially different, riskier project than this one.
eval.c is untouched. If CountKingSafetyDefects work happens later, it
should be a new, separate migration document starting from its actual
(unblocked heuristic) behavior, not a resumption of this one.
Also updates section 4-7 status notes to reflect what's actually done
vs. still blocked on section 6's toggle (GetAttacks alone, no longer
entangled with a king-safety timeline).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Jntky4yGUTyQVaGCXms4F2
|
|
Board-representation migration, sections 2-3 (GetAttacks half):
- board.c: VerifyPositionConsistency's bbPieces consistency check
(migration section 2), verified clean via gmake TEST=1 with the
assert live.
- POSITION.bbPawns[2]: new incrementally-maintained per-color pawn
location bitboard (chess.h), maintained at the same 6 move.c sites
as bbPieces, populated from scratch in fen.c. Distinct from the
pawn-hash-keyed bbPawnLocations; this one needs no
SEARCHER_THREAD_CONTEXT, so it's reachable from GetAttacks's actual
call sites (which only ever have a POSITION*).
- data.c/chess.h/main.c: g_RookRayAll/g_BishopRayAll (all 4 per-square
ray directions pre-ORed) and g_PawnAttackOriginBB[2][128] startup
tables, plus FastFirstBit/FastLastBit (static inline bsf/bsr
wrappers, chess.h) -- supporting tables/helpers for the primitive
below.
- see.c: _WhoAttacksSquareBB (bitboard "who attacks square X" query)
and _GetAttacksBB (SEE_LIST-populating PoC wrapping it), side by
side with the existing SlowGetAttacks/asm GetAttacks -- not wired
into the GetAttacks macro yet (section 6), pure addition.
- testsee.c: SeeListsAreEqual made order-independent (SEE() sorts the
list right after GetAttacks returns, so order was never semantically
significant); TestGetAttacks extended to run _GetAttacksBB as a
third comparison across the existing 20,000-random-position sweep;
added an interleaved asm/Slow/BB cycles-per-call benchmark across
opening/middlegame/endgame positions.
- testsup.c: fixed GenerateRandomLegalPosition (used by the sweep
above) to maintain bbPieces/bbPawns at its two hand-placement sites
-- a latent gap since section 1 that made its own
VerifyPositionConsistency legality gate almost always reject
generated positions, causing large, variable retry-loop slowdowns.
Verified: 20,000-position x every-square x both-colors correctness
sweep passes (gmake TEST=1), precommit_check.sh clean (self-test +
DEBUG smoke test). Benchmark: _GetAttacksBB is ~0.53-0.55x asm
GetAttacks's cycles/call (opening/middlegame) and ~0.89x (endgame) --
faster, not just equivalent, primarily from replacing bbOccupied's
up-to-16-iteration pawn loop with two bbPawns ORs, plus a
g_PawnAttackOriginBB table lookup replacing per-call pawn-delta
arithmetic and per-direction/per-side-group early-outs in the slider
walk. See board_representation/MIGRATION.md section 3 for the full
writeup, including a reverted approach that measured slower and why,
and the CountKingSafetyDefects half's re-scoped (not yet implemented)
design.
Also confirmed (not caused by this work, not fixed here): a
pre-existing non-deterministic MP-race assertion in util.c:1093's PV
printing, reproduced independently on a clean HEAD checkout.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Jntky4yGUTyQVaGCXms4F2
|
|
Board-representation migration, section 1: add POSITION.bbPieces[2][8]
(per-color, per-piece-type location bitboards, indexed like the
existing uNonPawnCount) as incrementally-maintained state, not a
per-Eval()-call rebuild -- the structural fix for why the earlier
attack-presence-bitboard work measured slower, not faster.
- chess.h: bbPieces[2][8] field; extern decls for data.c's
g_RookRayToEdge/g_BishopRayToEdge/g_KnightAttacksBB ray tables and
their Initialize* functions (needed by the planned bitboard-backed
GetAttacks/CountKingSafetyDefects primitive, section 3).
- fen.c: populate bbPieces during piece placement; zeroing is free via
the existing memset(p, 0, sizeof(POSITION)).
- move.c: maintain bbPieces at all 6 non-pawn piece-movement functions
(SlidePiece/LiftPiece/PlacePiece and their WithoutSigs siblings used
by UnmakeMove) -- covers every move type: normal moves, captures,
both-side castling, promotion with/without capture, en passant, and
every undo.
- board.c: extend VerifyPositionConsistency's existing non-pawn
piece-list walk with a parallel bbPieces reconstruction-and-compare,
rather than a separate bespoke check.
- data.c/main.c: pulled ray-to-edge/knight-attack tables from stash
(needed by section 3, not section 1 itself, but zero-risk to land
now).
Also, while verifying: COOR_TO_BB was a table lookup (BBSQUARE[idx])
measured ~5-7% slower than the pure-ALU shift already sitting unused in
SLOWCOOR_TO_BB (whose "SLOW" name reflects a stale assumption about
variable shifts never actually tested on this hardware). Switched
COOR_TO_BB to the shift; fixed testbitboard.c's existing but broken
(dead-code-eliminated, silently reporting "0 cycles/op") comparison
benchmark for both while at it.
Verified via gmake TEST=1 (including TestMakeUnmakeMove's explicit
en-passant/promotion-with-capture/both-castling coverage) and
debug_smoke_test.sh, both clean; release build clean and runs normally.
Nothing reads bbPieces yet -- pure addition, zero behavioral risk.
See board_representation/MIGRATION.md for the full plan.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Jntky4yGUTyQVaGCXms4F2
|