From f4ba7ce67a0a4b77d9d641b4010dfc73f3b534b2 Mon Sep 17 00:00:00 2001 From: Disservin Date: Mon, 9 Sep 2024 17:07:36 +0200 Subject: [PATCH 01/16] Restore development closes https://github.com/official-stockfish/Stockfish/pull/5580 No functional change --- src/misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc.cpp b/src/misc.cpp index 91cdbc4d..664ab4b8 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -38,7 +38,7 @@ namespace Stockfish { namespace { // Version number or dev. -constexpr std::string_view version = "17"; +constexpr std::string_view version = "dev"; // Our fancy logging facility. The trick here is to replace cin.rdbuf() and // cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We -- 2.39.5 From 4fb04eb3df9279cd7b8c3d43dbf1916b3c74bea3 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Fri, 30 Aug 2024 14:09:24 +0300 Subject: [PATCH 02/16] Simplify history bonus After we recently added the disallowance for negative bonuses, it is no longer necessary to keep the max comparison in the previous step. Passed STC: LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 72000 W: 18820 L: 18637 D: 34543 Ptnml(0-2): 267, 8489, 18276, 8730, 238 https://tests.stockfishchess.org/tests/view/66ce132cbf8c9d8780fdabe7 Passed LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 67452 W: 17136 L: 16961 D: 33355 Ptnml(0-2): 35, 7489, 18519, 7632, 51 https://tests.stockfishchess.org/tests/view/66cf6ad49de3e7f9b33d1010 closes https://github.com/official-stockfish/Stockfish/pull/5554 Bench: 1147012 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index ad2c35e7..9d950c0e 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1347,7 +1347,7 @@ moves_loop: // When in check, search starts here + 134 * (!(ss - 1)->inCheck && bestValue <= -(ss - 1)->staticEval - 91)); // Proportional to "how much damage we have to undo" - bonus += std::clamp(-(ss - 1)->statScore / 100, -94, 304); + bonus += std::min(-(ss - 1)->statScore / 100, 304); bonus = std::max(bonus, 0); -- 2.39.5 From ddc9f48bc3e0b1d22b2d1259d5d45d4640e0374d Mon Sep 17 00:00:00 2001 From: Shawn Xu Date: Fri, 23 Aug 2024 17:13:49 -0700 Subject: [PATCH 03/16] Introduce Material Correction History Idea from Caissa (https://github.com/Witek902/Caissa) chess engine. Add a secondary correction history indexed by the material key of a position. The material key is the zobrist hash representing the number of pieces left in a position. Passed STC: LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 189472 W: 49360 L: 48813 D: 91299 Ptnml(0-2): 666, 22453, 47953, 22996, 668 https://tests.stockfishchess.org/tests/view/66cbddafbf8c9d8780fda9f1 Passed LTC: LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 224190 W: 57022 L: 56312 D: 110856 Ptnml(0-2): 197, 24723, 61540, 25443, 192 https://tests.stockfishchess.org/tests/view/66cd529bbf8c9d8780fdab4c closes https://github.com/official-stockfish/Stockfish/pull/5556 Bench: 1462697 --- src/movepick.h | 30 ++++++++++++++++++++++-------- src/search.cpp | 11 ++++++++--- src/search.h | 11 ++++++----- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/movepick.h b/src/movepick.h index 61f6368e..651091b0 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -34,14 +34,15 @@ namespace Stockfish { -constexpr int PAWN_HISTORY_SIZE = 512; // has to be a power of 2 -constexpr int CORRECTION_HISTORY_SIZE = 16384; // has to be a power of 2 -constexpr int CORRECTION_HISTORY_LIMIT = 1024; +constexpr int PAWN_HISTORY_SIZE = 512; // has to be a power of 2 +constexpr int PAWN_CORRECTION_HISTORY_SIZE = 16384; // has to be a power of 2 +constexpr int MATERIAL_CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2 +constexpr int CORRECTION_HISTORY_LIMIT = 1024; static_assert((PAWN_HISTORY_SIZE & (PAWN_HISTORY_SIZE - 1)) == 0, "PAWN_HISTORY_SIZE has to be a power of 2"); -static_assert((CORRECTION_HISTORY_SIZE & (CORRECTION_HISTORY_SIZE - 1)) == 0, +static_assert((PAWN_CORRECTION_HISTORY_SIZE & (PAWN_CORRECTION_HISTORY_SIZE - 1)) == 0, "CORRECTION_HISTORY_SIZE has to be a power of 2"); enum PawnHistoryType { @@ -51,7 +52,11 @@ enum PawnHistoryType { template inline int pawn_structure_index(const Position& pos) { - return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : CORRECTION_HISTORY_SIZE) - 1); + return pos.pawn_key() & ((T == Normal ? PAWN_HISTORY_SIZE : PAWN_CORRECTION_HISTORY_SIZE) - 1); +} + +inline int material_index(const Position& pos) { + return pos.material_key() & (MATERIAL_CORRECTION_HISTORY_SIZE - 1); } // StatsEntry stores the stat table value. It is usually a number but could @@ -133,9 +138,18 @@ using ContinuationHistory = Stats // PawnHistory is addressed by the pawn structure and a move's [piece][to] using PawnHistory = Stats; -// CorrectionHistory is addressed by color and pawn structure -using CorrectionHistory = - Stats; + +// Correction histories record differences between the static evaluation of +// positions and their search score. It is used to improve the static evaluation +// used by some search heuristics. + +// PawnCorrectionHistory is addressed by color and pawn structure +using PawnCorrectionHistory = + Stats; + +// MaterialCorrectionHistory is addressed by color and material configuration +using MaterialCorrectionHistory = + Stats; // The MovePicker class is used to pick one pseudo-legal move at a time from the // current position. The most important method is next_move(), which emits one diff --git a/src/search.cpp b/src/search.cpp index 9d950c0e..bc85a5c3 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -81,7 +81,10 @@ constexpr int futility_move_count(bool improving, Depth depth) { // Add correctionHistory value to raw staticEval and guarantee evaluation // does not hit the tablebase range. Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos) { - auto cv = w.correctionHistory[pos.side_to_move()][pawn_structure_index(pos)]; + const auto pcv = + w.pawnCorrectionHistory[pos.side_to_move()][pawn_structure_index(pos)]; + const auto mcv = w.materialCorrectionHistory[pos.side_to_move()][material_index(pos)]; + const auto cv = (2 * pcv + mcv) / 3; v += 66 * cv / 512; return std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1); } @@ -487,7 +490,8 @@ void Search::Worker::clear() { mainHistory.fill(0); captureHistory.fill(-700); pawnHistory.fill(-1188); - correctionHistory.fill(0); + pawnCorrectionHistory.fill(0); + materialCorrectionHistory.fill(0); for (bool inCheck : {false, true}) for (StatsType c : {NoCaptures, Captures}) @@ -1390,7 +1394,8 @@ moves_loop: // When in check, search starts here { auto bonus = std::clamp(int(bestValue - ss->staticEval) * depth / 8, -CORRECTION_HISTORY_LIMIT / 4, CORRECTION_HISTORY_LIMIT / 4); - thisThread->correctionHistory[us][pawn_structure_index(pos)] << bonus; + thisThread->pawnCorrectionHistory[us][pawn_structure_index(pos)] << bonus; + thisThread->materialCorrectionHistory[us][material_index(pos)] << bonus; } assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); diff --git a/src/search.h b/src/search.h index 0f635186..c9fe9e18 100644 --- a/src/search.h +++ b/src/search.h @@ -277,11 +277,12 @@ class Worker { void ensure_network_replicated(); // Public because they need to be updatable by the stats - ButterflyHistory mainHistory; - CapturePieceToHistory captureHistory; - ContinuationHistory continuationHistory[2][2]; - PawnHistory pawnHistory; - CorrectionHistory correctionHistory; + ButterflyHistory mainHistory; + CapturePieceToHistory captureHistory; + ContinuationHistory continuationHistory[2][2]; + PawnHistory pawnHistory; + PawnCorrectionHistory pawnCorrectionHistory; + MaterialCorrectionHistory materialCorrectionHistory; private: void iterative_deepening(); -- 2.39.5 From e74452ae44df35aeda21e81bb2eec883a7a45c38 Mon Sep 17 00:00:00 2001 From: Daniel Monroe Date: Sun, 1 Sep 2024 20:56:09 -0400 Subject: [PATCH 04/16] Reduce on ttcaptures if not capture Tweak ttcapture reduction. Reduce on ttcaptures only if the current move is a capture Passed STC: LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 94912 W: 24896 L: 24492 D: 45524 Ptnml(0-2): 301, 11197, 24087, 11539, 332 https://tests.stockfishchess.org/tests/view/66cd2264bf8c9d8780fdab34 Passed LTC: LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 60738 W: 15465 L: 15096 D: 30177 Ptnml(0-2): 42, 6573, 16775, 6932, 47 https://tests.stockfishchess.org/tests/view/66cf356d9de3e7f9b33d0fde closes https://github.com/official-stockfish/Stockfish/pull/5562 Bench: 1268700 --- src/search.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index bc85a5c3..aab5c743 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1140,8 +1140,8 @@ moves_loop: // When in check, search starts here if (cutNode) r += 2 - (ttData.depth >= depth && ss->ttPv); - // Increase reduction if ttMove is a capture (~3 Elo) - if (ttCapture) + // Increase reduction if ttMove is a capture but the current move is not a capture (~3 Elo) + if (ttCapture && !capture) r++; // Increase reduction if next ply has a lot of fail high (~5 Elo) -- 2.39.5 From 66a7965b0fab4d1ae59203039b0b2262dbf2bcc0 Mon Sep 17 00:00:00 2001 From: xu-shawn <50402888+xu-shawn@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:31:40 -0700 Subject: [PATCH 05/16] Copy scripts directory in distributed packages closes https://github.com/official-stockfish/Stockfish/pull/5571 No functional change --- .github/workflows/upload_binaries.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/upload_binaries.yml b/.github/workflows/upload_binaries.yml index c5a2cd10..1067f6e7 100644 --- a/.github/workflows/upload_binaries.yml +++ b/.github/workflows/upload_binaries.yml @@ -59,6 +59,7 @@ jobs: mv "${{ matrix.config.simple_name }} ${{ matrix.binaries }}" stockfish-workflow cd stockfish-workflow cp -r src ../stockfish/ + cp -r scripts ../stockfish/ cp stockfish-$NAME-$BINARY$EXT ../stockfish/ cp "Top CPU Contributors.txt" ../stockfish/ cp Copying.txt ../stockfish/ -- 2.39.5 From 1b310cc87e22840621284f27f1f5873c9b9c0384 Mon Sep 17 00:00:00 2001 From: MinetaS Date: Mon, 2 Sep 2024 19:22:18 +0900 Subject: [PATCH 06/16] Export and clean up net downloading script Fixes https://github.com/official-stockfish/Stockfish/issues/5564 This patch extracts the net downloading script in Makefile into an external script file. Also the script is moderately rewritten for improved readability and speed. * Use wget preferentially over curl, as curl is known to have slight overhead. * Use command instead of hash to check if command exists. Reportedly, hash always returns zero in some POSIX shells even when the command fails. * Command existence checks (wget/curl, sha256sum) are performed only once at the beginning. * Each of common patterns is encapsulated in a function (get_nnue_filename, validate_network). * Print out error/warning messages to stderr. closes https://github.com/official-stockfish/Stockfish/pull/5563 No functional change Co-authored-by: Disservin --- .github/workflows/tests.yml | 12 +++--- scripts/net.sh | 75 +++++++++++++++++++++++++++++++++++++ src/Makefile | 52 +------------------------ 3 files changed, 82 insertions(+), 57 deletions(-) create mode 100755 scripts/net.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8d209a4f..a826e6f0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -143,7 +143,7 @@ jobs: FROM ${{ matrix.config.base_image }} WORKDIR /app RUN apk update && apk add make g++ - CMD ["sh", "script.sh"] + CMD ["sh", "src/script.sh"] EOF - name: Download required macOS packages @@ -176,7 +176,7 @@ jobs: $COMPCXX -v else echo "$COMPCXX -v" > script.sh - docker run --rm --platform ${{ matrix.config.platform }} -v ${{ github.workspace }}/src:/app sf_builder + docker run --rm --platform ${{ matrix.config.platform }} -v ${{ github.workspace }}:/app sf_builder fi - name: Test help target @@ -342,8 +342,8 @@ jobs: - name: Test riscv64 build if: matrix.config.run_riscv64_tests run: | - echo "export LDFLAGS='-static' && make clean && make -j4 ARCH=riscv64 build" > script.sh - docker run --rm --platform ${{ matrix.config.platform }} -v ${{ github.workspace }}/src:/app sf_builder + echo "cd src && export LDFLAGS='-static' && make clean && make -j4 ARCH=riscv64 build" > script.sh + docker run --rm --platform ${{ matrix.config.platform }} -v ${{ github.workspace }}:/app sf_builder ../tests/signature.sh $benchref # ppc64 tests @@ -351,8 +351,8 @@ jobs: - name: Test ppc64 build if: matrix.config.run_ppc64_tests run: | - echo "export LDFLAGS='-static' && make clean && make -j4 ARCH=ppc-64 build" > script.sh - docker run --rm --platform ${{ matrix.config.platform }} -v ${{ github.workspace }}/src:/app sf_builder + echo "cd src && export LDFLAGS='-static' && make clean && make -j4 ARCH=ppc-64 build" > script.sh + docker run --rm --platform ${{ matrix.config.platform }} -v ${{ github.workspace }}:/app sf_builder ../tests/signature.sh $benchref # Other tests diff --git a/scripts/net.sh b/scripts/net.sh new file mode 100755 index 00000000..168fbad6 --- /dev/null +++ b/scripts/net.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +wget_or_curl=$( (command -v wget > /dev/null 2>&1 && echo "wget -q") || \ + (command -v curl > /dev/null 2>&1 && echo "curl -L -s -k")) + +if [ -z "$wget_or_curl" ]; then + >&2 printf "%s\n" "Neither wget or curl is installed." \ + "Install one of these tools to download NNUE files automatically." + exit 1 +fi + +sha256sum=$( (command -v shasum > /dev/null 2>&1 && echo "shasum -a 256") || \ + (command -v sha256sum > /dev/null 2>&1 && echo "sha256sum")) + +if [ -z "$sha256sum" ]; then + >&2 echo "sha256sum not found, NNUE files will be assumed valid." +fi + +get_nnue_filename() { + grep "$1" evaluate.h | grep "#define" | sed "s/.*\(nn-[a-z0-9]\{12\}.nnue\).*/\1/" +} + +validate_network() { + # If no sha256sum command is available, assume the file is always valid. + if [ -n "$sha256sum" ] && [ -f "$1" ]; then + if [ "$1" != "nn-$($sha256sum "$1" | cut -c 1-12).nnue" ]; then + rm -f "$1" + return 1 + fi + fi +} + +fetch_network() { + _filename="$(get_nnue_filename "$1")" + + if [ -z "$_filename" ]; then + >&2 echo "NNUE file name not found for: $1" + return 1 + fi + + if [ -f "$_filename" ]; then + if validate_network "$_filename"; then + echo "Existing $_filename validated, skipping download" + return + else + echo "Removing invalid NNUE file: $_filename" + fi + fi + + for url in \ + "https://tests.stockfishchess.org/api/nn/$_filename" \ + "https://github.com/official-stockfish/networks/raw/master/$_filename"; do + echo "Downloading from $url ..." + if $wget_or_curl "$url"; then + if validate_network "$_filename"; then + echo "Successfully validated $_filename" + else + echo "Downloaded $_filename is invalid" + continue + fi + else + echo "Failed to download from $url" + fi + if [ -f "$_filename" ]; then + return + fi + done + + # Download was not successful in the loop, return false. + >&2 echo "Failed to download $_filename" + return 1 +} + +fetch_network EvalFileDefaultNameBig && \ +fetch_network EvalFileDefaultNameSmall diff --git a/src/Makefile b/src/Makefile index 7142b972..042d9479 100644 --- a/src/Makefile +++ b/src/Makefile @@ -917,59 +917,9 @@ profileclean: @rm -f stockfish.res @rm -f ./-lstdc++.res -define fetch_network - @echo "Default net: $(nnuenet)" - @if [ "x$(curl_or_wget)" = "x" ]; then \ - echo "Neither curl nor wget is installed. Install one of these tools unless the net has been downloaded manually"; \ - fi - @if [ "x$(shasum_command)" = "x" ]; then \ - echo "shasum / sha256sum not found, skipping net validation"; \ - elif test -f "$(nnuenet)"; then \ - if [ "$(nnuenet)" != "nn-"`$(shasum_command) $(nnuenet) | cut -c1-12`".nnue" ]; then \ - echo "Removing invalid network"; rm -f $(nnuenet); \ - fi; \ - fi; - @for nnuedownloadurl in "$(nnuedownloadurl1)" "$(nnuedownloadurl2)"; do \ - if test -f "$(nnuenet)"; then \ - echo "$(nnuenet) available : OK"; break; \ - else \ - if [ "x$(curl_or_wget)" != "x" ]; then \ - echo "Downloading $${nnuedownloadurl}"; $(curl_or_wget) $${nnuedownloadurl} > $(nnuenet);\ - else \ - echo "No net found and download not possible"; exit 1;\ - fi; \ - fi; \ - if [ "x$(shasum_command)" != "x" ]; then \ - if [ "$(nnuenet)" != "nn-"`$(shasum_command) $(nnuenet) | cut -c1-12`".nnue" ]; then \ - echo "Removing failed download"; rm -f $(nnuenet); \ - fi; \ - fi; \ - done - @if ! test -f "$(nnuenet)"; then \ - echo "Failed to download $(nnuenet)."; \ - fi; - @if [ "x$(shasum_command)" != "x" ]; then \ - if [ "$(nnuenet)" = "nn-"`$(shasum_command) $(nnuenet) | cut -c1-12`".nnue" ]; then \ - echo "Network validated"; break; \ - fi; \ - fi; -endef - -# set up shell variables for the net stuff -define netvariables -$(eval nnuenet := $(shell grep $(1) evaluate.h | grep define | sed 's/.*\(nn-[a-z0-9]\{12\}.nnue\).*/\1/')) -$(eval nnuedownloadurl1 := https://tests.stockfishchess.org/api/nn/$(nnuenet)) -$(eval nnuedownloadurl2 := https://github.com/official-stockfish/networks/raw/master/$(nnuenet)) -$(eval curl_or_wget := $(shell if hash curl 2>/dev/null; then echo "curl -skL"; elif hash wget 2>/dev/null; then echo "wget -qO-"; fi)) -$(eval shasum_command := $(shell if hash shasum 2>/dev/null; then echo "shasum -a 256 "; elif hash sha256sum 2>/dev/null; then echo "sha256sum "; fi)) -endef - # evaluation network (nnue) net: - $(call netvariables, EvalFileDefaultNameBig) - $(call fetch_network) - $(call netvariables, EvalFileDefaultNameSmall) - $(call fetch_network) + @$(SHELL) ../scripts/net.sh format: $(CLANG-FORMAT) -i $(SRCS) $(HEADERS) -style=file -- 2.39.5 From d7e3a708d456ff2793c2392c13d8d9cbea61aaba Mon Sep 17 00:00:00 2001 From: xu-shawn <50402888+xu-shawn@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:20:40 -0700 Subject: [PATCH 07/16] Remove ARCH=... from README.md closes https://github.com/official-stockfish/Stockfish/pull/5570 No functional change --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52b123cb..25da319d 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ descriptions. An example suitable for most Intel and AMD chips: ``` cd src -make -j profile-build ARCH=x86-64-avx2 +make -j profile-build ``` Detailed compilation instructions for all platforms can be found in our -- 2.39.5 From a8cb002038bf314764a737077864a961c0e1d145 Mon Sep 17 00:00:00 2001 From: Michael Chaly Date: Sat, 7 Sep 2024 18:46:09 +0300 Subject: [PATCH 08/16] Simplify ttmove reduction Remove condition that clamps reductions for tt move. Passed STC: https://tests.stockfishchess.org/tests/view/66d5f1239de3e7f9b33d14b0 LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 91136 W: 23805 L: 23646 D: 43685 Ptnml(0-2): 334, 10328, 24066, 10525, 315 Passed LTC: https://tests.stockfishchess.org/tests/view/66d7c5889de3e7f9b33d1721 LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 139242 W: 35130 L: 35030 D: 69082 Ptnml(0-2): 78, 15200, 38986, 15258, 99 closes https://github.com/official-stockfish/Stockfish/pull/5574 Bench: 1268715 --- src/search.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index aab5c743..1ed849f2 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1148,10 +1148,9 @@ moves_loop: // When in check, search starts here if ((ss + 1)->cutoffCnt > 3) r += 1 + allNode; - // For first picked move (ttMove) reduce reduction, but never allow - // reduction to go below 0 (~3 Elo) + // For first picked move (ttMove) reduce reduction (~3 Elo) else if (move == ttData.move) - r = std::max(0, r - 2); + r -= 2; ss->statScore = 2 * thisThread->mainHistory[us][move.from_to()] + (*contHist[0])[movedPiece][move.to_sq()] -- 2.39.5 From effa2460710aef54465967796099916a5f0d13d3 Mon Sep 17 00:00:00 2001 From: Disservin Date: Sat, 7 Sep 2024 20:34:10 +0200 Subject: [PATCH 09/16] Use optional for the engine path - A small quality of file change is to change the type of engine path from a string to an optional string, skips the binary directory lookup, which is commonly disabled by people who create wasm builds or include stockfish as a library. closes https://github.com/official-stockfish/Stockfish/pull/5575 No functional change --- src/engine.cpp | 4 ++-- src/engine.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 81bb260b..b5cc3f83 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -47,8 +47,8 @@ namespace NN = Eval::NNUE; constexpr auto StartFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; constexpr int MaxHashMB = Is64Bit ? 33554432 : 2048; -Engine::Engine(std::string path) : - binaryDirectory(CommandLine::get_binary_directory(path)), +Engine::Engine(std::optional path) : + binaryDirectory(path ? CommandLine::get_binary_directory(*path) : ""), numaContext(NumaConfig::from_system()), states(new std::deque(1)), threads(), diff --git a/src/engine.h b/src/engine.h index f3c78398..efab1c6a 100644 --- a/src/engine.h +++ b/src/engine.h @@ -47,7 +47,7 @@ class Engine { using InfoFull = Search::InfoFull; using InfoIter = Search::InfoIteration; - Engine(std::string path = ""); + Engine(std::optional path = std::nullopt); // Cannot be movable due to components holding backreferences to fields Engine(const Engine&) = delete; -- 2.39.5 From 2680c9c7992f6565e9a2f0acc52260af55e56b5a Mon Sep 17 00:00:00 2001 From: MinetaS Date: Fri, 6 Sep 2024 22:14:47 +0900 Subject: [PATCH 10/16] Small speedup in incremental accumulator updates Instead of updating at most two accumulators, update all accumluators during incremental updates. Tests have shown that this change yields a small speedup of at least 0.5%, and up to 1% with shorter TC. Passed STC: LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 54368 W: 14179 L: 13842 D: 26347 Ptnml(0-2): 173, 6122, 14262, 6449, 178 https://tests.stockfishchess.org/tests/view/66db038a9de3e7f9b33d1ad9 Passed 5+0.05: LLR: 2.98 (-2.94,2.94) <0.00,2.00> Total: 55040 W: 14682 L: 14322 D: 26036 Ptnml(0-2): 303, 6364, 13856, 6664, 333 https://tests.stockfishchess.org/tests/view/66dbc325dc53972b68218ba7 Passed non-regression LTC: LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 57390 W: 14555 L: 14376 D: 28459 Ptnml(0-2): 37, 5876, 16683, 6069, 30 https://tests.stockfishchess.org/tests/view/66dbc30adc53972b68218ba5 closes https://github.com/official-stockfish/Stockfish/pull/5576 No functional change --- src/nnue/nnue_feature_transformer.h | 330 ++++++++++++---------------- src/position.cpp | 2 + src/position.h | 1 + 3 files changed, 140 insertions(+), 193 deletions(-) diff --git a/src/nnue/nnue_feature_transformer.h b/src/nnue/nnue_feature_transformer.h index 2f74dcae..fa180678 100644 --- a/src/nnue/nnue_feature_transformer.h +++ b/src/nnue/nnue_feature_transformer.h @@ -453,11 +453,10 @@ class FeatureTransformer { private: template - [[nodiscard]] std::pair - try_find_computed_accumulator(const Position& pos) const { + StateInfo* try_find_computed_accumulator(const Position& pos) const { // Look for a usable accumulator of an earlier position. We keep track // of the estimated gain in terms of features to be added/subtracted. - StateInfo *st = pos.state(), *next = nullptr; + StateInfo* st = pos.state(); int gain = FeatureSet::refresh_cost(pos); while (st->previous && !(st->*accPtr).computed[Perspective]) { @@ -466,30 +465,17 @@ class FeatureTransformer { if (FeatureSet::requires_refresh(st, Perspective) || (gain -= FeatureSet::update_cost(st) + 1) < 0) break; - next = st; - st = st->previous; + st = st->previous; } - return {st, next}; + return st; } - // NOTE: The parameter states_to_update is an array of position states. - // All states must be sequential, that is states_to_update[i] must - // either be reachable by repeatedly applying ->previous from - // states_to_update[i+1], and computed_st must be reachable by - // repeatedly applying ->previous on states_to_update[0]. - template - void update_accumulator_incremental(const Position& pos, - StateInfo* computed_st, - StateInfo* states_to_update[N]) const { - static_assert(N > 0); - assert([&]() { - for (size_t i = 0; i < N; ++i) - { - if (states_to_update[i] == nullptr) - return false; - } - return true; - }()); + // It computes the accumulator of the next position, or updates the + // current position's accumulator if CurrentOnly is true. + template + void update_accumulator_incremental(const Position& pos, StateInfo* computed) const { + assert((computed->*accPtr).computed[Perspective]); + assert(computed->next != nullptr); #ifdef VECTOR // Gcc-10.2 unnecessarily spills AVX2 registers if this array @@ -498,205 +484,186 @@ class FeatureTransformer { psqt_vec_t psqt[NumPsqtRegs]; #endif - // Update incrementally going back through states_to_update. - // Gather all features to be updated. const Square ksq = pos.square(Perspective); // The size must be enough to contain the largest possible update. // That might depend on the feature set and generally relies on the // feature set's update cost calculation to be correct and never allow // updates with more added/removed features than MaxActiveDimensions. - FeatureSet::IndexList removed[N], added[N]; - - for (int i = N - 1; i >= 0; --i) - { - (states_to_update[i]->*accPtr).computed[Perspective] = true; - - const StateInfo* end_state = i == 0 ? computed_st : states_to_update[i - 1]; + FeatureSet::IndexList removed, added; - for (StateInfo* st2 = states_to_update[i]; st2 != end_state; st2 = st2->previous) - FeatureSet::append_changed_indices(ksq, st2->dirtyPiece, removed[i], - added[i]); - } + if constexpr (CurrentOnly) + for (StateInfo* st = pos.state(); st != computed; st = st->previous) + FeatureSet::append_changed_indices(ksq, st->dirtyPiece, removed, + added); + else + FeatureSet::append_changed_indices(ksq, computed->next->dirtyPiece, + removed, added); - StateInfo* st = computed_st; + StateInfo* next = CurrentOnly ? pos.state() : computed->next; + assert(!(next->*accPtr).computed[Perspective]); - // Now update the accumulators listed in states_to_update[], - // where the last element is a sentinel. #ifdef VECTOR - - if (N == 1 && (removed[0].size() == 1 || removed[0].size() == 2) && added[0].size() == 1) + if ((removed.size() == 1 || removed.size() == 2) && added.size() == 1) { - assert(states_to_update[0]); - auto accIn = - reinterpret_cast(&(st->*accPtr).accumulation[Perspective][0]); - auto accOut = reinterpret_cast( - &(states_to_update[0]->*accPtr).accumulation[Perspective][0]); + reinterpret_cast(&(computed->*accPtr).accumulation[Perspective][0]); + auto accOut = reinterpret_cast(&(next->*accPtr).accumulation[Perspective][0]); - const IndexType offsetR0 = HalfDimensions * removed[0][0]; + const IndexType offsetR0 = HalfDimensions * removed[0]; auto columnR0 = reinterpret_cast(&weights[offsetR0]); - const IndexType offsetA = HalfDimensions * added[0][0]; + const IndexType offsetA = HalfDimensions * added[0]; auto columnA = reinterpret_cast(&weights[offsetA]); - if (removed[0].size() == 1) + if (removed.size() == 1) { - for (IndexType k = 0; k < HalfDimensions * sizeof(std::int16_t) / sizeof(vec_t); - ++k) - accOut[k] = vec_add_16(vec_sub_16(accIn[k], columnR0[k]), columnA[k]); + for (IndexType i = 0; i < HalfDimensions * sizeof(WeightType) / sizeof(vec_t); ++i) + accOut[i] = vec_add_16(vec_sub_16(accIn[i], columnR0[i]), columnA[i]); } else { - const IndexType offsetR1 = HalfDimensions * removed[0][1]; + const IndexType offsetR1 = HalfDimensions * removed[1]; auto columnR1 = reinterpret_cast(&weights[offsetR1]); - for (IndexType k = 0; k < HalfDimensions * sizeof(std::int16_t) / sizeof(vec_t); - ++k) - accOut[k] = vec_sub_16(vec_add_16(accIn[k], columnA[k]), - vec_add_16(columnR0[k], columnR1[k])); + for (IndexType i = 0; i < HalfDimensions * sizeof(WeightType) / sizeof(vec_t); ++i) + accOut[i] = vec_sub_16(vec_add_16(accIn[i], columnA[i]), + vec_add_16(columnR0[i], columnR1[i])); } - auto accPsqtIn = - reinterpret_cast(&(st->*accPtr).psqtAccumulation[Perspective][0]); - auto accPsqtOut = reinterpret_cast( - &(states_to_update[0]->*accPtr).psqtAccumulation[Perspective][0]); + auto accPsqtIn = reinterpret_cast( + &(computed->*accPtr).psqtAccumulation[Perspective][0]); + auto accPsqtOut = + reinterpret_cast(&(next->*accPtr).psqtAccumulation[Perspective][0]); - const IndexType offsetPsqtR0 = PSQTBuckets * removed[0][0]; + const IndexType offsetPsqtR0 = PSQTBuckets * removed[0]; auto columnPsqtR0 = reinterpret_cast(&psqtWeights[offsetPsqtR0]); - const IndexType offsetPsqtA = PSQTBuckets * added[0][0]; + const IndexType offsetPsqtA = PSQTBuckets * added[0]; auto columnPsqtA = reinterpret_cast(&psqtWeights[offsetPsqtA]); - if (removed[0].size() == 1) + if (removed.size() == 1) { - for (std::size_t k = 0; k < PSQTBuckets * sizeof(std::int32_t) / sizeof(psqt_vec_t); - ++k) - accPsqtOut[k] = vec_add_psqt_32(vec_sub_psqt_32(accPsqtIn[k], columnPsqtR0[k]), - columnPsqtA[k]); + for (std::size_t i = 0; + i < PSQTBuckets * sizeof(PSQTWeightType) / sizeof(psqt_vec_t); ++i) + accPsqtOut[i] = vec_add_psqt_32(vec_sub_psqt_32(accPsqtIn[i], columnPsqtR0[i]), + columnPsqtA[i]); } else { - const IndexType offsetPsqtR1 = PSQTBuckets * removed[0][1]; + const IndexType offsetPsqtR1 = PSQTBuckets * removed[1]; auto columnPsqtR1 = reinterpret_cast(&psqtWeights[offsetPsqtR1]); - for (std::size_t k = 0; k < PSQTBuckets * sizeof(std::int32_t) / sizeof(psqt_vec_t); - ++k) - accPsqtOut[k] = - vec_sub_psqt_32(vec_add_psqt_32(accPsqtIn[k], columnPsqtA[k]), - vec_add_psqt_32(columnPsqtR0[k], columnPsqtR1[k])); + for (std::size_t i = 0; + i < PSQTBuckets * sizeof(PSQTWeightType) / sizeof(psqt_vec_t); ++i) + accPsqtOut[i] = + vec_sub_psqt_32(vec_add_psqt_32(accPsqtIn[i], columnPsqtA[i]), + vec_add_psqt_32(columnPsqtR0[i], columnPsqtR1[i])); } } else { - for (IndexType j = 0; j < HalfDimensions / TileHeight; ++j) + for (IndexType i = 0; i < HalfDimensions / TileHeight; ++i) { // Load accumulator auto accTileIn = reinterpret_cast( - &(st->*accPtr).accumulation[Perspective][j * TileHeight]); - for (IndexType k = 0; k < NumRegs; ++k) - acc[k] = vec_load(&accTileIn[k]); + &(computed->*accPtr).accumulation[Perspective][i * TileHeight]); + for (IndexType j = 0; j < NumRegs; ++j) + acc[j] = vec_load(&accTileIn[j]); + + // Difference calculation for the deactivated features + for (const auto index : removed) + { + const IndexType offset = HalfDimensions * index + i * TileHeight; + auto column = reinterpret_cast(&weights[offset]); + for (IndexType j = 0; j < NumRegs; ++j) + acc[j] = vec_sub_16(acc[j], column[j]); + } - for (IndexType i = 0; i < N; ++i) + // Difference calculation for the activated features + for (const auto index : added) { - // Difference calculation for the deactivated features - for (const auto index : removed[i]) - { - const IndexType offset = HalfDimensions * index + j * TileHeight; - auto column = reinterpret_cast(&weights[offset]); - for (IndexType k = 0; k < NumRegs; ++k) - acc[k] = vec_sub_16(acc[k], column[k]); - } - - // Difference calculation for the activated features - for (const auto index : added[i]) - { - const IndexType offset = HalfDimensions * index + j * TileHeight; - auto column = reinterpret_cast(&weights[offset]); - for (IndexType k = 0; k < NumRegs; ++k) - acc[k] = vec_add_16(acc[k], column[k]); - } - - // Store accumulator - auto accTileOut = reinterpret_cast( - &(states_to_update[i]->*accPtr).accumulation[Perspective][j * TileHeight]); - for (IndexType k = 0; k < NumRegs; ++k) - vec_store(&accTileOut[k], acc[k]); + const IndexType offset = HalfDimensions * index + i * TileHeight; + auto column = reinterpret_cast(&weights[offset]); + for (IndexType j = 0; j < NumRegs; ++j) + acc[j] = vec_add_16(acc[j], column[j]); } + + // Store accumulator + auto accTileOut = reinterpret_cast( + &(next->*accPtr).accumulation[Perspective][i * TileHeight]); + for (IndexType j = 0; j < NumRegs; ++j) + vec_store(&accTileOut[j], acc[j]); } - for (IndexType j = 0; j < PSQTBuckets / PsqtTileHeight; ++j) + for (IndexType i = 0; i < PSQTBuckets / PsqtTileHeight; ++i) { // Load accumulator auto accTilePsqtIn = reinterpret_cast( - &(st->*accPtr).psqtAccumulation[Perspective][j * PsqtTileHeight]); - for (std::size_t k = 0; k < NumPsqtRegs; ++k) - psqt[k] = vec_load_psqt(&accTilePsqtIn[k]); + &(computed->*accPtr).psqtAccumulation[Perspective][i * PsqtTileHeight]); + for (std::size_t j = 0; j < NumPsqtRegs; ++j) + psqt[j] = vec_load_psqt(&accTilePsqtIn[j]); + + // Difference calculation for the deactivated features + for (const auto index : removed) + { + const IndexType offset = PSQTBuckets * index + i * PsqtTileHeight; + auto columnPsqt = reinterpret_cast(&psqtWeights[offset]); + for (std::size_t j = 0; j < NumPsqtRegs; ++j) + psqt[j] = vec_sub_psqt_32(psqt[j], columnPsqt[j]); + } - for (IndexType i = 0; i < N; ++i) + // Difference calculation for the activated features + for (const auto index : added) { - // Difference calculation for the deactivated features - for (const auto index : removed[i]) - { - const IndexType offset = PSQTBuckets * index + j * PsqtTileHeight; - auto columnPsqt = reinterpret_cast(&psqtWeights[offset]); - for (std::size_t k = 0; k < NumPsqtRegs; ++k) - psqt[k] = vec_sub_psqt_32(psqt[k], columnPsqt[k]); - } - - // Difference calculation for the activated features - for (const auto index : added[i]) - { - const IndexType offset = PSQTBuckets * index + j * PsqtTileHeight; - auto columnPsqt = reinterpret_cast(&psqtWeights[offset]); - for (std::size_t k = 0; k < NumPsqtRegs; ++k) - psqt[k] = vec_add_psqt_32(psqt[k], columnPsqt[k]); - } - - // Store accumulator - auto accTilePsqtOut = reinterpret_cast( - &(states_to_update[i]->*accPtr) - .psqtAccumulation[Perspective][j * PsqtTileHeight]); - for (std::size_t k = 0; k < NumPsqtRegs; ++k) - vec_store_psqt(&accTilePsqtOut[k], psqt[k]); + const IndexType offset = PSQTBuckets * index + i * PsqtTileHeight; + auto columnPsqt = reinterpret_cast(&psqtWeights[offset]); + for (std::size_t j = 0; j < NumPsqtRegs; ++j) + psqt[j] = vec_add_psqt_32(psqt[j], columnPsqt[j]); } + + // Store accumulator + auto accTilePsqtOut = reinterpret_cast( + &(next->*accPtr).psqtAccumulation[Perspective][i * PsqtTileHeight]); + for (std::size_t j = 0; j < NumPsqtRegs; ++j) + vec_store_psqt(&accTilePsqtOut[j], psqt[j]); } } #else - for (IndexType i = 0; i < N; ++i) + std::memcpy((next->*accPtr).accumulation[Perspective], + (computed->*accPtr).accumulation[Perspective], + HalfDimensions * sizeof(BiasType)); + std::memcpy((next->*accPtr).psqtAccumulation[Perspective], + (computed->*accPtr).psqtAccumulation[Perspective], + PSQTBuckets * sizeof(PSQTWeightType)); + + // Difference calculation for the deactivated features + for (const auto index : removed) { - std::memcpy((states_to_update[i]->*accPtr).accumulation[Perspective], - (st->*accPtr).accumulation[Perspective], HalfDimensions * sizeof(BiasType)); - - for (std::size_t k = 0; k < PSQTBuckets; ++k) - (states_to_update[i]->*accPtr).psqtAccumulation[Perspective][k] = - (st->*accPtr).psqtAccumulation[Perspective][k]; - - st = states_to_update[i]; - - // Difference calculation for the deactivated features - for (const auto index : removed[i]) - { - const IndexType offset = HalfDimensions * index; - for (IndexType j = 0; j < HalfDimensions; ++j) - (st->*accPtr).accumulation[Perspective][j] -= weights[offset + j]; + const IndexType offset = HalfDimensions * index; + for (IndexType i = 0; i < HalfDimensions; ++i) + (next->*accPtr).accumulation[Perspective][i] -= weights[offset + i]; - for (std::size_t k = 0; k < PSQTBuckets; ++k) - (st->*accPtr).psqtAccumulation[Perspective][k] -= - psqtWeights[index * PSQTBuckets + k]; - } + for (std::size_t i = 0; i < PSQTBuckets; ++i) + (next->*accPtr).psqtAccumulation[Perspective][i] -= + psqtWeights[index * PSQTBuckets + i]; + } - // Difference calculation for the activated features - for (const auto index : added[i]) - { - const IndexType offset = HalfDimensions * index; - for (IndexType j = 0; j < HalfDimensions; ++j) - (st->*accPtr).accumulation[Perspective][j] += weights[offset + j]; + // Difference calculation for the activated features + for (const auto index : added) + { + const IndexType offset = HalfDimensions * index; + for (IndexType i = 0; i < HalfDimensions; ++i) + (next->*accPtr).accumulation[Perspective][i] += weights[offset + i]; - for (std::size_t k = 0; k < PSQTBuckets; ++k) - (st->*accPtr).psqtAccumulation[Perspective][k] += - psqtWeights[index * PSQTBuckets + k]; - } + for (std::size_t i = 0; i < PSQTBuckets; ++i) + (next->*accPtr).psqtAccumulation[Perspective][i] += + psqtWeights[index * PSQTBuckets + i]; } #endif + + (next->*accPtr).computed[Perspective] = true; + + if (!CurrentOnly && next != pos.state()) + update_accumulator_incremental(pos, next); } template @@ -871,14 +838,10 @@ class FeatureTransformer { if ((pos.state()->*accPtr).computed[Perspective]) return; - auto [oldest_st, _] = try_find_computed_accumulator(pos); + StateInfo* oldest = try_find_computed_accumulator(pos); - if ((oldest_st->*accPtr).computed[Perspective]) - { - // Only update current position accumulator to minimize work - StateInfo* states_to_update[1] = {pos.state()}; - update_accumulator_incremental(pos, oldest_st, states_to_update); - } + if ((oldest->*accPtr).computed[Perspective] && oldest != pos.state()) + update_accumulator_incremental(pos, oldest); else update_accumulator_refresh_cache(pos, cache); } @@ -887,31 +850,12 @@ class FeatureTransformer { void update_accumulator(const Position& pos, AccumulatorCaches::Cache* cache) const { - auto [oldest_st, next] = try_find_computed_accumulator(pos); - - if ((oldest_st->*accPtr).computed[Perspective]) - { - if (next == nullptr) - return; - - // Now update the accumulators listed in states_to_update[], where - // the last element is a sentinel. Currently we update two accumulators: - // 1. for the current position - // 2. the next accumulator after the computed one - // The heuristic may change in the future. - if (next == pos.state()) - { - StateInfo* states_to_update[1] = {next}; - - update_accumulator_incremental(pos, oldest_st, states_to_update); - } - else - { - StateInfo* states_to_update[2] = {next, pos.state()}; + StateInfo* oldest = try_find_computed_accumulator(pos); - update_accumulator_incremental(pos, oldest_st, states_to_update); - } - } + if ((oldest->*accPtr).computed[Perspective] && oldest != pos.state()) + // Start from the oldest computed accumulator, update all the + // accumulators up to the current position. + update_accumulator_incremental(pos, oldest); else update_accumulator_refresh_cache(pos, cache); } diff --git a/src/position.cpp b/src/position.cpp index d374b1c0..df95ffef 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -671,6 +671,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { // our state pointer to point to the new (ready to be updated) state. std::memcpy(&newSt, st, offsetof(StateInfo, key)); newSt.previous = st; + st->next = &newSt; st = &newSt; // Increment ply counters. In particular, rule50 will be reset to zero later on @@ -963,6 +964,7 @@ void Position::do_null_move(StateInfo& newSt, TranspositionTable& tt) { std::memcpy(&newSt, st, offsetof(StateInfo, accumulatorBig)); newSt.previous = st; + st->next = &newSt; st = &newSt; st->dirtyPiece.dirty_num = 0; diff --git a/src/position.h b/src/position.h index 064dd5fa..6cac1731 100644 --- a/src/position.h +++ b/src/position.h @@ -53,6 +53,7 @@ struct StateInfo { Key key; Bitboard checkersBB; StateInfo* previous; + StateInfo* next; Bitboard blockersForKing[COLOR_NB]; Bitboard pinners[COLOR_NB]; Bitboard checkSquares[PIECE_TYPE_NB]; -- 2.39.5 From 6de25872361de9515bdb25bf1d0391311d074012 Mon Sep 17 00:00:00 2001 From: MinetaS Date: Sat, 31 Aug 2024 16:35:17 +0900 Subject: [PATCH 11/16] Remove statScore condition in NMP Eliminate the condition that is nearly 100% likelihood of being true. Passed non-regression STC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 208832 W: 54053 L: 54022 D: 100757 Ptnml(0-2): 753, 24987, 52901, 25026, 749 https://tests.stockfishchess.org/tests/view/66cddb50bf8c9d8780fdabaf Passed non-regression LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 154344 W: 39132 L: 39047 D: 76165 Ptnml(0-2): 115, 17231, 42403, 17300, 123 https://tests.stockfishchess.org/tests/view/66cfafe39de3e7f9b33d1050 closes https://github.com/official-stockfish/Stockfish/pull/5558 Bench: 1393697 --- src/search.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 1ed849f2..d26f43db 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -773,10 +773,9 @@ Value Search::Worker::search( return beta + (eval - beta) / 3; // Step 9. Null move search with verification search (~35 Elo) - if (cutNode && (ss - 1)->currentMove != Move::null() && (ss - 1)->statScore < 14389 - && eval >= beta && ss->staticEval >= beta - 21 * depth + 390 && !excludedMove - && pos.non_pawn_material(us) && ss->ply >= thisThread->nmpMinPly - && beta > VALUE_TB_LOSS_IN_MAX_PLY) + if (cutNode && (ss - 1)->currentMove != Move::null() && eval >= beta + && ss->staticEval >= beta - 21 * depth + 390 && !excludedMove && pos.non_pawn_material(us) + && ss->ply >= thisThread->nmpMinPly && beta > VALUE_TB_LOSS_IN_MAX_PLY) { assert(eval - beta >= 0); -- 2.39.5 From d8e49cdbdd8076d85b137510ee5637e36db1074f Mon Sep 17 00:00:00 2001 From: Nonlinear2 <131959792+Nonlinear2@users.noreply.github.com> Date: Mon, 9 Sep 2024 22:32:00 +0200 Subject: [PATCH 12/16] Remove the `moveCount` increase in the LMR condition. Passed non-regression STC: LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 87104 W: 22630 L: 22464 D: 42010 Ptnml(0-2): 316, 10295, 22132, 10525, 284 https://tests.stockfishchess.org/tests/view/66dccd00dc53972b68218c60 Passed non-regression LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 94050 W: 23869 L: 23722 D: 46459 Ptnml(0-2): 49, 10400, 25985, 10537, 54 https://tests.stockfishchess.org/tests/view/66dd69c7dc53972b68218ca5 closes https://github.com/official-stockfish/Stockfish/pull/5582 Bench: 1281840 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index d26f43db..ac0b9c6d 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1159,7 +1159,7 @@ moves_loop: // When in check, search starts here r -= ss->statScore / 10898; // Step 17. Late moves reduction / extension (LMR, ~117 Elo) - if (depth >= 2 && moveCount > 1 + (rootNode && depth < 10)) + if (depth >= 2 && moveCount > 1) { // In general we want to cap the LMR depth search at newDepth, but when // reduction is negative, we allow this move a limited search extension -- 2.39.5 From f677aee28baedcab4d3110d0a5c414621ed805c4 Mon Sep 17 00:00:00 2001 From: MinetaS Date: Wed, 11 Sep 2024 05:14:01 +0900 Subject: [PATCH 13/16] Fix net downloading script The recent commit introduced a bug in the net downloading script that the file is not downloaded correctly and the content is redirected to stdout. closes https://github.com/official-stockfish/Stockfish/pull/5585 No functional change --- scripts/net.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/net.sh b/scripts/net.sh index 168fbad6..0bc57a19 100755 --- a/scripts/net.sh +++ b/scripts/net.sh @@ -1,7 +1,7 @@ #!/bin/sh -wget_or_curl=$( (command -v wget > /dev/null 2>&1 && echo "wget -q") || \ - (command -v curl > /dev/null 2>&1 && echo "curl -L -s -k")) +wget_or_curl=$( (command -v wget > /dev/null 2>&1 && echo "wget -qO-") || \ + (command -v curl > /dev/null 2>&1 && echo "curl -skL")) if [ -z "$wget_or_curl" ]; then >&2 printf "%s\n" "Neither wget or curl is installed." \ @@ -51,7 +51,7 @@ fetch_network() { "https://tests.stockfishchess.org/api/nn/$_filename" \ "https://github.com/official-stockfish/networks/raw/master/$_filename"; do echo "Downloading from $url ..." - if $wget_or_curl "$url"; then + if $wget_or_curl "$url" > "$_filename"; then if validate_network "$_filename"; then echo "Successfully validated $_filename" else -- 2.39.5 From 85fdf3a84d180b812f379dcc45cdd653ebf14f22 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Fri, 13 Sep 2024 14:29:55 +0200 Subject: [PATCH 14/16] Remove a spurious diff against upstream. --- src/ucioption.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ucioption.cpp b/src/ucioption.cpp index 1f07333c..49d85063 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -52,8 +52,7 @@ static void on_hash_size(const Option& o) { TT.resize(size_t(o)); } static void on_logger(const Option& o) { start_logger(o); } static void on_threads(const Option& o) { Threads.set(size_t(o)); } static void on_tb_path(const Option& o) { Tablebases::init(o); } -static void on_use_NNUE(const Option& ) { Eval::NNUE::init(); } -static void on_eval_file(const Option& ) { Eval::NNUE::init(); } +static void on_eval_file(const Option&) { Eval::NNUE::init(); } static void on_rpc_server_address(const Option& o) { if (hash_probe_thread) { hash_probe_thread->Shutdown(); -- 2.39.5 From c3cbfa5c6b382ac38e0b1d9bda4405a5843def37 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Fri, 13 Sep 2024 15:24:21 +0200 Subject: [PATCH 15/16] Be more honest about GIT_DATE when we lag behind in our merging. --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 51824d3d..680c439d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -742,7 +742,7 @@ ifneq ($(GIT_SHA), ) endif ### 3.8.2 Try to include git commit date for versioning -GIT_DATE := $(shell git show -s --date=format:'%Y%m%d' --format=%cd HEAD 2>/dev/null) +GIT_DATE := $(shell git show -s --date=format:'%Y%m%d' --format=%cd `git merge-base HEAD upstream/master` 2>/dev/null) ifneq ($(GIT_DATE), ) CXXFLAGS += -DGIT_DATE=$(GIT_DATE) endif -- 2.39.5 From 20a6e2cc382f42f4f57dad1a041a1b98da19c124 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Fri, 13 Sep 2024 15:25:06 +0200 Subject: [PATCH 16/16] Improve mergeability a bit. --- src/Makefile | 5 +++-- src/uci.cpp | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index 680c439d..6ea918fd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -55,8 +55,9 @@ PGOBENCH = $(WINE_PATH) ./$(EXE) bench SRCS = benchmark.cpp bitboard.cpp evaluate.cpp main.cpp \ misc.cpp movegen.cpp movepick.cpp position.cpp \ search.cpp thread.cpp timeman.cpp tt.cpp uci.cpp ucioption.cpp tune.cpp syzygy/tbprobe.cpp \ - nnue/nnue_misc.cpp nnue/features/half_ka_v2_hm.cpp nnue/network.cpp \ - hashprobe.grpc.pb.cc hashprobe.pb.cc hash_probe_impl.cpp + nnue/nnue_misc.cpp nnue/features/half_ka_v2_hm.cpp nnue/network.cpp + +SRCS += hashprobe.grpc.pb.cc hashprobe.pb.cc hash_probe_impl.cpp CLISRCS = client.cpp hashprobe.grpc.pb.cc hashprobe.pb.cc uci.cpp HEADERS = benchmark.h bitboard.h evaluate.h misc.h movegen.h movepick.h \ diff --git a/src/uci.cpp b/src/uci.cpp index 361cf2cc..bfda86f9 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -47,12 +47,14 @@ namespace Stockfish { +std::unique_ptr hash_probe_thread; + constexpr auto StartFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; constexpr int MaxHashMB = Is64Bit ? 33554432 : 2048; + namespace NN = Eval::NNUE; -std::unique_ptr hash_probe_thread; UCI::UCI(int argc, char** argv) : networks(NN::Networks( -- 2.39.5