MutliPV behavior?

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Joerg Oster
Posts: 937
Joined: Fri Mar 10, 2006 4:29 pm
Location: Germany

Re: MutliPV behavior?

Post by Joerg Oster »

Ovyron wrote:
syzygy wrote:I'm not entirely sure why you are referring to MultiPV here. In MultiPV you do end up with final scores of the best N moves. (I may not have read what you wrote carefully enough though.)
It's because MultiPV is meant to be used for analysis.

In analysis, the user would have some tree stored somewhere with backsolved scores of positions.

The old behavior allowed the user to insert into their tree the scores of the most interesting moves, even if they exceeded the MultiPV limit. They were given to the user "for free." Now if the user wants to know actual scores of those moves he'd need to make them on the board or rely on go searchmoves to exclude the moves already analyzed from the search.

Here's an example of the old behavior. Let's say that the user analyzes with MultiPV=4 and to depth 28.

At depth 27 (I'm using letters for the moves):

A. 0.29
B. 0.25
C. 0.19
D. 0.10

Now, it starts depth 28.

A has a score of 0.28.
B falls down to a score of 0.07
C falls down to a score of 0.06
D falls down to a score of 0.00

Now, and only now, the engine examines other moves.

E has a score of 0.11
F has a score of 0.09
G has a score of 0.08

The Shredder Classic GUI (up to version 3) has a feature "Continuous Display", that allows the user to see what happened in all the iterations of MultiPV.

The user can add this to the tree:

A. 0.28
E. 0.11
F. 0.09
G. 0.08
B. 0.07
C. 0.06
D. 0.00

That's 7 moves for the price of 4.

With the current behavior:

At depth 27:

A. 0.29
B. 0.25
C. 0.19
D. 0.10

Now, it starts depth 28.

A has a score of 0.28.
B fails low, Stockfish returns E with a score of 0.11
C fails low, Stockfish returns F with a score of 0.09
D fails low, Stockfish returns G with a score of 0.08

The user is left scratching his head, not knowing what happened to B, C, or D (making Stockfish show fail lows doesn't help because those scores aren't safe to add to the tree.) To get those scores, the user would need MultiPV=7, but switching to it now is more costly than old behavior, and the user doesn't know when this is going to happen, so it can't use 7 from the start.

The user can only add this to the tree:

A. 0.28
E. 0.11
F. 0.09
G. 0.08

Now, suppose the user interacts with the positions until A, E, F and G are refuted to a score of <0.08.

In the old bevahior, the user can jump already to B, which is now the best move. With the current behavior, the user has to take means to get a 5th alternative.

What code would need to be changed so that the engine behaves like in Marco Belli's post in Fail Lows?
elcabesa wrote:Stocksfish search the first best result and you'll see the counter going from 1 to 30,
then it search the second best move and you'll see the counter going from 2 to 30,
then it search the third best move and you'll see the counter going from 3 to 30,

and so on ....
Stockfish already is doing it exactly the way Marco Belli described.
See MultiPV=5 output of iteration 20 for the start position.
  • info depth 19 seldepth 28 multipv 1 score cp 53 nodes 7852604 nps 1328922 hashfull 101 tbhits 0 time 5909 pv e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 g8f6 f1d3 b8c6 e1g1 f8e7 b1c3 e8g8 c1f4 c6b4 a2a3 b4d3 d1d3 e7d6 f4d6
    info depth 19 seldepth 24 multipv 2 score cp 39 nodes 7852604 nps 1328922 hashfull 101 tbhits 0 time 5909 pv e2e3 e7e6 d2d4 f8e7 c2c4 g8f6 g1f3 e8g8 f1d3 d7d5 e1g1 c7c5 d4c5 e7c5 a2a3 d5c4 d3c4 b8c6 c4d3 e6e5 b1c3
    info depth 19 seldepth 30 multipv 3 score cp 37 nodes 7852604 nps 1328922 hashfull 101 tbhits 0 time 5909 pv d2d4 g8f6 c1f4 e7e6 g1f3 d7d5 e2e3 c7c5 f1e2 c5d4 e3d4 f8d6 f4d6 d8d6 e1g1 e8g8 c2c3 c8d7 b1d2 b8c6 f1e1
    info depth 19 seldepth 25 multipv 4 score cp 37 nodes 7852604 nps 1328922 hashfull 101 tbhits 0 time 5909 pv g1f3 d7d5 d2d4 e7e6 e2e3 g8f6 c2c4 f8e7 b1c3 e8g8 f1e2 c7c5 d4c5 b8c6 c4d5 f6d5 c1d2 d5c3 d2c3
    info depth 19 seldepth 26 multipv 5 score cp 15 nodes 7852604 nps 1328922 hashfull 101 tbhits 0 time 5909 pv b1c3 d7d5 d2d4 g8f6 c1f4 e7e6 e2e3 f8b4 g1e2 e8g8 a2a3 b4d6 f4d6 d8d6 e2f4 c8d7 f1e2 d6b6 a1b1 c7c5
    info depth 20 currmove e2e4 currmovenumber 1
    info depth 20 currmove b1c3 currmovenumber 2
    info depth 20 currmove e2e3 currmovenumber 3
    info depth 20 currmove c2c3 currmovenumber 4
    info depth 20 currmove d2d4 currmovenumber 5
    info depth 20 currmove c2c4 currmovenumber 6
    info depth 20 currmove a2a3 currmovenumber 7
    info depth 20 currmove b2b4 currmovenumber 8
    info depth 20 currmove d2d3 currmovenumber 9
    info depth 20 currmove h2h3 currmovenumber 10
    info depth 20 currmove g1f3 currmovenumber 11
    info depth 20 currmove f2f3 currmovenumber 12
    info depth 20 currmove h2h4 currmovenumber 13
    info depth 20 currmove g2g4 currmovenumber 14
    info depth 20 currmove f2f4 currmovenumber 15
    info depth 20 currmove b2b3 currmovenumber 16
    info depth 20 currmove b1a3 currmovenumber 17
    info depth 20 currmove g2g3 currmovenumber 18
    info depth 20 currmove a2a4 currmovenumber 19
    info depth 20 currmove g1h3 currmovenumber 20
    info depth 20 currmove e2e4 currmovenumber 1
    info depth 20 currmove b1c3 currmovenumber 2
    info depth 20 currmove e2e3 currmovenumber 3
    info depth 20 currmove c2c3 currmovenumber 4
    info depth 20 currmove d2d3 currmovenumber 5
    info depth 20 currmove g1f3 currmovenumber 6
    info depth 20 currmove d2d4 currmovenumber 7
    info depth 20 currmove a2a3 currmovenumber 8
    info depth 20 currmove f2f3 currmovenumber 9
    info depth 20 currmove f2f4 currmovenumber 10
    info depth 20 currmove h2h3 currmovenumber 11
    info depth 20 currmove g2g3 currmovenumber 12
    info depth 20 currmove h2h4 currmovenumber 13
    info depth 20 currmove b2b4 currmovenumber 14
    info depth 20 currmove b2b3 currmovenumber 15
    info depth 20 currmove g1h3 currmovenumber 16
    info depth 20 currmove a2a4 currmovenumber 17
    info depth 20 currmove c2c4 currmovenumber 18
    info depth 20 currmove g2g4 currmovenumber 19
    info depth 20 currmove b1a3 currmovenumber 20
    info depth 20 seldepth 29 multipv 1 score cp 45 nodes 8867315 nps 1323677 hashfull 120 tbhits 0 time 6699 pv e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 g8f6 f1d3 f8d6 e1g1 e8g8 b1c3 b8c6 c1g5 c6b4 c3b5 h7h6 g5f6 d8f6 b5d6 f6d6 f3e5 d6b6
    info depth 19 seldepth 24 multipv 2 score cp 39 nodes 8867315 nps 1323677 hashfull 120 tbhits 0 time 6699 pv e2e3 e7e6 d2d4 f8e7 c2c4 g8f6 g1f3 e8g8 f1d3 d7d5 e1g1 c7c5 d4c5 e7c5 a2a3 d5c4 d3c4 b8c6 c4d3 e6e5 b1c3
    info depth 19 seldepth 30 multipv 3 score cp 37 nodes 8867315 nps 1323677 hashfull 120 tbhits 0 time 6699 pv d2d4 g8f6 c1f4 e7e6 g1f3 d7d5 e2e3 c7c5 f1e2 c5d4 e3d4 f8d6 f4d6 d8d6 e1g1 e8g8 c2c3 c8d7 b1d2 b8c6 f1e1
    info depth 19 seldepth 25 multipv 4 score cp 37 nodes 8867315 nps 1323677 hashfull 120 tbhits 0 time 6699 pv g1f3 d7d5 d2d4 e7e6 e2e3 g8f6 c2c4 f8e7 b1c3 e8g8 f1e2 c7c5 d4c5 b8c6 c4d5 f6d5 c1d2 d5c3 d2c3
    info depth 19 seldepth 26 multipv 5 score cp 15 nodes 8867315 nps 1323677 hashfull 120 tbhits 0 time 6699 pv b1c3 d7d5 d2d4 g8f6 c1f4 e7e6 e2e3 f8b4 g1e2 e8g8 a2a3 b4d6 f4d6 d8d6 e2f4 c8d7 f1e2 d6b6 a1b1 c7c5
    info depth 20 currmove e2e3 currmovenumber 2
    info depth 20 currmove b1c3 currmovenumber 3
    info depth 20 currmove d2d4 currmovenumber 4
    info depth 20 currmove g1f3 currmovenumber 5
    info depth 20 currmove c2c4 currmovenumber 6
    info depth 20 currmove c2c3 currmovenumber 7
    info depth 20 currmove b2b4 currmovenumber 8
    info depth 20 currmove a2a3 currmovenumber 9
    info depth 20 currmove h2h3 currmovenumber 10
    info depth 20 currmove b2b3 currmovenumber 11
    info depth 20 currmove f2f3 currmovenumber 12
    info depth 20 currmove d2d3 currmovenumber 13
    info depth 20 currmove g2g3 currmovenumber 14
    info depth 20 currmove f2f4 currmovenumber 15
    info depth 20 currmove g1h3 currmovenumber 16
    info depth 20 currmove b1a3 currmovenumber 17
    info depth 20 currmove h2h4 currmovenumber 18
    info depth 20 currmove a2a4 currmovenumber 19
    info depth 20 currmove g2g4 currmovenumber 20
    info depth 20 seldepth 29 multipv 1 score cp 45 nodes 10227970 nps 1318377 hashfull 142 tbhits 0 time 7758 pv e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 g8f6 f1d3 f8d6 e1g1 e8g8 b1c3 b8c6 c1g5 c6b4 c3b5 h7h6 g5f6 d8f6 b5d6 f6d6 f3e5 d6b6
    info depth 20 seldepth 25 multipv 2 score cp 34 nodes 10227970 nps 1318377 hashfull 142 tbhits 0 time 7758 pv e2e3 e7e6 d2d4 f8e7 c2c4 g8f6 g1f3 d7d5 b1c3 e8g8 f1e2 c7c5 c4d5 c5d4 e3d4 f6d5 e1g1 b8c6 e2d3 d5b4 d3b1
    info depth 19 seldepth 30 multipv 3 score cp 37 nodes 10227970 nps 1318377 hashfull 142 tbhits 0 time 7758 pv d2d4 g8f6 c1f4 e7e6 g1f3 d7d5 e2e3 c7c5 f1e2 c5d4 e3d4 f8d6 f4d6 d8d6 e1g1 e8g8 c2c3 c8d7 b1d2 b8c6 f1e1
    info depth 19 seldepth 25 multipv 4 score cp 37 nodes 10227970 nps 1318377 hashfull 142 tbhits 0 time 7758 pv g1f3 d7d5 d2d4 e7e6 e2e3 g8f6 c2c4 f8e7 b1c3 e8g8 f1e2 c7c5 d4c5 b8c6 c4d5 f6d5 c1d2 d5c3 d2c3
    info depth 19 seldepth 26 multipv 5 score cp 15 nodes 10227970 nps 1318377 hashfull 142 tbhits 0 time 7758 pv b1c3 d7d5 d2d4 g8f6 c1f4 e7e6 e2e3 f8b4 g1e2 e8g8 a2a3 b4d6 f4d6 d8d6 e2f4 c8d7 f1e2 d6b6 a1b1 c7c5
    info depth 20 currmove d2d4 currmovenumber 3
    info depth 20 currmove d2d4 currmovenumber 3
    info depth 20 currmove g1f3 currmovenumber 4
    info depth 20 currmove c2c4 currmovenumber 5
    info depth 20 currmove b1c3 currmovenumber 6
    info depth 20 currmove h2h3 currmovenumber 7
    info depth 20 currmove a2a3 currmovenumber 8
    info depth 20 currmove c2c3 currmovenumber 9
    info depth 20 currmove b2b3 currmovenumber 10
    info depth 20 currmove d2d3 currmovenumber 11
    info depth 20 currmove b1a3 currmovenumber 12
    info depth 20 currmove b2b4 currmovenumber 13
    info depth 20 currmove f2f3 currmovenumber 14
    info depth 20 currmove g2g3 currmovenumber 15
    info depth 20 currmove a2a4 currmovenumber 16
    info depth 20 currmove f2f4 currmovenumber 17
    info depth 20 currmove g2g4 currmovenumber 18
    info depth 20 currmove h2h4 currmovenumber 19
    info depth 20 currmove g1h3 currmovenumber 20
    info depth 20 seldepth 29 multipv 1 score cp 45 nodes 11349334 nps 1317239 hashfull 155 tbhits 0 time 8616 pv e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 g8f6 f1d3 f8d6 e1g1 e8g8 b1c3 b8c6 c1g5 c6b4 c3b5 h7h6 g5f6 d8f6 b5d6 f6d6 f3e5 d6b6
    info depth 20 seldepth 25 multipv 2 score cp 34 nodes 11349334 nps 1317239 hashfull 155 tbhits 0 time 8616 pv e2e3 e7e6 d2d4 f8e7 c2c4 g8f6 g1f3 d7d5 b1c3 e8g8 f1e2 c7c5 c4d5 c5d4 e3d4 f6d5 e1g1 b8c6 e2d3 d5b4 d3b1
    info depth 20 seldepth 28 multipv 3 score cp 32 nodes 11349334 nps 1317239 hashfull 155 tbhits 0 time 8616 pv d2d4 d7d5 e2e3 g8f6 g1f3 e7e6 f1e2 c7c5 e1g1 b8c6 c2c4 f8e7 d4c5 e8g8 b1c3 e7c5 c4d5 e6d5 a2a3 c5b6 c3a4 b6a5
    info depth 19 seldepth 25 multipv 4 score cp 37 nodes 11349334 nps 1317239 hashfull 155 tbhits 0 time 8616 pv g1f3 d7d5 d2d4 e7e6 e2e3 g8f6 c2c4 f8e7 b1c3 e8g8 f1e2 c7c5 d4c5 b8c6 c4d5 f6d5 c1d2 d5c3 d2c3
    info depth 19 seldepth 26 multipv 5 score cp 15 nodes 11349334 nps 1317239 hashfull 155 tbhits 0 time 8616 pv b1c3 d7d5 d2d4 g8f6 c1f4 e7e6 e2e3 f8b4 g1e2 e8g8 a2a3 b4d6 f4d6 d8d6 e2f4 c8d7 f1e2 d6b6 a1b1 c7c5
    info depth 20 currmove g1f3 currmovenumber 4
    info depth 20 currmove b1c3 currmovenumber 5
    info depth 20 currmove c2c3 currmovenumber 6
    info depth 20 currmove d2d3 currmovenumber 7
    info depth 20 currmove c2c4 currmovenumber 8
    info depth 20 currmove a2a3 currmovenumber 9
    info depth 20 currmove b2b3 currmovenumber 10
    info depth 20 currmove h2h3 currmovenumber 11
    info depth 20 currmove b2b4 currmovenumber 12
    info depth 20 currmove b1a3 currmovenumber 13
    info depth 20 currmove f2f4 currmovenumber 14
    info depth 20 currmove f2f3 currmovenumber 15
    info depth 20 currmove g2g3 currmovenumber 16
    info depth 20 currmove a2a4 currmovenumber 17
    info depth 20 currmove g2g4 currmovenumber 18
    info depth 20 currmove h2h4 currmovenumber 19
    info depth 20 currmove g1h3 currmovenumber 20
    info depth 20 currmove g1f3 currmovenumber 4
    info depth 20 currmove b1c3 currmovenumber 5
    info depth 20 currmove c2c4 currmovenumber 6
    info depth 20 currmove c2c3 currmovenumber 7
    info depth 20 currmove f2f3 currmovenumber 8
    info depth 20 currmove f2f4 currmovenumber 9
    info depth 20 currmove d2d3 currmovenumber 10
    info depth 20 currmove a2a3 currmovenumber 11
    info depth 20 currmove h2h3 currmovenumber 12
    info depth 20 currmove b2b3 currmovenumber 13
    info depth 20 currmove g2g4 currmovenumber 14
    info depth 20 currmove b2b4 currmovenumber 15
    info depth 20 currmove a2a4 currmovenumber 16
    info depth 20 currmove h2h4 currmovenumber 17
    info depth 20 currmove g2g3 currmovenumber 18
    info depth 20 currmove b1a3 currmovenumber 19
    info depth 20 currmove g1h3 currmovenumber 20
    info depth 20 seldepth 29 multipv 1 score cp 45 nodes 12212620 nps 1316015 hashfull 167 tbhits 0 time 9280 pv e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 g8f6 f1d3 f8d6 e1g1 e8g8 b1c3 b8c6 c1g5 c6b4 c3b5 h7h6 g5f6 d8f6 b5d6 f6d6 f3e5 d6b6
    info depth 20 seldepth 28 multipv 2 score cp 35 nodes 12212620 nps 1316015 hashfull 167 tbhits 0 time 9280 pv g1f3 d7d5 e2e3 c7c5 d2d4 g8f6 c2c4 c5d4 c4d5 d4e3 c1e3 f6d5 b1c3 d5e3 d1d8 e8d8 f2e3 b8c6 a1d1 d8c7 f1c4 e7e6 e1g1 f8b4 c3b5 c7b6
    info depth 20 seldepth 25 multipv 3 score cp 34 nodes 12212620 nps 1316015 hashfull 167 tbhits 0 time 9280 pv e2e3 e7e6 d2d4 f8e7 c2c4 g8f6 g1f3 d7d5 b1c3 e8g8 f1e2 c7c5 c4d5 c5d4 e3d4 f6d5 e1g1 b8c6 e2d3 d5b4 d3b1
    info depth 20 seldepth 28 multipv 4 score cp 32 nodes 12212620 nps 1316015 hashfull 167 tbhits 0 time 9280 pv d2d4 d7d5 e2e3 g8f6 g1f3 e7e6 f1e2 c7c5 e1g1 b8c6 c2c4 f8e7 d4c5 e8g8 b1c3 e7c5 c4d5 e6d5 a2a3 c5b6 c3a4 b6a5
    info depth 19 seldepth 26 multipv 5 score cp 15 nodes 12212620 nps 1316015 hashfull 167 tbhits 0 time 9280 pv b1c3 d7d5 d2d4 g8f6 c1f4 e7e6 e2e3 f8b4 g1e2 e8g8 a2a3 b4d6 f4d6 d8d6 e2f4 c8d7 f1e2 d6b6 a1b1 c7c5
    info depth 20 currmove b1c3 currmovenumber 5
    info depth 20 currmove a2a3 currmovenumber 6
    info depth 20 currmove c2c3 currmovenumber 7
    info depth 20 currmove d2d3 currmovenumber 8
    info depth 20 currmove c2c4 currmovenumber 9
    info depth 20 currmove f2f3 currmovenumber 10
    info depth 20 currmove b2b4 currmovenumber 11
    info depth 20 currmove g2g3 currmovenumber 12
    info depth 20 currmove h2h3 currmovenumber 13
    info depth 20 currmove b2b3 currmovenumber 14
    info depth 20 currmove f2f4 currmovenumber 15
    info depth 20 currmove b1a3 currmovenumber 16
    info depth 20 currmove g2g4 currmovenumber 17
    info depth 20 currmove h2h4 currmovenumber 18
    info depth 20 currmove a2a4 currmovenumber 19
    info depth 20 currmove g1h3 currmovenumber 20
    info depth 20 seldepth 29 multipv 1 score cp 45 nodes 12488997 nps 1316016 hashfull 172 tbhits 0 time 9490 pv e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 g8f6 f1d3 f8d6 e1g1 e8g8 b1c3 b8c6 c1g5 c6b4 c3b5 h7h6 g5f6 d8f6 b5d6 f6d6 f3e5 d6b6
    info depth 20 seldepth 28 multipv 2 score cp 35 nodes 12488997 nps 1316016 hashfull 172 tbhits 0 time 9490 pv g1f3 d7d5 e2e3 c7c5 d2d4 g8f6 c2c4 c5d4 c4d5 d4e3 c1e3 f6d5 b1c3 d5e3 d1d8 e8d8 f2e3 b8c6 a1d1 d8c7 f1c4 e7e6 e1g1 f8b4 c3b5 c7b6
    info depth 20 seldepth 25 multipv 3 score cp 34 nodes 12488997 nps 1316016 hashfull 172 tbhits 0 time 9490 pv e2e3 e7e6 d2d4 f8e7 c2c4 g8f6 g1f3 d7d5 b1c3 e8g8 f1e2 c7c5 c4d5 c5d4 e3d4 f6d5 e1g1 b8c6 e2d3 d5b4 d3b1
    info depth 20 seldepth 28 multipv 4 score cp 32 nodes 12488997 nps 1316016 hashfull 172 tbhits 0 time 9490 pv d2d4 d7d5 e2e3 g8f6 g1f3 e7e6 f1e2 c7c5 e1g1 b8c6 c2c4 f8e7 d4c5 e8g8 b1c3 e7c5 c4d5 e6d5 a2a3 c5b6 c3a4 b6a5
    info depth 20 seldepth 22 multipv 5 score cp 16 nodes 12488997 nps 1316016 hashfull 172 tbhits 0 time 9490 pv b1c3 d7d5 d2d4 g8f6 c1f4 e7e6 e2e3 f8b4 g1e2 e8g8 a2a3 b4d6 f4d6 d8d6 e2f4 c7c5 d4c5 d6c5 f4d3 c5e7
Jörg Oster
elcabesa
Posts: 855
Joined: Sun May 23, 2010 1:32 pm

Re: MutliPV behavior?

Post by elcabesa »

Joerg Oster wrote:
What code would need to be changed so that the engine behaves like in Marco Belli's post in Fail Lows?
Stockfish already is doing it exactly the way Marco Belli described.
See MultiPV=5 output of iteration 20 for the start position.
thank you :)

if you look at the graphical interface you will not see all the things we have explained here because the interface update every x millisecond to not slow down too much the system. but you'll see the MULTI PV you have requested
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: MutliPV behavior?

Post by syzygy »

elcabesa wrote:
Joerg Oster wrote:
What code would need to be changed so that the engine behaves like in Marco Belli's post in Fail Lows?
Stockfish already is doing it exactly the way Marco Belli described.
See MultiPV=5 output of iteration 20 for the start position.
thank you :)

if you look at the graphical interface you will not see all the things we have explained here because the interface update every x millisecond to not slow down too much the system. but you'll see the MULTI PV you have requested
But there is not really a dispute about what SF does.

The perceived "problem" is this: if Nf3 is in the top N moves at iteration 20, but not anymore at iteration 21, SF does not show a score and PV for Nf3 at iteration 21 (so the user does not get to know why it suddenly fails, something that its PV could probably tell).

The observation is correct, since that is how SF works by design. I don't think it is actually a problem, but it is clear that there are different opinions on this point.
User avatar
Ovyron
Posts: 4556
Joined: Tue Jul 03, 2007 4:30 am

Re: MutliPV behavior?

Post by Ovyron »

syzygy wrote:But it's actually 7 moves for the price of 7 in terms of search work.
Only in this instance, for this specific position, in all the other positions the user analyses (say, the ones analyzed to refute A, E, F and G), it was faster MultiPV 4. In other positions it was only one that failed low, so it was 5 moves for the price of 5, and so on. The engine sets 4 as the minimum number of moves to show scores for, but if they fail low and are replaced by others, the engine would give scores to the other moves "for free" (what I mean by this below.)

Basically, the old behavior allowed the engine to show the score of more moves if the position is complex enough that the main moves from the previous iteration failed low. My example is a extreme case, usually it's just one of the move failing low to never be seen again, so the old behavior would have shows the score of 5 moves.

I didn't mean the user gets the three extra moves's scores for free, I know the search takes longer to figure out those scores, I meant the user gets them for free because they don't need to do anything to know those scores, unlike the case in "current behavior" where the user would need to use "go searchmoves" to ask the engine for the score of the fifth best move.

Now, it has dawned on me to use "always score main move" (sit on fail lows, and resolve them to a score, before checking alternative moves) only in the last iteration the user is interested in, in this case Depth 28.

So in my dream world, Stockfish (and the other engines that now behave like this) would have an "always score main move" tick box, and a depth box where the user would specify, at what point in the search the engine uses old behavior, so that the engine shows the scores of all the interesting moves, those that were best on previous iteration.

In the example, if the user used "Depth 28" for this box, the engine would finish up to depth 27 normally (would do it faster than in old behavior), at depth 28 (and beyond) the engine would be forced to give a score to all the moves of the previous iteration, and then the user gets to know what happened to those moves and was able to add them to their tree.
(Of course the 7th move in your list may not be the 7th best move... it might be the 30th best move. Why is it still interesting? Maybe in rare cases it is, but in general?)
In general the new ("new" as in, it replaced the old one, it's not new as it has been used for several years) behavior would just be like the old behavior but faster, as the top moves from previous iteration would be the same as in the last iteration.

But it causes slowdown to the user then they are not, as the user has to figure out the scores of those moves manually.

The Zappa Mexico II engine went over this, and would even show moves that would temporarily fail high to appear in MultiPV, though it had a check box to hide them. It was the best thing out there to look for interesting moves in a position, so that, often these moves that temporarily failed high but Zappa rejected later (so, with "Hide Fail Highs" on, the user wouldn't have ever known about them) turned out to be the best.

Unfortunately, Zappa is so weak by today's standards that those kind of moves are already found by top engines without interaction, so it is useless now, but moves hard to find that the engine is missing (say, the best move doesn't appear with MuliPV=4) are still common place, and getting a score for them if the engine had them on previous iteration saves time to the user.

The reason I'm not commenting on SinglePV is that SinglePV behavior is fine.

For a given position, that the user that has a tree of variations may do the following:

Extend the moves of the main variation (the one backsolved with the best score, so that this move is the best)
Look for alternative moves in the main variation (the user already has those if the positions were already examined with MultiPV)
Extend the moves of side variations (to check if they can beat the score of the main one, and become the new main variation)
Look for alternative moves in the side variation

Note this is recursive, each node has its own main variation and sidelines.

Extending sidelines is best done in SinglePV, since it's unlikely sidelines become mainlines, and you want to get deeper on them as fast as possible to examine others that might become new mainlines, so MultiPV is too costly on them, and using "go searchmoves" to look for alternatives on them is fine (you'd only do it when the main lines of the side lines fall down.) You don't care about what happened to moves of previous iterations because these lines are likely to not be important.

But whenever there's a side line you're overlooking that would become main line if you extended it, you want it to appear in your radar ASAP, this new behavior of MultiPV difficultes this because it limits the numer of side lines the user is able to add to the tree "for free" (without having to look for alternative moves in the variations, because they're already there for the complex positions where the engine discards and replaces the main moves of previous iterations, perhaps mistakenly.)
User avatar
Ovyron
Posts: 4556
Joined: Tue Jul 03, 2007 4:30 am

Re: MutliPV behavior?

Post by Ovyron »

Joerg Oster wrote:Stockfish already is doing it exactly the way Marco Belli described.
See MultiPV=5 output of iteration 20 for the start position.
Your example shows that all 5 moves remained the same. I've clearly been talking about situations where one of the moves fails low and it's remplazed by another.

The old behavior would show a score for this move, and wouldn't move to look at alternative moves until it had a score.

The new behavior just discards the move.

In my previous post, I admit this is optimal for most of the search, but in the last iteration that the user reads to insert move into their tree, this could waste time if the discarded move is needed later (for positions where the user needs an alternative move beyond the MultiPV lines that they used, because after refuting them, their score is now below the last best that they had.)
Joerg Oster
Posts: 937
Joined: Fri Mar 10, 2006 4:29 pm
Location: Germany

Re: MutliPV behavior?

Post by Joerg Oster »

Ovyron wrote:
Joerg Oster wrote:Stockfish already is doing it exactly the way Marco Belli described.
See MultiPV=5 output of iteration 20 for the start position.
Your example shows that all 5 moves remained the same. I've clearly been talking about situations where one of the moves fails low and it's remplazed by another.

The old behavior would show a score for this move, and wouldn't move to look at alternative moves until it had a score.

The new behavior just discards the move.

In my previous post, I admit this is optimal for most of the search, but in the last iteration that the user reads to insert move into their tree, this could waste time if the discarded move is needed later (for positions where the user needs an alternative move beyond the MultiPV lines that they used, because after refuting them, their score is now below the last best that they had.)
So you want to see the info of the move that fails-low until it gets replaced by another move?
Then you must follow my advice given earlier in this thread.

Stockfish suppresses the output of this info since this commit: https://github.com/official-stockfish/S ... e331d52de3
Jörg Oster
User avatar
Ovyron
Posts: 4556
Joined: Tue Jul 03, 2007 4:30 am

Re: MutliPV behavior?

Post by Ovyron »

Joerg Oster wrote:So you want to see the info of the move that fails-low until it gets replaced by another move?
No, I want Stockfish to stick with the move that fail-lows until its score is resolved, without jumping to check alternative moves that would replace it.

This is how old Multi-PV used to work, and still works in many engines that implement it.
elcabesa
Posts: 855
Joined: Sun May 23, 2010 1:32 pm

Re: MutliPV behavior?

Post by elcabesa »

this is not what Stockfish and some other engine do. sorry.

you ask for the best 5 moves and as soon as it understand that a move is not good it move to other moves, because it's the fastest way to give you the best 5 moves.

so sorry, it doesn't do that, you have to try the move if you want to understand why it's not one of the 5 best move.
Joerg Oster
Posts: 937
Joined: Fri Mar 10, 2006 4:29 pm
Location: Germany

Re: MutliPV behavior?

Post by Joerg Oster »

Ovyron wrote:
Joerg Oster wrote:So you want to see the info of the move that fails-low until it gets replaced by another move?
No, I want Stockfish to stick with the move that fail-lows until its score is resolved, without jumping to check alternative moves that would replace it.

This is how old Multi-PV used to work, and still works in many engines that implement it.
Stockfish does resolve the fail-low before it checks for alternative moves.
The problem seems to be that Stockfish, and most likely many other engines as well,
only prints new info line(s) after a new sorting of the k-best moves.

And as a consequence, you don't get to see the final score and pv of the now inferior line.
Jörg Oster
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: MutliPV behavior?

Post by syzygy »

Joerg Oster wrote:
Ovyron wrote:
Joerg Oster wrote:So you want to see the info of the move that fails-low until it gets replaced by another move?
No, I want Stockfish to stick with the move that fail-lows until its score is resolved, without jumping to check alternative moves that would replace it.

This is how old Multi-PV used to work, and still works in many engines that implement it.
Stockfish does resolve the fail-low before it checks for alternative moves.
A fail low happens when search<Pv> returns a value at or below alpha at the root of the search. Stockfish then lowers alpha (widens the aspiration window) and searches all moves again, etc. If another move is above alpha before the current best move is above alpha, the PV of the current best move will not be resolved and so cannot be shown.