Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the engine doesn't respond with bestmove #3532

Closed
voyag opened this issue Jun 6, 2021 · 35 comments
Closed

the engine doesn't respond with bestmove #3532

voyag opened this issue Jun 6, 2021 · 35 comments

Comments

@voyag
Copy link

voyag commented Jun 6, 2021

With the current development version, from console with the following commands the engine stall and doesn't respond with bestmove
setoption name Hash value 4 setoption name Contempt value 0 ucinewgame position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130 go depth 10

@locutus2
Copy link
Member

locutus2 commented Jun 7, 2021

Have you first insert the uci command?. SF responds then with the know options and uciok.
Second you have to insert the commands always in a separate line:

uci
setoption name Hash value 4
setoption name Contempt value 0
ucinewgame
position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
go depth 10

Then it works. Tested with the current master 'Reduce in LMR reduction on PvNode' (self compiled).
Here my output:

info string NNUE evaluation using nn-7e66505906a6.nnue enabled
info depth 1 seldepth 1 multipv 1 score cp 119 nodes 23 nps 23000 tbhits 0 time 1 pv c3b4
info depth 2 seldepth 2 multipv 1 score cp 84 nodes 121 nps 60500 tbhits 0 time 2 pv c3b3 b7a8
info depth 3 seldepth 3 multipv 1 score cp 116 nodes 225 nps 112500 tbhits 0 time 2 pv g1b6 b7a8 c3b4
info depth 4 seldepth 4 multipv 1 score cp 125 nodes 298 nps 149000 tbhits 0 time 2 pv c3b3 b7a8 g1d4
info depth 5 seldepth 5 multipv 1 score cp 97 nodes 974 nps 487000 tbhits 0 time 2 pv g1b6 b7a8 c3d3 a8b7 b6e3
info depth 6 seldepth 6 multipv 1 score cp 132 nodes 1441 nps 480333 tbhits 0 time 3 pv g1c5 b7a8 c3d4 a8b7
info depth 7 seldepth 7 multipv 1 score cp 144 nodes 1834 nps 611333 tbhits 0 time 3 pv g1c5 b7a8 c3d4 a8b7 d4d5 b7a8
info depth 8 seldepth 10 multipv 1 score cp 425 nodes 3095 nps 773750 tbhits 0 time 4 pv g1b6 b7a8 c3d4 a8b7 d4c5 b7a8
info depth 9 seldepth 10 multipv 1 score cp 289 nodes 32586 nps 1629300 tbhits 0 time 20 pv g1c5 b7a8 c3d3 a8b7 d3e4 b7a8 e4f5 a8b7
info depth 10 seldepth 12 multipv 1 score cp 363 nodes 32739 nps 1636950 tbhits 0 time 20 pv g1c5 b7a8 c3d3 a8b7 d3e4 b7a8 e4f5
bestmove g1c5 ponder b7a8

@voyag
Copy link
Author

voyag commented Jun 7, 2021

Sure the version is changed, try those commands with the version: Makefile: Extend sanitize support

@snicolet
Copy link
Member

snicolet commented Jun 8, 2021

@voyag I can't reproduce the problem on my Mac.

Could you please show us the make command you have used, and then the output of ./stockfish compiler for your version? Thanks!

@voyag
Copy link
Author

voyag commented Jun 8, 2021

@snicolet
Copy link
Member

snicolet commented Jun 8, 2021

OK. Could you try the output of ./stockfish compiler? Just to be sure that stockfish executable launches at all

@voyag
Copy link
Author

voyag commented Jun 8, 2021

Stockfish 050621 by the Stockfish developers (see AUTHORS file)

Compiled by g++ (GNUC) 7.5.0 on Linux
Compilation settings include: 64bit AVX2 SSE41 SSSE3 SSE2 POPCNT
VERSION macro expands to: 7.5.0

@locutus2
Copy link
Member

locutus2 commented Jun 8, 2021

I have compiled the same version by myself and i get a result but it stucks at depth 9 and we never reach depth 10 (at least not in the time i waited).

info string NNUE evaluation using nn-7e66505906a6.nnue enabled
info depth 1 seldepth 1 multipv 1 score cp 119 nodes 23 nps 11500 tbhits 0 time 2 pv c3b4
info depth 2 seldepth 2 multipv 1 score cp 84 nodes 121 nps 60500 tbhits 0 time 2 pv c3b3 b7a8
info depth 3 seldepth 3 multipv 1 score cp 116 nodes 225 nps 112500 tbhits 0 time 2 pv g1b6 b7a8 c3b4
info depth 4 seldepth 4 multipv 1 score cp 125 nodes 298 nps 149000 tbhits 0 time 2 pv c3b3 b7a8 g1d4
info depth 5 seldepth 5 multipv 1 score cp 97 nodes 868 nps 289333 tbhits 0 time 3 pv g1b6 b7a8 c3d3 a8b7 b6e3
info depth 6 seldepth 6 multipv 1 score cp 132 nodes 1485 nps 495000 tbhits 0 time 3 pv g1c5 b7a8 c3d4 a8b7
info depth 7 seldepth 7 multipv 1 score cp 144 nodes 1965 nps 655000 tbhits 0 time 3 pv g1c5 b7a8 c3d4 a8b7 d4d5 b7a8
info depth 8 seldepth 10 multipv 1 score cp 425 nodes 3343 nps 835750 tbhits 0 time 4 pv g1b6 b7a8 c3d4 a8b7 d4c5 b7a8 c5c6
info depth 9 seldepth 10 multipv 1 score cp 330 nodes 57567 nps 1857000 tbhits 0 time 31 pv c3d3 b7a8 g1b6 a8b7 d3e4 b7a8 e4d4 a8b7

Stockfish 080621 by the Stockfish developers (see AUTHORS file)

Compiled by g++ (GNUC) 9.2.1 on Linux
Compilation settings include: 64bit AVX2 SSE41 SSSE3 SSE2 POPCNT
VERSION macro expands to: 9.2.1 20191102

The same holds for the bmi2 compile.

EDIT: the version from abrok have the same behavior

@snicolet
Copy link
Member

snicolet commented Jun 8, 2021

Some remarks:

  • we are very near the 50 moves limit
  • the position is a draw because of the bad bishop (in fact I think it would still be a draw if we removed the black pawn, added as many white pawns as we want on the 'a' column and as many white bishops on black squares as we want on the board)

So this is a difficult position for SF, she is searching and searching and hitting draws by 50 moves rule all over the place. But in fact everything is fine, as the move she will eventually output after the stop keyword by the GUI is a draw anyway.

Depending on the exact version and the exact hash amount the command go infinite will appear to "be stuck" at different depth:

./stockfish
position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
go infinite

@vondele
Copy link
Member

vondele commented Jun 8, 2021

would be interesting to see how long we need to reach depth 10 on that position. Eventually there should be some output. I wonder if we have some extensions that are not limited one way or another.

@locutus2
Copy link
Member

locutus2 commented Jun 8, 2021

I have done more degugging and the search goes for root depth 10 at least to depth 144. ANd the reason is the singular extension. I try here to restrict this: https://tests.stockfishchess.org/tests/view/60bfb0b1457376eb8bcaa88c
With this patch we reach at least depth 34.

@locutus2
Copy link
Member

locutus2 commented Jun 8, 2021

Here constrain the extension=2 case to captures/promotions: https://tests.stockfishchess.org/tests/view/60bfb3b6457376eb8bcaa895.

Here we reach around depth 24.

@snicolet
Copy link
Member

snicolet commented Jun 8, 2021

Do you think it would be possible to compare somehow the current level reached in search (as given by A = ss->ply) and the nominal root depth we asked for (as given in B = rootDepth), to prevent singular extensions when A - B > 30 (say) or maybe A > 2B?

@locutus2
Copy link
Member

locutus2 commented Jun 8, 2021

@snicolet
Yes, but i think comparing ss->ply + depth (estimated length of current variant) to root depth is better. Here my first try: https://tests.stockfishchess.org/tests/view/60bfb906457376eb8bcaa89a

Here we reach around depth 18.

@joergoster
Copy link
Contributor

2 * rootDepth is probably too strict. I'd also recommend to test as some kind of bugfix, no?

@snicolet
Copy link
Member

snicolet commented Jun 8, 2021

In this position every move by Black is probably singular, because Black has only the a8 and b7 squares to hold the draw.

So Black takes the extension at every node in line 1073 of search.cpp (and probably even the double extension, hence the search explosion):

           if (value < singularBeta)
          {
              extension = 1;
              singularQuietLMR = !ttCapture;
              if (!PvNode && value < singularBeta - 93)
                  extension = 2;
          }

I think I will play with the idea to take the extensions with probability 50% (something like that), and see what happens.

          if (value < singularBeta)
          {
              if ((pos.key() & 3) <= 1)
              {
                  extension = 1;
                  singularQuietLMR = !ttCapture;
                  if (!PvNode && value < singularBeta - 93)
                      extension = 2;
              }
          }

@snicolet
Copy link
Member

snicolet commented Jun 8, 2021

What happens is that the bench goes from 5530620 to 3478751, it is funny, at least :-)

https://tests.stockfishchess.org/tests/view/60bfc823457376eb8bcaa8a6

@jhellis3
Copy link
Contributor

jhellis3 commented Jun 8, 2021

In Crystal, I added the condition: && depth < rootDepth - ss->ply. YMMV.

@joergoster
Copy link
Contributor

Another possibility is to keep track of the total extension of a subtree and stop allowing to extend further at some point.
Btw, are we sure this is the only problem here?

@jhellis3
Copy link
Contributor

jhellis3 commented Jun 8, 2021

Most likely, yes. +2 extensions are really dangerous. TBH, I was surprised when this made it in without comment. I had to do something about it in Crystal because the combo of the +2 here and on game cycles was preventing bench from completing.

@vondele
Copy link
Member

vondele commented Jun 9, 2021

since this doesn't appear to be a problem with SF13, do we know which recent commit has triggered this?

I've started two more tests:
remove extension by 2: https://tests.stockfishchess.org/tests/view/60c0599d457376eb8bcaa93b (stopped, see same test here https://tests.stockfishchess.org/tests/view/60bfb6b5457376eb8bcaa898)
limit extension by 2 by 50mc: https://tests.stockfishchess.org/tests/view/60c05a58457376eb8bcaa93d

just disabling extension by 2 seems not possible for now.

@joergoster
Copy link
Contributor

It's also worth noting that even when reaching higher depths SF doesn't give drawish scores.
For example:

info depth 32 seldepth 55 multipv 1 score cp 165 nodes 2060966860 nps 2129018 hashfull 732 tbhits 0 time 968036 pv c3b3 b7a8 b3a2 a8b7 g1f2 b7a8 f2d4 a8b7 a2b1 b7a8 b1c1 a8b7 c1d1 b7a8 d4b6 a8b7 b6e3 b7a8 d1c2 a8b7 e3g1 b7a8 c2b3 a8b7 b3b4 b7a8 g1c5 a8b7 b4a5 b7a8 a5b5 a8b7 b5b4 b7a8 b4c3 a8b7 c5f2 b7a8 c3d2 a8b7 f2d4 b7a8 d4b6 a8b7 d2d3 b7a8 d3e2 a8b7 b6d4 b7a8 d4e3 a8b7

Older versions have no problem. (Stockfish 6)

info depth 34 seldepth 47 multipv 1 score cp 6 nodes 43689402 nps 4018524 tbhits 0 time 10872 pv c3d3 b7a8 g1c5 a8b7 d3e4 b7a8 e4f5 a8b7 f5g5 b7a8 g5h6 a8b7 h6g7 b7a8 c5d4 a8b7 g7g8 b7a8 g8h7 a8b7 d4c5 b7a8 c5e3 a8b7 a7a8r b7a8 h7h6 a8b7 h6g5 b7a8 e3c5 a8b7 c5f2 b7a8 g5f4 a8b7 f2g3 b7a8 f4e3 a8b7 g3e5 b7a8 e3e4 a8b7 e5d4 b7a8 a3a4

@vondele
Copy link
Member

vondele commented Jun 9, 2021

sf 6 switches at 21 from 215 to 6, sf 7 - sf11 have a bit unstable eval, last high eval is 350 at depth 13 for sf11. I would see this as a independent issue, seems like nnue doesn't know this endgame, and we don't switch to classical?

@Sopel97
Copy link
Member

Sopel97 commented Jun 9, 2021

This might not be an issue for play, where the search is cut by maximum allowed time, but is an issue for analysis. Perhaps a fix could be applied only to infinite analysis, where the user relies on periodic updates.

@ddobbelaere
Copy link
Contributor

ddobbelaere commented Jun 9, 2021

Interesting position. As a human you can quickly prove it's a draw with perfect play as follows: without the black pawn on b5 it's a well-known draw (wrong-colored bishop, doesn't matter there are two a-pawns, black plays Ka8, Kb7 alternatingly till hell freezes). The only thing white can try is to force black to play b4, in an attempt to transform the pawn on a3 into a b-pawn, but this is only possible after trapping the black king in the corner with e.g. Kb6 (for white), but then after b4 axb4 is stalemate. Not taking the pawn on b4 of course amounts to nothing for white, black can play b3, b2 etc. next and force a capture or blockade...


4c02998 explains why we don't switch to classical as often as before (before this simplification, we would always have switched to classical, as apart from pawns and kings, there is only a single bishop present, which is the precise corner case checked in the code), but I agree this "switching behavior" in itself is a separate issue.

[speculation]
Even so, probably the issue in the current thread only manifests itself for this specific position from 4c02998 onwards.
[/speculation]

@vondele
Copy link
Member

vondele commented Jun 9, 2021

I'm currently testing at LTC (after passed STC) https://tests.stockfishchess.org/tests/view/60c07eac457376eb8bcaa965 which make sure extensions terminate. It fixes the testcase, even if it is still a bit slower. It does appear to gain a little Elo. While search during game play will terminate, if this continues for a few moves, one will run out of time quickly.

@joergoster
Copy link
Contributor

With classical eval:

ucinewgame
position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
go infinite
info string classical evaluation enabled
info depth 1 seldepth 1 multipv 1 score cp 0 nodes 23 nps 23000 tbhits 0 time 1 pv a3a4
info depth 2 seldepth 2 multipv 1 score cp 0 nodes 90 nps 90000 tbhits 0 time 1 pv a3a4 b5a4
info depth 3 seldepth 3 multipv 1 score cp 0 nodes 163 nps 163000 tbhits 0 time 1 pv a3a4 b5a4 a7a8r b7a8
info depth 4 seldepth 4 multipv 1 score cp 0 nodes 259 nps 259000 tbhits 0 time 1 pv a3a4 b5a4 a7a8r b7a8
info depth 5 seldepth 5 multipv 1 score cp 0 nodes 481 nps 481000 tbhits 0 time 1 pv a3a4 b5a4 a7a8r b7a8 g1a7
info depth 6 seldepth 6 multipv 1 score cp 0 nodes 1146 nps 1146000 tbhits 0 time 1 pv a3a4 b5a4 a7a8r b7a8 g1a7 a8a7
info depth 7 seldepth 7 multipv 1 score cp 0 nodes 2404 nps 1202000 tbhits 0 time 2 pv c3d2 b7a8 g1f2 a8b7 f2g1
info depth 8 seldepth 8 multipv 1 score cp 348 nodes 3995 nps 1331666 tbhits 0 time 3 pv c3b3 b7a8 b3b4 a8b7 b4a5 b7a8
info depth 9 seldepth 10 multipv 1 score cp 0 nodes 14551 nps 1616777 tbhits 0 time 9 pv g1f2 b7a8 c3b3 a8b7 b3c2 b7a8 c2b3
info depth 10 seldepth 12 multipv 1 score cp 265 nodes 16280 nps 1628000 tbhits 0 time 10 pv c3b3 b7a8 b3b4 a8b7 b4a5 b7a8 g1f2 a8b7
info depth 11 seldepth 12 multipv 1 score cp 321 nodes 18487 nps 1680636 tbhits 0 time 11 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8 d3c3 a8b7
info depth 12 seldepth 14 multipv 1 score cp 338 nodes 25623 nps 1708200 tbhits 0 time 15 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8 d3c3 a8b7 c3b4 b7a8 b4a5 a8b7 a7a8r b7a8
info depth 13 seldepth 19 multipv 1 score cp 0 nodes 255775 nps 2204956 tbhits 0 time 116 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8
info depth 14 seldepth 21 multipv 1 score cp 0 nodes 283412 nps 2214156 tbhits 0 time 128 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8
info depth 15 seldepth 22 multipv 1 score cp 0 nodes 323385 nps 2185033 tbhits 0 time 148 pv c3d2 b7a8 d2d3 a8b7
info depth 16 seldepth 22 multipv 1 score cp 0 nodes 393703 nps 2175154 tbhits 0 time 181 pv c3d2 b7a8 d2d3 a8b7
info depth 17 seldepth 22 multipv 1 score cp 0 nodes 440405 nps 2180222 tbhits 0 time 202 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8
info depth 18 seldepth 22 multipv 1 score cp 0 nodes 560009 nps 2187535 tbhits 0 time 256 pv c3d2 b7a8 d2d3 a8b7
info depth 19 seldepth 22 multipv 1 score cp 0 nodes 708696 nps 2207775 tbhits 0 time 321 pv c3d2 b7a8 d2d3 a8b7
info depth 20 seldepth 22 multipv 1 score cp 0 nodes 880566 nps 2212477 tbhits 0 time 398 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8
info depth 21 seldepth 22 multipv 1 score cp 0 nodes 1099129 nps 2229470 tbhits 0 time 493 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8
info depth 22 seldepth 22 multipv 1 score cp 0 nodes 1310578 nps 2232671 tbhits 0 time 587 pv c3d2 b7a8 d2d3 a8b7
info depth 23 seldepth 22 multipv 1 score cp 0 nodes 1562939 nps 2252073 tbhits 0 time 694 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8
info depth 24 seldepth 22 multipv 1 score cp 0 nodes 1878747 nps 2255398 tbhits 0 time 833 pv c3d2 b7a8 d2d3 a8b7
info depth 25 seldepth 22 multipv 1 score cp 0 nodes 2224426 nps 2267508 tbhits 0 time 981 pv c3d2 b7a8 d2d3 a8b7
info depth 26 seldepth 22 multipv 1 score cp 0 nodes 2572300 nps 2268342 hashfull 268 tbhits 0 time 1134 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8
info depth 27 seldepth 22 multipv 1 score cp 0 nodes 3197379 nps 2275714 hashfull 323 tbhits 0 time 1405 pv c3d2 b7a8 d2d3 a8b7 g1f2 b7a8

As you can see classical eval does know it's a draw almost immediately. And because of this, search doesn't go into this pathological behaviour. Again, search and eval are much more connected than one might think. ;-)

I have no doubt, though, that in some way or another we must guard against doing too many extensions at once.

@vondele
Copy link
Member

vondele commented Jun 9, 2021

I've scheduled a test which enables classical eval again for low piece endgames, and this leads to the right eval for this endgame. However, it won't pass fishtest https://tests.stockfishchess.org/tests/view/60c0ea80457376eb8bcaa9bd

@vondele
Copy link
Member

vondele commented Jun 9, 2021

The test here passed STC and LTC, and improves the situation (in particular the testcase above): https://tests.stockfishchess.org/tests/view/60c07eac457376eb8bcaa965

However, it is still not fully fixed, a related testcase takes very long to complete depth 25.

Maybe there are better alternatives?

@joergoster
Copy link
Contributor

@vondele How is my cap_ext patch (see fishtest) doing on that related testcase?

@vondele
Copy link
Member

vondele commented Jun 9, 2021

let me first paste the testcase:

uci
setoption name Hash value 4
setoption name Contempt value 0
ucinewgame
position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 0 130
go depth 25

@vondele
Copy link
Member

vondele commented Jun 9, 2021

@joergoster passes with your branch.

@vondele
Copy link
Member

vondele commented Jun 9, 2021

@joergoster
Copy link
Contributor

Great! Thanks for testing.

@locutus2
Copy link
Member

locutus2 commented Jun 9, 2021

Try to tackle this by excluding endgames from big extension (The problem should be there more lilkely).
https://tests.stockfishchess.org/tests/view/60c13ab1457376eb8bcaaa1b

@vondele
Copy link
Member

vondele commented Jun 11, 2021

The following fix passed testing, and should be a robust way to avoid the explosion. https://tests.stockfishchess.org/tests/view/60c196fb457376eb8bcaaa6b I'll make a PR.

vondele added a commit to vondele/Stockfish that referenced this issue Jun 11, 2021
double extensions can lead to search explosions, for specific positions.
Currently, however, this double extensions is worth about 10Elo and can't be removed.
This patch instead limits the number of double extensions given to a maximum of 3.

This fixes official-stockfish#3532
where the following testcase was shown to be problematic:

```
uci
setoption name Hash value 4
setoption name Contempt value 0
ucinewgame
position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
go depth 20
```

passed STC:
https://tests.stockfishchess.org/tests/view/60c13161457376eb8bcaaa0f
LLR: 2.94 (-2.94,2.94) <-2.50,0.50>
Total: 166440 W: 5559 L: 5594 D: 155287
Ptnml(0-2): 106, 4921, 73197, 4894, 102

passed LTC:
https://tests.stockfishchess.org/tests/view/60c196fb457376eb8bcaaa6b
LLR: 2.95 (-2.94,2.94) <-2.50,0.50>
Total: 73256 W: 6114 L: 6062 D: 61080
Ptnml(0-2): 222, 4912, 26306, 4968, 220

Bench: 5067605
vondele added a commit to vondele/Stockfish that referenced this issue Jun 11, 2021
double extensions can lead to search explosions, for specific positions.
Currently, however, this double extensions is worth about 10Elo and can't be removed.
This patch instead limits the number of double extensions given to a maximum of 3.

This fixes official-stockfish#3532
where the following testcase was shown to be problematic:

```
uci
setoption name Hash value 4
setoption name Contempt value 0
ucinewgame
position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
go depth 20
```

passed STC:
https://tests.stockfishchess.org/tests/view/60c13161457376eb8bcaaa0f
LLR: 2.95 (-2.94,2.94) <-2.50,0.50>
Total: 73256 W: 6114 L: 6062 D: 61080
Ptnml(0-2): 222, 4912, 26306, 4968, 220

passed LTC:
https://tests.stockfishchess.org/tests/view/60c196fb457376eb8bcaaa6b
LLR: 2.94 (-2.94,2.94) <-2.50,0.50>
Total: 166440 W: 5559 L: 5594 D: 155287
Ptnml(0-2): 106, 4921, 73197, 4894, 102

Bench: 5067605
snicolet referenced this issue in TopoIogist/Stockfish Sep 17, 2021
snicolet added a commit to snicolet/Stockfish that referenced this issue Sep 23, 2021
This patch detects some search explosions due to double extensions in
our search algorithm which can happen in some pathological positions,
and takes measure to ensure progress even in these pathological situations.

While a small number of double extensions can be useful during search
(for example to resolve a tactical sequence), a sustained regime of
double extensions leads to search explosion and a non-finishing search.
See the discussion in official-stockfish/Stockfish#3544
and the issue official-stockfish/Stockfish#3532 .

The implemented algorithm is as follows:

a) at each node during search, store the current depth in the stack.
   Double extensions are by definition levels of the stack where the
   depth at ply N is strictly higher than depth at ply N-1.

b) during search, calculate for each thread a running average of the
   number of double extensions in the last 4096 visited nodes.

c) if one thread has more than 2% of double extensions for a sustained
   period of time (6 millions consecutive nodes, or about 4 seconds on
   my iMac), we decide that this thread is in an explosion state and
   we calm down this thread by preventing it to do any double extension
   for the next 6 millions nodes.

-----------

Example where the patch solves a search explosion:

```
./stockfish
ucinewgame
position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
go infinite
```

This algorithm does not affect search in normal, non-pathological positions.
We verified that usual bench is unchanged up to depth 20 at least, for instance,
and that the node numbers are unchanged for a search of the starting position
at depth 32.

-------------

Bench: 5575265
snicolet added a commit to snicolet/Stockfish that referenced this issue Sep 23, 2021
This patch detects some search explosions due to double extensions in
our search algorithm which can happen in some pathological positions,
and takes measure to ensure progress even in these pathological situations.

While a small number of double extensions can be useful during search
(for example to resolve a tactical sequence), a sustained regime of
double extensions leads to search explosion and a non-finishing search.
See the discussion in official-stockfish/Stockfish#3544
and the issue official-stockfish/Stockfish#3532 .

The implemented algorithm is as follows:

a) at each node during search, store the current depth in the stack.
   Double extensions are by definition levels of the stack where the
   depth at ply N is strictly higher than depth at ply N-1.

b) during search, calculate for each thread a running average of the
   number of double extensions in the last 4096 visited nodes.

c) if one thread has more than 2% of double extensions for a sustained
   period of time (6 millions consecutive nodes, or about 4 seconds on
   my iMac), we decide that this thread is in an explosion state and
   we calm down this thread by preventing it to do any double extension
   for the next 6 millions nodes.

-----------

Example where the patch solves a search explosion:

```
./stockfish
ucinewgame
position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
go infinite
```

This algorithm does not affect search in normal, non-pathological positions.
We verified that usual bench is unchanged up to depth 20 at least, for instance,
and that the node numbers are unchanged for a search of the starting position
at depth 32.

-------------

Bench: 5575265
snicolet added a commit to snicolet/Stockfish that referenced this issue Sep 23, 2021
This patch detects some search explosions due to double extensions in
our search algorithm which can happen in some pathological positions,
and takes measure to ensure progress even in these pathological situations.

While a small number of double extensions can be useful during search
(for example to resolve a tactical sequence), a sustained regime of
double extensions leads to search explosion and a non-finishing search.
See the discussion in official-stockfish/Stockfish#3544
and the issue official-stockfish/Stockfish#3532 .

The implemented algorithm is as follows:

a) at each node during search, store the current depth in the stack.
   Double extensions are by definition levels of the stack where the
   depth at ply N is strictly higher than depth at ply N-1.

b) during search, calculate for each thread a running average of the
   number of double extensions in the last 4096 visited nodes.

c) if one thread has more than 2% of double extensions for a sustained
   period of time (6 millions consecutive nodes, or about 4 seconds on
   my iMac), we decide that this thread is in an explosion state and
   we calm down this thread by preventing it to do any double extension
   for the next 6 millions nodes.

-----------

Example where the patch solves a search explosion:

```
./stockfish
ucinewgame
position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
go infinite
```

This algorithm does not affect search in normal, non-pathological positions.
We verified that usual bench is unchanged up to depth 20 at least, for instance,
and that the node numbers are unchanged for a search of the starting position
at depth 32.

-------------

See official-stockfish/Stockfish#3714

Bench: 5575265
snicolet added a commit that referenced this issue Sep 23, 2021
This patch detects some search explosions (due to double extensions in
search.cpp) which can happen in some pathological positions, and takes
measures to ensure progress in search even for these pathological situations.

While a small number of double extensions can be useful during search
(for example to resolve a tactical sequence), a sustained regime of
double extensions leads to search explosion and a non-finishing search.
See the discussion in #3544
and the issue #3532 .

The implemented algorithm is the following:

a) at each node during search, store the current depth in the stack.
   Double extensions are by definition levels of the stack where the
   depth at ply N is strictly higher than depth at ply N-1.

b) during search, calculate for each thread a running average of the
   number of double extensions in the last 4096 visited nodes.

c) if one thread has more than 2% of double extensions for a sustained
   period of time (6 millions consecutive nodes, or about 4 seconds on
   my iMac), we decide that this thread is in an explosion state and
   we calm down this thread by preventing it to do any double extension
   for the next 6 millions nodes.

To calculate the running averages, we also introduced a auxiliary class
generalizing the computations of ttHitAverage variable we already had in
code. The implementation uses an exponential moving average of period 4096
and resolution 1/1024, and all computations are done with integers for
efficiency.

-----------

Example where the patch solves a search explosion:

```
   ./stockfish
   ucinewgame
   position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
   go infinite
```

This algorithm does not affect search in normal, non-pathological positions.
We verified, for instance, that the usual bench is unchanged up to depth 20
at least, and that the node numbers are unchanged for a search of the starting
position at depth 32.

-------------

See #3714

Bench: 5575265
Joachim26 pushed a commit to Joachim26/StockfishNPS that referenced this issue Mar 28, 2023
This patch detects some search explosions (due to double extensions in
search.cpp) which can happen in some pathological positions, and takes
measures to ensure progress in search even for these pathological situations.

While a small number of double extensions can be useful during search
(for example to resolve a tactical sequence), a sustained regime of
double extensions leads to search explosion and a non-finishing search.
See the discussion in official-stockfish#3544
and the issue official-stockfish#3532 .

The implemented algorithm is the following:

a) at each node during search, store the current depth in the stack.
   Double extensions are by definition levels of the stack where the
   depth at ply N is strictly higher than depth at ply N-1.

b) during search, calculate for each thread a running average of the
   number of double extensions in the last 4096 visited nodes.

c) if one thread has more than 2% of double extensions for a sustained
   period of time (6 millions consecutive nodes, or about 4 seconds on
   my iMac), we decide that this thread is in an explosion state and
   we calm down this thread by preventing it to do any double extension
   for the next 6 millions nodes.

To calculate the running averages, we also introduced a auxiliary class
generalizing the computations of ttHitAverage variable we already had in
code. The implementation uses an exponential moving average of period 4096
and resolution 1/1024, and all computations are done with integers for
efficiency.

-----------

Example where the patch solves a search explosion:

```
   ./stockfish
   ucinewgame
   position fen 8/Pk6/8/1p6/8/P1K5/8/6B1 w - - 37 130
   go infinite
```

This algorithm does not affect search in normal, non-pathological positions.
We verified, for instance, that the usual bench is unchanged up to depth 20
at least, and that the node numbers are unchanged for a search of the starting
position at depth 32.

-------------

See official-stockfish#3714

Bench: 5575265
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants