LeelaChessZero / lc0

The rewritten engine, originally for tensorflow. Now all other backends have been ported here.
GNU General Public License v3.0
2.44k stars 529 forks source link

LC0 hangs when probing Syzygy.cc 6 man tablebases on certain positions #1389

Open dje-dev opened 4 years ago

dje-dev commented 4 years ago

Performing analysis from certain positions causes LC0 (e.g. version 0.25) to hang infinitely when Syzygy tablebases are in use.

Example:

hangs, stuck infinitely in a tight loop in syzygy.cc:
while (i < be->num) { i = fill_squares(pos, ei->pieces, flip, flip ? 0x38 : 0, p, i); }

rooklift commented 4 years ago

I was able to reproduce this in 0.26 with just 5-man TB.

rooklift commented 4 years ago

Some log from Nibbler. After sending stop we get some output, one of the considered moves is the illegal Rxf2.

--> isready
--> go infinite
< readyok
--> stop
< info depth 1 seldepth 1 time 39588 nodes 1 score cp -321 wdl 1 168 831 nps 0 tbhits 0 multipv 1 pv c2f2
INVALID / ILLEGAL MOVE RECEIVED: c2f2
< info depth 1 seldepth 1 time 39588 nodes 1 score cp -321 wdl 1 168 831 nps 0 tbhits 0 multipv 2 pv g1h2
< info depth 1 seldepth 1 time 39588 nodes 1 score cp -321 wdl 1 168 831 nps 0 tbhits 0 multipv 3 pv g1f2
< info depth 1 seldepth 1 time 39588 nodes 1 score cp -321 wdl 1 168 831 nps 0 tbhits 0 multipv 4 pv g1h1
< info depth 1 seldepth 1 time 39588 nodes 1 score cp -321 wdl 1 168 831 nps 0 tbhits 0 multipv 5 pv g1f1
< info string g1f1  (152 ) N:       0 (+ 0) (P:  9.91%) (WL:  -.-----) (D: -.---) (M:  -.-) (Q: -0.83009) (U: 0.21283) (S: -0.61726) (V:  -.----) 
< info string g1h1  (153 ) N:       0 (+ 0) (P: 11.07%) (WL:  -.-----) (D: -.---) (M:  -.-) (Q: -0.83009) (U: 0.23779) (S: -0.59230) (V:  -.----) 
< info string g1f2  (155 ) N:       0 (+ 0) (P: 14.17%) (WL:  -.-----) (D: -.---) (M:  -.-) (Q: -0.83009) (U: 0.30430) (S: -0.52579) (V:  -.----) 
< info string g1h2  (157 ) N:       0 (+ 0) (P: 15.05%) (WL:  -.-----) (D: -.---) (M:  -.-) (Q: -0.83009) (U: 0.32304) (S: -0.50705) (V:  -.----) 
< info string c2f2  (254 ) N:       0 (+ 1) (P: 49.80%) (WL:  0.00000) (D: 0.000) (M:  0.0) (Q:  0.00000) (U: 0.53469) (S: -0.29540) (V:  -.----) 
INVALID / ILLEGAL MOVE RECEIVED: c2f2
< info string node  (   5) N:       1 (+ 1) (P:  0.00%) (WL: -0.83009) (D: 0.167) (M: 12.9) (Q: -0.83009) (V: -0.8301) 
< bestmove c2f2
rooklift commented 4 years ago

Ah. This position cannot actually arise (no legal move sequence ever has 2 pawns giving check at once). That's bound to be part of the problem. Presumably tablebases only deal with legal positions.

dje-dev commented 4 years ago

Ah, good observation, indeed probably related and makes this less dangerous. I checked a online lookup side and it reported "invalid FEN." However this seems hard to do in all generality, since I doubt determining reachability is a easily computable.

syzygy1 commented 4 years ago

The tablebases don't really know about reachable and non-reachable positions. The problem in this case seems to be that the move generator thinks that Rxf2 is legal. (The TB probing code must check all (legal) capturing moves when probing a position due to how the compression scheme works.)

It is a bit surprising that LC0’s move generator (or the move generator of its TB code?) would think Rxf2 is legal.

syzygy1 commented 4 years ago

The surprise has an explanation: https://github.com/LeelaChessZero/lc0/blob/2f1465484ff8687376e62d82131ac5555cb25565/src/chess/board.cc#L865

LC0 correctly assumes that at most one pawn can give check in a legal/reachable position. Since LC0 thinks there is no double check here and Rxf2 captures a checker, it concludes that Rxf2 is legal.

Still, it is not so nice that LC0 freezes in a position that most GUIs won't detect as illegal...

Naphthalin commented 2 years ago

I tested the position without TBs, and while Nibbler doesn't show Rxf2 as a legal move, lc0 still does.

borg323 commented 2 years ago

Since this is an assumption in the move generator, we should add an extra check in ChessBoard:SetFromFen() that only one pawn gives check.