mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 20:57:10 +00:00
Failed VVLTC non-regression https://tests.stockfishchess.org/tests/view/69d562b84088e069540a2288 LLR: -2.96 (-2.94,2.94) <-1.75,0.25> Total: 386998 W: 99181 L: 99760 D: 188057 Ptnml(0-2): 35, 35792, 122429, 35203, 40 Failed STC non-regression https://tests.stockfishchess.org/tests/view/69f3c6601e5788938e86a99e LLR: -2.93 (-2.94,2.94) <-1.75,0.25> Total: 33696 W: 8492 L: 8795 D: 16409 Ptnml(0-2): 124, 4209, 8504, 3868, 143 Many thanks to Dubslow, Torom, ces42, Shawn, vondele, Disservin and others for discussion. ## Summary The venerable small net has been around for quite some time now, and while the big net architecture has substantially advanced with TI, the small net has stayed with plain HalfKA. It therefore presents a few burdens: multiple net architectures to maintain, multiple nets to train, and a whole lot of templates to deal with the variable L1 size. Locally I measure a slowdown of -2.5% in NPS with this branch – and it's probably more on non-AVX512 architectures – but a pure slowdown of that magnitude would lead to more dramatic losses (even at VVLTC) than exhibited in the above tests, suggesting that the small net's lower eval quality is deleterious. Bonus: Shawn found this interesting PGN among the VVLTC games: https://lichess.org/study/hvo8jflc/OeTOityv `master` seems to misevaluate the fortress because all positions go to small net (the material difference is larger than the threshold). closes https://github.com/official-stockfish/Stockfish/pull/6796 Bench: 2877007
120 lines
3.5 KiB
C++
120 lines
3.5 KiB
C++
/*
|
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
|
Copyright (C) 2004-2026 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/>.
|
|
*/
|
|
|
|
#ifndef NETWORK_H_INCLUDED
|
|
#define NETWORK_H_INCLUDED
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <tuple>
|
|
|
|
#include "../types.h"
|
|
#include "nnue_architecture.h"
|
|
#include "nnue_feature_transformer.h"
|
|
#include "nnue_misc.h"
|
|
|
|
namespace Stockfish {
|
|
class Position;
|
|
}
|
|
|
|
namespace Stockfish::Eval::NNUE {
|
|
|
|
class AccumulatorStack;
|
|
struct AccumulatorCaches;
|
|
|
|
using NetworkOutput = std::tuple<Value, Value>;
|
|
|
|
// The network must be a trivial type, i.e. the memory must be in-line.
|
|
// This is required to allow sharing the network via shared memory, as
|
|
// there is no way to run destructors.
|
|
class Network {
|
|
public:
|
|
Network(EvalFile file) :
|
|
evalFile(file) {}
|
|
|
|
Network(const Network& other) = default;
|
|
Network(Network&& other) = default;
|
|
|
|
Network& operator=(const Network& other) = default;
|
|
Network& operator=(Network&& other) = default;
|
|
|
|
void load(const std::string& rootDirectory, std::string evalfilePath);
|
|
bool save(const std::optional<std::string>& filename) const;
|
|
|
|
std::size_t get_content_hash() const;
|
|
|
|
NetworkOutput evaluate(const Position& pos,
|
|
AccumulatorStack& accumulatorStack,
|
|
AccumulatorCaches& cache) const;
|
|
|
|
|
|
void verify(std::string evalfilePath, const std::function<void(std::string_view)>&) const;
|
|
NnueEvalTrace trace_evaluate(const Position& pos,
|
|
AccumulatorStack& accumulatorStack,
|
|
AccumulatorCaches& cache) const;
|
|
|
|
private:
|
|
void load_user_net(const std::string&, const std::string&);
|
|
void load_internal();
|
|
|
|
void initialize();
|
|
|
|
bool save(std::ostream&, const std::string&, const std::string&) const;
|
|
std::optional<std::string> load(std::istream&);
|
|
|
|
bool read_header(std::istream&, std::uint32_t*, std::string*) const;
|
|
bool write_header(std::ostream&, std::uint32_t, const std::string&) const;
|
|
|
|
bool read_parameters(std::istream&, std::string&);
|
|
bool write_parameters(std::ostream&, const std::string&) const;
|
|
|
|
// Input feature converter
|
|
FeatureTransformer featureTransformer;
|
|
|
|
// Evaluation function
|
|
NetworkArchitecture network[LayerStacks];
|
|
|
|
EvalFile evalFile;
|
|
|
|
bool initialized = false;
|
|
|
|
// Hash value of evaluation function structure
|
|
static constexpr std::uint32_t hash =
|
|
FeatureTransformer::get_hash_value() ^ NetworkArchitecture::get_hash_value();
|
|
|
|
friend struct AccumulatorCaches;
|
|
};
|
|
|
|
|
|
} // namespace Stockfish
|
|
|
|
template<>
|
|
struct std::hash<Stockfish::Eval::NNUE::Network> {
|
|
std::size_t operator()(const Stockfish::Eval::NNUE::Network& network) const noexcept {
|
|
return network.get_content_hash();
|
|
}
|
|
};
|
|
|
|
#endif
|