mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
Failed STC (https://tests.stockfishchess.org/tests/view/6a4f36355529b8472df7ff7e): LLR: -2.94 (-2.94,2.94) <0.00,2.00> Total: 144768 W: 38003 L: 38051 D: 68714 Ptnml(0-2): 521, 17154, 37050, 17170, 489 Passed LTC (https://tests.stockfishchess.org/tests/view/6a501dad5529b8472df80103): LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 189888 W: 49613 L: 48984 D: 91291 Ptnml(0-2): 122, 20406, 53256, 21041, 119 Passed VLTC (https://tests.stockfishchess.org/tests/view/6a52892c5529b8472df80481): LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 46124 W: 12156 L: 11865 D: 22103 Ptnml(0-2): 12, 4523, 13696, 4824, 7 Passed VVLTC (https://tests.stockfishchess.org/tests/view/6a566a285529b8472df80b84): LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 44698 W: 11805 L: 11507 D: 21386 Ptnml(0-2): 9, 3819, 14395, 4117, 9 This PR adds pawn pair features, a new set of features that is indexed by pairs of pawns occupying the same or adjacent files (hence "3-wide"). Because these are a superset of pawn–pawn interactions in threat inputs (including the recently added pawn-pusher inputs), those are removed. HalfKA features remain unchanged. Pawn-pair features were invented by Jonathan for Pawnocchio, based on his observation that in a net trained on *all* pairs of pawns, the most important pawn pairs were those differing by at most one file. sscg13 made the necessary changes to the trainer (https://github.com/official-stockfish/nnue-pytorch/pull/502) and initial changes to inference. The slowdown was originally far too large (some 10%); following major optimizations from Jonathan and a bit from me, the slowdown is small enough for a comfortable LTC pass; on my machine I get a 3.5% slowdown overall. I expect there are further "easy" speedups in the new code, so this gap should narrow a bit. Nettest PR: https://github.com/vondele/nettest/pull/359 closes https://github.com/official-stockfish/Stockfish/pull/6982 Bench: 2718396 Co-Authored-By: anematode <timothy.herchen@gmail.com> Co-Authored-By: Jonathan Hallström <lmj.hallstrom@gmail.com>
137 lines
4.9 KiB
C++
137 lines
4.9 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/>.
|
|
*/
|
|
|
|
// Class for difference calculation of NNUE evaluation function
|
|
|
|
#ifndef NNUE_ACCUMULATOR_H_INCLUDED
|
|
#define NNUE_ACCUMULATOR_H_INCLUDED
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <cstring>
|
|
|
|
#include "../types.h"
|
|
#include "../misc.h"
|
|
#include "nnue_architecture.h"
|
|
#include "nnue_common.h"
|
|
|
|
namespace Stockfish {
|
|
class Position;
|
|
}
|
|
|
|
namespace Stockfish::Eval::NNUE {
|
|
|
|
struct alignas(CacheLineSize) Accumulator;
|
|
|
|
class FeatureTransformer;
|
|
|
|
// Class that holds the result of affine transformation of input features,
|
|
// combined HalfKA + Threats
|
|
struct alignas(CacheLineSize) Accumulator {
|
|
std::array<std::array<i16, L1>, COLOR_NB> accumulation;
|
|
std::array<std::array<i32, PSQTBuckets>, COLOR_NB> psqtAccumulation;
|
|
std::array<bool, COLOR_NB> computed = {};
|
|
};
|
|
|
|
|
|
// AccumulatorCaches struct provides per-thread accumulator caches, where each
|
|
// cache contains multiple entries for each of the possible king squares.
|
|
// When the accumulator needs to be refreshed, the cached entry is used to more
|
|
// efficiently update the accumulator, instead of rebuilding it from scratch.
|
|
// This idea, was first described by Luecx (author of Koivisto) and
|
|
// is commonly referred to as "Finny Tables".
|
|
struct AccumulatorCaches {
|
|
template<typename Network>
|
|
AccumulatorCaches(const Network& network) {
|
|
clear(network);
|
|
}
|
|
|
|
struct alignas(CacheLineSize) Entry {
|
|
std::array<BiasType, L1> accumulation;
|
|
std::array<PSQTWeightType, PSQTBuckets> psqtAccumulation;
|
|
std::array<Piece, SQUARE_NB> pieces;
|
|
Bitboard pieceBB;
|
|
|
|
// To initialize a refresh entry, we set all its bitboards empty,
|
|
// so we put the biases in the accumulation, without any weights on top
|
|
void clear(const std::array<BiasType, L1>& biases) {
|
|
accumulation = biases;
|
|
std::memset(reinterpret_cast<std::byte*>(this) + offsetof(Entry, psqtAccumulation), 0,
|
|
sizeof(Entry) - offsetof(Entry, psqtAccumulation));
|
|
}
|
|
};
|
|
|
|
template<typename Network>
|
|
void clear(const Network& network) {
|
|
for (auto& entries1D : entries)
|
|
for (auto& entry : entries1D)
|
|
entry.clear(network.featureTransformer.biases);
|
|
}
|
|
|
|
std::array<Entry, COLOR_NB>& operator[](Square sq) { return entries[sq]; }
|
|
|
|
std::array<std::array<Entry, COLOR_NB>, SQUARE_NB> entries;
|
|
};
|
|
|
|
|
|
struct AccumulatorState: public Accumulator, Dirties {};
|
|
|
|
class AccumulatorStack {
|
|
public:
|
|
static constexpr usize MaxSize = MAX_PLY + 1;
|
|
|
|
[[nodiscard]] const AccumulatorState& latest() const noexcept;
|
|
|
|
void reset() noexcept;
|
|
Dirties& push() noexcept;
|
|
void pop() noexcept;
|
|
|
|
void evaluate(const Position& pos,
|
|
const FeatureTransformer& featureTransformer,
|
|
// Silence spurious warning on GCC 10
|
|
[[maybe_unused]] AccumulatorCaches& cache) noexcept;
|
|
|
|
private:
|
|
[[nodiscard]] AccumulatorState& mut_latest() noexcept;
|
|
|
|
void evaluate_side(Color perspective,
|
|
const Position& pos,
|
|
const FeatureTransformer& featureTransformer,
|
|
// Silence spurious warning on GCC 10
|
|
[[maybe_unused]] AccumulatorCaches& cache) noexcept;
|
|
|
|
[[nodiscard]] usize find_last_usable_accumulator(Color perspective) const noexcept;
|
|
|
|
void forward_update_incremental(Color perspective,
|
|
const Position& pos,
|
|
const FeatureTransformer& featureTransformer,
|
|
const usize begin) noexcept;
|
|
|
|
void backward_update_incremental(Color perspective,
|
|
const Position& pos,
|
|
const FeatureTransformer& featureTransformer,
|
|
const usize end) noexcept;
|
|
|
|
std::array<AccumulatorState, MaxSize> accumulators;
|
|
usize size = 1;
|
|
};
|
|
|
|
} // namespace Stockfish::Eval::NNUE
|
|
|
|
#endif // NNUE_ACCUMULATOR_H_INCLUDED
|