mirror of
https://github.com/opelly27/Stockfish.git
synced 2026-05-20 07:27:46 +00:00
49ef4c935a
For each thread persist an accumulator cache for the network, 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". When the accumulator needs to be refreshed, instead of filling it with biases and adding every piece from scratch, we... 1. Take the `AccumulatorRefreshEntry` associated with the new king bucket 2. Calculate the features to activate and deactivate (from differences between bitboards in the entry and bitboards of the actual position) 3. Apply the updates on the refresh entry 4. Copy the content of the refresh entry accumulator to the accumulator we were refreshing 5. Copy the bitboards from the position to the refresh entry, to match the newly updated accumulator Results at STC: https://tests.stockfishchess.org/tests/view/662301573fe04ce4cefc1386 (first version) https://tests.stockfishchess.org/tests/view/6627fa063fe04ce4cefc6560 (final) Non-Regression between first and final: https://tests.stockfishchess.org/tests/view/662801e33fe04ce4cefc660a STC SMP: https://tests.stockfishchess.org/tests/view/662808133fe04ce4cefc667c closes https://github.com/official-stockfish/Stockfish/pull/5183 No functional change
89 lines
3.8 KiB
C++
89 lines
3.8 KiB
C++
/*
|
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
|
Copyright (C) 2004-2024 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/>.
|
|
*/
|
|
|
|
//Definition of input features HalfKAv2_hm of NNUE evaluation function
|
|
|
|
#include "half_ka_v2_hm.h"
|
|
|
|
#include "../../bitboard.h"
|
|
#include "../../position.h"
|
|
#include "../../types.h"
|
|
#include "../nnue_accumulator.h"
|
|
|
|
namespace Stockfish::Eval::NNUE::Features {
|
|
|
|
// Index of a feature for a given king position and another piece on some square
|
|
template<Color Perspective>
|
|
inline IndexType HalfKAv2_hm::make_index(Square s, Piece pc, Square ksq) {
|
|
return IndexType((int(s) ^ OrientTBL[Perspective][ksq]) + PieceSquareIndex[Perspective][pc]
|
|
+ KingBuckets[Perspective][ksq]);
|
|
}
|
|
|
|
// Get a list of indices for active features
|
|
template<Color Perspective>
|
|
void HalfKAv2_hm::append_active_indices(const Position& pos, IndexList& active) {
|
|
Square ksq = pos.square<KING>(Perspective);
|
|
Bitboard bb = pos.pieces();
|
|
while (bb)
|
|
{
|
|
Square s = pop_lsb(bb);
|
|
active.push_back(make_index<Perspective>(s, pos.piece_on(s), ksq));
|
|
}
|
|
}
|
|
|
|
// Explicit template instantiations
|
|
template void HalfKAv2_hm::append_active_indices<WHITE>(const Position& pos, IndexList& active);
|
|
template void HalfKAv2_hm::append_active_indices<BLACK>(const Position& pos, IndexList& active);
|
|
template IndexType HalfKAv2_hm::make_index<WHITE>(Square s, Piece pc, Square ksq);
|
|
template IndexType HalfKAv2_hm::make_index<BLACK>(Square s, Piece pc, Square ksq);
|
|
|
|
// Get a list of indices for recently changed features
|
|
template<Color Perspective>
|
|
void HalfKAv2_hm::append_changed_indices(Square ksq,
|
|
const DirtyPiece& dp,
|
|
IndexList& removed,
|
|
IndexList& added) {
|
|
for (int i = 0; i < dp.dirty_num; ++i)
|
|
{
|
|
if (dp.from[i] != SQ_NONE)
|
|
removed.push_back(make_index<Perspective>(dp.from[i], dp.piece[i], ksq));
|
|
if (dp.to[i] != SQ_NONE)
|
|
added.push_back(make_index<Perspective>(dp.to[i], dp.piece[i], ksq));
|
|
}
|
|
}
|
|
|
|
// Explicit template instantiations
|
|
template void HalfKAv2_hm::append_changed_indices<WHITE>(Square ksq,
|
|
const DirtyPiece& dp,
|
|
IndexList& removed,
|
|
IndexList& added);
|
|
template void HalfKAv2_hm::append_changed_indices<BLACK>(Square ksq,
|
|
const DirtyPiece& dp,
|
|
IndexList& removed,
|
|
IndexList& added);
|
|
|
|
int HalfKAv2_hm::update_cost(const StateInfo* st) { return st->dirtyPiece.dirty_num; }
|
|
|
|
int HalfKAv2_hm::refresh_cost(const Position& pos) { return pos.count<ALL_PIECES>(); }
|
|
|
|
bool HalfKAv2_hm::requires_refresh(const StateInfo* st, Color perspective) {
|
|
return st->dirtyPiece.piece[0] == make_piece(perspective, KING);
|
|
}
|
|
|
|
} // namespace Stockfish::Eval::NNUE::Features
|