1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
Pawnhash size tunable from cmdline again
Think about when to avoid nullmove pruning based on checks in the line
r2r4/p4pk1/2p3p1/1p1nPR2/5p1Q/2N5/PPPq4/1K4R1 w - - 0 0 -- check extension crazy
2026-09-18: sharded ASSERT-fuzzing harness -- the technique that found
the CommonSearchInit PV-staleness bug (DEBUG binary + gdb, batch mode,
`script <shard>.ep_` at a shallow sd, let it run until either an
ASSERT/SIGSEGV or clean exit) generalizes well and should be run
routinely, not just once ad hoc. Shard tests/cross_sectional_200k.ep_
(or any large stratified pool) into N pieces and run N concurrent
DEBUG-build _typhoon processes under gdb, one per shard, each logging
to its own file; investigate any hit (assert message + gdb backtrace)
the same way this session did. Needs a full core budget (N cores) so
it collides with self-play match runs -- schedule it for whenever the
box isn't already saturated by match_play.py workers, not concurrently
with them.
2026-10-04: We need to go faster.
- Can we get rid of rgSquares[] completely and use bitboards everywhere?
- Eliminate SEE calls?
- profile a super-lazy-always (material-only Eval() exit, forced
unconditionally, throwaway diagnostic build a la the zero-
selection-budget move-ordering trick -- never commit it) binary
against Crafty at matched depth/positions to find out where our
nps actually goes once eval is ~free. Scott's educated guess is
SEE and the is-this-move-a-check / legal-reply-to-check generators
dominate once eval is out of the way, not eval itself -- also
suspect given the earlier `<=`-to-`<` SEE-skip experiment on line
~4178 (skip SEE on same-piece- for-same-piece captures) barely
changed speed but made trees fatter (more nodes needed), i.e. that
SEE call was doing real pruning work, not just costing
time. Before assuming check-detection costs are irreducible,
confirm "is this move a check" is answered via O(1) bitboard AND
against the enemy king square from the post-move attack bitboard,
not via a generate-and-filter pass -- Scott believes he already
does this "cheaply" but isn't sure it's the fastest available
method. Single-legal-reply-to- check detection is likely the
genuinely unavoidable cost of the three (needs a real legal-move
count in the child position) -- worth checking whether it
early-exits as soon as a 2nd legal move is found rather than
generating the full list.
2026-10-04: Modify self-play harness to record eval score / PVs per
move in the PGN output. Make self-play harness able to play crafty
and then test the HEAD/candidate against crafty.
Remove all line-ending whitespace in one commit.
Fix the input queue --batch mode one thing after the script; like this breaks it.
Add nullmoves skipped to the output. Redo the output in general.
Train the fuck out of the NNUE.
Figure out how Stockfish is so efficient with the tree it searches:
position fen 2q1r1k1/1ppb4/r2p1Pp1/p4n1p/2P1n3/5NPP/PP3Q1K/2BRRB2 w - -
go depth 18
info string Available processors: 0-23
info string Using 1 thread
info string NNUE evaluation using nn-1a298aa575a0.nnue (109MiB, (86896, 1024, 32, 32, 1))
info string Network replica 1: Shared memory.
info depth 1 seldepth 5 multipv 1 score cp 433 nodes 47 nps 47000 hashfull 0 tbhits 0 time 1 pv e1e4
info depth 2 seldepth 3 multipv 1 score cp 433 nodes 92 nps 92000 hashfull 0 tbhits 0 time 1 pv e1e4 e8e4
info depth 3 seldepth 4 multipv 1 score cp 433 nodes 140 nps 140000 hashfull 0 tbhits 0 time 1 pv e1e4 e8e4 f3g5
info depth 4 seldepth 6 multipv 1 score cp 433 nodes 199 nps 199000 hashfull 0 tbhits 0 time 1 pv e1e4 e8e4 f3g5 e4e6
info depth 5 seldepth 11 multipv 1 score cp 433 nodes 273 nps 273000 hashfull 0 tbhits 0 time 1 pv e1e4 e8e4 f3g5 e4e6 f6f7 g8g7
info depth 6 seldepth 11 multipv 1 score cp 433 nodes 347 nps 347000 hashfull 0 tbhits 0 time 1 pv e1e4 e8e4 f3g5 e4e6 f6f7 g8g7
info depth 7 seldepth 11 multipv 1 score cp 664 nodes 613 nps 613000 hashfull 0 tbhits 0 time 1 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7e7 g5e4
info depth 8 seldepth 12 multipv 1 score cp 808 nodes 1070 nps 356666 hashfull 0 tbhits 0 time 3 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7f8
info depth 9 seldepth 11 multipv 1 score cp 762 nodes 1201 nps 400333 hashfull 0 tbhits 0 time 3 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7f8 g5e4 f8g7 e4g5
info depth 10 seldepth 11 multipv 1 score cp 747 nodes 1387 nps 346750 hashfull 0 tbhits 0 time 4 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7g8 g5e4
info depth 11 seldepth 12 multipv 1 score cp 707 nodes 1527 nps 381750 hashfull 0 tbhits 0 time 4 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7g8 g5e4 a5a4 e4g5 a6a5 a2a3
info depth 12 seldepth 15 multipv 1 score cp 630 nodes 1864 nps 310666 hashfull 0 tbhits 0 time 6 pv f6f7 g8f7 e1e4 d7a4 f3g5 f7g8 e4e8 c8e8 d1d5
info depth 13 seldepth 15 multipv 1 score cp 725 nodes 2579 nps 286555 hashfull 1 tbhits 0 time 9 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7f8 g5e4 f8g8 d1e1
info depth 14 seldepth 17 multipv 1 score cp 659 nodes 3095 nps 281363 hashfull 1 tbhits 0 time 11 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7g8 g5e4 d7c6 e4g5 a5a4 g3g4 h5g4
info depth 15 seldepth 21 multipv 1 score cp 713 nodes 8091 nps 212921 hashfull 3 tbhits 0 time 38 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7g8 g5e4 h5h4 g3h4 d7a4 d1e1 a4c6 e4g5 c6a4 e1e6
info depth 16 seldepth 21 multipv 1 score cp 776 nodes 12732 nps 205354 hashfull 4 tbhits 0 time 62 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7g8 g5e4 d7c6 e4g5 c8f8 f1g2 a5a4 g2d5 c6d5 c4d5
info depth 17 seldepth 20 multipv 1 score cp 766 nodes 16215 nps 202687 hashfull 6 tbhits 0 time 80 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7g8 g5e4 d7c6 e4g5 c8f8 c4c5
info depth 18 seldepth 20 multipv 1 score cp 745 nodes 20330 nps 209587 hashfull 7 tbhits 0 time 97 pv f6f7 g8f7 e1e4 e8e4 f3g5 f7g7 g5e4 c8e8 d1e1 e8e5 e4g5 e5c5 f2c5 d6c5 g3g4 h5g4 h3g4 f5h6
bestmove f6f7 ponder g8f7
vs
The root position is: 2q1r1k1/1ppb4/r2p1Pp1/p4n1p/2P1n3/5NPP/PP3Q1K/2BRRB2 w - - 0 0
1 -0.03 00:00.000 11 Kg1 Nxf6
1 +0.02 00:00.000 47 Qc2 Nfxg3
1 +0.75 00:00.000 174 f7+ Kxf7 Ng5+ Nxg5 Rxe8
2 +0.02 00:00.001 242 Qc2 Nfxg3
3 +0.12 00:00.003 985 Qc2 Nexg3 Kg1 Rxe1
3+ +0.77 00:00.004 1173 Qc2 Nexg3 Kg1 Rxe1 ++
3+ +2.27 00:00.004 1201 Qc2 Nexg3 Kg1 Rxe1 ++
3 +2.44 00:00.005 1459 f7+ Kh8 fxe8=Q+ Qxe8 Kg1 Nxf2 Rxe8+ Bxe8 Kxf2
4 +2.10 00:00.006 1918 f7+ Kxf7 Rxe4 Rb6 Re2 Rxe2 Bxe2
5 +2.40 00:00.012 4554 f7+ Kxf7 Rxe4 Rb6 Bg2 Rxe4 Ng5+ Kg8 Nxe4
6 +2.40 00:00.016 6369 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Rc6
7 +2.47 00:00.036 13990 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Rc6 Kg1
8- +1.72 00:00.051 19006 FL --
8 +1.72 00:00.052 19420 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Ng5 Rb6
9+ +2.47 00:00.058 21469 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Ng5 Rb6 ++
9 +2.72 00:00.132 50019 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Ng5 Kh8 Nf7+ Kg8
10 +2.48 00:00.169 62659 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Bg2 Rb6 Bg5 Bxe4 Bxe4
11 +2.67 00:00.272 98649 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Ng5 Rb6 b3 Qe8 Rd3
12 +2.80 00:00.766 276128 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Qf4 Kh8 b3 Bxe4 Bb2+ Kh7 Qxe4
13 +2.76 00:01.245 451989 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Bd3 Kh8 Bg5 Rb6 Nf6 Rxb2 Qxb2
14 +2.65 00:02.940 1055458 f7+ Kxf7 Rxe4 Rf8 Nh4 Rb6 Nxf5 gxf5
15 +2.99 00:28.737 10301994 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Bd3 Qe6 Ng5 Qf6 c5 h4 g4 Ra8 cxd6 Qxd6+ Kg1
16 +3.03 00:35.934 12793964 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Ng5 Rb6 b3 Nh6 Qf6 Ng4+ hxg4
17 +3.04 00:47.526 17013639 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Bc6 Ng5 Rb6 b3 Qb8 <TT> Bd3 Bd7 Bxf5 Bxf5 Qf3 Rc6
Read ./DEEPER_PRUNING.md for thoughts.
Neural kings and pawns evaluator trained on EGTB + deep endgame position searches.
|