Skip to content

feat(eval): Add passed pawn terms that read the stop and queening squares - #406

Merged
aywrite merged 1 commit into
masterfrom
claude/passed-pawn-read-squares-kcwu8i
Oct 14, 2026
Merged

aywrite merged 1 commit into
masterfrom
claude/passed-pawn-read-squares-kcwu8i

Conversation

@aywrite

@aywrite aywrite commented Oct 14, 2026

Copy link
Copy Markdown
Owner

The pawn structure prices a passer by its file and rank alone, so a
blockaded passer counts as a free one and neither king's position matters.
This adds a leaf term for passers on the fourth to the seventh, by rank:
both kings' king step distance from the stop square and from the queening
square, whether the stop is taken, whether the other side attacks it, and
whether no piece stands between the pawn and the eighth.

The weights were fitted on 5,026,360 quiet positions from 109,141 games
with every other weight held, over five folds that hold out both games of
an opening pair together. Held out loss fell by 0.000440 at 22 standard
errors clustered on the pair. That fit read a blockaded passer on the
seventh above a free one in the ending and paid an attacked stop in the
midgame, which is what a corpus of quiet positions teaches, so the weights
shipped are a refit with each one held to the sign chess expects: 0.000393
at 19.6 standard errors, and the same at whole centipawns. The term's
spread over the held out positions is 21 cp.

The passers depend on the pawns alone, so the set is kept in a table of
its own under the pawn key, and only the squares are read at each leaf.
The term costs 4.83% of the games suite's instructions (1,073.5 to 1,125.3
a node over the same 9,409,127 nodes). Setting every weight to zero turns
it off at compile time.

The bench grows 7.5%. Two tests needed a new reading of the tree: the rook
and pawns ending now ties two moves at depth six, so the aspiration test
uses the quiet middlegame, and WAC.021's floor at depth nine now comes
after 105,374 nodes, so the budget moves to 120,000. The effort test's
sampling goes from one node in ten to one in four, since at ten no sampled
key was reached by one side alone. The tactical suite
finds 230 rather than 228 and the strategic suite scores 104,395 rather
than 104,298.

Bench: 11916992
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01RY5UTjLftn71Vk2HrJ5iUS

…ares

The pawn structure prices a passer by its file and rank alone, so a
blockaded passer counts as a free one and neither king's position matters.
This adds a leaf term for passers on the fourth to the seventh, by rank:
both kings' king step distance from the stop square and from the queening
square, whether the stop is taken, whether the other side attacks it, and
whether no piece stands between the pawn and the eighth.

The weights were fitted on 5,026,360 quiet positions from 109,141 games
with every other weight held, over five folds that hold out both games of
an opening pair together. Held out loss fell by 0.000440 at 22 standard
errors clustered on the pair. That fit read a blockaded passer on the
seventh above a free one in the ending and paid an attacked stop in the
midgame, which is what a corpus of quiet positions teaches, so the weights
shipped are a refit with each one held to the sign chess expects: 0.000393
at 19.6 standard errors, and the same at whole centipawns. The term's
spread over the held out positions is 21 cp.

The passers depend on the pawns alone, so the set is kept in a table of
its own under the pawn key, and only the squares are read at each leaf.
The term costs 4.83% of the games suite's instructions (1,073.5 to 1,125.3
a node over the same 9,409,127 nodes). Setting every weight to zero turns
it off at compile time.

The bench grows 7.5%. Two tests needed a new reading of the tree: the rook
and pawns ending now ties two moves at depth six, so the aspiration test
uses the quiet middlegame, and WAC.021's floor at depth nine now comes
after 105,374 nodes, so the budget moves to 120,000. The effort test's
sampling goes from one node in ten to one in four, since at ten no sampled
key was reached by one side alone. The tactical suite
finds 230 rather than 228 and the strategic suite scores 104,395 rather
than 104,298.

Bench: 11916992
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RY5UTjLftn71Vk2HrJ5iUS
@github-actions

Copy link
Copy Markdown
Contributor

Speed against 72564490

Measured on AMD EPYC 9V74 80-Core Processor.
Both sides built with rustc 1.99.0 (b940084d7 2026-09-28).

Both sides built and run on this runner in this job, the way
scripts/speed.sh measures a perf commit. Each round runs
both sides on a layout of its own, the same compiled code with
its code and data shuffled and moved, so the 95% interval carries
where the code landed as well as the run. The verdict holds the
interval against a 1% threshold. The default layout, the one a
release ships, is measured after as a diagnostic. The node
counts are the search's: they move when the search does, and a
speed change leaves them alone.

round     base nps  candidate nps  change
    1      4245753        4467308   +5.2%
    2      4481561        4480530   -0.0%
    3      4508988        4611947   +2.3%
    4      4320082        4427917   +2.5%
    5      4314360        4536446   +5.1%
    6      4542852        4721051   +3.9%
    7      4467080        4740513   +6.1%
    8      4423875        4804229   +8.6%
    9      4529617        4634219   +2.3%
   10      4401917        4593199   +4.3%
   11      4513361        4310619   -4.5%
   12      4414834        4587919   +3.9%
   13      4421978        4601791   +4.1%
   14      4452038        4539247   +2.0%
   15      4464028        4456489   -0.2%
   16      4574833        4556769   -0.4%
   17      4290888        4388003   +2.3%
   18      4221672        4299575   +1.8%
   19      4174081        4604639  +10.3%
   20      4146764        4318354   +4.1%
   21      4266569        4452957   +4.4%
   22      4502121        4607926   +2.4%
   23      4428108        4406156   -0.5%
   24      4401755        4242818   -3.6%
   25      4587888        4403841   -4.0%
   26      4440101        4526337   +1.9%
   27      4391149        4481858   +2.1%
   28      4446120        4480237   +0.8%
   29      4440085        4532252   +2.1%
   30      4258829        4305235   +1.1%
   31      4321159        4437100   +2.7%
   32      4275879        4529456   +5.9%
   33      4644646        4752935   +2.3%
   34      4550554        4550530   -0.0%
   35      4646518        4575779   -1.5%
   36      4478609        4417236   -1.4%
   37      4495617        4437670   -1.3%
   38      4606086        4504201   -2.2%
   39      4413393        4527403   +2.6%
   40      4419238        4505473   +2.0%

              nodes    time  median nps  faster half
base       11088536  2.50 s     4434096      4518635
candidate  11916992  2.64 s     4515905      4606729
change        +7.5%   +5.5%       +1.8%        +1.9%

paired change +2.1%, 95% interval +1.0% to +3.0%
diagnostic, on the default layout alone +1.8%, 95% interval -0.1% to +3.3%, 13 rounds

the node counts differ, so this is a search change as well as a speed
one. nps only says what a node costs. Time to depth is what the change is
worth at this depth, and whether the new tree is the right one is for
games to say.

Speed: +2.1% (bench nps, 95% interval +1.0% to +3.0%, 40 interleaved rounds over shuffled layouts vs 72564490)

The instructions each side's bench executed, counted under
cachegrind. The count repeats to within a few hundred
instructions, so a small change here is a real one, but it
prices instructions only: cache misses, mispredicted branches
and where the code lands are the speed's to show.

instructions against 72564490, one cachegrind run a side, bench

             instructions     nodes  per node
base       14,997,100,706  11088536    1352.5
candidate  15,968,842,059  11916992    1340.0
change             +6.48%    +7.47%    -0.92%

the trees differ, so the count moved with the search as well as the code; the per node column is the nearer reading

@aywrite
aywrite merged commit fee1404 into master Oct 14, 2026
42 of 43 checks passed
@aywrite
aywrite deleted the claude/passed-pawn-read-squares-kcwu8i branch October 14, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants