Official release version of Stockfish 17
Bench: 1484730
---
Stockfish 17
Today we have the pleasure to announce a new major release of Stockfish. As
always, you can freely download it at https://stockfishchess.org/download and
use it in the GUI of your choice.
Don’t forget to join our Discord server[1] to get in touch with the community
of developers and users of the project!
*Quality of chess play*
In tests against Stockfish 16, this release brings an Elo gain of up to 46
points[2] and wins up to 4.5 times more game pairs[3] than it loses. In
practice, high-quality moves are now found in less time, with a user upgrading
from Stockfish 14 being able to analyze games at least 6 times[4] faster with
Stockfish 17 while maintaining roughly the same quality.
During this development period, Stockfish won its 9th consecutive first place
in the main league of the Top Chess Engine Championship (TCEC)[5], and the 24th
consecutive first place in the main events (bullet, blitz, and rapid) of the
Computer Chess Championship (CCC)[6].
*Update highlights*
*Improved engine lines*
This release introduces principal variations (PVs) that are more informative
for mate and decisive table base (TB) scores. In both cases, the PV will
contain all moves up to checkmate. For mate scores, the PV shown is the best
variation known to the engine at that point, while for table base wins, it
follows, based on the TB, a sequence of moves that preserves the game outcome
to checkmate.
*NUMA performance optimization*
For high-end computers with multiple CPUs (typically a dual-socket architecture
with 100+ cores), this release automatically improves performance with a
`NumaPolicy` setting that optimizes non-uniform memory access (NUMA). Although
typical consumer hardware will not benefit, speedups of up to 2.8x[7] have been
measured.
*Shoutouts*
*ChessDB*
During the past 1.5 years, hundreds of cores have been continuously running
Stockfish to grow a database of analyzed positions. This chess cloud
database[8] now contains well over 45 billion positions, providing excellent
coverage of all openings and commonly played lines. This database is already
integrated into GUIs such as En Croissant[9] and Nibbler[10], which access it
through the public API.
*Leela Chess Zero*
Generally considered to be the strongest GPU engine, it continues to provide
open data which is essential for training our NNUE networks. They released
version 0.31.1[11] of their engine a few weeks ago, check it out!
*Website redesign*
Our website has undergone a redesign in recent months, most notably in our home
page[12], now featuring a darker color scheme and a more modern aesthetic,
while still maintaining its core identity. We hope you'll like it as much as we
do!
*Thank you*
The Stockfish project builds on a thriving community of enthusiasts (thanks
everybody!) who contribute their expertise, time, and resources to build a free
and open-source chess engine that is robust, widely available, and very strong.
We would like to express our gratitude for the 11k stars[13] that light up our
GitHub project! Thank you for your support and encouragement – your recognition
means a lot to us.
We invite our chess fans to join the Fishtest testing framework[14] to
contribute compute resources needed for development. Programmers can contribute
to the project either directly to Stockfish[15] (C++), to Fishtest[16] (HTML,
CSS, JavaScript, and Python), to our trainer nnue-pytorch[17] (C++ and Python),
or to our website[18] (HTML, CSS/SCSS, and JavaScript).
The Stockfish team
[1] https://discord.gg/GWDRS3kU6R
[2] https://tests.stockfishchess.org/tests/view/66d738ba9de3e7f9b33d159a
[3] https://tests.stockfishchess.org/tests/view/66d738f39de3e7f9b33d15a0
[4] https://github.com/official-stockfish/Stockfish/wiki/Useful-data#equivalent-time-odds-and-normalized-game-pair-elo
[5] https://en.wikipedia.org/wiki/Stockfish_(chess)#Top_Chess_Engine_Championship
[6] https://en.wikipedia.org/wiki/Stockfish_(chess)#Chess.com_Computer_Chess_Championship
[7] https://github.com/official-stockfish/Stockfish/pull/5285
[8] https://chessdb.cn/queryc_en/
[9] https://encroissant.org/
[10] https://github.com/rooklift/nibbler
[11] https://github.com/LeelaChessZero/lc0/releases/tag/v0.31.1
[12] https://stockfishchess.org/
[13] https://github.com/official-stockfish/Stockfish/stargazers
[14] https://github.com/official-stockfish/fishtest/wiki/Running-the-worker
[15] https://github.com/official-stockfish/Stockfish
[16] https://github.com/official-stockfish/fishtest
[17] https://github.com/official-stockfish/nnue-pytorch
[18] https://github.com/official-stockfish/stockfish-web
Created from 2 distinct spsa tunes of the latest main net (nn-31337bea577c.nnue)
and applying the params to the prior main net (nn-e8bac1c07a5a.nnue). This
effectively reverts the modifications to output weights and biases in
https://github.com/official-stockfish/Stockfish/pull/5509
SPSA:
A: 6000, alpha: 0.602, gamma: 0.101
1st - 437 feature transformer biases where values are < 25
54k / 120k games at 180+1.8
https://tests.stockfishchess.org/tests/view/66af98ac4ff211be9d4edad0
nn-808259761cca.nnue
2nd - 208 L2 weights where values are zero
112k / 120k games at 180+1.8
https://tests.stockfishchess.org/tests/view/66b0c3074ff211be9d4edbe5
nn-a56cb8c3d477.nnue
When creating the above 2 nets (nn-808259761cca.nnue, nn-a56cb8c3d477.nnue),
spsa params were unintentionally applied to nn-e8bac1c07a5a.nnue rather
than nn-31337bea577c.nnue due to an issue in a script that creates nets
by applying spsa results to base nets.
Since they both passed STC and were neutral or slightly positive at LTC,
they were combined to see if the elo from each set of params was additive.
The 2 nets can be merged on top of nn-e8bac1c07a5a.nnue with:
https://github.com/linrock/nnue-tools/blob/90942d3/spsa/combine_nnue.py
```
python3 combine_nnue.py \
nn-e8bac1c07a5a.nnue \
nn-808259761cca.nnue \
nn-a56cb8c3d477.nnue
```
Merging yields nn-87caa003fc6a.nnue which was renamed to nn-1111cefa1111.nnue
with an updated nnue-namer around 10x faster than before by:
- using a prefix trie for efficient prefix matches
- modifying 4 non-functional bytes near the end of the file instead of 2
https://github.com/linrock/nnue-namer
Thanks to @MinetaS for pointing out in #nnue-dev what the non-functional bytes are:
L3 is 32, 4 bytes for biases, 32 bytes for weights. (fc_2)
So -38 and -37 are technically -2 and -1 of fc_1 (type AffineTransform<30, 32>)
And since InputDimension is padded to 32 there are total 32 of 2 adjacent bytes padding.
So yes, it's non-functional whatever values are there.
It's possible to tweak bytes at -38 - 32 * N and -37 - 32 * N given N = 0 ... 31
The net renamed with the new method passed non-regression STC vs. the original net:
https://tests.stockfishchess.org/tests/view/66c0f0a821503a509c13b332
To print the spsa params with nnue-pytorch:
```
import features
from serialize import NNUEReader
feature_set = features.get_feature_set_from_name("HalfKAv2_hm")
with open("nn-31337bea577c.nnue", "rb") as f:
model = NNUEReader(f, feature_set).model
c_end = 16
for i,ft_bias in enumerate(model.input.bias.data[:3072]):
value = int(ft_bias * 254)
if abs(value) < 25:
print(f"ftB[{i}],{value},-1024,1024,{c_end},0.0020")
c_end = 6
for i in range(8):
for j in range(32):
for k in range(30):
value = int(model.layer_stacks.l2.weight.data[32 * i + j, k] * 64)
if value == 0:
print(f"twoW[{i}][{j}][{k}],{value},-127,127,{c_end},0.0020")
```
New params found with the same method as:
https://github.com/official-stockfish/Stockfish/pull/5459
Passed STC:
https://tests.stockfishchess.org/tests/view/66b4d4464ff211be9d4edf6e
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 136416 W: 35753 L: 35283 D: 65380
Ptnml(0-2): 510, 16159, 34416, 16597, 526
Passed LTC:
https://tests.stockfishchess.org/tests/view/66b76e814ff211be9d4ee1cc
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 159336 W: 40753 L: 40178 D: 78405
Ptnml(0-2): 126, 17497, 43864, 18038, 143
closes https://github.com/official-stockfish/Stockfish/pull/5534
bench 1613043
This patch moves the DotProd code into the propagation function which
has sequential access optimization. To prove the speedup, the comparison
is done without the sparse layer. With the sparse layer the effect is
marginal (GCC 0.3%, LLVM/Clang 0.1%).
For both tests, binary is compiled with GCC 14.1. Each test had 50 runs.
Sparse layer included:
```
speedup = +0.0030
P(speedup > 0) = 1.0000
```
Sparse layer excluded:
```
speedup = +0.0561
P(speedup > 0) = 1.0000
```
closes https://github.com/official-stockfish/Stockfish/pull/5520
No functional change
Since simplification of quiet checks in qsearch this depth isn't used by
any function at all apart movepicker, which also doesn't use passed
qsearch depth in any way, so can be removed. No functional change.
closes https://github.com/official-stockfish/Stockfish/pull/5514
No functional change
Created by updating output weights (256) and biases (8)
of the previous main net with values found with spsa around
101k / 120k games at 140+1.4.
264 spsa params: output weights and biases in nn-e8bac1c07a5a.nnue
A: 6000, alpha: 0.602, gamma: 0.101
weights: [-127, 127], c_end = 6
biases: [-8192, 8192], c_end = 64
Among the 264 params, 189 weights and all 8 biases were changed.
Changes in the weights:
- mean: -0.111 +/- 3.57
- range: [-8, 8]
Found with the same method as:
https://github.com/official-stockfish/Stockfish/pull/5459
Due to the original name (nn-ea8c9128c325.nnue) being too similar
to the previous main net (nn-e8bac1c07a5a.nnue) and creating confusion,
it was renamed by making non-functional changes to the .nnue file
the same way as past nets with:
https://github.com/linrock/nnue-namer
To verify that bench is the same and view the modified non-functional bytes:
```
echo -e "setoption name EvalFile value nn-ea8c9128c325.nnue\nbench" | ./stockfish
echo -e "setoption name EvalFile value nn-31337bea577c.nnue\nbench" | ./stockfish
cmp -l nn-ea8c9128c325.nnue nn-31337bea577c.nnue
diff <(xxd nn-ea8c9128c325.nnue) <(xxd nn-31337bea577c.nnue)
```
Passed STC:
https://tests.stockfishchess.org/tests/view/669564154ff211be9d4ec080
LLR: 2.93 (-2.94,2.94) <0.00,2.00>
Total: 57280 W: 15139 L: 14789 D: 27352
Ptnml(0-2): 209, 6685, 14522, 6995, 229
Passed LTC:
https://tests.stockfishchess.org/tests/view/669694204ff211be9d4ec1b4
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 63030 W: 16093 L: 15720 D: 31217
Ptnml(0-2): 47, 6766, 17516, 7139, 47
closes https://github.com/official-stockfish/Stockfish/pull/5509
bench 1371485
even if beta is below TB range, once we return probcutBeta with beta + 390 we
can return wrong TB value, and guard against ttData.value being `VALUE_NONE`
closes https://github.com/official-stockfish/Stockfish/pull/5499
bench: 1440277
These values represent the lowest Elo rating in the skill level calculation,
and the highest one, but it's not clear from the code where these values come
from other than the comment. This should improve code readability and
maintainability. It makes the purpose of the values clear and allows for easy
modification if the Elo range for skill level calculation changes in the
future. Moved the Skill struct definition from search.cpp to search.h header
file to define the Search::Skill struct, making it accessible from other files.
closes https://github.com/official-stockfish/Stockfish/pull/5508
No functional change
in the case of MultiPV, the first move of the Nth multiPV could actually turn a
winning position in a losing one, so don't attempt to correct it. Instead,
always perform the first move without correction.
Fixes#5505
Closes https://github.com/official-stockfish/Stockfish/pull/5506
No functional change
now checks correctness of PV lines with TB score.
uses 3-4-5 man table bases, downloaded from lichess,
which are cached with the appropriate action.
closes https://github.com/official-stockfish/Stockfish/pull/5500
No functional change
This patch removes lmrDepth limit for quiet moves history based pruning.
Previously removal of this type of depth limits was considered bad because it
was performing bad for matetrack - but with this pruning heuristic this
shouldn't be that bad because it's "naturally" depth limited by history
threshold and should be completely disabled at depth >= 15 or so. Also this
heuristic in previous years was known to scale non-linearly - bigger lmrDepth
thresholds were better at longer time controls and removing it completely
probably should scale pretty well.
Passed STC:
https://tests.stockfishchess.org/tests/view/6692b89b4ff211be9d4eab21
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 114464 W: 29675 L: 29545 D: 55244
Ptnml(0-2): 372, 12516, 31329, 12640, 375
Passed LTC:
https://tests.stockfishchess.org/tests/view/6692c4554ff211be9d4eab3d
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 67746 W: 17182 L: 17014 D: 33550
Ptnml(0-2): 28, 6993, 19652, 7183, 17
closes https://github.com/official-stockfish/Stockfish/pull/5485
Bench: 1250388
now uses the following format:
`info string Found 510 WDL and 510 DTZ tablebase files (up to 6-man).`
this clarifies exactly what has been found, as the difference matters,
e.g. for the PV extension of TB scores.
closes https://github.com/official-stockfish/Stockfish/pull/5471
No functional change
- Capitalize comments
- Reformat multi-lines comments to equalize the widths of the lines
- Try to keep the width of comments around 85 characters
- Remove periods at the end of single-line comments
closes https://github.com/official-stockfish/Stockfish/pull/5469
No functional change
In probcut move loop, everything is enclosed within a large if statement. I've
changed it to guard clauses to stay consistent with other move loops.
closes https://github.com/official-stockfish/Stockfish/pull/5463
No functional change
Created by modifying L2 weights from the previous main net (nn-74f1d263ae9a.nnue)
with params found by spsa around 9k / 120k games at 120+1.2.
370 spsa params - L2 weights in nn-74f1d263ae9a.nnue where |val| >= 50
A: 6000, alpha: 0.602, gamma: 0.101
weights: [-127, 127], c_end = 6
To print the spsa params with nnue-pytorch:
```
import features
from serialize import NNUEReader
feature_set = features.get_feature_set_from_name("HalfKAv2_hm")
with open("nn-74f1d263ae9a.nnue", "rb") as f:
model = NNUEReader(f, feature_set).model
c_end = 6
for i in range(8):
for j in range(32):
for k in range(30):
value = int(model.layer_stacks.l2.weight[32 * i + j, k] * 64)
if abs(value) >= 50:
print(f"twoW[{i}][{j}][{k}],{value},-127,127,{c_end},0.0020")
```
Among the 370 params, 229 weights were changed.
avg change: 0.0961 ± 1.67
range: [-4, 3]
The number of weights changed, grouped by layer stack index,
shows more weights were modified in the lower piece count buckets:
[54, 52, 29, 23, 22, 18, 14, 17]
Found with the same method described in:
https://github.com/official-stockfish/Stockfish/pull/5459
Passed STC:
https://tests.stockfishchess.org/tests/view/668aec9a58083e5fd88239e7
LLR: 3.00 (-2.94,2.94) <0.00,2.00>
Total: 52384 W: 13569 L: 13226 D: 25589
Ptnml(0-2): 127, 6141, 13335, 6440, 149
Passed LTC:
https://tests.stockfishchess.org/tests/view/668af50658083e5fd8823a0b
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 46974 W: 12006 L: 11668 D: 23300
Ptnml(0-2): 25, 4992, 13121, 5318, 31
closes https://github.com/official-stockfish/Stockfish/pull/5466
bench 1300471
Always use the posix function posix_memalign() as aligned memory
allocator on Apple computers. This should allow to compile Stockfish
out of the box on all versions of Mac OS X.
Patch tested on the following systems (apart from the CI) :
• Mac OS 10.9.6 (arch x86-64-sse41-popcnt) with gcc-10
• Mac OS 10.13.6 (arch x86-64-bmi2) with gcc-10, gcc-14 and clang-11
• Mac OS 14.1.1 (arch apple-silicon) with clang-15
closes https://github.com/official-stockfish/Stockfish/pull/5462
No functional change
Created by setting output weights (256) and biases (8) of the previous main net
nn-ddcfb9224cdb.nnue to values found around 12k / 120k spsa games at 120+1.2
This used modified fishtest dev workers to construct .nnue files from
spsa params, then load them with EvalFile when running tests:
https://github.com/linrock/fishtest/tree/spsa-file-modified-nnue/worker
Inspired by researching loading spsa params from files:
https://github.com/official-stockfish/fishtest/pull/1926
Scripts for modifying nnue files and preparing params:
https://github.com/linrock/nnue-pytorch/tree/no-gpu-modify-nnue
spsa params:
weights: [-127, 127], c_end = 6
biases: [-8192, 8192], c_end = 64
Example of reading output weights and biases from the previous main net using
nnue-pytorch and printing spsa params in a format compatible with fishtest:
```
import features
from serialize import NNUEReader
feature_set = features.get_feature_set_from_name("HalfKAv2_hm")
with open("nn-ddcfb9224cdb.nnue", "rb") as f:
model = NNUEReader(f, feature_set).model
c_end_weights = 6
c_end_biases = 64
for i in range(8):
for j in range(32):
value = round(int(model.layer_stacks.output.weight[i, j] * 600 * 16) / 127)
print(f"oW[{i}][{j}],{value},-127,127,{c_end_weights},0.0020")
for i in range(8):
value = int(model.layer_stacks.output.bias[i] * 600 * 16)
print(f"oB[{i}],{value},-8192,8192,{c_end_biases},0.0020")
```
For more info on spsa tuning params in nets:
https://github.com/official-stockfish/Stockfish/pull/5149https://github.com/official-stockfish/Stockfish/pull/5254
Passed STC:
https://tests.stockfishchess.org/tests/view/66894d64e59d990b103f8a37
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 32000 W: 8443 L: 8137 D: 15420
Ptnml(0-2): 80, 3627, 8309, 3875, 109
Passed LTC:
https://tests.stockfishchess.org/tests/view/6689668ce59d990b103f8b8b
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 172176 W: 43822 L: 43225 D: 85129
Ptnml(0-2): 97, 18821, 47633, 19462, 75
closes https://github.com/official-stockfish/Stockfish/pull/5459
bench 1120091
Currently (after #5407), SF has the property that any PV line with a decisive
TB score contains the corresponding TB position, with a score that correctly
identifies the depth at which TB are entered. The PV line that follows might
not preserve the game outcome, but can easily be verified and extended based on
TB information. This patch provides this functionality, simply extending the PV
lines on output, this doesn't affect search.
Indeed, if DTZ tables are available, search based PV lines that correspond to
decisive TB scores are verified to preserve game outcome, truncating the line
as needed. Subsequently, such PV lines are extended with a game outcome
preserving line until mate, as a possible continuation. These lines are not
optimal mating lines, but are similar to what a user could produce on a website
like https://syzygy-tables.info/ clicking always the top ranked move, i.e.
minimizing or maximizing DTZ (with a simple tie-breaker for moves that have
identical DTZ), and are thus an just an illustration of how to game can be won.
A similar approach is already in established in
https://github.com/joergoster/Stockfish/tree/matefish2
This also contributes to addressing #5175 where SF can give an incorrect TB
win/loss for positions in TB with a movecounter that doesn't reflect optimal
play. While the full solution requires either TB generated differently, or a
search when ranking rootmoves, current SF will eventually find a draw in these
cases, in practice quite quickly, e.g.
`1kq5/q2r4/5K2/8/8/8/8/7Q w - - 96 1`
`8/8/6k1/3B4/3K4/4N3/8/8 w - - 54 106`
Gives the same results as master on an extended set of test positions from
9173d29c41
with the exception of the above mentioned fen where this commit improves.
With https://github.com/vondele/matetrack using 6men TB, all generated PVs verify:
```
Using ../Stockfish/src/stockfish.syzygyExtend on matetrack.epd with --nodes 1000000 --syzygyPath /chess/syzygy/3-4-5-6/WDL:/chess/syzygy/3-4-5-6/DTZ
Engine ID: Stockfish dev-20240704-ff227954
Total FENs: 6555
Found mates: 3299
Best mates: 2582
Found TB wins: 568
```
As repeated DTZ probing could be slow a procedure (100ms+ on HDD, a few ms on
SSD), the extension is only done as long as the time taken is less than half
the `Move Overhead` parameter. For tournaments where these lines might be of
interest to the user, a suitable `Move Overhead` might be needed (e.g. TCEC has
1000ms already).
closes https://github.com/official-stockfish/Stockfish/pull/5414
No functional change
To avoid output that depends on timing, output currmove and similar only from depth > 30
onward. Current choice of 3s makes the output of the same search depending on
the system load, and doesn't always start at move 1. Depth 30 is nowadays
reached in a few seconds on most systems.
closes https://github.com/official-stockfish/Stockfish/pull/5436
No functional change
do not upload some unneeded intermediate directories,
disable running authenticated git commands with the checkout action.
Thanks to Yaron A for the report.
closes https://github.com/official-stockfish/Stockfish/pull/5435
No functional change
Follow up from #5404 ... current location leads to troubles with Aquarium GUI
Fixes#5430
Now prints the information on threads and available processors at the beginning
of search, where info about the networks is already printed (and is known to
work)
closes https://github.com/official-stockfish/Stockfish/pull/5433
No functional change.
This patch introduces history updates to probcut. Standard depth - 3 bonus and
maluses are given to the capture that caused fail high and previously searched
captures, respectively. Similar to #5243, a negative history fill is applied to
compensate for an increase in capture history average, thus improving the
scaling of this patch.
Passed STC:
LLR: 2.95 (-2.94,2.94) <0.00,2.00>
Total: 84832 W: 21941 L: 21556 D: 41335
Ptnml(0-2): 226, 9927, 21688, 10386, 189
https://tests.stockfishchess.org/tests/view/6682fab9389b9ee542b1d029
Passed LTC:
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 104298 W: 26469 L: 26011 D: 51818
Ptnml(0-2): 43, 11458, 28677, 11940, 31
https://tests.stockfishchess.org/tests/view/6682ff06389b9ee542b1d0a0
closes https://github.com/official-stockfish/Stockfish/pull/5428
bench 1281351
this action plays games under fast-chess with a `debug=yes` compiled binary.
It checks for triggered asserts in the code, or generally for engine disconnects.
closes https://github.com/official-stockfish/Stockfish/pull/5403
No functional change
try to avoid missing good moves for opponent or engine, by updating bestMove
also when value == bestValue (i.e. value == alpha) under certain conditions.
In particular require this is at higher depth in the tree, leaving the logic
near the root unchanged, and only apply randomly. Avoid doing this near mate
scores, leaving mate PVs intact.
Passed SMP STC 6+0.06 th7 :
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 42040 W: 10930 L: 10624 D: 20486
Ptnml(0-2): 28, 4682, 11289, 4998, 23
https://tests.stockfishchess.org/tests/view/66608b00c340c8eed7757d1d
Passed SMP LTC 24+0.24 th7 :
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 73692 W: 18978 L: 18600 D: 36114
Ptnml(0-2): 9, 7421, 21614, 7787, 15
https://tests.stockfishchess.org/tests/view/666095e8c340c8eed7757d49
closes https://github.com/official-stockfish/Stockfish/pull/5367
Bench 1205168
In case a stop is received during multithreaded searches, the PV of the best
thread might be printed without the correct upperbound/lowerbound indicators.
This was due to the pvIdx variable being incremented after receiving the stop.
passed STC:
https://tests.stockfishchess.org/tests/view/666985da602682471b064d08
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 196576 W: 51039 L: 50996 D: 94541
Ptnml(0-2): 760, 22545, 51603, 22652, 728
closes https://github.com/official-stockfish/Stockfish/pull/5391
Bench: 1160467
currently extensions can cause depth to exceed MAX_PLY.
This triggers the assert near line 542 in search when running a binary compiled with `debug=yes` on a testcase like:
```
position fen 7K/P1p1p1p1/2P1P1Pk/6pP/3p2P1/1P6/3P4/8 w - - 0 1
go nodes 1000000
```
passed STC
https://tests.stockfishchess.org/tests/view/6668a56a602682471b064c8d
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 143936 W: 37338 L: 37238 D: 69360
Ptnml(0-2): 514, 16335, 38149, 16477, 493
closes https://github.com/official-stockfish/Stockfish/pull/5383
Bench: 1160467
Move the engine options into the engine class, also avoid duplicated
initializations after startup. UCIEngine needs to register an add_listener to
listen to all option changes and print these. Also avoid a double
initialization of the TT, which was the case with the old state.
closes https://github.com/official-stockfish/Stockfish/pull/5356
No functional change
1. Fix GetProcessGroupAffinity still not getting properly aligned memory
sometimes.
2. Fix a very theoretically possible heap corruption if
GetActiveProcessorGroupCount changes between calls.
3. Fully determine affinity on Windows 11 and Windows Server 2022. It
should only ever be indeterminate in case of an error.
4. Separate isDeterminate for old and new API, as they are &'d together
we still can end up with a subset of processors even if one API is
indeterminate.
5. likely_used_old_api() that is based on actual affinity that's been
detected
6. IMPORTANT: Gather affinities at startup, so that we only later use
the affinites set at startup. Not only does this prevent us from our
own calls interfering with detection but it also means subsequent
setoption NumaPolicy calls should behave as expected.
7. Fix ERROR_INSUFFICIENT_BUFFER from GetThreadSelectedCpuSetMasks being
treated like an error.
Should resolve
02ff76630b (commitcomment-142790025)
closes https://github.com/official-stockfish/Stockfish/pull/5372
Bench: 1231853
Can be used in case a GUI (e.g. ChessBase 17 see #5307) sets affinity to a
single processor group, but the user would like to use the full capabilities of
the hardware. Improves affinity handling on Windows in case of multiple
available APIs and existing affinities.
closes https://github.com/official-stockfish/Stockfish/pull/5353
No functional change
Passed STC:
https://tests.stockfishchess.org/tests/view/665ce3f8fd45fb0f907c537f
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 282784 W: 73032 L: 73082 D: 136670
Ptnml(0-2): 680, 31845, 76364, 31851, 652
Recently when I overhauled these comments, Disservin asked why these
were so much lower: they're a relic from when we had a third QS stage at
-5. Now we don't, so fix these to the obvious place.
I was fairly sure it was nonfunctional but ran the nonreg to be double
sure.
closes https://github.com/official-stockfish/Stockfish/pull/5343
Bench: 1057383
Previously, we had two type aliases, LargePagePtr and AlignedPtr, which
required manually initializing the aligned memory for the pointer.
The new helpers:
- make_unique_aligned
- make_unique_large_page
are now available for allocating aligned memory (with large pages). They
behave similarly to std::make_unique, ensuring objects allocated with
these functions follow RAII.
The old approach had issues with initializing non-trivial types or
arrays of objects. The evaluation function of the network is now a
unique pointer to an array instead of an array of unique pointers.
Memory related functions have been moved into memory.h
Passed High Hash Pressure Test Non-Regression STC:
https://tests.stockfishchess.org/tests/view/665b2b36586058766677cfd2
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 476992 W: 122426 L: 122677 D: 231889
Ptnml(0-2): 1145, 51027, 134419, 50744, 1161
Failed Normal Non-Regression STC:
https://tests.stockfishchess.org/tests/view/665b2997586058766677cfc8
LLR: -2.94 (-2.94,2.94) <-1.75,0.25>
Total: 877312 W: 225233 L: 226395 D: 425684
Ptnml(0-2): 2110, 94642, 246239, 93630, 2035
Probably a fluke since there shouldn't be a real slowndown and it has also
passed the high hash pressure test.
closes https://github.com/official-stockfish/Stockfish/pull/5332
No functional change
This reverts commit 783dfc2eb2.
could lead to a division by zero for:
ttValue = (ttValue * tte->depth() + beta) / (tte->depth() + 1)
as other threads can overwrite the tte with a QS depth of -1.
closes https://github.com/official-stockfish/Stockfish/pull/5338
Bench: 1280020
This is reintroduction of the recently simplified logic - if positive tt cutoff
occurs return not a tt value but smth between it and beta. Difference is that
instead of static linear combination there we use basically the same formula as
we do in the main search - with the only difference being using tt depth
instead of depth, which makes a lot of sense.
Passed STC:
https://tests.stockfishchess.org/tests/view/665b3a34f4a1fd0c208ea870
LLR: 2.95 (-2.94,2.94) <0.00,2.00>
Total: 54944 W: 14239 L: 13896 D: 26809
Ptnml(0-2): 151, 6407, 14008, 6760, 146
Passed LTC:
https://tests.stockfishchess.org/tests/view/665b520011645bd3d3fac341
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 90540 W: 23070 L: 22640 D: 44830
Ptnml(0-2): 39, 9903, 24965, 10315, 48
closes https://github.com/official-stockfish/Stockfish/pull/5336
bench 1381237
The idea is, that if we have the information that the singular search failed low and therefore produced an upperbound score, we can use the score from singularsearch as approximate upperbound as to what bestValue our non ttMoves will produce. If this value is well below alpha, we assume that all non-ttMoves will score below alpha and therfore can skip more moves.
This patch also sets up variables for future patches wanting to use teh singular search result outside of singular extensions, in singularBound and singularValue, meaning further patches using this search result to affect various pruning techniques can be tried.
Passed STC:
https://tests.stockfishchess.org/tests/view/6658d13e6b0e318cefa90120
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 85632 W: 22112 L: 21725 D: 41795
Ptnml(0-2): 243, 10010, 21947, 10349, 267
Passed LTC:
https://tests.stockfishchess.org/tests/view/6658dd356b0e318cefa9016a
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 243978 W: 62014 L: 61272 D: 120692
Ptnml(0-2): 128, 26598, 67791, 27348, 124
closes https://github.com/official-stockfish/Stockfish/pull/5325
bench 1397172
Specialize and privatize NumaConfig::get_process_affinity.
Only enable NUMA capability for 64-bit Windows.
Following #5307 and some more testing it was determined that the way affinity
was being determined on Windows was incorrect, based on incorrect assumptions
about GetNumaProcessorNodeEx.
This patch fixes the issue by attempting to retrieve the actual process'
processor affinity using Windows API. However one issue persists that is not
addressable due to limitations of Windows, and will have to be considered a
limitation. If affinities were set using SetThreadAffinityMask instead of
SetThreadSelectedCpuSetMasks and GetProcessGroupAffinity returns more than 1
group it is NOT POSSIBLE to determine the affinity programmatically on Windows.
In such case the implementation assumes no affinites are set and will consider
all processors available for execution.
closes https://github.com/official-stockfish/Stockfish/pull/5312
No functional change
This PR updates the internal WDL model, using data from 2.5M games played by SF-dev (3c62ad7).
Note that the normalizing constant has increased from 329 to 368.
Changes to the fitting procedure:
* the value for --materialMin was increased from 10 to 17: including data with less material leads to less accuracy for larger material count values
* the data was filtered to only include single thread LTC games at 60+0.6
* the data was filtered to only include games from master against patches that are (approximatively) within 5 nElo of master
For more information and plots of the model see PR#5309
closes https://github.com/official-stockfish/Stockfish/pull/5309
No functional change
As stockfish nets and search evolve, the existing time control appears
to give too little time at STC, roughly correct at LTC, and too little
at VLTC+.
This change adds an adjustment to the optExtra calculation. This
adjustment is easy to retune and refine, so it should be easier to keep
up-to-date than the more complex calculations used for optConstant and
optScale.
Passed STC 10+0.1:
LLR: 2.93 (-2.94,2.94) <0.00,2.00>
Total: 169568 W: 43803 L: 43295 D: 82470
Ptnml(0-2): 485, 19679, 44055, 19973, 592
https://tests.stockfishchess.org/tests/view/66531865a86388d5e27da9fa
Yellow LTC 60+0.6:
LLR: -2.94 (-2.94,2.94) <0.50,2.50>
Total: 209970 W: 53087 L: 52914 D: 103969
Ptnml(0-2): 91, 19652, 65314, 19849, 79
https://tests.stockfishchess.org/tests/view/6653e38ba86388d5e27daaa0
Passed VLTC 180+1.8 :
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 85618 W: 21735 L: 21342 D: 42541
Ptnml(0-2): 15, 8267, 25848, 8668, 11
https://tests.stockfishchess.org/tests/view/6655131da86388d5e27db95f
closes https://github.com/official-stockfish/Stockfish/pull/5297
Bench: 1212167
Allow for NUMA memory replication for NNUE weights. Bind threads to ensure execution on a specific NUMA node.
This patch introduces NUMA memory replication, currently only utilized for the NNUE weights. Along with it comes all machinery required to identify NUMA nodes and bind threads to specific processors/nodes. It also comes with small changes to Thread and ThreadPool to allow easier execution of custom functions on the designated thread. Old thread binding (WinProcGroup) machinery is removed because it's incompatible with this patch. Small changes to unrelated parts of the code were made to ensure correctness, like some classes being made unmovable, raw pointers replaced with unique_ptr. etc.
Windows 7 and Windows 10 is partially supported. Windows 11 is fully supported. Linux is fully supported, with explicit exclusion of Android. No additional dependencies.
-----------------
A new UCI option `NumaPolicy` is introduced. It can take the following values:
```
system - gathers NUMA node information from the system (lscpu or windows api), for each threads binds it to a single NUMA node
none - assumes there is 1 NUMA node, never binds threads
auto - this is the default value, depends on the number of set threads and NUMA nodes, will only enable binding on multinode systems and when the number of threads reaches a threshold (dependent on node size and count)
[[custom]] -
// ':'-separated numa nodes
// ','-separated cpu indices
// supports "first-last" range syntax for cpu indices,
for example '0-15,32-47:16-31,48-63'
```
Setting `NumaPolicy` forces recreation of the threads in the ThreadPool, which in turn forces the recreation of the TT.
The threads are distributed among NUMA nodes in a round-robin fashion based on fill percentage (i.e. it will strive to fill all NUMA nodes evenly). Threads are bound to NUMA nodes, not specific processors, because that's our only requirement and the OS can schedule them better.
Special care is made that maximum memory usage on systems that do not require memory replication stays as previously, that is, unnecessary copies are avoided.
On linux the process' processor affinity is respected. This means that if you for example use taskset to restrict Stockfish to a single NUMA node then the `system` and `auto` settings will only see a single NUMA node (more precisely, the processors included in the current affinity mask) and act accordingly.
-----------------
We can't ensure that a memory allocation takes place on a given NUMA node without using libnuma on linux, or using appropriate custom allocators on windows (https://learn.microsoft.com/en-us/windows/win32/memory/allocating-memory-from-a-numa-node), so to avoid complications the current implementation relies on first-touch policy. Due to this we also rely on the memory allocator to give us a new chunk of untouched memory from the system. This appears to work reliably on linux, but results may vary.
MacOS is not supported, because AFAIK it's not affected, and implementation would be problematic anyway.
Windows is supported since Windows 7 (https://learn.microsoft.com/en-us/windows/win32/api/processtopologyapi/nf-processtopologyapi-setthreadgroupaffinity). Until Windows 11/Server 2022 NUMA nodes are split such that they cannot span processor groups. This is because before Windows 11/Server 2022 it's not possible to set thread affinity spanning processor groups. The splitting is done manually in some cases (required after Windows 10 Build 20348). Since Windows 11/Server 2022 we can set affinites spanning processor group so this splitting is not done, so the behaviour is pretty much like on linux.
Linux is supported, **without** libnuma requirement. `lscpu` is expected.
-----------------
Passed 60+1 @ 256t 16000MB hash: https://tests.stockfishchess.org/tests/view/6654e443a86388d5e27db0d8
```
LLR: 2.95 (-2.94,2.94) <0.00,10.00>
Total: 278 W: 110 L: 29 D: 139
Ptnml(0-2): 0, 1, 56, 82, 0
```
Passed SMP STC: https://tests.stockfishchess.org/tests/view/6654fc74a86388d5e27db1cd
```
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 67152 W: 17354 L: 17177 D: 32621
Ptnml(0-2): 64, 7428, 18408, 7619, 57
```
Passed STC: https://tests.stockfishchess.org/tests/view/6654fb27a86388d5e27db15c
```
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 131648 W: 34155 L: 34045 D: 63448
Ptnml(0-2): 426, 13878, 37096, 14008, 416
```
fixes#5253
closes https://github.com/official-stockfish/Stockfish/pull/5285
No functional change
This speedup was first inspired by a comment by @AndyGrant on my recent
PR "If mullo_epi16 would preserve the signedness, then this could be
used to remove 50% of the max operations during the halfkp-pairwise
mat-mul relu deal."
That got me thinking, because although mullo_epi16 did not preserve the
signedness, mulhi_epi16 did, and so we could shift left and then use
mulhi_epi16, instead of shifting right after the mullo.
However, due to some issues with shifting into the sign bit, the FT
weights and biases had to be multiplied by 2 for the optimisation to
work.
Speedup on "Arch=x86-64-bmi2 COMP=clang", courtesy of @Torom
Result of 50 runs
base (...es/stockfish) = 962946 +/- 1202
test (...ise-max-less) = 979696 +/- 1084
diff = +16750 +/- 1794
speedup = +0.0174
P(speedup > 0) = 1.0000
CPU: 4 x Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
Hyperthreading: on
Also a speedup on "COMP=gcc", courtesy of Torom once again
Result of 50 runs
base (...tockfish_gcc) = 966033 +/- 1574
test (...max-less_gcc) = 983319 +/- 1513
diff = +17286 +/- 2515
speedup = +0.0179
P(speedup > 0) = 1.0000
CPU: 4 x Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
Hyperthreading: on
Passed STC:
LLR: 2.96 (-2.94,2.94) <0.00,2.00>
Total: 67712 W: 17715 L: 17358 D: 32639
Ptnml(0-2): 225, 7472, 18140, 7759, 260
https://tests.stockfishchess.org/tests/view/664c1d75830eb9f886616906
closes https://github.com/official-stockfish/Stockfish/pull/5282
No functional change
Also "fix" movepicker to allow depths between CHECKS and NO_CHECKS,
which makes them easier to tweak (not that they get tweaked hardly ever)
(This was more beneficial when there was a third stage to DEPTH_QS, but
it's still an improvement now)
closes https://github.com/official-stockfish/Stockfish/pull/5205
No functional change
Removes some max calls
Some speedup stats, courtesy of @AndyGrant (albeit measured in an alternate implementation)
Dev 749240 nps
Base 748495 nps
Gain 0.100%
289936 games
STC:
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 203040 W: 52213 L: 52179 D: 98648
Ptnml(0-2): 480, 20722, 59139, 20642, 537
https://tests.stockfishchess.org/tests/view/664805fe6dcff0d1d6b05f2ccloses#5261
No functional change
Created by first retraining the spsa-tuned main net `nn-ae6a388e4a1a.nnue` with:
- using v6-dd data without bestmove captures removed
- addition of T80 mar2024 data
- increasing loss by 20% when Q is too high
- torch.compile changes for marginal training speed gains
And then SPSA tuning weights of epoch 899 following methods described in:
https://github.com/official-stockfish/Stockfish/pull/5149
This net was reached at 92k out of 120k steps in this 70+0.7 th 7 SPSA tuning run:
https://tests.stockfishchess.org/tests/view/66413b7df9f4e8fc783c9bbb
Thanks to @Viren6 for suggesting usage of:
- c value 4 for the weights
- c value 128 for the biases
Scripts for automating applying fishtest spsa params to exporting tuned .nnue are in:
https://github.com/linrock/nnue-tools/tree/master/spsa
Before spsa tuning, epoch 899 was nn-f85738aefa84.nnue
https://tests.stockfishchess.org/tests/view/663e5c893a2f9702074bc167
After initially training with max-epoch 800, training was resumed with max-epoch 1000.
```
experiment-name: 3072--S11--more-data-v6-dd-t80-mar2024--see-ge0-20p-more-loss-high-q-sk28-l8
nnue-pytorch-branch: linrock/nnue-pytorch/3072-r21-skip-more-wdl-see-ge0-20p-more-loss-high-q-torch-compile-more
start-from-engine-test-net: False
start-from-model: /data/config/apr2024-3072/nn-ae6a388e4a1a.nnue
early-fen-skipping: 28
training-dataset:
/data/S11-mar2024/:
- leela96.v2.min.binpack
- test60-2021-11-12-novdec-12tb7p.v6-dd.min.binpack
- test78-2022-01-to-05-jantomay-16tb7p.v6-dd.min.binpack
- test80-2022-06-jun-16tb7p.v6-dd.min.binpack
- test80-2022-08-aug-16tb7p.v6-dd.min.binpack
- test80-2022-09-sep-16tb7p.v6-dd.min.binpack
- test80-2023-01-jan-16tb7p.v6-sk20.min.binpack
- test80-2023-02-feb-16tb7p.v6-sk20.min.binpack
- test80-2023-03-mar-2tb7p.v6-sk16.min.binpack
- test80-2023-04-apr-2tb7p.v6-sk16.min.binpack
- test80-2023-05-may-2tb7p.v6.min.binpack
# https://github.com/official-stockfish/Stockfish/pull/4782
- test80-2023-06-jun-2tb7p.binpack
- test80-2023-07-jul-2tb7p.binpack
# https://github.com/official-stockfish/Stockfish/pull/4972
- test80-2023-08-aug-2tb7p.v6.min.binpack
- test80-2023-09-sep-2tb7p.binpack
- test80-2023-10-oct-2tb7p.binpack
# S9 new data: https://github.com/official-stockfish/Stockfish/pull/5056
- test80-2023-11-nov-2tb7p.binpack
- test80-2023-12-dec-2tb7p.binpack
# S10 new data: https://github.com/official-stockfish/Stockfish/pull/5149
- test80-2024-01-jan-2tb7p.binpack
- test80-2024-02-feb-2tb7p.binpack
# S11 new data
- test80-2024-03-mar-2tb7p.binpack
/data/filt-v6-dd/:
- test77-dec2021-16tb7p-filter-v6-dd.binpack
- test78-juntosep2022-16tb7p-filter-v6-dd.binpack
- test79-apr2022-16tb7p-filter-v6-dd.binpack
- test79-may2022-16tb7p-filter-v6-dd.binpack
- test80-jul2022-16tb7p-filter-v6-dd.binpack
- test80-oct2022-16tb7p-filter-v6-dd.binpack
- test80-nov2022-16tb7p-filter-v6-dd.binpack
num-epochs: 1000
lr: 4.375e-4
gamma: 0.995
start-lambda: 0.8
end-lambda: 0.7
```
Training data can be found at:
https://robotmoon.com/nnue-training-data/
Local elo at 25k nodes per move:
nn-epoch899.nnue : 4.6 +/- 1.4
Passed STC:
https://tests.stockfishchess.org/tests/view/6645454893ce6da3e93b31ae
LLR: 2.95 (-2.94,2.94) <0.00,2.00>
Total: 95232 W: 24598 L: 24194 D: 46440
Ptnml(0-2): 294, 11215, 24180, 11647, 280
Passed LTC:
https://tests.stockfishchess.org/tests/view/6645522d93ce6da3e93b31df
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 320544 W: 81432 L: 80524 D: 158588
Ptnml(0-2): 164, 35659, 87696, 36611, 142
closes https://github.com/official-stockfish/Stockfish/pull/5254
bench 1995552
Basically the same idea as it is for continuation/main history, but it
has some tweaks.
1) it has * 2 multiplier for bonus instead of full/half bonus - for
whatever reason this seems to work better;
2) attempts with this type of big bonuses scaled somewhat poorly (or
were unlucky at longer time controls), but after measuring the fact
that average value of pawn history in LMR after adding this bonuses
increased by substantial number (for multiplier 1,5 it increased by
smth like 400~ from 8192 cap) attempts were made to make default pawn
history negative to compensate it - and version with multiplier 2 and
initial fill value -900 passed.
Passed STC:
https://tests.stockfishchess.org/tests/view/66424815f9f4e8fc783cba59
LLR: 2.93 (-2.94,2.94) <0.00,2.00>
Total: 115008 W: 30001 L: 29564 D: 55443
Ptnml(0-2): 432, 13629, 28903, 14150, 390
Passed LTC:
https://tests.stockfishchess.org/tests/view/6642f5437134c82f3f7a3ffa
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 56448 W: 14432 L: 14067 D: 27949
Ptnml(0-2): 36, 6268, 15254, 6627, 39
Bench: 1857237
Stockfish appears to take too much time on the first move of a game and
then not enough on moves 2,3,4... Probably caused by most of the factors
that increase time usually applying on the first move.
Attempts to give more time to the subsequent moves have not worked so
far, but this change to simply reduce first move time by 5% worked.
STC 10+0.1 :
LLR: 2.96 (-2.94,2.94) <0.00,2.00>
Total: 78496 W: 20516 L: 20135 D: 37845
Ptnml(0-2): 340, 8859, 20456, 9266, 327
https://tests.stockfishchess.org/tests/view/663d47bf507ebe1c0e9200ba
LTC 60+0.6 :
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 94872 W: 24179 L: 23751 D: 46942
Ptnml(0-2): 61, 9743, 27405, 10161, 66
https://tests.stockfishchess.org/tests/view/663e779cbb28828150dd9089
closes https://github.com/official-stockfish/Stockfish/pull/5235
Bench: 1876282
1. The current time management system utilizes limits.inc and
limits.time, which can represent either milliseconds or node count,
depending on whether the nodestime option is active. There have been
several modifications which brought Elo gain for typical uses (i.e.
real-time matches), however some of these changes overlooked such
distinction. This patch adjusts constants and multiplication/division to
more accurately simulate real TC conditions when nodestime is used.
2. The advance_nodes_time function has a bug that can extend the time
limit when availableNodes reaches exact zero. This patch fixes the bug
by initializing the variable to -1 and make sure it does not go below
zero.
3. elapsed_time function is newly introduced to print PV in the UCI
output based on real time. This makes PV output more consistent with the
behavior of trivial use cases.
closes https://github.com/official-stockfish/Stockfish/pull/5186
No functional changes
If there is an upper bound stored in the transposition table, but we still have a ttMove, the upperbound indicates that the last time the ttMove was tried, it failed low. This fail low indicates that the ttMove may not be good, so this patch introduces a depth reduction of one for cutnodes with such ttMoves.
Passed STC:
https://tests.stockfishchess.org/tests/view/663be4d1ca93dad645f7f45f
LLR: 2.93 (-2.94,2.94) <0.00,2.00>
Total: 139424 W: 35900 L: 35433 D: 68091
Ptnml(0-2): 425, 16357, 35743, 16700, 487
Passed LTC:
https://tests.stockfishchess.org/tests/view/663bec95ca93dad645f7f5c8
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 129690 W: 32902 L: 32390 D: 64398
Ptnml(0-2): 63, 14304, 35610, 14794, 74
closes https://github.com/official-stockfish/Stockfish/pull/5227
bench 2257437
Make it formula more in line with what we use in search - current formula is more or less the one we used years ago for search but since then it was remade, this patch remakes qsearch formula to almost exactly the same as we use in search - with sum of conthist 0, 1 and pawn structure history.
Passed STC:
https://tests.stockfishchess.org/tests/view/6639c8421343f0cb16716206
LLR: 2.93 (-2.94,2.94) <0.00,2.00>
Total: 84992 W: 22414 L: 22019 D: 40559
Ptnml(0-2): 358, 9992, 21440, 10309, 397
Passed LTC:
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 119136 W: 30407 L: 29916 D: 58813
Ptnml(0-2): 46, 13192, 32622, 13641, 67
closes https://github.com/official-stockfish/Stockfish/pull/5224
Bench: 2138659
The idea came to me by checking for trends from the megafauzi tunes, since the values of the divisor for this specific formula were as follows:
stc: 15990
mtc: 16117
ltc: 14805
vltc: 12719
new vltc passed by Muzhen: 12076
This shows a clear trend related to time control, the higher it is, the lower the optimum value for the divisor seems to be.
So I tried a simple formula, using educated guesses based on some calculations, tests show it works pretty fine, and it can still be further tuned at VLTC in the future to scale even better.
Passed STC:
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 431360 W: 110791 L: 109898 D: 210671
Ptnml(0-2): 1182, 50846, 110698, 51805, 1149
https://tests.stockfishchess.org/tests/view/663770409819650825aa269f
Passed LTC:
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 114114 W: 29109 L: 28625 D: 56380
Ptnml(0-2): 105, 12628, 31101, 13124, 99
https://tests.stockfishchess.org/tests/view/66378c099819650825aa73f6https://github.com/official-stockfish/Stockfish/pull/5223
bench: 2273551
This adds the functions `update_refutations` and `update_quiet_histories` to better distinguish the two. `update_quiet_stats` now just calls both of these functions.
The functional side of this patch is two-fold:
1. Stop refutations being updated when we carry out multicut
2. Update pawn history every time we update other quiet histories
Yellow STC:
LLR: -2.95 (-2.94,2.94) <0.00,2.00>
Total: 238976 W: 61506 L: 61415 D: 116055
Ptnml(0-2): 846, 28628, 60456, 28705, 853
https://tests.stockfishchess.org/tests/view/66321b5ed01fb9ac9bcdca83
However, it passed in <-1.75, 0.25> bounds:
$ python3 sprt.py --wins 61506 --losses 61415 --draws 116055 --elo0 -1.75 --elo1 0.25
ELO: 0.132 +- 0.998 [-0.865, 1.13]
LLR: 4.15 [-1.75, 0.25] (-2.94, 2.94)
H1 Accepted
Passed LTC:
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 399126 W: 100730 L: 100896 D: 197500
Ptnml(0-2): 116, 44328, 110843, 44158, 118
https://tests.stockfishchess.org/tests/view/66357b0473559a8aa857ba6fcloses#5215
Bench 2370967
Saves a (currently) 800 KB allocation and deallocation when running
`eval`, not particularly significant and zero impact on play but not
necessary either.
closes https://github.com/official-stockfish/Stockfish/pull/5201
No functional change
Adds size in memory as well as layer sizes as in
info string NNUE evaluation using nn-ae6a388e4a1a.nnue (132MiB, (22528, 3072, 15, 32, 1))
info string NNUE evaluation using nn-baff1ede1f90.nnue (6MiB, (22528, 128, 15, 32, 1))
For example, the size in MiB is useful to keep the fishtest memory sizes up-to-date,
the L1-L3 sizes give a useful hint about the architecture used.
closes https://github.com/official-stockfish/Stockfish/pull/5193
No functional change
For each thread persist an accumulator cache for the network, where each
cache contains multiple entries for each of the possible king squares.
When the accumulator needs to be refreshed, the cached entry is used to more
efficiently update the accumulator, instead of rebuilding it from scratch.
This idea, was first described by Luecx (author of Koivisto) and
is commonly referred to as "Finny Tables".
When the accumulator needs to be refreshed, instead of filling it with
biases and adding every piece from scratch, we...
1. Take the `AccumulatorRefreshEntry` associated with the new king bucket
2. Calculate the features to activate and deactivate (from differences
between bitboards in the entry and bitboards of the actual position)
3. Apply the updates on the refresh entry
4. Copy the content of the refresh entry accumulator to the accumulator
we were refreshing
5. Copy the bitboards from the position to the refresh entry, to match
the newly updated accumulator
Results at STC:
https://tests.stockfishchess.org/tests/view/662301573fe04ce4cefc1386
(first version)
https://tests.stockfishchess.org/tests/view/6627fa063fe04ce4cefc6560
(final)
Non-Regression between first and final:
https://tests.stockfishchess.org/tests/view/662801e33fe04ce4cefc660a
STC SMP:
https://tests.stockfishchess.org/tests/view/662808133fe04ce4cefc667c
closes https://github.com/official-stockfish/Stockfish/pull/5183
No functional change
Parameters Tune, adding also another tunable parameter (npmDiv) to be
variable for different nets (bignet, smallnet, psqtOnly smallnet). P.s:
The changed values are only the parameters where there is agreement
among the different time controls, so in other words, the tunings are
telling us that changing these specific values to this specific
direction is good in all time controls, so there shouldn't be a high
risk of regressing at longer time controls.
Passed STC:
LLR: 2.97 (-2.94,2.94) <0.00,2.00>
Total: 39552 W: 10329 L: 9999 D: 19224
Ptnml(0-2): 156, 4592, 9989, 4844, 195
https://tests.stockfishchess.org/tests/view/661be9a0bd68065432a088c0
Passed LTC:
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 56394 W: 14439 L: 14078 D: 27877
Ptnml(0-2): 30, 6152, 15480, 6497, 38
https://tests.stockfishchess.org/tests/view/661c746296961e72eb565406
closes https://github.com/official-stockfish/Stockfish/pull/5187
Bench: 1836777
Previously it was possible to also get the node counter after running a bench with perft, i.e.
`./stockfish bench 1 1 5 current perft`, caused by a small regression from the uci refactoring.
```
Nodes searched: 4865609
===========================
Total time (ms) : 18
Nodes searched : 4865609
Nodes/second : 270311611
````
closes https://github.com/official-stockfish/Stockfish/pull/5188
No functional change
We change the definition of "age" from "age of this position" to "age of this TT entry".
In this way, despite being on the same position, when we save into TT, we always prefer the new entry as compared to the old one.
Passed STC:
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 152256 W: 39597 L: 39110 D: 73549
Ptnml(0-2): 556, 17562, 39398, 18063, 549
https://tests.stockfishchess.org/tests/view/6620faee3fe04ce4cefbf215
Passed LTC:
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 51564 W: 13242 L: 12895 D: 25427
Ptnml(0-2): 24, 5464, 14463, 5803, 28
https://tests.stockfishchess.org/tests/view/66231ab53fe04ce4cefc153ecloses#5184
Bench 1479416
It makes more sense to not (potentially) change the developers alsr entropy setting to make the test run through. This should be an active choice even if the test then might fail locally for them.
closes https://github.com/official-stockfish/Stockfish/pull/5182
No functional change
the recent refactoring has shown some limitations of our testing, hence we add a couple of more tests including:
* expected mate score
* expected mated score
* expected in TB win score
* expected in TB loss score
* expected info line output
* expected info line output (wdl)
closes https://github.com/official-stockfish/Stockfish/pull/5181
No functional change
Fix another case of 9032c6cbe7
* TB values can have a distance of 0, mainly when we are in a tb position but haven't found mate.
* Add a missing whitespace to UCIEngine::on_update_no_moves()
Closes https://github.com/official-stockfish/Stockfish/pull/5172
No functional change
Also fixes searchmoves.
Drop the need of a Position object in uci.cpp.
A side note, it is still required for the static functions,
but these should be moved to a different namespace/class
later on, since sf kinda relies on them.
closes https://github.com/official-stockfish/Stockfish/pull/5169
No functional change
The assignment (ss + 1)->excludedMove = Move::none() can be simplified away because when that line is reached, (ss + 1)->excludedMove is always already none. The only moment stack[x]->excludedMove is modified, is during singular search, but it is reset to none right after the singular search is finished.
closes https://github.com/official-stockfish/Stockfish/pull/5153
No functional change
The same functionality is available by using COMPCXX and having another variable which does the same is just confusing.
There was only one mention on Stockfish Wiki about this which has been changed to COMPCXX.
closes https://github.com/official-stockfish/Stockfish/pull/5154
No functional change
Part 2 of the Split UCI into UCIEngine and Engine refactor.
This creates function callbacks for search to use when an update should occur.
The benching in uci.cpp for example does this to extract the total nodes
searched.
No functional change
This is another refactor which aims to decouple uci from stockfish. A new engine
class manages all engine related logic and uci is a "small" wrapper around it.
In the future we should also try to remove the need for the Position object in
the uci and replace the options with an actual options struct instead of using a
map. Also convert the std::string's in the Info structs a string_view.
closes#5147
No functional change
In the last couple of months we sometimes saw duplicated prereleases uploaded to GitHub, possibly due to some racy behavior when concurrent jobs create a prerelease. This now creates an empty prerelease at the beginning of the CI and the binaries are later just attached to this one.
closes https://github.com/official-stockfish/Stockfish/pull/5144
No functional change
This PR proposes to change the parameter dependence of Stockfish's
internal WDL model from full move counter to material count. In addition
it ensures that an evaluation of 100 centipawns always corresponds to a
50% win probability at fishtest LTC, whereas for master this holds only
at move number 32. See also
https://github.com/official-stockfish/Stockfish/pull/4920 and the
discussion therein.
The new model was fitted based on about 340M positions extracted from
5.6M fishtest LTC games from the last three weeks, involving SF versions
from e67cc979fd (SF 16.1) to current
master.
The involved commands are for
[WDL_model](https://github.com/official-stockfish/WDL_model) are:
```
./updateWDL.sh --firstrev e67cc979fd
python scoreWDL.py updateWDL.json --plot save --pgnName update_material.png --momType "material" --momTarget 58 --materialMin 10 --modelFitting optimizeProbability
```
The anchor `58` for the material count value was chosen to be as close
as possible to the observed average material count of fishtest LTC games
at move 32 (`43`), while not changing the value of
`NormalizeToPawnValue` compared to the move-based WDL model by more than
1.
The patch only affects the displayed cp and wdl values.
closes https://github.com/official-stockfish/Stockfish/pull/5121
No functional change
Before, one always had to keep track of the bonus one assigns to a history to stop
the stats from overflowing. This is a quality of life improvement. Since this would often go unnoticed during benching.
Passed non-regression bounds:
https://tests.stockfishchess.org/tests/view/65ef2af40ec64f0526c44cbc
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 179232 W: 46513 L: 46450 D: 86269
Ptnml(0-2): 716, 20323, 47452, 20432, 693
closes https://github.com/official-stockfish/Stockfish/pull/5116
No functional change
Reported by @Torom over discord.
> dev build fails on Raspberry Pi 5 with clang
```
clang++ -o stockfish benchmark.o bitboard.o evaluate.o main.o misc.o movegen.o movepick.o position.o search.o thread.o timeman.o tt.o uci.o ucioption.o tune.o tbprobe.o nnue_misc.o half_ka_v2_hm.o network.o -fprofile-instr-generate -latomic -lpthread -Wall -Wcast-qual -fno-exceptions -std=c++17 -fprofile-instr-generate -pedantic -Wextra -Wshadow -Wmissing-prototypes -Wconditional-uninitialized -DUSE_PTHREADS -DNDEBUG -O3 -funroll-loops -DIS_64BIT -DUSE_POPCNT -DUSE_NEON=8 -march=armv8.2-a+dotprod -DUSE_NEON_DOTPROD -DGIT_SHA=627974c9 -DGIT_DATE=20240312 -DARCH=armv8-dotprod -flto=full
/tmp/lto-llvm-e9300e.o: in function `_GLOBAL__sub_I_network.cpp':
ld-temp.o:(.text.startup+0x704c): relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `gEmbeddedNNUEBigEnd' defined in .rodata section in /tmp/lto-llvm-e9300e.o
/usr/bin/ld: ld-temp.o:(.text.startup+0x704c): warning: one possible cause of this error is that the symbol is being referenced in the indicated code as if it had a larger alignment than was declared where it was defined
ld-temp.o:(.text.startup+0x7068): relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `gEmbeddedNNUESmallEnd' defined in .rodata section in /tmp/lto-llvm-e9300e.o
/usr/bin/ld: ld-temp.o:(.text.startup+0x7068): warning: one possible cause of this error is that the symbol is being referenced in the indicated code as if it had a larger alignment than was declared where it was defined
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Makefile:1051: stockfish] Error 1
make[2]: Leaving directory '/home/torsten/chess/Stockfish_master/src'
make[1]: *** [Makefile:1058: clang-profile-make] Error 2
make[1]: Leaving directory '/home/torsten/chess/Stockfish_master/src'
make: *** [Makefile:886: profile-build] Error 2
```
closes https://github.com/official-stockfish/Stockfish/pull/5106
No functional change
- fix naming convention for `workingDirectory`
- use type alias for `EvalFiles` everywhere
- move `ponderMode` into `LimitsType`
- move limits parsing into standalone static function
closes https://github.com/official-stockfish/Stockfish/pull/5098
No functional change
Fixes two issues with master for go mate x:
- when running go mate x in losing positions, master always goes to the
maximal depth, arguably against what the UCI protocol demands
- when running go mate x in winning positions with multiple
threads, master may return non-mate scores from the search (this issue
is present in stockfish since at least sf16) The issues are fixed by
(a) also checking if score is mate -x and by (b) only letting
mainthread stop the search for go mate x commands, and by not looking
for a best thread but using mainthread as per the default. Related:
niklasf/python-chess#1070
More diagnostics can be found here peregrineshahin#6 (comment)
closes https://github.com/official-stockfish/Stockfish/pull/5094
No functional change
Co-Authored-By: Robert Nürnberg <28635489+robertnurnberg@users.noreply.github.com>
This reduces the futiltiy_margin if our opponents last move was bad by
around ~1/3 when not improving and ~1/2.7 when improving, the idea being
to retroactively futility prune moves that were played, but turned out
to be bad. A bad move is being defined as their staticEval before their
move being lower as our staticEval now is. If the depth is 2 and we are
improving the opponent worsening flag is not set, in order to not risk
having a too low futility_margin, due to the fact that when these
conditions are met the futility_margin already drops quite low.
Passed STC:
https://tests.stockfishchess.org/tests/live_elo/65e3977bf2ef6c733362aae3
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 122432 W: 31884 L: 31436 D: 59112
Ptnml(0-2): 467, 14404, 31035, 14834, 476
Passed LTC:
https://tests.stockfishchess.org/tests/live_elo/65e47f40f2ef6c733362b6d2
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 421692 W: 106572 L: 105452 D: 209668
Ptnml(0-2): 216, 47217, 114865, 48327, 221
closes https://github.com/official-stockfish/Stockfish/pull/5092
Bench: 1565939
Created by retraining the previous main net `nn-b1a57edbea57.nnue` with:
- some of the same options as before:
- ranger21, more WDL skipping, 15% more loss when Q is too high
- removal of the huge 514G pre-interleaved binpack
- removal of SF-generated dfrc data (dfrc99-16tb7p-filt-v2.min.binpack)
- interleaving many binpacks at training time
- training with some bestmove capture positions where SEE < 0
- increased usage of torch.compile to speed up training by up to 40%
```yaml
experiment-name: 2560--S10-dfrc0-to-dec2023-skip-more-wdl-15p-more-loss-high-q-see-ge0-sk28
nnue-pytorch-branch: linrock/nnue-pytorch/r21-more-wdl-skip-15p-more-loss-high-q-skip-see-ge0-torch-compile-more
start-from-engine-test-net: True
early-fen-skipping: 28
training-dataset:
# similar, not the exact same as:
# https://github.com/official-stockfish/Stockfish/pull/4635
- /data/S5-5af/leela96.v2.min.binpack
- /data/S5-5af/test60-2021-11-12-novdec-12tb7p.v6-dd.min.binpack
- /data/S5-5af/test77-2021-12-dec-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test78-2022-01-to-05-jantomay-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test78-2022-06-to-09-juntosep-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test79-2022-04-apr-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test79-2022-05-may-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test80-2022-06-jun-16tb7p.v6-dd.min.unmin.binpack
- /data/S5-5af/test80-2022-07-jul-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test80-2022-08-aug-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test80-2022-09-sep-16tb7p.v6-dd.min.unmin.binpack
- /data/S5-5af/test80-2022-10-oct-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test80-2022-11-nov-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test80-2023-01-jan-16tb7p.v6-sk20.min.binpack
- /data/S5-5af/test80-2023-02-feb-16tb7p.v6-dd.min.binpack
- /data/S5-5af/test80-2023-03-mar-2tb7p.min.unmin.binpack
- /data/S5-5af/test80-2023-04-apr-2tb7p.binpack
- /data/S5-5af/test80-2023-05-may-2tb7p.min.dd.binpack
# https://github.com/official-stockfish/Stockfish/pull/4782
- /data/S6-1ee1aba5ed/test80-2023-06-jun-2tb7p.binpack
- /data/S6-1ee1aba5ed/test80-2023-07-jul-2tb7p.min.binpack
# https://github.com/official-stockfish/Stockfish/pull/4972
- /data/S8-baff1edbea57/test80-2023-08-aug-2tb7p.v6.min.binpack
- /data/S8-baff1edbea57/test80-2023-09-sep-2tb7p.binpack
- /data/S8-baff1edbea57/test80-2023-10-oct-2tb7p.binpack
# https://github.com/official-stockfish/Stockfish/pull/5056
- /data/S9-b1a57edbea57/test80-2023-11-nov-2tb7p.binpack
- /data/S9-b1a57edbea57/test80-2023-12-dec-2tb7p.binpack
num-epochs: 800
lr: 4.375e-4
gamma: 0.995
start-lambda: 1.0
end-lambda: 0.7
```
This particular net was reached at epoch 759. Use of more torch.compile decorators
in nnue-pytorch model.py than in the previous main net training run sped up training
by up to 40% on Tesla gpus when using recent pytorch compiled with cuda 12:
https://github.com/linrock/nnue-tools/blob/7fb9831/Dockerfile
Skipping positions with bestmove captures where static exchange evaluation is >= 0
is based on the implementation from Sopel's NNUE training & experimentation log:
https://docs.google.com/document/d/1gTlrr02qSNKiXNZ_SuO4-RjK4MXBiFlLE6jvNqqMkAY
Experiment 293 - only skip captures with see>=0
Positions with bestmove captures where score == 0 are always skipped for
compatibility with minimized binpacks, since the original minimizer sets
scores to 0 for slight improvements in compression.
The trainer branch used was:
https://github.com/linrock/nnue-pytorch/tree/r21-more-wdl-skip-15p-more-loss-high-q-skip-see-ge0-torch-compile-more
Binpacks were renamed to be sorted chronologically by default when sorted by name.
The binpack data are otherwise the same as binpacks with similar names in the prior
naming convention.
Training data can be found at:
https://robotmoon.com/nnue-training-data/
Passed STC:
https://tests.stockfishchess.org/tests/view/65e3ddd1f2ef6c733362ae5c
LLR: 2.92 (-2.94,2.94) <0.00,2.00>
Total: 149792 W: 39153 L: 38661 D: 71978
Ptnml(0-2): 675, 17586, 37905, 18032, 698
Passed LTC:
https://tests.stockfishchess.org/tests/view/65e4d91c416ecd92c162a69b
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 64416 W: 16517 L: 16135 D: 31764
Ptnml(0-2): 38, 7218, 17313, 7602, 37
closes https://github.com/official-stockfish/Stockfish/pull/5090
Bench: 1373183
send "position fen 5K2/8/2qk4/2nPp3/3r4/6B1/B7/3R4 w - e6\n"
send "go depth 18\n"
expect "score mate 1"
expect "pv d5e6"
expect "bestmove d5e6"
send "ucinewgame\n"
send "position fen 2brrb2/8/p7/Q7/1p1kpPp1/1P1pN1K1/3P4/8 b - -\n"
send "go depth 18\n"
expect "score mate -1"
expect "bestmove"
send "ucinewgame\n"
send "position fen 7K/P1p1p1p1/2P1P1Pk/6pP/3p2P1/1P6/3P4/8 w - - 0 1\n"
send "go nodes 500000\n"
expect "bestmove"
send "ucinewgame\n"
send "position fen 8/5R2/2K1P3/4k3/8/b1PPpp1B/5p2/8 w - -\n"
send "go depth 18 searchmoves c6d7\n"
expect "score mate 2 * pv c6d7 * f7f5"
expect "bestmove c6d7"
send "ucinewgame\n"
send "position fen 8/5R2/2K1P3/4k3/8/b1PPpp1B/5p2/8 w - -\n"
send "go mate 2 searchmoves c6d7\n"
expect "score mate 2 * pv c6d7"
expect "bestmove c6d7"
send "ucinewgame\n"
send "position fen 8/5R2/2K1P3/4k3/8/b1PPpp1B/5p2/8 w - -\n"
send "go nodes 500000 searchmoves c6d7\n"
expect "score mate 2 * pv c6d7 * f7f5"
expect "bestmove c6d7"
send "ucinewgame\n"
send "position fen 1NR2B2/5p2/5p2/1p1kpp2/1P2rp2/2P1pB2/2P1P1K1/8 b - - \n"
send "go depth 27\n"
expect "score mate -2"
expect "pv d5e6 c8d8"
expect "bestmove d5e6"
send "ucinewgame\n"
send "position fen 8/5R2/2K1P3/4k3/8/b1PPpp1B/5p2/8 w - - moves c6d7 f2f1q\n"
send "go depth 18\n"
expect "score mate 1 * pv f7f5"
expect "bestmove f7f5"
send "ucinewgame\n"
send "position fen 8/5R2/2K1P3/4k3/8/b1PPpp1B/5p2/8 w - -\n"
send "go depth 18 searchmoves c6d7\n"
expect "score mate 2 * pv c6d7 * f7f5"
expect "bestmove c6d7"
send "ucinewgame\n"
send "position fen 8/5R2/2K1P3/4k3/8/b1PPpp1B/5p2/8 w - - moves c6d7\n"
send "go depth 18 searchmoves e3e2\n"
expect "score mate -1 * pv e3e2 f7f5"
expect "bestmove e3e2"
send "setoption name EvalFile value verify.nnue\n"
send "position startpos\n"
send "go depth 5\n"
@@ -147,6 +226,13 @@ cat << EOF > game.exp
send "setoption name MultiPV value 4\n"
send "position startpos\n"
send "go depth 5\n"
expect "bestmove"
send "setoption name Skill Level value 10\n"
send "position startpos\n"
send "go depth 5\n"
expect "bestmove"
send "setoption name Skill Level value 20\n"
send "quit\n"
expect eof
@@ -164,17 +250,30 @@ fi
cat << EOF > syzygy.exp
set timeout 240
# to correctly catch eof we need the following line
# expect_before timeout { exit 2 } eof { exit 3 }
expect_before timeout { exit 2 }
spawn $exeprefix ./stockfish
expect "Stockfish"
send "uci\n"
send "setoption name SyzygyPath value ../tests/syzygy/\n"
expect "info string Found 35 tablebases" {} timeout {exit 1}
expect "info string Found 35 WDL and 35 DTZ tablebase files (up to 4-man)."
send "bench 128 1 8 default depth\n"
expect "Nodes searched :"
send "ucinewgame\n"
send "position fen 4k3/PP6/8/8/8/8/8/4K3 w - - 0 1\n"
send "go depth 5\n"
expect -re {score cp 20000|score mate}
expect "bestmove"
send "ucinewgame\n"
send "position fen 8/1P6/2B5/8/4K3/8/6k1/8 w - - 0 1\n"
send "go depth 5\n"
expect -re {score cp 20000|score mate}
expect "bestmove"
send "ucinewgame\n"
send "position fen 8/1P6/2B5/8/4K3/8/6k1/8 b - - 0 1\n"
send "go depth 5\n"
expect -re {score cp -20000|score mate}
expect "bestmove"
send "quit\n"
expect eof
@@ -187,6 +286,9 @@ EOF
for exp in game.exp syzygy.exp
do
echo"======== $exp =============="
cat $exp
echo"============================"
echo"$prefix expect $exp$postfix"
eval"$prefix expect $exp$postfix"
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.