mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-26 03:56:50 +08:00
Add a HalfKA architecture (a product of K - king, and A - any piece) along with all required infrastructure. HalfKA doesn't discriminate kings compared to HalfKP. Keep old architecture as the default one.
This commit is contained in:
50
src/nnue/features/a.cpp
Normal file
50
src/nnue/features/a.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "a.h"
|
||||
#include "index_list.h"
|
||||
|
||||
// Definition of input feature A of NNUE evaluation function
|
||||
namespace Eval::NNUE::Features {
|
||||
|
||||
// Orient a square according to perspective (flip rank for black)
|
||||
inline Square orient(Color perspective, Square s) {
|
||||
return Square(int(s) ^ (bool(perspective) * SQ_A8));
|
||||
}
|
||||
|
||||
// Find the index of the feature quantity from the king position and PieceSquare
|
||||
inline IndexType A::make_index(
|
||||
Color perspective, Square s, Piece pc) {
|
||||
return IndexType(orient(perspective, s) + kpp_board_index[pc][perspective]);
|
||||
}
|
||||
|
||||
// Get a list of indices with a value of 1 among the features
|
||||
void A::append_active_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* active) {
|
||||
|
||||
Bitboard bb = pos.pieces();
|
||||
while (bb) {
|
||||
Square s = pop_lsb(&bb);
|
||||
active->push_back(make_index(perspective, s, pos.piece_on(s)));
|
||||
}
|
||||
}
|
||||
|
||||
// Get a list of indices whose values have changed from the previous one in the feature quantity
|
||||
void A::append_changed_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* removed,
|
||||
IndexList* added) {
|
||||
|
||||
const auto& dp = pos.state()->dirtyPiece;
|
||||
for (int i = 0; i < dp.dirty_num; ++i) {
|
||||
Piece pc = dp.piece[i];
|
||||
|
||||
if (dp.from[i] != SQ_NONE)
|
||||
removed->push_back(make_index(perspective, dp.from[i], pc));
|
||||
|
||||
if (dp.to[i] != SQ_NONE)
|
||||
added->push_back(make_index(perspective, dp.to[i], pc));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Eval::NNUE::Features
|
||||
54
src/nnue/features/a.h
Normal file
54
src/nnue/features/a.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef _NNUE_FEATURES_A_H_
|
||||
#define _NNUE_FEATURES_A_H_
|
||||
|
||||
#include "features_common.h"
|
||||
|
||||
#include "evaluate.h"
|
||||
|
||||
// Definition of input feature A of NNUE evaluation function
|
||||
// A is a union of P features and K features, so technically the
|
||||
// same effect can be achieved by including both P and K features
|
||||
// but it would result in slower index appending because
|
||||
// P would conditionally exclude K features and vice versa,
|
||||
// where A doesn't have any conditionals.
|
||||
namespace Eval::NNUE::Features {
|
||||
|
||||
// Feature P: PieceSquare of pieces other than balls
|
||||
class A {
|
||||
public:
|
||||
// feature quantity name
|
||||
static constexpr const char* kName = "A";
|
||||
|
||||
// Hash value embedded in the evaluation function file
|
||||
static constexpr std::uint32_t kHashValue = 0x7A4C414Cu;
|
||||
|
||||
// number of feature dimensions
|
||||
static constexpr IndexType kDimensions = PS_END2;
|
||||
|
||||
// The maximum value of the number of indexes whose value is 1 at the same time among the feature values
|
||||
static constexpr IndexType kMaxActiveDimensions = 32;
|
||||
|
||||
// Timing of full calculation instead of difference calculation
|
||||
static constexpr TriggerEvent kRefreshTrigger = TriggerEvent::kNone;
|
||||
|
||||
// Get a list of indices with a value of 1 among the features
|
||||
static void append_active_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* active);
|
||||
|
||||
// Get a list of indices whose values have changed from the previous one in the feature quantity
|
||||
static void append_changed_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* removed,
|
||||
IndexList* added);
|
||||
|
||||
private:
|
||||
// Index of a feature for a given piece on some square
|
||||
static IndexType make_index(Color perspective, Square s, Piece pc);
|
||||
};
|
||||
|
||||
} // namespace Eval::NNUE::Features
|
||||
|
||||
#endif // #ifndef _NNUE_FEATURES_UNION_P_K_H_
|
||||
89
src/nnue/features/half_ka.cpp
Normal file
89
src/nnue/features/half_ka.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||
Copyright (C) 2004-2020 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 HalfKA of NNUE evaluation function
|
||||
|
||||
#include "half_ka.h"
|
||||
#include "index_list.h"
|
||||
|
||||
namespace Eval::NNUE::Features {
|
||||
|
||||
// Orient a square according to perspective (flip rank for black)
|
||||
inline Square orient(Color perspective, Square s) {
|
||||
return Square(int(s) ^ (bool(perspective) * SQ_A8));
|
||||
}
|
||||
|
||||
// Find the index of the feature quantity from the king position and PieceSquare
|
||||
template <Side AssociatedKing>
|
||||
inline IndexType HalfKA<AssociatedKing>::make_index(
|
||||
Color perspective,
|
||||
Square s,
|
||||
Piece pc,
|
||||
Square ksq) {
|
||||
|
||||
return IndexType(orient(perspective, s) + kpp_board_index[pc][perspective] + PS_END2 * ksq);
|
||||
}
|
||||
|
||||
// Get a list of indices for active features
|
||||
template <Side AssociatedKing>
|
||||
void HalfKA<AssociatedKing>::append_active_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* active) {
|
||||
|
||||
Square ksq = orient(
|
||||
perspective,
|
||||
pos.square<KING>(
|
||||
AssociatedKing == Side::kFriend ? perspective : ~perspective));
|
||||
|
||||
Bitboard bb = pos.pieces();
|
||||
while (bb) {
|
||||
Square s = pop_lsb(&bb);
|
||||
active->push_back(make_index(perspective, s, pos.piece_on(s), ksq));
|
||||
}
|
||||
}
|
||||
|
||||
// Get a list of indices for recently changed features
|
||||
template <Side AssociatedKing>
|
||||
void HalfKA<AssociatedKing>::append_changed_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* removed,
|
||||
IndexList* added) {
|
||||
|
||||
Square ksq = orient(
|
||||
perspective,
|
||||
pos.square<KING>(
|
||||
AssociatedKing == Side::kFriend ? perspective : ~perspective));
|
||||
|
||||
const auto& dp = pos.state()->dirtyPiece;
|
||||
for (int i = 0; i < dp.dirty_num; ++i) {
|
||||
Piece pc = dp.piece[i];
|
||||
|
||||
if (dp.from[i] != SQ_NONE)
|
||||
removed->push_back(make_index(perspective, dp.from[i], pc, ksq));
|
||||
|
||||
if (dp.to[i] != SQ_NONE)
|
||||
added->push_back(make_index(perspective, dp.to[i], pc, ksq));
|
||||
}
|
||||
}
|
||||
|
||||
template class HalfKA<Side::kFriend>;
|
||||
template class HalfKA<Side::kEnemy>;
|
||||
|
||||
} // namespace Eval::NNUE::Features
|
||||
75
src/nnue/features/half_ka.h
Normal file
75
src/nnue/features/half_ka.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||
Copyright (C) 2004-2020 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 NNUE_FEATURES_HALF_KA_H_INCLUDED
|
||||
#define NNUE_FEATURES_HALF_KA_H_INCLUDED
|
||||
|
||||
#include "features_common.h"
|
||||
|
||||
#include "evaluate.h"
|
||||
|
||||
//Definition of input features HalfKPK of NNUE evaluation function
|
||||
namespace Eval::NNUE::Features {
|
||||
|
||||
// Feature HalfKPK: Combination of the position of own king
|
||||
// and the position of pieces other than kings
|
||||
template <Side AssociatedKing>
|
||||
class HalfKA {
|
||||
|
||||
public:
|
||||
// Feature name
|
||||
static constexpr const char* kName = (AssociatedKing == Side::kFriend) ?
|
||||
"HalfKA(Friend)" : "HalfKA(Enemy)";
|
||||
|
||||
// Hash value embedded in the evaluation file
|
||||
static constexpr std::uint32_t kHashValue =
|
||||
0x5F134CB9u ^ (AssociatedKing == Side::kFriend);
|
||||
|
||||
// Number of feature dimensions
|
||||
static constexpr IndexType kDimensions =
|
||||
static_cast<IndexType>(SQUARE_NB) * static_cast<IndexType>(PS_END2);
|
||||
|
||||
// Maximum number of simultaneously active features
|
||||
static constexpr IndexType kMaxActiveDimensions = 32;
|
||||
|
||||
// Trigger for full calculation instead of difference calculation
|
||||
static constexpr TriggerEvent kRefreshTrigger =
|
||||
(AssociatedKing == Side::kFriend) ?
|
||||
TriggerEvent::kFriendKingMoved : TriggerEvent::kEnemyKingMoved;
|
||||
|
||||
// Get a list of indices for active features
|
||||
static void append_active_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* active);
|
||||
|
||||
// Get a list of indices for recently changed features
|
||||
static void append_changed_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* removed,
|
||||
IndexList* added);
|
||||
|
||||
private:
|
||||
// Index of a feature for a given king position and another piece on some square
|
||||
static IndexType make_index(Color perspective, Square s, Piece pc, Square sq_k);
|
||||
};
|
||||
|
||||
} // namespace Eval::NNUE::Features
|
||||
|
||||
#endif // #ifndef NNUE_FEATURES_HALF_KA_H_INCLUDED
|
||||
86
src/nnue/features/half_relative_ka.cpp
Normal file
86
src/nnue/features/half_relative_ka.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
#include "half_relative_ka.h"
|
||||
#include "index_list.h"
|
||||
|
||||
//Definition of input features HalfRelativeKA of NNUE evaluation function
|
||||
namespace Eval::NNUE::Features {
|
||||
|
||||
// Orient a square according to perspective (flip rank for black)
|
||||
inline Square orient(Color perspective, Square s) {
|
||||
return Square(int(s) ^ (bool(perspective) * SQ_A8));
|
||||
}
|
||||
|
||||
// Find the index of the feature quantity from the ball position and PieceSquare
|
||||
template <Side AssociatedKing>
|
||||
inline IndexType HalfRelativeKA<AssociatedKing>::make_index(
|
||||
Color perspective,
|
||||
Square s,
|
||||
Piece pc,
|
||||
Square sq_k) {
|
||||
|
||||
const IndexType p = IndexType(orient(perspective, s) + kpp_board_index[pc][perspective]);
|
||||
return make_index(sq_k, p);
|
||||
}
|
||||
|
||||
// Find the index of the feature quantity from the ball position and PieceSquare
|
||||
template <Side AssociatedKing>
|
||||
inline IndexType HalfRelativeKA<AssociatedKing>::make_index(
|
||||
Square sq_k,
|
||||
IndexType p) {
|
||||
|
||||
constexpr IndexType W = kBoardWidth;
|
||||
constexpr IndexType H = kBoardHeight;
|
||||
const IndexType piece_index = (p - PS_W_PAWN) / SQUARE_NB;
|
||||
const Square sq_p = static_cast<Square>((p - PS_W_PAWN) % SQUARE_NB);
|
||||
const IndexType relative_file = file_of(sq_p) - file_of(sq_k) + (W / 2);
|
||||
const IndexType relative_rank = rank_of(sq_p) - rank_of(sq_k) + (H / 2);
|
||||
return H * W * piece_index + H * relative_file + relative_rank;
|
||||
}
|
||||
|
||||
// Get a list of indices with a value of 1 among the features
|
||||
template <Side AssociatedKing>
|
||||
void HalfRelativeKA<AssociatedKing>::append_active_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* active) {
|
||||
|
||||
Square ksq = orient(
|
||||
perspective,
|
||||
pos.square<KING>(
|
||||
AssociatedKing == Side::kFriend ? perspective : ~perspective));
|
||||
|
||||
Bitboard bb = pos.pieces();
|
||||
while (bb) {
|
||||
Square s = pop_lsb(&bb);
|
||||
active->push_back(make_index(perspective, s, pos.piece_on(s), ksq));
|
||||
}
|
||||
}
|
||||
|
||||
// Get a list of indices whose values have changed from the previous one in the feature quantity
|
||||
template <Side AssociatedKing>
|
||||
void HalfRelativeKA<AssociatedKing>::append_changed_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* removed,
|
||||
IndexList* added) {
|
||||
|
||||
Square ksq = orient(
|
||||
perspective,
|
||||
pos.square<KING>(
|
||||
AssociatedKing == Side::kFriend ? perspective : ~perspective));
|
||||
|
||||
const auto& dp = pos.state()->dirtyPiece;
|
||||
for (int i = 0; i < dp.dirty_num; ++i) {
|
||||
Piece pc = dp.piece[i];
|
||||
|
||||
if (dp.from[i] != SQ_NONE)
|
||||
removed->push_back(make_index(perspective, dp.from[i], pc, ksq));
|
||||
|
||||
if (dp.to[i] != SQ_NONE)
|
||||
added->push_back(make_index(perspective, dp.to[i], pc, ksq));
|
||||
}
|
||||
}
|
||||
|
||||
template class HalfRelativeKA<Side::kFriend>;
|
||||
template class HalfRelativeKA<Side::kEnemy>;
|
||||
|
||||
} // namespace Eval::NNUE::Features
|
||||
68
src/nnue/features/half_relative_ka.h
Normal file
68
src/nnue/features/half_relative_ka.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef _NNUE_FEATURES_HALF_RELATIVE_KA_H_
|
||||
#define _NNUE_FEATURES_HALF_RELATIVE_KA_H_
|
||||
|
||||
#include "features_common.h"
|
||||
|
||||
#include "evaluate.h"
|
||||
|
||||
// Definition of input features HalfRelativeKA of NNUE evaluation function
|
||||
// K - King
|
||||
// A - Any piece
|
||||
// KA - product of K and A
|
||||
namespace Eval::NNUE::Features {
|
||||
|
||||
// Feature HalfRelativeKA: Relative position of each piece other than the ball based on own ball or enemy ball
|
||||
template <Side AssociatedKing>
|
||||
class HalfRelativeKA {
|
||||
public:
|
||||
// feature quantity name
|
||||
static constexpr const char* kName = (AssociatedKing == Side::kFriend) ?
|
||||
"HalfRelativeKA(Friend)" : "HalfRelativeKA(Enemy)";
|
||||
|
||||
// Hash value embedded in the evaluation function file
|
||||
static constexpr std::uint32_t kHashValue =
|
||||
0xA123051Fu ^ (AssociatedKing == Side::kFriend);
|
||||
|
||||
static constexpr IndexType kNumPieceKinds = 6 * 2;
|
||||
|
||||
// width of the virtual board with the ball in the center
|
||||
static constexpr IndexType kBoardWidth = FILE_NB * 2 - 1;
|
||||
|
||||
// height of a virtual board with balls in the center
|
||||
static constexpr IndexType kBoardHeight = RANK_NB * 2 - 1;
|
||||
|
||||
// number of feature dimensions
|
||||
static constexpr IndexType kDimensions =
|
||||
kNumPieceKinds * kBoardHeight * kBoardWidth;
|
||||
|
||||
// The maximum value of the number of indexes whose value is 1 at the same time among the feature values
|
||||
static constexpr IndexType kMaxActiveDimensions = 32;
|
||||
|
||||
// Timing of full calculation instead of difference calculation
|
||||
static constexpr TriggerEvent kRefreshTrigger =
|
||||
(AssociatedKing == Side::kFriend) ?
|
||||
TriggerEvent::kFriendKingMoved : TriggerEvent::kEnemyKingMoved;
|
||||
|
||||
// Get a list of indices with a value of 1 among the features
|
||||
static void append_active_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* active);
|
||||
|
||||
// Get a list of indices whose values have changed from the previous one in the feature quantity
|
||||
static void append_changed_indices(
|
||||
const Position& pos,
|
||||
Color perspective,
|
||||
IndexList* removed,
|
||||
IndexList* added);
|
||||
|
||||
// Find the index of the feature quantity from the ball position and PieceSquare
|
||||
static IndexType make_index(Square s, IndexType p);
|
||||
|
||||
// Find the index of the feature quantity from the ball position and PieceSquare
|
||||
static IndexType make_index(Color perspective, Square s, Piece pc, Square sq_k);
|
||||
};
|
||||
|
||||
} // namespace Eval::NNUE::Features
|
||||
|
||||
#endif // #ifndef _NNUE_FEATURES_HALF_RELATIVE_KA_H_
|
||||
Reference in New Issue
Block a user