Skip to content

Commit bfb2654

Browse files
committed
Merge with latest Stockfish development branch (last revision: b5e8169a85f6937d7d9d90612863fe5eec72d6ca)
1 parent 057cce2 commit bfb2654

32 files changed

+1262
-1062
lines changed

src/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ SRCS = benchmark.cpp bitboard.cpp evaluate.cpp main.cpp \
6868
# nnue/layers/sqr_clipped_relu.h nnue/nnue_accumulator.h nnue/nnue_architecture.h \
6969
# nnue/nnue_common.h nnue/nnue_feature_transformer.h position.h \
7070
# search.h syzygy/tbprobe.h thread.h thread_win32_osx.h timeman.h \
71-
# tt.h tune.h types.h uci.h
71+
# tt.h tune.h types.h uci.h ucioption.h
7272

7373
OBJS = $(notdir $(SRCS:.cpp=.o))
7474

@@ -392,7 +392,7 @@ ifeq ($(MAKELEVEL),0)
392392
export ENV_LDFLAGS := $(LDFLAGS)
393393
endif
394394

395-
CXXFLAGS = $(ENV_CXXFLAGS) -Wall -Wcast-qual -fno-exceptions -std=c++17 $(EXTRACXXFLAGS) -DPOLYFISH
395+
CXXFLAGS = $(ENV_CXXFLAGS) -Wall -Wcast-qual -fno-exceptions -std=c++17 -DPOLYFISH $(EXTRACXXFLAGS)
396396
DEPENDFLAGS = $(ENV_DEPENDFLAGS) -std=c++17
397397
LDFLAGS = $(ENV_LDFLAGS) $(EXTRALDFLAGS)
398398

src/book/book.cpp

+13-10
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Polyfish::Book
1212
{
1313
namespace
1414
{
15-
Book* create_book(const string& filename)
15+
Book* create_book(const std::string& filename)
1616
{
1717
size_t extIndex = filename.find_last_of('.');
1818
if (extIndex == string::npos)
@@ -32,13 +32,13 @@ namespace Polyfish::Book
3232
constexpr size_t NumBooks = 2;
3333
Book* books[NumBooks];
3434

35-
void init()
35+
void init(const OptionsMap& options)
3636
{
3737
for (size_t i = 0; i < NumBooks; ++i)
3838
books[i] = nullptr;
3939

40-
on_book(0, (string)Options["CTG/BIN Book 1 File"]);
41-
on_book(1, (string)Options["CTG/BIN Book 2 File"]);
40+
on_book(0, options);
41+
on_book(1, options);
4242
}
4343

4444
void finalize()
@@ -50,12 +50,15 @@ namespace Polyfish::Book
5050
}
5151
}
5252

53-
void on_book(int index, const string& filename)
53+
void on_book(int index, const OptionsMap& options)
5454
{
5555
//Close previous book if any
5656
delete books[index];
5757
books[index] = nullptr;
5858

59+
60+
std::string filename = std::string(options[Utility::format_string("CTG/BIN Book %d File", index + 1)]);
61+
5962
//Load new book
6063
if (Utility::is_empty_filename(filename))
6164
return;
@@ -79,16 +82,16 @@ namespace Polyfish::Book
7982
books[index] = book;
8083
}
8184

82-
Move probe(const Position& pos)
85+
Move probe(const Position& pos, const OptionsMap& options)
8386
{
8487
int moveNumber = 1 + pos.game_ply() / 2;
8588
Move bookMove = Move::none();
8689

8790
for (size_t i = 0; i < NumBooks; ++i)
8891
{
89-
if (books[i] != nullptr && (int)Options[Utility::format_string("Book %d Depth", i + 1)] >= moveNumber)
92+
if (books[i] != nullptr && int(options[Utility::format_string("Book %d Depth", i + 1)]) >= moveNumber)
9093
{
91-
bookMove = books[i]->probe(pos, (size_t)(int)Options[Utility::format_string("Book %d Width", i + 1)], (bool)Options[Utility::format_string("(CTG) Book %d Only Green", i + 1)]);
94+
bookMove = books[i]->probe(pos, size_t(int(options[Utility::format_string("Book %d Width", i + 1)])), bool(options[Utility::format_string("(CTG) Book %d Only Green", i + 1)]));
9295
if (bookMove != Move::none())
9396
break;
9497
}
@@ -97,7 +100,7 @@ namespace Polyfish::Book
97100
return bookMove;
98101
}
99102

100-
void show_moves(const Position& pos)
103+
void show_moves(const Position& pos, const OptionsMap& options)
101104
{
102105
cout << pos << endl << endl;
103106

@@ -109,7 +112,7 @@ namespace Polyfish::Book
109112
}
110113
else
111114
{
112-
cout << "Book " << i + 1 << " (" << books[i]->type() << "): " << (std::string)Options[Utility::format_string("CTG/BIN Book %d File", i + 1)] << endl;
115+
cout << "Book " << i + 1 << " (" << books[i]->type() << "): " << std::string(options[Utility::format_string("CTG/BIN Book %d File", i + 1)]) << endl;
113116
books[i]->show_moves(pos);
114117
}
115118
}

src/book/book.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ namespace Polyfish::Book
7171
virtual void show_moves(const Position& pos) const = 0;
7272
};
7373

74-
void init();
74+
void init(const OptionsMap& options);
7575
void finalize();
7676

77-
void on_book(int index, const std::string& filename);
78-
Move probe(const Position& pos);
79-
void show_moves(const Position& pos);
77+
void on_book(int index, const OptionsMap& options);
78+
Move probe(const Position& pos, const OptionsMap& options);
79+
void show_moves(const Position& pos, const OptionsMap& options);
8080
}
8181

8282
#endif

src/book/ctg/ctg.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ namespace Polyfish::Book::CTG
10091009
//Position object to be used to play the moves
10101010
StateInfo si[2];
10111011
Position p;
1012-
p.set(pos.fen(), pos.is_chess960(), &si[0], pos.this_thread());
1012+
p.set(pos.fen(), pos.is_chess960(), &si[0]);
10131013

10141014
//Read position statistics
10151015
get_stats(positionData, ctgMoveList.positionStats, false);
@@ -1066,7 +1066,7 @@ namespace Polyfish::Book::CTG
10661066
return "CTG";
10671067
}
10681068

1069-
bool CtgBook::open(const string& f)
1069+
bool CtgBook::open(const std::string& f)
10701070
{
10711071
//Close current file
10721072
close();

src/book/polyglot/polyglot.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ namespace Polyfish::Book::Polyglot
482482
filename.clear();
483483
}
484484

485-
bool PolyglotBook::open(const string& f)
485+
bool PolyglotBook::open(const std::string& f)
486486
{
487487
//If same file and same size -> nothing to do
488488
if (Utility::is_same_file(f, filename) && Utility::get_file_size(f) == bookDataLength)

src/evaluate.cpp

+39-35
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <fstream>
2626
#include <iomanip>
2727
#include <iostream>
28+
#include <optional>
2829
#include <sstream>
2930
#include <unordered_map>
3031
#include <vector>
@@ -34,9 +35,9 @@
3435
#include "nnue/evaluate_nnue.h"
3536
#include "nnue/nnue_architecture.h"
3637
#include "position.h"
37-
#include "thread.h"
3838
#include "types.h"
3939
#include "uci.h"
40+
#include "ucioption.h"
4041

4142
// Macro to embed the default efficiently updatable neural network (NNUE) file
4243
// data in the engine binary (using incbin.h, by Dale Weiler).
@@ -62,10 +63,6 @@ namespace Polyfish {
6263

6364
namespace Eval {
6465

65-
std::unordered_map<NNUE::NetSize, EvalFile> EvalFiles = {
66-
{NNUE::Big, {"EvalFile", EvalFileDefaultNameBig, "None"}},
67-
{NNUE::Small, {"EvalFileSmall", EvalFileDefaultNameSmall, "None"}}};
68-
6966

7067
// Tries to load a NNUE network at startup time, or when the engine
7168
// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
@@ -74,37 +71,44 @@ std::unordered_map<NNUE::NetSize, EvalFile> EvalFiles = {
7471
// network may be embedded in the binary), in the active working directory and
7572
// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
7673
// variable to have the engine search in a special directory in their distro.
77-
void NNUE::init() {
74+
NNUE::EvalFiles NNUE::load_networks(const std::string& rootDirectory,
75+
const OptionsMap& options,
76+
NNUE::EvalFiles evalFiles) {
7877

79-
for (auto& [netSize, evalFile] : EvalFiles)
78+
for (auto& [netSize, evalFile] : evalFiles)
8079
{
8180
// Replace with
82-
// Options[evalFile.option_name]
81+
// options[evalFile.optionName]
8382
// once fishtest supports the uci option EvalFileSmall
84-
std::string user_eval_file = Options[evalFile.option_name];
83+
std::string user_eval_file = options[evalFile.optionName];
8584

8685
if (user_eval_file.empty())
87-
user_eval_file = evalFile.default_name;
86+
user_eval_file = evalFile.defaultName;
8887

8988
#if defined(DEFAULT_NNUE_DIRECTORY)
90-
std::vector<std::string> dirs = {"<internal>", "", CommandLine::binaryDirectory,
89+
std::vector<std::string> dirs = {"<internal>", "", rootDirectory,
9190
stringify(DEFAULT_NNUE_DIRECTORY)};
9291
#else
93-
std::vector<std::string> dirs = {"<internal>", "", CommandLine::binaryDirectory};
92+
std::vector<std::string> dirs = {"<internal>", "", rootDirectory};
9493
#endif
9594

9695
for (const std::string& directory : dirs)
9796
{
98-
if (evalFile.selected_name != user_eval_file)
97+
if (evalFile.current != user_eval_file)
9998
{
10099
if (directory != "<internal>")
101100
{
102101
std::ifstream stream(directory + user_eval_file, std::ios::binary);
103-
if (NNUE::load_eval(user_eval_file, stream, netSize))
104-
evalFile.selected_name = user_eval_file;
102+
auto description = NNUE::load_eval(stream, netSize);
103+
104+
if (description.has_value())
105+
{
106+
evalFile.current = user_eval_file;
107+
evalFile.netDescription = description.value();
108+
}
105109
}
106110

107-
if (directory == "<internal>" && user_eval_file == evalFile.default_name)
111+
if (directory == "<internal>" && user_eval_file == evalFile.defaultName)
108112
{
109113
// C++ way to prepare a buffer for a memory stream
110114
class MemoryBuffer: public std::basic_streambuf<char> {
@@ -123,27 +127,35 @@ void NNUE::init() {
123127
(void) gEmbeddedNNUESmallEnd;
124128

125129
std::istream stream(&buffer);
126-
if (NNUE::load_eval(user_eval_file, stream, netSize))
127-
evalFile.selected_name = user_eval_file;
130+
auto description = NNUE::load_eval(stream, netSize);
131+
132+
if (description.has_value())
133+
{
134+
evalFile.current = user_eval_file;
135+
evalFile.netDescription = description.value();
136+
}
128137
}
129138
}
130139
}
131140
}
141+
142+
return evalFiles;
132143
}
133144

134145
// Verifies that the last net used was loaded successfully
135-
void NNUE::verify() {
146+
void NNUE::verify(const OptionsMap& options,
147+
const std::unordered_map<Eval::NNUE::NetSize, EvalFile>& evalFiles) {
136148

137-
for (const auto& [netSize, evalFile] : EvalFiles)
149+
for (const auto& [netSize, evalFile] : evalFiles)
138150
{
139151
// Replace with
140-
// Options[evalFile.option_name]
152+
// options[evalFile.optionName]
141153
// once fishtest supports the uci option EvalFileSmall
142-
std::string user_eval_file = Options[evalFile.option_name];
154+
std::string user_eval_file = options[evalFile.optionName];
143155
if (user_eval_file.empty())
144-
user_eval_file = evalFile.default_name;
156+
user_eval_file = evalFile.defaultName;
145157

146-
if (evalFile.selected_name != user_eval_file)
158+
if (evalFile.current != user_eval_file)
147159
{
148160
std::string msg1 =
149161
"Network evaluation parameters compatible with the engine must be available.";
@@ -153,7 +165,7 @@ void NNUE::verify() {
153165
"including the directory name, to the network file.";
154166
std::string msg4 = "The default net can be downloaded from: "
155167
"https://tests.stockfishchess.org/api/nn/"
156-
+ evalFile.default_name;
168+
+ evalFile.defaultName;
157169
std::string msg5 = "The engine will be terminated now.";
158170

159171
sync_cout << "info string ERROR: " << msg1 << sync_endl;
@@ -181,7 +193,7 @@ int Eval::simple_eval(const Position& pos, Color c) {
181193

182194
// Evaluate is the evaluator for the outer world. It returns a static evaluation
183195
// of the position from the point of view of the side to move.
184-
Value Eval::evaluate(const Position& pos) {
196+
Value Eval::evaluate(const Position& pos, int optimism) {
185197

186198
assert(!pos.checkers());
187199

@@ -202,8 +214,6 @@ Value Eval::evaluate(const Position& pos) {
202214
Value nnue = smallNet ? NNUE::evaluate<NNUE::Small>(pos, true, &nnueComplexity)
203215
: NNUE::evaluate<NNUE::Big>(pos, true, &nnueComplexity);
204216

205-
int optimism = pos.this_thread()->optimism[stm];
206-
207217
// Blend optimism and eval with nnue complexity and material imbalance
208218
optimism += optimism * (nnueComplexity + std::abs(simpleEval - nnue)) / 512;
209219
nnue -= nnue * (nnueComplexity + std::abs(simpleEval - nnue)) / 32768;
@@ -230,12 +240,6 @@ std::string Eval::trace(Position& pos) {
230240
if (pos.checkers())
231241
return "Final evaluation: none (in check)";
232242

233-
// Reset any global variable used in eval
234-
pos.this_thread()->bestValue = VALUE_ZERO;
235-
pos.this_thread()->rootSimpleEval = VALUE_ZERO;
236-
pos.this_thread()->optimism[WHITE] = VALUE_ZERO;
237-
pos.this_thread()->optimism[BLACK] = VALUE_ZERO;
238-
239243
std::stringstream ss;
240244
ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
241245
ss << '\n' << NNUE::trace(pos) << '\n';
@@ -247,7 +251,7 @@ std::string Eval::trace(Position& pos) {
247251
v = pos.side_to_move() == WHITE ? v : -v;
248252
ss << "NNUE evaluation " << 0.01 * UCI::to_cp(v) << " (white side)\n";
249253

250-
v = evaluate(pos);
254+
v = evaluate(pos, VALUE_ZERO);
251255
v = pos.side_to_move() == WHITE ? v : -v;
252256
ss << "Final evaluation " << 0.01 * UCI::to_cp(v) << " (white side)";
253257
ss << " [with scaled NNUE, ...]";

src/evaluate.h

+17-11
Original file line numberDiff line numberDiff line change
@@ -27,36 +27,42 @@
2727
namespace Polyfish {
2828

2929
class Position;
30+
class OptionsMap;
3031

3132
namespace Eval {
3233

3334
std::string trace(Position& pos);
3435

3536
int simple_eval(const Position& pos, Color c);
36-
Value evaluate(const Position& pos);
37+
Value evaluate(const Position& pos, int optimism);
3738

3839
// The default net name MUST follow the format nn-[SHA256 first 12 digits].nnue
3940
// for the build process (profile-build and fishtest) to work. Do not change the
4041
// name of the macro, as it is used in the Makefile.
4142
#define EvalFileDefaultNameBig "nn-baff1edbea57.nnue"
4243
#define EvalFileDefaultNameSmall "nn-baff1ede1f90.nnue"
4344

45+
struct EvalFile {
46+
// UCI option name
47+
std::string optionName;
48+
// Default net name, will use one of the macros above
49+
std::string defaultName;
50+
// Selected net name, either via uci option or default
51+
std::string current;
52+
// Net description extracted from the net file
53+
std::string netDescription;
54+
};
55+
4456
namespace NNUE {
4557

4658
enum NetSize : int;
4759

48-
void init();
49-
void verify();
50-
51-
} // namespace NNUE
60+
using EvalFiles = std::unordered_map<Eval::NNUE::NetSize, EvalFile>;
5261

53-
struct EvalFile {
54-
std::string option_name;
55-
std::string default_name;
56-
std::string selected_name;
57-
};
62+
EvalFiles load_networks(const std::string&, const OptionsMap&, EvalFiles);
63+
void verify(const OptionsMap&, const EvalFiles&);
5864

59-
extern std::unordered_map<NNUE::NetSize, EvalFile> EvalFiles;
65+
} // namespace NNUE
6066

6167
} // namespace Eval
6268

0 commit comments

Comments
 (0)