Fix weird indexing bug

[Passed
STC](https://tests.stockfishchess.org/tests/live_elo/69cf6a5d1668971c9da23ae1)
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 51104 W: 13376 L: 13180 D: 24548
Ptnml(0-2): 134, 5555, 13963, 5781, 119

[Passed
LTC](https://tests.stockfishchess.org/tests/live_elo/69d00a7ee2b443cb2670b5c6)
LLR: 2.95 (-2.94,2.94) <-1.75,0.25>
Total: 101256 W: 25867 L: 25732 D: 49657
Ptnml(0-2): 59, 10423, 29520, 10576, 50

When processing a promotion we add/remove nonsensical threats, namely,
piece threats of pawns on the 1st or 8th rank. This is not only
inefficient but also seems to lead to an obscure bug during a
promotion–capture + `double_inc_update` that causes a lingering invalid
feature. Currently – as an artifact of the training process – these
parts of the net are filled with random values in [-1,1], which is why
there is a bench change.

@ces42 did a helpful analysis:

> checking bench with depth 17 actually shows that the bug in has been
there all the time since 8e5392d7 (when threat inputs was merged into
master)
> i.e. double_inc_update for ThreatFeatureSet has always been slightly
bugged

After this patch is applied we'll be able to better compress the net by
filling the invalid features with 0, w/o changing bench. I expect a
15%-ish size savings.

closes https://github.com/official-stockfish/Stockfish/pull/6701

Bench: 2700393
This commit is contained in:
anematode
2026-04-09 21:53:08 +02:00
committed by Disservin
parent ef27b4db7b
commit ead7e650da
+11 -4
View File
@@ -966,13 +966,22 @@ void Position::do_move(Move m,
// Move the piece. The tricky Chess960 castling is handled earlier // Move the piece. The tricky Chess960 castling is handled earlier
if (m.type_of() != CASTLING) if (m.type_of() != CASTLING)
{ {
Piece toPc = pc;
if (m.type_of() == PROMOTION)
toPc = make_piece(us, m.promotion_type());
if (captured && m.type_of() != EN_PASSANT) if (captured && m.type_of() != EN_PASSANT)
{ {
remove_piece(from, &dts); remove_piece(from, &dts);
swap_piece(to, pc, &dts); swap_piece(to, toPc, &dts);
} }
else else if (pc == toPc)
move_piece(from, to, &dts); move_piece(from, to, &dts);
else
{
remove_piece(from, &dts);
put_piece(toPc, to, &dts);
}
} }
// If the moving piece is a pawn do some special extra work // If the moving piece is a pawn do some special extra work
@@ -1011,8 +1020,6 @@ void Position::do_move(Move m,
assert(relative_rank(us, to) == RANK_8); assert(relative_rank(us, to) == RANK_8);
assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN); assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN);
swap_piece(to, promotion, &dts);
dp.add_pc = promotion; dp.add_pc = promotion;
dp.add_sq = to; dp.add_sq = to;
dp.to = SQ_NONE; dp.to = SQ_NONE;