Skip to content

simple Makefile autodetect for ARCH and BITS - #312

Open
RBEGamer wants to merge 2596 commits into
mcostalba:masterfrom
official-stockfish:master
Open

simple Makefile autodetect for ARCH and BITS#312
RBEGamer wants to merge 2596 commits into
mcostalba:masterfrom
official-stockfish:master

Conversation

@RBEGamer

Copy link
Copy Markdown

I added a simple autodetect flag for the makefile:
make build ARCH=autodetect
### 2.1.1 Simple Defaults Autodetection ifeq ($(ARCH),autodetect) arch = $(shell uname -m) bits = $(shell getconf LONG_BIT) endif
I used the modification in my docker build system.
Maybe its useful!

@dav1312
dav1312 force-pushed the master branch 2 times, most recently from 9173bb1 to e0afedd Compare October 5, 2023 14:08
FauziAkram and others added 25 commits April 9, 2026 21:53
Using the already existing pawn_single_push_bb helper which encapsulates
the exact same logic.

closes #6700

No functional change
[Passed
STC](https://tests.stockfishchess.org/tests/live_elo/69cf6a5d1668971c9da23ae1)
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 51104 W: 13376 L: 13180 D: 24548
Ptnml(0-2): 134, 5555, 13963, 5781, 119

[Passed
LTC](https://tests.stockfishchess.org/tests/live_elo/69d00a7ee2b443cb2670b5c6)
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 101256 W: 25867 L: 25732 D: 49657
Ptnml(0-2): 59, 10423, 29520, 10576, 50

When processing a promotion we add/remove nonsensical threats, namely,
piece threats of pawns on the 1st or 8th rank. This is not only
inefficient but also seems to lead to an obscure bug during a
promotion–capture + `double_inc_update` that causes a lingering invalid
feature. Currently – as an artifact of the training process – these
parts of the net are filled with random values in [-1,1], which is why
there is a bench change.

@ces42 did a helpful analysis:

> checking bench with depth 17 actually shows that the bug in has been
there all the time since 8e5392d (when threat inputs was merged into
master)
> i.e. double_inc_update for ThreatFeatureSet has always been slightly
bugged

After this patch is applied we'll be able to better compress the net by
filling the invalid features with 0, w/o changing bench. I expect a
15%-ish size savings.

closes #6701

Bench: 2700393
Instead of checking whether a threat index is valid and then writing to
a vector if it isn't, we can instead always write to the buffer of the
vector, and only increase the size of the vector if the index is valid.

This saves some branch mispredictions.

passed STC:
https://tests.stockfishchess.org/tests/view/69ceb1689f7a7e3fdfc9a44b
LLR: 2.95 (-2.94,2.94) <0.00,2.00>
Total: 205760 W: 53109 L: 52561 D: 100090
Ptnml(0-2): 603, 22552, 56076, 22992, 657

local speedtest shows
```
Result of 100 runs (cycles)
===========================
base (...ockfish.orig) =     296886  +/- 1645
test (...kfish.df0822) =     298862  +/- 1662
speedup %              =      +0.67  +/- 0.19
                         [95% CI; t-statistic]

p(speedup > 0)   =  1.0000
p(speedup > .5%) =  0.9562

CPU: 16 x Intel(R) Core(TM) Ultra 9 185H
Hyperthreading: on
```

closes #6703

No functional change
The uci pv suppression and PV roll-back logic in master is a bit
convoluted, which makes it hard to reason about the code. In fact,
subtle bugs that led to wrong mated-in scores in game play or a mismatch
between bestmove and first PV move were only recently fixed. Moreover,
in master the uci pv output through `pv()` is called in four different
places.

This PR proposes to simplify this logic. In this patch, the PV is sent
to the GUI from within `iterative_deepening()` only (a) for fail
highs/lows or (b) when an iteration for a root move is completed. All
other PV outputs are now handled by `start_searching()`, just before the
bestmove extraction. This easily ensures that bestmove (and ponder move)
will always be in sync with the final PV output.

The only noticeable change to master is for multi-threaded searches that
do not involve `limits.depth`. Here master would show both the PV from
the aborted search in main thread, as well as the new PV from the
selected best thread. This patch would only show the latter.

While at it, we also remove the requirement to finish at least a depth 1
search and simplify the logic around stalemates/checkmates at root and
in particular avoid any PVs that start with `Move::none()`.

Passed STC non-reg:
LLR: 2.96 (-2.94,2.94) <-1.75,0.25>
Total: 72416 W: 18784 L: 18609 D: 35023
Ptnml(0-2): 200, 7762, 20127, 7901, 218
https://tests.stockfishchess.org/tests/view/69d3ef0c33584dad27b3c85a

closes #6704

No functional change
Passed STC non-reg:
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 102272 W: 26553 L: 26411 D: 49308
Ptnml(0-2): 269, 11212, 28036, 11346, 273
https://tests.stockfishchess.org/tests/view/69d0f1c5e2b443cb2670b710

closes #6707

No functional change
For some time now we can trust the threads' exact win/loss scores. This
allows for some simplification in the best thread selection code.

closes #6708

No functional change
Passed non-regression STC:
https://tests.stockfishchess.org/tests/view/69d2d3de61a12cebe17ede38
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 68384 W: 17646 L: 17459 D: 33279
Ptnml(0-2): 200, 8058, 17496, 8231, 207

Passed non-regression LTC:
https://tests.stockfishchess.org/tests/view/69d4293433584dad27b3c8cb
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 37290 W: 9582 L: 9380 D: 18328
Ptnml(0-2): 18, 3915, 10579, 4113, 20

closes #6711

Bench: 2923401
the assert checks for `bestThreadDecisive && newThreadDecisive`. However `newThreadDecisive` is not guaranteed at this point, leading to assertion failures. This PR rearranges the conditions to ensure correctness.

closes #6716

No functional change
A bit tricky to identify, but in `apple-silicon` builds, specifying a value for
`SyzygyPath` could still lead to crashes at certain depths from a
SIGBUS/SIGSEGV.

This PR replaces the `std::count_if()` adjustment in `tbprobe.cpp`'s
`do_probe_table()` with an annotated handwritten loop, avoiding the clang/LTO
miscompilation behind the crash.

closes #6721

No functional change.
STC: https://tests.stockfishchess.org/tests/view/69d586a64088e069540a22aa
LLR: 2.93 (-2.94,2.94) <0.00,2.00>
Total: 63520 W: 16579 L: 16233 D: 30708
Ptnml(0-2): 138, 7179, 16825, 7435, 183

LTC: https://tests.stockfishchess.org/tests/view/69d6ddd79ffee997bab13a98
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 227100 W: 58279 L: 57591 D: 111230
Ptnml(0-2): 95, 23435, 65828, 24071, 121

Transition highBestMoveEffort smoothly instead of abruptly. May also be more amenable to future tuning.

closes #6729

Bench: 2923401
Trained with the following yaml definition https://github.com/Disservin/nettest/blob/8da0a21503adb341bc89ca20b4e2f166c7c9720d/threats.yaml

and the following trainer change
official-stockfish/nnue-pytorch@d87c248

Initially I saw a lot of weird 0 scores in the binpack, since then @linrock has explained to me/us their meaning and mentioned that they are actually mostly skipped.. except a very small percentage, however it seems this change was still beneficial.

Passed STC:
https://tests.stockfishchess.org/tests/view/69db95f43ca80bdf151d4913
LLR: 2.95 (-2.94,2.94) <0.00,2.00>
Total: 106272 W: 27916 L: 27489 D: 50867
Ptnml(0-2): 420, 12533, 26841, 12884, 458

Passed LTC:
https://tests.stockfishchess.org/tests/view/69ddd9003ca80bdf151d4c4d
LLR: 2.94 (-2.94,2.94) <0.50,2.50>
Total: 29748 W: 7775 L: 7470 D: 14503
Ptnml(0-2): 24, 3136, 8247, 3445, 22

closes #6730

Bench: 3108996
STC: https://tests.stockfishchess.org/tests/view/69cf29ed1668971c9da23a5a
LLR: 3.47 (-2.94,2.94) <-1.75,0.25>
Total: 193760 W: 50142 L: 50051 D: 93567
Ptnml(0-2): 534, 21375, 52980, 21448, 543

* Simplify retval and arithmetic semantics
* Remove mixing of int and uint8_t

I find this overall much easier to reason about

(Also rename a DEPTH constant per mstembera's suggestion #5766 (comment))

closes #6702

No functional change
Conditions for no pawn pushes, non-pawn material and last captured piece are already such restrictive that we don't need to artificially set checkers bitboard for legal move generation.
Also moving the check for available pawn pushes at first place, as it should already filter about 90% of cases.

Passed STC and LTC non-regression tests.
 LLR: 2.96 (-2.94,2.94) <-1.75,0.25>
Total: 171232 W: 44202 L: 44131 D: 82899
Ptnml(0-2): 466, 18809, 47023, 18824, 494
https://tests.stockfishchess.org/tests/view/69d3623b61a12cebe17ededa

LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 55662 W: 14424 L: 14247 D: 26991
Ptnml(0-2): 38, 5479, 16609, 5678, 27
https://tests.stockfishchess.org/tests/view/69d64cada07a818b0a25f95e

And also neutral on 10k fixed games test with custom stalemate book.
 Elo: 0.24 ± 0.9 (95%) LOS: 69.9%
Total: 10000 W: 4681 L: 4674 D: 645
Ptnml(0-2): 0, 87, 4819, 94, 0
nElo: 1.81 ± 6.8 (95%) PairsRatio: 1.08
https://tests.stockfishchess.org/tests/view/69d7e4183ca80bdf151d43b8

closes #6715

Bench: 2984258
In C++, all standard input streams (including std::istringstream) are initialized with the skipws format flag enabled by default. Because these stream objects are scoped locally and freshly constructed on each loop iteration, we are guaranteed that skipws is already active.

closes #6719

No functional change
Use a dedicated struct for keeping track of the pv moves.

anematode pointed out that we can use the ValueList for this as well, left that open for a future patch.

Passed Non Regression
https://tests.stockfishchess.org/tests/view/69d399cfec2dc6794cf18376
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 267264 W: 68895 L: 68927 D: 129442
Ptnml(0-2): 790, 29238, 73566, 29290, 748

closes #6726

No functional change
Since as of 9417552 the en passant square is
only set if there is a legal en passant capture, the special handling is
redundant

Passed Non-Regression STC:
https://tests.stockfishchess.org/tests/view/696ffb6512ee1f6231b96fe8
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 79072 W: 20380 L: 20210 D: 38482.

closes #6560

No functional change
We maintain support for quite a few x86 ISA extensions but relied on the end
user to select the binary that is best for their system.  We can detect at
runtime which architecture to use, and ship a single binary (per OS/ISA
combination). This PR does so, maintaining performance.

This is what I've landed on after quite a few iterations. Basically, we build
each arch separately, use `cpuid` to select one, and jump to that arch's main
function. Some details:

- The preprocessor macro `UNIVERSAL_BINARY` is defined when building for the universal binary.

- The Makefile target `universal-object-[no]pgo` is added, which produces a `stockfish.o` in each arch's build directory.

- To prevent symbol collisions between the multiple builds, we `#define Stockfish Stockfish_[arch]`. Furthermore we wrap the `main` function in `namespace Stockfish { }`.

- We can still get PGO data by linking to a per-arch binary, with `Stockfish_x86_64_avx2::main` as `main`, and running `bench`.
    - For arches not supported by the host we can use Intel SDE – this is what we do in CI.

- When embedding the NNUE, we use C++26/C23 `#embed` instead of `INCBIN`. The issue with `INCBIN` is that it injects assembly directives that we have no control over.
    - To ensure there's only one copy of the networks in the final binary, we define the network data as weak symbols in each per-arch build. Then, in the final link, we add a special nnue_embed.cpp which provides strong symbols.
    - This does require GCC 15. Statically linking libstdc++ allows the binary to still run on older OSes though. And latest msys2 already does static linking + is based off GCC 15.2.0

building can be as simple as

make -j profile-build ARCH=x86-64-universal

or using the sde if the host doesn't support all architectures supported in the
universal binary, and the default host compiler is not recent enough.

make -j profile-build ARCH=x86-64-universal RUN_PREFIX="/path/to/sde -future --" CXX=g++-15

This change is also integrated in CI, so universal binaries are available as
downloadable artifacts.

Next we could also do ARM64, especially Android (all Apple silicon users use
the same binary). It also might be worth getting this to work with clang.

closes #6740

No functional change
Updates the information printed in the "eval" command. Removes piece value estimation, and adds both small and big net eval information.

closes #6743

No functional change
Passed STC:
LLR: 2.97 (-2.94,2.94) <0.00,2.00>
Total: 677344 W: 175301 L: 174041 D: 328002
Ptnml(0-2): 2018, 79669, 174166, 80673, 2146
https://tests.stockfishchess.org/tests/view/69cfae021668971c9da23b80

Passed LTC:
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 46470 W: 11988 L: 11651 D: 22831
Ptnml(0-2): 37, 4877, 13055, 5244, 22
https://tests.stockfishchess.org/tests/view/69dcd13c3ca80bdf151d4ab5

Passed VLTC (non-reg.):
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 58986 W: 15120 L: 14947 D: 28919
Ptnml(0-2): 7, 5835, 17636, 6008, 7
https://tests.stockfishchess.org/tests/view/69debc6c5c67bee7d241ffe9

closes #6741

Bench: 2723949
closes #6735

No functional change
Fix MultiArray::at() which was marked noexcept despite delegating to
std::array::at() that throws on out-of-range. Per review feedback, at() now
keeps standard bounds-checking semantics (only noexcept removed), and
operator[] gains an assert for debug-mode safety.

All eight correction history lookups in search.cpp (correction_value and
update_correction_history) are switched from .at(us) to [us].

Passed STC:
https://tests.stockfishchess.org/tests/view/69de7a735c67bee7d241ff92
LLR: 2.96 (-2.94,2.94) <-1.75,0.25>
Total: 77536 W: 20031 L: 19860 D: 37645
Ptnml(0-2): 221, 8411, 21338, 8572, 226

closes #6734

No functional change
to a simpler and cleaner version

Passed non-reg test:
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 175648 W: 45156 L: 45091 D: 85401
Ptnml(0-2): 459, 19228, 48383, 19297, 457
https://tests.stockfishchess.org/tests/view/69d8d9263ca80bdf151d454a

closes #6733

No functional change
In setup_benchmark, the variables evaluating the current ply simply mirror the
exact iterative progress of the string arrays loop (since ply just increments
by 1 with every pass). We can delete the separate integer assignment and
execute it securely within the loop declaration.

closes #6732

No functional change
vondele and others added 30 commits August 19, 2026 18:39
The tail byte was read as signed char, so bytes >= 0x80 sign-extended and erased previously accumulated bytes in the hash. Read it as u8.

closes #7067

No functional change

Co-authored-by: ppigazzini <pasquale.pigazzini@gmail.com>
elapsed() returns nodes while nodestime is active, but check_time compared it against limits.movetime in milliseconds without conversion, so movetime silently meant nodes. Convert movetime to nodes before init's early return.

closes #7068

No functional change

Co-authored-by: ppigazzini <pasquale.pigazzini@gmail.com>
Worker::clear partitioned correctionHistory and pawnHistory by NUMA thread
index, but then filled the shared continuationHistory from every worker.
Since continuationHistory is constant-size and shared only within a NUMA
node, have only thread 0 of each node initialize it

closes #7069

No functional change

Co-authored-by: ppigazzini <pasquale.pigazzini@gmail.com>
speedtest multiplied user-supplied seconds and threads in int, which could overflow and produce negative movetime or Hash values. Clamp each input to the range the option layer accepts and report corrections.

closes #7070

No functional change

Co-authored-by: ppigazzini <pasquale.pigazzini@gmail.com>
STC Ice Lake: https://tests.stockfishchess.org/tests/view/6a7d0c325ebead9b2e78724a
LLR: 4.20 (-2.94,2.94) <-1.75,0.25>
Total: 266880 W: 67650 L: 67577 D: 131653
Ptnml(0-2): 373, 28574, 75459, 28675, 359

STC Non Ice Lake: https://tests.stockfishchess.org/tests/view/6a7d6a8f5ebead9b2e7872d0
LLR: 3.12 (-2.94,2.94) <-1.75,0.25>
Total: 278112 W: 71067 L: 71095 D: 135950
Ptnml(0-2): 485, 29231, 79629, 29249, 462

This is a fixed version of #7048 which had a regression on Ice Lake.
Thanks to @Torom for catching it and to @anematode for suggesting separate tests.

closes #7075

No functional change
Make the existing MADV_HUGEPAGE request effective for the Linux shared NNUE
mapping.

Map large shared objects at a 2 MiB-aligned address and request MADV_COLLAPSE
after the creating process initializes the network.

pyshbench, 30 runs:

```text
Platform / target                  Speedup    95% CI
Graviton 3 / armv8-dotprod         +2.675%    [+2.495%, +2.856%]
AMD Zen 3 / x86-64-bmi2            +0.479%    [+0.182%, +0.776%]
Intel Sapphire / x86-64-avx512icl  +2.073%    [+1.675%, +2.470%]
```

STC passed:

```text
LLR: 2.96 (-2.94,2.94) <0.00,2.00>
Total: 37344 W: 9716 L: 9419 D: 18209
Ptnml(0-2): 54, 3890, 10497, 4167, 64
```

https://tests.stockfishchess.org/tests/view/6a80cc2adb2c105c37ecd9cf

closes #7058

No functional change
Update the release pipeline so that we can create immutable releases.
The problem of the previous pipeline was that the release was created first and only afterwards the binaries were added, which is not possible with immutable releases.

https://github.com/Disservin/Stockfish/actions/runs/32180223600
<img width="1113" height="710" alt="image" src="https://github.com/user-attachments/assets/1e4945f7-3557-4c1f-afe2-7be0ed2b1060" />

closes #7076

No functional change
pthread_create's return value was ignored, so a failed spawn left the engine hanging forever waiting for a searching flag no thread would clear. Report the error and exit. Avoid using std::thread. Intends to consolidate #7060 and #7065 by making `NativeThread` more customizable.

closes #7072

No functional change

Co-authored-by: Timothy Herchen <timothy.herchen@gmail.com>
Co-authored-by: ppigazzini <pasquale.pigazzini@gmail.com>
Per Rob's comment https://discord.com/channels/435943710472011776/813919248455827515/1539144885255536761 and in the spirit of similar PRs.

Feel free to comment whatever uncontroversial claenups and I will apply them

Changes:
- Add Jonathan to `AUTHORS` which we missed when merging pawn-pair inputs
- Mr. Dubslow's changes from #6942
- mstembera's style tweaks
- niklasf's CLOEXEC enjoyment
- lemtea's `.size() == 0` -> `empty()`

closes #7074

No functional change

Co-authored-by: Dubslow <bunslow@gmail.com>
Bug: On MSVC sf_always_inline expands to ```__forceinline```, which already implies ```inline```, so definitions writing both triggered "warning C4141 ('inline' used more than once)".

Fix: Moved ```inline``` into the macro and removed it from all definition sites.
GCC/Clang still get ```inline __attribute__((always_inline))```.   ```inline``` is in the macro since the attribute alone would not set linkage.

[Edit]
Also adds MSVC coverage to CI as requested.

closes #7078

No functional change
Failure-path tests were masking valgrind leak reports because
--error-exitcode=42 was being treated as the expected non-zero
exit code. Add an expect_failure flag so these tests run valgrind
with --leak-check=no, while still checking ERROR SUMMARY for real
memory errors. Populate CLI output from stdout/stderr so valgrind
output is visible to postfix_check, and only print the captured
test output when a test fails.

closes #7081

No functional change
Fixes #7049

closes #7088

No functional change
This PR simplifies the recent patch #7040, while still allowing Stockfish to consistently pass the CI `go mate` run involving 61 positions with DTM from 1 to 4 plies.

Results of a deterministic th1 run covering these 61 positions are as follows.
```
Loaded 61 FENs with 61 bm values, with |bm| (min avg max): 1 2 2.

Matetrack started for ./sf.master on matetrack.epd matedtrack.epd with --bmMax 2 --mate 0 ...
100%|███████████████████████████████████████████| 61/61 [00:17<00:00,  3.54it/s]

Using ./sf.master on matetrack.epd matedtrack.epd with --bmMax 2 --mate 0
Engine ID:     Stockfish dev-20260819-229f6339
Total FENs:    61
Found mates:   61
Best mates:    61

Best mate statistics:
|bm| = 1 - mates found: 21 = 100.0% of 21; nodes (min avg max): 4 343 1372, depth (min avg max): 1 4 12
|bm| = 2 - mates found: 40 = 100.0% of 40; nodes (min avg max): 16 402441 15454156, depth (min avg max): 1 10 24
All best mates found: 61 = 100.0% of 61; nodes (min avg max): 4 264014 15454156, depth (min avg max): 1 8 24
```
```
Loaded 61 FENs with 61 bm values, with |bm| (min avg max): 1 2 2.

Matetrack started for ./sf.patch on matetrack.epd matedtrack.epd with --bmMax 2 --mate 0 ...
100%|███████████████████████████████████████████| 61/61 [00:02<00:00, 24.64it/s]

Using ./sf.patch on matetrack.epd matedtrack.epd with --bmMax 2 --mate 0
Engine ID:     Stockfish dev-20260824-1a3ceee9
Total FENs:    61
Found mates:   61
Best mates:    61

Best mate statistics:
|bm| = 1 - mates found: 21 = 100.0% of 21; nodes (min avg max): 4 343 1372, depth (min avg max): 1 4 12
|bm| = 2 - mates found: 40 = 100.0% of 40; nodes (min avg max): 16 20068 255722, depth (min avg max): 1 9 21
All best mates found: 61 = 100.0% of 61; nodes (min avg max): 4 13277 255722, depth (min avg max): 1 8 21
```
The above shows that patch outperforms master 2s:17s, and 13277:264014 nodes.

In addition, patch shows a healthy increase in (best) mates found on matetrack:
```
Using ./sf.patch on matetrack.epd with --nodes 1000000
Engine ID:     Stockfish dev-20260824-1a3ceee9
Total FENs:    6554
Found mates:   3700
Best mates:    2457
```
This compares with 3202, 2263 for master, see https://github.com/vondele/matetrack/blob/c88991a2558b326e2119ca0e5cc9554d60e559ab/matetrack1000000.csv#L4530.

The numbers for the classic mate suite are:
```
Loaded 280 FENs with 280 bm values, with |bm| (min avg max): 10 15 21.

Matetrack started for ./sf.patch on classic280.epd with --nodes 1000000 ...
100%|███████████████████████████████████████████| 56/56 [00:26<00:00,  2.13it/s]

Using ./sf.patch on classic280.epd with --nodes 1000000
Engine ID:     Stockfish dev-20260824-1a3ceee9
Total FENs:    280
Found mates:   128
Best mates:    31
```
This compares with 165, 24 for master, see https://github.com/vondele/matetrack/blob/c88991a2558b326e2119ca0e5cc9554d60e559ab/classic1000000.csv#L4530.

Passed STC non-reg:
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 41504 W: 10764 L: 10559 D: 20181
Ptnml(0-2): 61, 4620, 11196, 4803, 72
https://tests.stockfishchess.org/tests/view/6a85b5af9960adfadf924292

Passed LTC non-reg:
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 111234 W: 28827 L: 28702 D: 53705
Ptnml(0-2): 32, 11680, 32064, 11813, 28
https://tests.stockfishchess.org/tests/view/6a86ef485b1b38ebda864e69

closes #7089

Bench: 2502027
This PR fixes two minor issues with master's PV extension code.

1. When 'nodestime' is active, master may abort PV extension if it takes too long (as measured in ms), rendering the produced results nondeterministic. The patch always completes the PV extensions. This has no effect on playing strength because the local calls to `pos.do_move()` do not update the global used nodes counter.

2. If standard time management is active, and the game is played with `multiPV > 1`, then extending several PVs may repeatedly use up to `moveOverhead / 2` ms, possibly leading to time losses. The patch fixes this by only extending the PV of the best move during game play.

closes #7079

No functional change
Master branch does not compile on some Unix systems since commit d077f9a (for instance compilation fails on Mac OS X 10.13.6 using GNUC 10.4.2).

The problem is that on such systems CMSG_SPACE() is not a compile time constant, so it cannot be used to allocate the size of the message buffer we use in shm_unix.h

The fix is to use a dynamic array instead of a stack array for the buffer. We use a standard C++ vector to get automatic memory management, and align it with our utilities in memory.h.

fixes  #7092

closes #7093

No functional change
should fix the common case of downloads not being successful.

Similarly cache the syzygy download.

closes #7094

No functional change

Co-authored-by: Joost VandeVondele <joost.vandevondele@gmail.com>
Worker/SharedHistories allocations on Linux were served by glibc malloc arenas, which survive thread destruction and can be reused by threads bound to a different NUMA node. This caused non-deterministic remote memory and lower NPS when Threads was set multiple times.

Route aligned_large_pages_alloc_with_hint() through direct mmap() on Linux, storing the base/size so aligned_large_pages_free() can munmap() the original mapping. Merge the existing x86_64 MAP_HUGETLB bookkeeping into the same registry.

fixes #6516

Benchmark: 288 threads, 36864 MB hash, depth 15 (10 runs per config)

```
| Build  | Case                     | Avg NPS     | Min NPS     | Max NPS     | Range     |
|--------|--------------------------|-------------|-------------|-------------|-----------|
| master | Case1 (Threads set x2)   | 253,196,264 | 252,034,443 | 254,396,860 | 2,362,417 |
| master | Case2 (Threads set x1)   | 248,224,546 | 247,304,918 | 249,306,273 | 2,001,355 |
| fix    | Case1 (Threads set x2)   | 254,675,607 | 253,991,054 | 255,600,403 | 1,609,349 |
| fix    | Case2 (Threads set x1)   | 254,931,057 | 253,979,373 | 256,334,683 | 2,355,310 |
```

closes #7095

No functional change
update to current

closes #7098

No functional change
Simplify the optimism scaling formula, keeping the i64 cast for safety.

LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 506336 W: 129447 L: 129738 D: 247151
Ptnml(0-2): 960, 59384, 132718, 59199, 907
Passed STC non-reg:

https://tests.stockfishchess.org/tests/view/6a79ff99a7e815d01b5603ad

Passed LTC non-reg:
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 138276 W: 35651 L: 35552 D: 67073
Ptnml(0-2): 37, 14851, 39261, 14954, 35
https://tests.stockfishchess.org/tests/view/6a842ae29960adfadf924008

closes #7097

Bench: 2497913
fixes incorrect handling of MAP_FAILED in
7ab49b9

closes #7102

No functional change
Clean up and add some comments.

closes #7100

No functional change
passed STC:
https://tests.stockfishchess.org/tests/view/6a8d043108c0f6a39c9e7eba
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 289440 W: 73563 L: 73617 D: 142260
Ptnml(0-2): 356, 30896, 82225, 30932, 311

closes #7090

No functional change
Passed STC
https://tests.stockfishchess.org/tests/view/6a8ab17b08c0f6a39c9e79ae
LLR: 2.96 (-2.94,2.94) <0.00,2.00>
Total: 96192 W: 24637 L: 24264 D: 47291
Ptnml(0-2): 136, 9961, 27552, 10288, 159

Passed avx2 STC:
https://tests.stockfishchess.org/tests/view/6a8cd16708c0f6a39c9e7e59
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 61024 W: 15789 L: 15457 D: 29778
Ptnml(0-2): 108, 6534, 16905, 6848, 117

Failed avx512icl STC:
https://tests.stockfishchess.org/tests/view/6a8cd14d08c0f6a39c9e7e57
LLR: -2.96 (-2.94,2.94) <0.00,2.00>
Total: 90368 W: 22968 L: 23088 D: 44312
Ptnml(0-2): 132, 9707, 25587, 9665, 93

Context: #7051 (comment)
Credit to bobbypaper for inspiring the idea. Gated to AVX2 because it seems neutral at best on other architectures.

Locally, despite the avx512icl failure:

Result of 500 runs
base (...kfish.master) =    1907788  +/- 1384
test (./stockfish    ) =    1930017  +/- 1426
diff                   =     +22230  +/- 1978

speedup         = +0.0117
P(speedup > 0) =  1.0000

closes #7096

No functional change
Fixes losses on time in cyclic time controls.

Results of master vs fix (40/1, 1t, 64MB, UHO_Lichess_4852_v1.epd):
Elo: -48.65 +/- 9.84, nElo: -76.63 +/- 15.29
LOS: 0.00 %, DrawRatio: 40.83 %, PairsRatio: 0.48
Games: 1984, Wins: 451, Losses: 727, Draws: 806, Points: 854.0 (43.04 %)
Ptnml(0-2): [81, 316, 405, 178, 12], WL/DD Ratio: 1.60

Master timeouts: 557, Fix timeouts: 0

Results of master vs fix (40/10, 1t, 64MB, UHO_Lichess_4852_v1.epd):
Elo: -8.10 +/- 3.45, nElo: -15.98 +/- 6.81
LOS: 0.00 %, DrawRatio: 52.00 %, PairsRatio: 0.84
Games: 10000, Wins: 2463, Losses: 2696, Draws: 4841, Points: 4883.5 (48.84 %)
Ptnml(0-2): [39, 1268, 2600, 1073, 20], WL/DD Ratio: 1.08

Master timeouts: 116, Fix timeouts: 0

closes #7117

No functional change
This PR updates the internal WDL model, using data from 2M games played by the revisions since 229f633. The normalizing constant decreases significantly from 385 to 304. That means the current 78cp will roughly map to 100cp.
```
> ./updateWDL.sh --firstrev 229f633
Running: ./updateWDL.sh --firstrev 229f633 --lasttrev HEAD --materialMin 17 --EloDiffMax 5
started at:  Tue 1 Sep 14:31:12 CEST 2026
Look recursively in directory pgns for games with max nElo difference 5 using books matching "UHO_Lichess_4852_v..epd" for SF revisions between 229f633 (from 2026-08-19 18:48:49 +0200) and HEAD (from 2026-08-29 09:16:46 +0200).
Based on 109147283 positions from 2046412 games, NormalizeToPawnValue should change from 385 to 304.
In the updated WDL model, 78cp would roughly map to 100cp.
ended at:  Tue 1 Sep 14:32:20 CEST 2026
```
```
> cat scoreWDL.log
Converting evals with NormalizeData = {'momType': 'material', 'momMin': 17, 'momMax': 78, 'momTarget': 58, 'as': [-72.32565836, 185.93832038, -144.58862193, 416.44950446]}.
Reading eval stats from updateWDL.json.
Retained (W,D,L) = (26673519, 54948054, 27525710) positions.
Saved distribution plot to updateWDLdistro.png.
Fit WDL model based on material.
Initial objective function:  0.3550415621263458
Final objective function:    0.3550400701834142
Optimization terminated successfully.
const int NormalizeToPawnValue = 304;
Corresponding spread = 61;
Corresponding normalized spread = 0.19927805405945914;
Draw rate at 0.0 eval at material 58 = 0.986853004859315;
Parameters in internal value units:
p_a = ((-142.721 * x / 58 + 372.352) * x / 58 + -340.711) * x / 58 + 415.235
p_b = ((5.938 * x / 58 + 15.613) * x / 58 + -30.578) * x / 58 + 69.639
    constexpr double as[] = {-142.72052667, 372.35176398, -340.71073572, 415.23490212};
    constexpr double bs[] = {5.93832785, 15.61267078, -30.57816876, 69.63866711};
Preparing plots.
Saved graphics to updateWDL.png.
Total elapsed time = 30.92s.
```
The patch only affects the displayed `cp` and `wdl` values, and nothing else.

closes #7120

No functional change
Repro with `-ftrapv`:

```
position fen 4rk2/2r2p2/3R1Bpn/7p/1pPp3P/1P3P2/3p2P1/3R3K w - - 0 36
go
```

```
info depth 27 seldepth 61 multipv 1 score cp 169 nodes 5778888 nps 514090 hashfull 964 tbhits 0 time 11241 pv d1d2 h6f5 d6b6 c7d7 h1g1 f8g8 d2e2 e8a8 e2a2 a
8c8 g1f2 g8h7 f6g5 h7g7 a2e2 c8a8 e2d2 a8e8 g5f6 g7h7 b6b4 e8e6 f6g5 f7f6 g5f4 f5h4 c4c5 g6g5 f4h2 h4f5 b4b6 e6b6 c5b6 f5e7 h2c7 e7c6 f2e2 d7d5
info depth 28 seldepth 62 multipv 1 score cp 169 nodes 6673438 nps 507833 hashfull 984 tbhits 0 time 13141 pv d1d2 h6f5 d6b6 c7d7 h1g1 f8g8 d2e2 e8a8 e2a2 a
8c8 g1f2 g8h7 f6g5 h7g7 a2d2 c8e8 g5f6 g7h7 b6b4 e8e6 f6g5 f7f6 g5f4 e6c6 g2g3 h7g8 b4b5 d4d3 c4c5 f5d4 d2d3 d4b5 d3d7 c6c5 f4d2 c5c2 f2e3 b5c3

Thread 4 "stockfish" received signal SIGABRT, Aborted.
(gdb) bt
[snip]
#5  0x00007ffff7bd8e55 in __mulvsi3 () from /lib/x86_64-linux-gnu/libgcc_s.so.1
#6  0x000000000043b8ce in Stockfish::(anonymous namespace)::update_continuation_histories(Stockfish::Search::Stack*, Stockfish::Piece, Stockfish::Square, in
t) ()
```

After this fix, the worst-case near-overflows across Stockfish that I could find (which are still this one!) still have a healthy margin:

```
MUL closest to overflow, margin: 1086513607 (10300680 x 103 -> 1060970040)
```

closes #7123

No functional change
Cast to `unsigned char` before calling these functions, matching the pattern already used elsewhere in the codebase (`UCIEngine::to_lower`, `CaseInsensitiveLess::operator()`).

closes #7126

No functional change

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
closes #7127

No functional change
When `availableNodes` hits 0 in master, on the next move we hit UB in `TimeManagement::init()`. More generally, the UB can happen whenever `availableNodes < npmsec`.

That is because `limits.time[us] == 0` gets passed into `scaledTime`, which is then used in `log10` to define `logTimeInSec`, leading to `-inf` in `optConstant` and hence `+inf` in `optScale`, if `originalTimeAdjust < 0`. Casting that `+inf` double value to the integer valued `optimumTime` via `TimePoint(std::max(1.0, optScale * timeLeft))` is undefined behavior.

The patch clamps `scaledTime` from below to 1.

closes #7129

No functional change
- Add a comment for each function of misc.cpp
- Improve comment indentation in tt.h and tt.cpp

closes #7130

No functional change
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.