From ddd250b9d655117920dd65a973cea2f8b3c57fce Mon Sep 17 00:00:00 2001 From: Disservin Date: Mon, 22 Apr 2024 19:24:10 +0200 Subject: [PATCH] Restore NPS output for Perft 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 --- src/benchmark.cpp | 2 +- src/benchmark.h | 2 +- src/engine.cpp | 14 ++++++++------ src/engine.h | 4 ++++ src/perft.h | 7 +++---- src/uci.cpp | 26 ++++++++++++++++++++++---- src/uci.h | 10 ++++++---- 7 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/benchmark.cpp b/src/benchmark.cpp index 267a6b4b..3622ac8a 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -93,7 +93,7 @@ const std::vector Defaults = { } // namespace -namespace Stockfish { +namespace Stockfish::Benchmark { // Builds a list of UCI commands to be run by bench. There // are five parameters: TT size in MB, number of search threads that diff --git a/src/benchmark.h b/src/benchmark.h index 8905fcb1..b1eba40f 100644 --- a/src/benchmark.h +++ b/src/benchmark.h @@ -23,7 +23,7 @@ #include #include -namespace Stockfish { +namespace Stockfish::Benchmark { std::vector setup_bench(const std::string&, std::istream&); diff --git a/src/engine.cpp b/src/engine.cpp index 325b971e..4625e00a 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "evaluate.h" #include "misc.h" @@ -54,14 +55,15 @@ Engine::Engine(std::string path) : pos.set(StartFEN, false, &states->back()); } -void Engine::go(const Search::LimitsType& limits) { +std::uint64_t Engine::perft(const std::string& fen, Depth depth, bool isChess960) { verify_networks(); - if (limits.perft) - { - perft(pos.fen(), limits.perft, options["UCI_Chess960"]); - return; - } + return Benchmark::perft(fen, depth, isChess960); +} + +void Engine::go(const Search::LimitsType& limits) { + assert(limits.perft == 0); + verify_networks(); threads.start_thinking(options, pos, states, limits); } diff --git a/src/engine.h b/src/engine.h index 7122ee59..041f5678 100644 --- a/src/engine.h +++ b/src/engine.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "nnue/network.h" #include "position.h" @@ -33,6 +34,7 @@ #include "thread.h" #include "tt.h" #include "ucioption.h" +#include "syzygy/tbprobe.h" // for Stockfish::Depth namespace Stockfish { @@ -45,6 +47,8 @@ class Engine { Engine(std::string path = ""); ~Engine() { wait_for_search_finished(); } + std::uint64_t perft(const std::string& fen, Depth depth, bool isChess960); + // non blocking call to start searching void go(const Search::LimitsType&); // non blocking call to stop searching diff --git a/src/perft.h b/src/perft.h index 2dbab828..e907742d 100644 --- a/src/perft.h +++ b/src/perft.h @@ -26,7 +26,7 @@ #include "types.h" #include "uci.h" -namespace Stockfish { +namespace Stockfish::Benchmark { // Utility to verify move generation. All the leaf nodes up // to the given depth are generated and counted, and the sum is returned. @@ -56,13 +56,12 @@ uint64_t perft(Position& pos, Depth depth) { return nodes; } -inline void perft(const std::string& fen, Depth depth, bool isChess960) { +inline uint64_t perft(const std::string& fen, Depth depth, bool isChess960) { StateListPtr states(new std::deque(1)); Position p; p.set(fen, isChess960, &states->back()); - uint64_t nodes = perft(p, depth); - sync_cout << "\nNodes searched: " << nodes << "\n" << sync_endl; + return perft(p, depth); } } diff --git a/src/uci.cpp b/src/uci.cpp index c707f6dc..cb686a02 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -219,7 +219,11 @@ Search::LimitsType UCIEngine::parse_limits(std::istream& is) { void UCIEngine::go(std::istringstream& is) { Search::LimitsType limits = parse_limits(is); - engine.go(limits); + + if (limits.perft) + perft(limits); + else + engine.go(limits); } void UCIEngine::bench(std::istream& args) { @@ -233,7 +237,7 @@ void UCIEngine::bench(std::istream& args) { on_update_full(i, options["UCI_ShowWDL"]); }); - std::vector list = setup_bench(engine.fen(), args); + std::vector list = Benchmark::setup_bench(engine.fen(), args); num = count_if(list.begin(), list.end(), [](const std::string& s) { return s.find("go ") == 0 || s.find("eval") == 0; }); @@ -251,8 +255,16 @@ void UCIEngine::bench(std::istream& args) { << std::endl; if (token == "go") { - go(is); - engine.wait_for_search_finished(); + Search::LimitsType limits = parse_limits(is); + + if (limits.perft) + nodes = perft(limits); + else + { + engine.go(limits); + engine.wait_for_search_finished(); + } + nodes += nodesSearched; nodesSearched = 0; } @@ -288,6 +300,12 @@ void UCIEngine::setoption(std::istringstream& is) { engine.get_options().setoption(is); } +std::uint64_t UCIEngine::perft(const Search::LimitsType& limits) { + auto nodes = engine.perft(engine.fen(), limits.perft, engine.get_options()["UCI_Chess960"]); + sync_cout << "\nNodes searched: " << nodes << "\n" << sync_endl; + return nodes; +} + void UCIEngine::position(std::istringstream& is) { std::string token, fen; diff --git a/src/uci.h b/src/uci.h index ee8c2814..55d580f9 100644 --- a/src/uci.h +++ b/src/uci.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "engine.h" #include "misc.h" @@ -57,10 +58,11 @@ class UCIEngine { Engine engine; CommandLine cli; - void go(std::istringstream& is); - void bench(std::istream& args); - void position(std::istringstream& is); - void setoption(std::istringstream& is); + void go(std::istringstream& is); + void bench(std::istream& args); + void position(std::istringstream& is); + void setoption(std::istringstream& is); + std::uint64_t perft(const Search::LimitsType&); static void on_update_no_moves(const Engine::InfoShort& info); static void on_update_full(const Engine::InfoFull& info, bool showWDL);