Bring the changes closer to official-stockfish/master

This commit is contained in:
Tomasz Sobczyk
2021-04-19 18:57:21 +02:00
parent 19f712cdbb
commit ba32bd5d70
28 changed files with 451 additions and 840 deletions

View File

@@ -52,8 +52,8 @@ SRCS = benchmark.cpp bitbase.cpp bitboard.cpp endgame.cpp evaluate.cpp main.cpp
nnue/evaluate_nnue.cpp \
nnue/features/half_kp.cpp \
tools/sfen_packer.cpp \
tools/gensfen.cpp \
tools/gensfen_nonpv.cpp \
tools/training_data_generator.cpp \
tools/training_data_generator_nonpv.cpp \
tools/opening_book.cpp \
tools/convert.cpp \
tools/transform.cpp \
@@ -113,7 +113,6 @@ else
SUPPORTED_ARCH=false
endif
blas = no
optimize = yes
debug = no
sanitize = no
@@ -309,9 +308,9 @@ endif
### ==========================================================================
### 3.1 Selecting compiler (default = gcc)
CXXFLAGS += -g -Wall -Wcast-qual -fno-exceptions -std=c++17 -fopenmp -I. $(EXTRACXXFLAGS)
LDFLAGS += -fopenmp $(EXTRALDFLAGS)
DEPENDFLAGS += -std=c++17 -I.
CXXFLAGS += -Wall -Wcast-qual -fno-exceptions -std=c++17 -I. $(EXTRACXXFLAGS)
DEPENDFLAGS += -std=c++17
LDFLAGS += $(EXTRALDFLAGS)
ifeq ($(COMP),)
COMP=gcc
@@ -465,28 +464,6 @@ ifneq ($(comp),mingw)
endif
endif
### 3.2.1. BLAS libraries
ifeq ($(blas), yes)
LDFLAGS += -lopenblas
ifeq ($(KERNEL),Linux)
LDFLAGS +=
else ifeq ($(KERNEL), Darwin)
CXXFLAGS += -I/usr/local/opt/openblas/include
LDFLAGS += -L/usr/local/opt/openblas/lib -lcblas
else
CXXFLAGS += -I/mingw64/include/OpenBLAS
ifeq ($(debug),yes)
LDFLAGS += -Wl,-static
else
LDFLAGS += -Wl,-s -static
endif
endif
CXXFLAGS += -DUSE_BLAS
endif
### 3.2.2 Debugging
ifeq ($(debug),no)
CXXFLAGS += -DNDEBUG
@@ -809,12 +786,12 @@ net:
# clean binaries and objects
objclean:
@rm -f $(EXE) *.o ./syzygy/*.o ./nnue/*.o ./nnue/features/*.o ./learn/*.o ./extra/*.o ./eval/*.o
@rm -f $(EXE) *.o ./syzygy/*.o ./nnue/*.o ./nnue/features/*.o ./tools/*.o ./extra/*.o ./eval/*.o
# clean auxiliary profiling files
profileclean:
@rm -rf profdir
@rm -f bench.txt *.gcda *.gcno ./syzygy/*.gcda ./nnue/*.gcda ./nnue/features/*.gcda *.s ./learn/*.gcda ./extra/*.gcda ./eval/*.gcda
@rm -f bench.txt *.gcda *.gcno ./syzygy/*.gcda ./nnue/*.gcda ./nnue/features/*.gcda *.s ./tools/*.gcda ./extra/*.gcda ./eval/*.gcda
@rm -f stockfish.profdata *.profraw
@rm -f $(PGO_TRAINING_DATA_FILE)

View File

@@ -664,85 +664,4 @@ void sleep(int ms)
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
void* aligned_malloc(size_t size, size_t align)
{
void* p = _mm_malloc(size, align);
if (p == nullptr)
{
std::cout << "info string can't allocate memory. sise = " << size << std::endl;
exit(1);
}
return p;
}
std::uint64_t get_file_size(std::fstream& fs)
{
auto pos = fs.tellg();
fs.seekg(0, fstream::end);
const uint64_t eofPos = (uint64_t)fs.tellg();
fs.clear(); // Otherwise, the next seek may fail.
fs.seekg(0, fstream::beg);
const uint64_t begPos = (uint64_t)fs.tellg();
fs.seekg(pos);
return eofPos - begPos;
}
int read_file_to_memory(std::string filename, std::function<void* (uint64_t)> callback_func)
{
fstream fs(filename, ios::in | ios::binary);
if (fs.fail())
return 1;
const uint64_t file_size = get_file_size(fs);
//std::cout << "filename = " << filename << " , file_size = " << file_size << endl;
// I know the file size, so call callback_func to get a buffer for this,
// Get the pointer.
void* ptr = callback_func(file_size);
// If the buffer could not be secured, or if the file size is different from the expected file size,
// It is supposed to return nullptr. At this time, reading is interrupted and an error is returned.
if (ptr == nullptr)
return 2;
// read in pieces
const uint64_t block_size = 1024 * 1024 * 1024; // number of elements to read in one read (1GB)
for (uint64_t pos = 0; pos < file_size; pos += block_size)
{
// size to read this time
uint64_t read_size = (pos + block_size < file_size) ? block_size : (file_size - pos);
fs.read((char*)ptr + pos, read_size);
// Read error occurred in the middle of the file.
if (fs.fail())
return 2;
//cout << ".";
}
fs.close();
return 0;
}
int write_memory_to_file(std::string filename, void* ptr, uint64_t size)
{
fstream fs(filename, ios::out | ios::binary);
if (fs.fail())
return 1;
const uint64_t block_size = 1024 * 1024 * 1024; // number of elements to write in one write (1GB)
for (uint64_t pos = 0; pos < size; pos += block_size)
{
// Memory size to write this time
uint64_t write_size = (pos + block_size < size) ? block_size : (size - pos);
fs.write((char*)ptr + pos, write_size);
//cout << ".";
}
fs.close();
return 0;
}
} // namespace Stockfish

View File

@@ -489,91 +489,10 @@ private:
namespace WinProcGroup {
void bindThisThread(size_t idx);
}
// sleep for the specified number of milliseconds.
extern void sleep(int ms);
// Returns a string that represents the current time. (Used for log output when learning evaluation function)
std::string now_string();
// When compiled with gcc/clang such as msys2, Windows Subsystem for Linux,
// In C++ std::ifstream, ::read() is a wrapper for that because it is not possible to read and write files larger than 2GB in one shot.
//
// callback_func of the argument of read_file_to_memory() uses the file size as an argument when the file can be opened
// It will be called back, so if you allocate a buffer and pass a function that returns the first pointer, it will be read there.
// These functions return non-zero on error, such as when the file cannot be found.
//
// Also, if the buffer cannot be allocated in the callback function or if the file size is different from the expected file size,
// Return nullptr. At this time, read_file_to_memory() interrupts reading and returns with an error.
std::uint64_t get_file_size(std::fstream& fs);
int read_file_to_memory(std::string filename, std::function<void* (uint64_t)> callback_func);
int write_memory_to_file(std::string filename, void* ptr, uint64_t size);
// --------------------
// async version of PRNG
// --------------------
// async version of PRNG
struct AsyncPRNG
{
AsyncPRNG() : prng() { }
AsyncPRNG(uint64_t seed) : prng(seed) { assert(seed); }
AsyncPRNG(const std::string& seed) : prng(seed) { }
// [ASYNC] Extract one random number.
template<typename T> T rand() {
std::unique_lock<std::mutex> lk(mutex);
return prng.rand<T>();
}
// [ASYNC] Returns a random number from 0 to n-1. (Not uniform distribution, but this is enough in reality)
uint64_t rand(uint64_t n) {
std::unique_lock<std::mutex> lk(mutex);
return prng.rand(n);
}
// Return the random seed used internally.
uint64_t get_seed() const { return prng.get_seed(); }
protected:
std::mutex mutex;
PRNG prng;
};
// Display a random seed. (For debugging)
inline std::ostream& operator<<(std::ostream& os, AsyncPRNG& prng)
{
os << "AsyncPRNG::seed = " << std::hex << prng.get_seed() << std::dec;
return os;
}
// --------------------
// Math
// --------------------
// Mathematical function used for progress calculation and learning
namespace Math {
inline double sigmoid(double x)
{
return 1.0 / (1.0 + std::exp(-x));
}
inline double dsigmoid(double x)
{
// Sigmoid function
// f(x) = 1/(1+exp(-x))
// the first derivative is
// f'(x) = df/dx = f(x)・{ 1-f(x)}
// becomes
return sigmoid(x) * (1.0 - sigmoid(x));
}
// Clip v so that it fits between [lo,hi].
// * In Stockfish, this function is written in bitboard.h.
template<class T> constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
return v < lo ? lo : v > hi ? hi : v;
}
}
void sleep(int ms);
namespace Algo {
// Fisher-Yates

View File

@@ -2,18 +2,18 @@
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Definition of input features and network structure used in NNUE evaluation function
@@ -21,33 +21,33 @@
#ifndef NNUE_HALFKP_256X2_32_32_H_INCLUDED
#define NNUE_HALFKP_256X2_32_32_H_INCLUDED
#include "nnue/features/feature_set.h"
#include "nnue/features/half_kp.h"
#include "../features/feature_set.h"
#include "../features/half_kp.h"
#include "nnue/layers/input_slice.h"
#include "nnue/layers/affine_transform.h"
#include "nnue/layers/clipped_relu.h"
#include "../layers/input_slice.h"
#include "../layers/affine_transform.h"
#include "../layers/clipped_relu.h"
namespace Stockfish::Eval::NNUE {
// Input features used in evaluation function
using RawFeatures = Features::FeatureSet<
Features::HalfKP<Features::Side::kFriend>>;
// Input features used in evaluation function
using RawFeatures = Features::FeatureSet<
Features::HalfKP<Features::Side::kFriend>>;
// Number of input feature dimensions after conversion
constexpr IndexType kTransformedFeatureDimensions = 256;
// Number of input feature dimensions after conversion
constexpr IndexType kTransformedFeatureDimensions = 256;
namespace Layers {
namespace Layers {
// Define network structure
using InputLayer = InputSlice<kTransformedFeatureDimensions * 2>;
using HiddenLayer1 = ClippedReLU<AffineTransform<InputLayer, 32>>;
using HiddenLayer2 = ClippedReLU<AffineTransform<HiddenLayer1, 32>>;
using OutputLayer = AffineTransform<HiddenLayer2, 1>;
// Define network structure
using InputLayer = InputSlice<kTransformedFeatureDimensions * 2>;
using HiddenLayer1 = ClippedReLU<AffineTransform<InputLayer, 32>>;
using HiddenLayer2 = ClippedReLU<AffineTransform<HiddenLayer1, 32>>;
using OutputLayer = AffineTransform<HiddenLayer2, 1>;
} // namespace Layers
} // namespace Layers
using Network = Layers::OutputLayer;
using Network = Layers::OutputLayer;
} // namespace Stockfish::Eval::NNUE

View File

@@ -1,14 +1,17 @@
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -138,4 +141,4 @@ namespace Stockfish::Eval::NNUE {
return ReadParameters(stream);
}
} // namespace Stockfish::Eval::NNUE
} // namespace Stockfish::Eval::NNUE

View File

@@ -1,14 +1,17 @@
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -53,4 +56,4 @@ namespace Stockfish::Eval::NNUE {
} // namespace Stockfish::Eval::NNUE
#endif // #ifndef NNUE_EVALUATE_NNUE_H_INCLUDED
#endif // #ifndef NNUE_EVALUATE_NNUE_H_INCLUDED

View File

@@ -1,14 +1,17 @@
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -63,4 +66,4 @@ namespace Stockfish::Eval::NNUE::Features {
} // namespace Stockfish::Eval::NNUE::Features
#endif // #ifndef NNUE_FEATURE_SET_H_INCLUDED
#endif // #ifndef NNUE_FEATURE_SET_H_INCLUDED

View File

@@ -2,18 +2,18 @@
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//Definition of input features HalfKP of NNUE evaluation function

View File

@@ -2,23 +2,26 @@
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//Definition of input features HalfKP of NNUE evaluation function
#ifndef NNUE_FEATURES_HALF_KP_H_INCLUDED
#define NNUE_FEATURES_HALF_KP_H_INCLUDED
#include "../../evaluate.h"
#include "features_common.h"
namespace Stockfish::Eval::NNUE::Features {

View File

@@ -1,14 +1,17 @@
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -458,4 +461,4 @@ namespace Stockfish::Eval::NNUE::Layers {
} // namespace Stockfish::Eval::NNUE::Layers
#endif // #ifndef NNUE_LAYERS_AFFINE_TRANSFORM_H_INCLUDED
#endif // #ifndef NNUE_LAYERS_AFFINE_TRANSFORM_H_INCLUDED

View File

@@ -47,8 +47,6 @@ namespace Stockfish::Eval::NNUE::Layers {
static constexpr std::size_t kBufferSize =
PreviousLayer::kBufferSize + kSelfBufferSize;
static constexpr int kLayerIndex = PreviousLayer::kLayerIndex + 1;
// Hash value embedded in the evaluation file
static constexpr std::uint32_t GetHashValue() {
std::uint32_t hash_value = 0x538D24C7u;
@@ -56,36 +54,11 @@ namespace Stockfish::Eval::NNUE::Layers {
return hash_value;
}
static std::string get_name() {
return "ClippedReLU[" +
std::to_string(kOutputDimensions) + "]";
}
// A string that represents the structure from the input layer to this layer
static std::string get_structure_string() {
return get_name() + "(" +
PreviousLayer::get_structure_string() + ")";
}
static std::string get_layers_info() {
std::string info = PreviousLayer::get_layers_info();
info += "\n - ";
info += std::to_string(kLayerIndex);
info += " - ";
info += get_name();
return info;
}
// Read network parameters
bool ReadParameters(std::istream& stream) {
return previous_layer_.ReadParameters(stream);
}
// write parameters
bool WriteParameters(std::ostream& stream) const {
return previous_layer_.WriteParameters(stream);
}
// Forward propagation
const OutputType* Propagate(
const TransformedFeatureType* transformed_features, char* buffer) const {
@@ -185,9 +158,6 @@ namespace Stockfish::Eval::NNUE::Layers {
}
private:
// Make the learning class a friend
friend class Trainer<ClippedReLU>;
PreviousLayer previous_layer_;
};

View File

@@ -41,8 +41,6 @@ class InputSlice {
// Size of forward propagation buffer used from the input layer to this layer
static constexpr std::size_t kBufferSize = 0;
static constexpr int kLayerIndex = 1;
// Hash value embedded in the evaluation file
static constexpr std::uint32_t GetHashValue() {
std::uint32_t hash_value = 0xEC42E90Du;
@@ -50,35 +48,10 @@ class InputSlice {
return hash_value;
}
static std::string get_name() {
return "InputSlice[" + std::to_string(kOutputDimensions) + "(" +
std::to_string(Offset) + ":" +
std::to_string(Offset + kOutputDimensions) + ")]";
}
// A string that represents the structure from the input layer to this layer
static std::string get_structure_string() {
return get_name();
}
static std::string get_layers_info() {
std::string info = " - ";
info += std::to_string(kLayerIndex);
info += " - ";
info += get_name();
return info;
}
// Read network parameters
bool ReadParameters(std::istream& /*stream*/) {
return true;
}
// write parameters
bool WriteParameters(std::ostream& /*stream*/) const {
return true;
}
// Forward propagation
const OutputType* Propagate(
const TransformedFeatureType* transformed_features,

View File

@@ -1,14 +1,17 @@
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -34,4 +37,4 @@ namespace Stockfish::Eval::NNUE {
} // namespace Stockfish::Eval::NNUE
#endif // NNUE_ACCUMULATOR_H_INCLUDED
#endif // NNUE_ACCUMULATOR_H_INCLUDED

View File

@@ -25,13 +25,6 @@
#include <cstring>
#include <iostream>
#if defined(__GNUC__ ) && (__GNUC__ < 8)
#include <experimental/filesystem>
namespace sys = std::experimental::filesystem;
#else
#include <filesystem>
namespace sys = std::filesystem;
#endif
#if defined(USE_AVX2)
#include <immintrin.h>
@@ -112,10 +105,6 @@ namespace Stockfish::Eval::NNUE {
using TransformedFeatureType = std::uint8_t;
using IndexType = std::uint32_t;
// Forward declaration of learning class template
template <typename Layer>
class Trainer;
// Round n up to be a multiple of base
template <typename IntType>
constexpr IntType CeilToMultiple(IntType n, IntType base) {

View File

@@ -1,14 +1,17 @@
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -411,4 +414,4 @@ namespace Stockfish::Eval::NNUE {
} // namespace Stockfish::Eval::NNUE
#endif // #ifndef NNUE_FEATURE_TRANSFORMER_H_INCLUDED
#endif // #ifndef NNUE_FEATURE_TRANSFORMER_H_INCLUDED

View File

@@ -1007,10 +1007,10 @@ void Position::do_null_move(StateInfo& newSt) {
st = &newSt;
// Used by NNUE
st->dirtyPiece.dirty_num = 0;
st->dirtyPiece.piece[0] = NO_PIECE; // Avoid checks in UpdateAccumulator()
st->accumulator.state[WHITE] = Eval::NNUE::EMPTY;
st->accumulator.state[BLACK] = Eval::NNUE::EMPTY;
auto& dp = st->dirtyPiece;
dp.dirty_num = 0;
if (st->epSquare != SQ_NONE)
{

View File

@@ -25,8 +25,10 @@
#include <chrono>
#include <random>
#include <regex>
#include <filesystem>
using namespace std;
namespace sys = std::filesystem;
namespace Stockfish::Tools
{
@@ -123,7 +125,7 @@ namespace Stockfish::Tools
score = (score - src_score_min_value) / (src_score_max_value - src_score_min_value);
// Scale to [dest_score_min_value, dest_score_max_value].
score = score * (dest_score_max_value - dest_score_min_value) + dest_score_min_value;
p.score = Math::clamp((int32_t)std::round(score), -(int32_t)VALUE_MATE, (int32_t)VALUE_MATE);
p.score = std::clamp((int32_t)std::round(score), -(int32_t)VALUE_MATE, (int32_t)VALUE_MATE);
}
else if (token == "ply") {
int temp;
@@ -414,7 +416,7 @@ namespace Stockfish::Tools
Value value = parse_score_from_pgn_extract(str_eval, success);
if (success) {
eval_found = true;
psv.score = Math::clamp(value, -VALUE_MATE, VALUE_MATE);
psv.score = std::clamp(value, -VALUE_MATE, VALUE_MATE);
}
#if defined(DEBUG_CONVERT_BIN_FROM_PGN_EXTRACT)

View File

@@ -1,4 +1,4 @@
#include "gensfen.h"
#include "training_data_generator.h"
#include "sfen_writer.h"
#include "packed_sfen.h"
@@ -37,7 +37,7 @@ using namespace std;
namespace Stockfish::Tools
{
// Class to generate sfen with multiple threads
struct Gensfen
struct TrainingDataGenerator
{
struct Params
{
@@ -123,7 +123,7 @@ namespace Stockfish::Tools
static constexpr uint64_t REPORT_STATS_EVERY = 200000;
static_assert(REPORT_STATS_EVERY % REPORT_DOT_EVERY == 0);
Gensfen(
TrainingDataGenerator(
const Params& prm
) :
params(prm),
@@ -205,7 +205,7 @@ namespace Stockfish::Tools
void maybe_report(uint64_t done);
};
void Gensfen::set_gensfen_search_limits()
void TrainingDataGenerator::set_gensfen_search_limits()
{
// About Search::Limits
// Be careful because this member variable is global and affects other threads.
@@ -224,7 +224,7 @@ namespace Stockfish::Tools
limits.depth = 0;
}
void Gensfen::generate(uint64_t limit)
void TrainingDataGenerator::generate(uint64_t limit)
{
last_stats_report_time = 0;
@@ -246,7 +246,7 @@ namespace Stockfish::Tools
std::cout << std::endl;
}
void Gensfen::generate_worker(
void TrainingDataGenerator::generate_worker(
Thread& th,
std::atomic<uint64_t>& counter,
uint64_t limit)
@@ -449,7 +449,7 @@ namespace Stockfish::Tools
}
}
bool Gensfen::was_seen_before(const Position& pos)
bool TrainingDataGenerator::was_seen_before(const Position& pos)
{
// Look into the position hashtable to see if the same
// position was seen before.
@@ -470,7 +470,7 @@ namespace Stockfish::Tools
}
}
optional<int8_t> Gensfen::get_current_game_result(
optional<int8_t> TrainingDataGenerator::get_current_game_result(
Position& pos,
const vector<int>& move_hist_scores) const
{
@@ -591,7 +591,7 @@ namespace Stockfish::Tools
return nullopt;
}
vector<uint8_t> Gensfen::generate_random_move_flags(PRNG& prng)
vector<uint8_t> TrainingDataGenerator::generate_random_move_flags(PRNG& prng)
{
vector<uint8_t> random_move_flag;
@@ -628,7 +628,7 @@ namespace Stockfish::Tools
return random_move_flag;
}
optional<Move> Gensfen::choose_random_move(
optional<Move> TrainingDataGenerator::choose_random_move(
PRNG& prng,
Position& pos,
std::vector<uint8_t>& random_move_flag,
@@ -725,7 +725,7 @@ namespace Stockfish::Tools
// 1 when winning. -1 when losing. Pass 0 for a draw.
// Return value: true if the specified number of
// sfens has already been reached and the process ends.
bool Gensfen::commit_psv(
bool TrainingDataGenerator::commit_psv(
Thread& th,
PSVector& sfens,
int8_t result,
@@ -770,7 +770,7 @@ namespace Stockfish::Tools
return false;
}
void Gensfen::report(uint64_t done, uint64_t new_done)
void TrainingDataGenerator::report(uint64_t done, uint64_t new_done)
{
const auto now_time = now();
const TimePoint elapsed = now_time - last_stats_report_time + 1;
@@ -786,7 +786,7 @@ namespace Stockfish::Tools
out = sync_region_cout.new_region();
}
void Gensfen::maybe_report(uint64_t done)
void TrainingDataGenerator::maybe_report(uint64_t done)
{
if (done % REPORT_DOT_EVERY == 0)
{
@@ -811,12 +811,12 @@ namespace Stockfish::Tools
}
// Command to generate a game record
void gensfen(istringstream& is)
void generate_training_data(istringstream& is)
{
// Number of generated game records default = 8 billion phases (Ponanza specification)
uint64_t loop_max = 8000000000UL;
Gensfen::Params params;
TrainingDataGenerator::Params params;
// Add a random number to the end of the file name.
bool random_file_name = false;
@@ -966,9 +966,9 @@ namespace Stockfish::Tools
Threads.main()->ponder = false;
Gensfen gensfen(params);
TrainingDataGenerator gensfen(params);
gensfen.generate(loop_max);
std::cout << "INFO: Gensfen finished." << endl;
std::cout << "INFO: TrainingDataGenerator finished." << endl;
}
}

View File

@@ -8,7 +8,7 @@
namespace Stockfish::Tools {
// Automatic generation of teacher position
void gensfen(std::istringstream& is);
void generate_training_data(std::istringstream& is);
}
#endif

View File

@@ -1,4 +1,4 @@
#include "gensfen_nonpv.h"
#include "training_data_generator_nonpv.h"
#include "sfen_writer.h"
#include "packed_sfen.h"
@@ -37,7 +37,7 @@ using namespace std;
namespace Stockfish::Tools
{
// Class to generate sfen with multiple threads
struct GensfenNonPv
struct TrainingDataGeneratorNonPv
{
struct Params
{
@@ -89,7 +89,7 @@ namespace Stockfish::Tools
static constexpr uint64_t REPORT_STATS_EVERY = 200000;
static_assert(REPORT_STATS_EVERY % REPORT_DOT_EVERY == 0);
GensfenNonPv(
TrainingDataGeneratorNonPv(
const Params& prm
) :
params(prm),
@@ -148,7 +148,7 @@ namespace Stockfish::Tools
void maybe_report(uint64_t done);
};
void GensfenNonPv::set_gensfen_search_limits()
void TrainingDataGeneratorNonPv::set_gensfen_search_limits()
{
// About Search::Limits
// Be careful because this member variable is global and affects other threads.
@@ -167,7 +167,7 @@ namespace Stockfish::Tools
limits.depth = 0;
}
void GensfenNonPv::generate(uint64_t limit)
void TrainingDataGeneratorNonPv::generate(uint64_t limit)
{
last_stats_report_time = 0;
@@ -189,7 +189,7 @@ namespace Stockfish::Tools
std::cout << std::endl;
}
PSVector GensfenNonPv::do_exploration(
PSVector TrainingDataGeneratorNonPv::do_exploration(
Thread& th,
int count)
{
@@ -253,7 +253,7 @@ namespace Stockfish::Tools
return psv;
}
void GensfenNonPv::generate_worker(
void TrainingDataGeneratorNonPv::generate_worker(
Thread& th,
std::atomic<uint64_t>& counter,
uint64_t limit)
@@ -323,7 +323,7 @@ namespace Stockfish::Tools
// 1 when winning. -1 when losing. Pass 0 for a draw.
// Return value: true if the specified number of
// sfens has already been reached and the process ends.
bool GensfenNonPv::commit_psv(
bool TrainingDataGeneratorNonPv::commit_psv(
Thread& th,
PSVector& sfens,
std::atomic<uint64_t>& counter,
@@ -347,7 +347,7 @@ namespace Stockfish::Tools
return false;
}
void GensfenNonPv::report(uint64_t done, uint64_t new_done)
void TrainingDataGeneratorNonPv::report(uint64_t done, uint64_t new_done)
{
const auto now_time = now();
const TimePoint elapsed = now_time - last_stats_report_time + 1;
@@ -363,7 +363,7 @@ namespace Stockfish::Tools
out = sync_region_cout.new_region();
}
void GensfenNonPv::maybe_report(uint64_t done)
void TrainingDataGeneratorNonPv::maybe_report(uint64_t done)
{
if (done % REPORT_DOT_EVERY == 0)
{
@@ -388,10 +388,10 @@ namespace Stockfish::Tools
}
// Command to generate a game record
void gensfen_nonpv(istringstream& is)
void generate_training_data_nonpv(istringstream& is)
{
// Number of generated game records default = 8 billion phases (Ponanza specification)
GensfenNonPv::Params params;
TrainingDataGeneratorNonPv::Params params;
uint64_t count = 1'000'000;
@@ -480,7 +480,7 @@ namespace Stockfish::Tools
Threads.main()->ponder = false;
GensfenNonPv gensfen(params);
TrainingDataGeneratorNonPv gensfen(params);
gensfen.generate(count);
std::cout << "INFO: gensfen_nonpv finished." << endl;

View File

@@ -6,7 +6,7 @@
namespace Stockfish::Tools {
// Automatic generation of teacher position
void gensfen_nonpv(std::istringstream& is);
void generate_training_data_nonpv(std::istringstream& is);
}
#endif

View File

@@ -33,8 +33,8 @@
#include "tt.h"
#include "uci.h"
#include "tools/gensfen.h"
#include "tools/gensfen_nonpv.h"
#include "tools/training_data_generator.h"
#include "tools/training_data_generator_nonpv.h"
#include "tools/convert.h"
#include "tools/transform.h"
#include "tools/stats.h"
@@ -209,14 +209,7 @@ void UCI::setoption(const std::string& name, const std::string& value)
// The win rate model returns the probability (per mille) of winning given an eval
// and a game-ply. The model fits rather accurately the LTC fishtest statistics.
int UCI::win_rate_model(Value v, int ply) {
// Return win rate in per mille (rounded to nearest)
return int(0.5 + win_rate_model_double(v, ply));
}
// The win rate model returns the probability (per mille) of winning given an eval
// and a game-ply. The model fits rather accurately the LTC fishtest statistics.
double UCI::win_rate_model_double(double v, int ply) {
int win_rate_model(Value v, int ply) {
// The model captures only up to 240 plies, so limit input (and rescale)
double m = std::min(240, ply) / 64.0;
@@ -230,10 +223,10 @@ double UCI::win_rate_model_double(double v, int ply) {
double b = (((bs[0] * m + bs[1]) * m + bs[2]) * m) + bs[3];
// Transform eval to centipawns with limited range
double x = std::clamp(double(100 * v) / PawnValueEg, -1000.0, 1000.0);
double x = std::clamp(double(100 * v) / PawnValueEg, -1000.0, 1000.0);
// Return win rate in per mille
return 1000.0 / (1 + std::exp((a - x) / b));
// Return win rate in per mille (rounded to nearest)
return int(0.5 + 1000 / (1 + std::exp((a - x) / b)));
}
// --------------------
@@ -327,8 +320,8 @@ void UCI::loop(int argc, char* argv[]) {
else if (token == "eval") trace_eval(pos);
else if (token == "compiler") sync_cout << compiler_info() << sync_endl;
else if (token == "gensfen") Tools::gensfen(is);
else if (token == "gensfen_nonpv") Tools::gensfen_nonpv(is);
else if (token == "generate_training_data") Tools::generate_training_data(is);
else if (token == "generate_training_data") Tools::generate_training_data_nonpv(is);
else if (token == "convert") Tools::convert(is);
else if (token == "convert_bin") Tools::convert_bin(is);
else if (token == "convert_plain") Tools::convert_plain(is);

View File

@@ -74,8 +74,6 @@ std::string square(Square s);
std::string move(Move m, bool chess960);
std::string pv(const Position& pos, Depth depth, Value alpha, Value beta);
std::string wdl(Value v, int ply);
int win_rate_model(Value v, int ply);
double win_rate_model_double(double v, int ply);
Move to_move(const Position& pos, std::string& str);
void setoption(const std::string& name, const std::string& value);