mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 16:53:09 +00:00
Refactor pv printing
Also fix the case which is currently printing depth 0. fixes #5019 closes https://github.com/official-stockfish/Stockfish/pull/5020 No functional change
This commit is contained in:
parent
13eb023fc0
commit
16afec0582
4 changed files with 66 additions and 79 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "evaluate.h"
|
#include "evaluate.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -192,9 +193,7 @@ void Search::Worker::start_searching() {
|
||||||
|
|
||||||
// Send again PV info if we have a new best thread
|
// Send again PV info if we have a new best thread
|
||||||
if (bestThread != this)
|
if (bestThread != this)
|
||||||
sync_cout << UCI::pv(*bestThread, main_manager()->tm.elapsed(threads.nodes_searched()),
|
sync_cout << main_manager()->pv(*bestThread, threads, tt, bestThread->completedDepth)
|
||||||
threads.nodes_searched(), threads.tb_hits(), tt.hashfull(),
|
|
||||||
tbConfig.rootInTB)
|
|
||||||
<< sync_endl;
|
<< sync_endl;
|
||||||
|
|
||||||
sync_cout << "bestmove " << UCI::move(bestThread->rootMoves[0].pv[0], rootPos.is_chess960());
|
sync_cout << "bestmove " << UCI::move(bestThread->rootMoves[0].pv[0], rootPos.is_chess960());
|
||||||
|
@ -336,10 +335,7 @@ void Search::Worker::iterative_deepening() {
|
||||||
// the UI) before a re-search.
|
// the UI) before a re-search.
|
||||||
if (mainThread && multiPV == 1 && (bestValue <= alpha || bestValue >= beta)
|
if (mainThread && multiPV == 1 && (bestValue <= alpha || bestValue >= beta)
|
||||||
&& mainThread->tm.elapsed(threads.nodes_searched()) > 3000)
|
&& mainThread->tm.elapsed(threads.nodes_searched()) > 3000)
|
||||||
sync_cout << UCI::pv(*this, mainThread->tm.elapsed(threads.nodes_searched()),
|
sync_cout << main_manager()->pv(*this, threads, tt, rootDepth) << sync_endl;
|
||||||
threads.nodes_searched(), threads.tb_hits(), tt.hashfull(),
|
|
||||||
tbConfig.rootInTB)
|
|
||||||
<< sync_endl;
|
|
||||||
|
|
||||||
// In case of failing low/high increase aspiration window and
|
// In case of failing low/high increase aspiration window and
|
||||||
// re-search, otherwise exit the loop.
|
// re-search, otherwise exit the loop.
|
||||||
|
@ -376,10 +372,7 @@ void Search::Worker::iterative_deepening() {
|
||||||
// had time to fully search other root-moves. Thus we suppress this output and
|
// had time to fully search other root-moves. Thus we suppress this output and
|
||||||
// below pick a proven score/PV for this thread (from the previous iteration).
|
// below pick a proven score/PV for this thread (from the previous iteration).
|
||||||
&& !(threads.abortedSearch && rootMoves[0].uciScore <= VALUE_TB_LOSS_IN_MAX_PLY))
|
&& !(threads.abortedSearch && rootMoves[0].uciScore <= VALUE_TB_LOSS_IN_MAX_PLY))
|
||||||
sync_cout << UCI::pv(*this, mainThread->tm.elapsed(threads.nodes_searched()),
|
sync_cout << main_manager()->pv(*this, threads, tt, rootDepth) << sync_endl;
|
||||||
threads.nodes_searched(), threads.tb_hits(), tt.hashfull(),
|
|
||||||
tbConfig.rootInTB)
|
|
||||||
<< sync_endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!threads.stop)
|
if (!threads.stop)
|
||||||
|
@ -1878,6 +1871,61 @@ void SearchManager::check_time(Search::Worker& worker) {
|
||||||
worker.threads.stop = worker.threads.abortedSearch = true;
|
worker.threads.stop = worker.threads.abortedSearch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SearchManager::pv(const Search::Worker& worker,
|
||||||
|
const ThreadPool& threads,
|
||||||
|
const TranspositionTable& tt,
|
||||||
|
Depth depth) const {
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
const auto nodes = threads.nodes_searched();
|
||||||
|
const auto& rootMoves = worker.rootMoves;
|
||||||
|
const auto& pos = worker.rootPos;
|
||||||
|
size_t pvIdx = worker.pvIdx;
|
||||||
|
TimePoint time = tm.elapsed(nodes) + 1;
|
||||||
|
size_t multiPV = std::min(size_t(worker.options["MultiPV"]), rootMoves.size());
|
||||||
|
uint64_t tbHits = threads.tb_hits() + (worker.tbConfig.rootInTB ? rootMoves.size() : 0);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < multiPV; ++i)
|
||||||
|
{
|
||||||
|
bool updated = rootMoves[i].score != -VALUE_INFINITE;
|
||||||
|
|
||||||
|
if (depth == 1 && !updated && i > 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Depth d = updated ? depth : std::max(1, depth - 1);
|
||||||
|
Value v = updated ? rootMoves[i].uciScore : rootMoves[i].previousScore;
|
||||||
|
|
||||||
|
if (v == -VALUE_INFINITE)
|
||||||
|
v = VALUE_ZERO;
|
||||||
|
|
||||||
|
bool tb = worker.tbConfig.rootInTB && std::abs(v) <= VALUE_TB;
|
||||||
|
v = tb ? rootMoves[i].tbScore : v;
|
||||||
|
|
||||||
|
if (ss.rdbuf()->in_avail()) // Not at first line
|
||||||
|
ss << "\n";
|
||||||
|
|
||||||
|
ss << "info"
|
||||||
|
<< " depth " << d << " seldepth " << rootMoves[i].selDepth << " multipv " << i + 1
|
||||||
|
<< " score " << UCI::value(v);
|
||||||
|
|
||||||
|
if (worker.options["UCI_ShowWDL"])
|
||||||
|
ss << UCI::wdl(v, pos.game_ply());
|
||||||
|
|
||||||
|
if (i == pvIdx && !tb && updated) // tablebase- and previous-scores are exact
|
||||||
|
ss << (rootMoves[i].scoreLowerbound
|
||||||
|
? " lowerbound"
|
||||||
|
: (rootMoves[i].scoreUpperbound ? " upperbound" : ""));
|
||||||
|
|
||||||
|
ss << " nodes " << nodes << " nps " << nodes * 1000 / time << " hashfull " << tt.hashfull()
|
||||||
|
<< " tbhits " << tbHits << " time " << time << " pv";
|
||||||
|
|
||||||
|
for (Move m : rootMoves[i].pv)
|
||||||
|
ss << " " << UCI::move(m, pos.is_chess960());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
// Called in case we have no ponder move before exiting the search,
|
// Called in case we have no ponder move before exiting the search,
|
||||||
// for instance, in case we stop the search during a fail high at root.
|
// for instance, in case we stop the search during a fail high at root.
|
||||||
// We try hard to have a ponder move to return to the GUI,
|
// We try hard to have a ponder move to return to the GUI,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "movepick.h"
|
#include "movepick.h"
|
||||||
|
@ -150,6 +151,11 @@ class SearchManager: public ISearchManager {
|
||||||
public:
|
public:
|
||||||
void check_time(Search::Worker& worker) override;
|
void check_time(Search::Worker& worker) override;
|
||||||
|
|
||||||
|
std::string pv(const Search::Worker& worker,
|
||||||
|
const ThreadPool& threads,
|
||||||
|
const TranspositionTable& tt,
|
||||||
|
Depth depth) const;
|
||||||
|
|
||||||
Stockfish::TimeManagement tm;
|
Stockfish::TimeManagement tm;
|
||||||
int callsCnt;
|
int callsCnt;
|
||||||
std::atomic_bool ponder;
|
std::atomic_bool ponder;
|
||||||
|
|
58
src/uci.cpp
58
src/uci.cpp
|
@ -28,6 +28,7 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
#include "benchmark.h"
|
#include "benchmark.h"
|
||||||
#include "evaluate.h"
|
#include "evaluate.h"
|
||||||
|
@ -365,63 +366,6 @@ std::string UCI::move(Move m, bool chess960) {
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string UCI::pv(const Search::Worker& workerThread,
|
|
||||||
TimePoint elapsed,
|
|
||||||
uint64_t nodesSearched,
|
|
||||||
uint64_t tb_hits,
|
|
||||||
int hashfull,
|
|
||||||
bool rootInTB) {
|
|
||||||
std::stringstream ss;
|
|
||||||
TimePoint time = elapsed + 1;
|
|
||||||
const auto& rootMoves = workerThread.rootMoves;
|
|
||||||
const auto& depth = workerThread.completedDepth;
|
|
||||||
const auto& pos = workerThread.rootPos;
|
|
||||||
size_t pvIdx = workerThread.pvIdx;
|
|
||||||
size_t multiPV = std::min(size_t(workerThread.options["MultiPV"]), rootMoves.size());
|
|
||||||
uint64_t tbHits = tb_hits + (rootInTB ? rootMoves.size() : 0);
|
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < multiPV; ++i)
|
|
||||||
{
|
|
||||||
bool updated = rootMoves[i].score != -VALUE_INFINITE;
|
|
||||||
|
|
||||||
if (depth == 1 && !updated && i > 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Depth d = updated ? depth : std::max(1, depth - 1);
|
|
||||||
Value v = updated ? rootMoves[i].uciScore : rootMoves[i].previousScore;
|
|
||||||
|
|
||||||
if (v == -VALUE_INFINITE)
|
|
||||||
v = VALUE_ZERO;
|
|
||||||
|
|
||||||
bool tb = rootInTB && std::abs(v) <= VALUE_TB;
|
|
||||||
v = tb ? rootMoves[i].tbScore : v;
|
|
||||||
|
|
||||||
if (ss.rdbuf()->in_avail()) // Not at first line
|
|
||||||
ss << "\n";
|
|
||||||
|
|
||||||
ss << "info"
|
|
||||||
<< " depth " << d << " seldepth " << rootMoves[i].selDepth << " multipv " << i + 1
|
|
||||||
<< " score " << value(v);
|
|
||||||
|
|
||||||
if (workerThread.options["UCI_ShowWDL"])
|
|
||||||
ss << wdl(v, pos.game_ply());
|
|
||||||
|
|
||||||
if (i == pvIdx && !tb && updated) // tablebase- and previous-scores are exact
|
|
||||||
ss << (rootMoves[i].scoreLowerbound
|
|
||||||
? " lowerbound"
|
|
||||||
: (rootMoves[i].scoreUpperbound ? " upperbound" : ""));
|
|
||||||
|
|
||||||
ss << " nodes " << nodesSearched << " nps " << nodesSearched * 1000 / time << " hashfull "
|
|
||||||
<< hashfull << " tbhits " << tbHits << " time " << time << " pv";
|
|
||||||
|
|
||||||
for (Move m : rootMoves[i].pv)
|
|
||||||
ss << " " << move(m, pos.is_chess960());
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// The win rate model returns the probability of winning (in per mille units) given an
|
// The win rate model returns the probability of winning (in per mille units) given an
|
||||||
// eval and a game ply. It fits the LTC fishtest statistics rather accurately.
|
// eval and a game ply. It fits the LTC fishtest statistics rather accurately.
|
||||||
|
|
11
src/uci.h
11
src/uci.h
|
@ -19,7 +19,6 @@
|
||||||
#ifndef UCI_H_INCLUDED
|
#ifndef UCI_H_INCLUDED
|
||||||
#define UCI_H_INCLUDED
|
#define UCI_H_INCLUDED
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -37,10 +36,6 @@ namespace Eval::NNUE {
|
||||||
enum NetSize : int;
|
enum NetSize : int;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Search {
|
|
||||||
class Worker;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Move;
|
class Move;
|
||||||
enum Square : int;
|
enum Square : int;
|
||||||
using Value = int;
|
using Value = int;
|
||||||
|
@ -55,12 +50,6 @@ class UCI {
|
||||||
static std::string value(Value v);
|
static std::string value(Value v);
|
||||||
static std::string square(Square s);
|
static std::string square(Square s);
|
||||||
static std::string move(Move m, bool chess960);
|
static std::string move(Move m, bool chess960);
|
||||||
static std::string pv(const Search::Worker& workerThread,
|
|
||||||
TimePoint elapsed,
|
|
||||||
uint64_t nodesSearched,
|
|
||||||
uint64_t tb_hits,
|
|
||||||
int hashfull,
|
|
||||||
bool rootInTB);
|
|
||||||
static std::string wdl(Value v, int ply);
|
static std::string wdl(Value v, int ply);
|
||||||
static Move to_move(const Position& pos, std::string& str);
|
static Move to_move(const Position& pos, std::string& str);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue