UCI pondering done right

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

mar
Posts: 2555
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: UCI pondering done right

Post by mar »

mar wrote: Sun Dec 16, 2018 11:27 am A workaround would be to use standard go wtime ... btime... instead of go ponder, then use go infinite when it's done, but this already seems very hacky even to me.
Hmm, in fact, this may work seamlessly actually. (I deleted this post before because I thought it was nonsense but it seems I was wrong)
For pondering, one would simply use go wtime ... btime ... from previous move.
There are two possible scenarios:
1) the engine finishes search before ponderhit/pondermiss; in this case the GUI would simply remember the move (best/ponder) and wait for the opponent. Then if it is a ponderhit, play immediately. If not, do a normal go wtime ... btime ... after opponent moves (pondermiss continuation)
the advantage is that you even save CPU resources this way except that you won't be able to "ponder more"
2) engine still searches when the opponent plays a move:
- if it's a ponder hit, the GUI waits for the search to finish and continues as in the case above (the GUI knows it's a ponderhit not based on PV but on the move the engine is pondering on)
- otherwise it was a ponder miss, the GUI sends a stop, waits for bestmove, discards it and does normal pondermiss search as above

So the only thing that'd be necessary to do is to stop the search when the engine receives a stop command - I think all engines have to handle correctly anyway due to timeout check.

So you were right, it should be possible and actually quite easy to implement. The only drawback is the engine won't spend more time in the case of a "ponderhit" before the opponent makes the move; one could start the infinite search now but I think it may be dangerous so I'd simply prefer to wait for the opponent to move;
or maybe alternatively the GUI might even already start another ponder search on the next ponder move, but it would be trickier
for the GUI, because this second ponder search may still turn out to be a pondermiss on primary ponder search.
In the extreme case the engine might be pondering up to n moves, this seems a bit weird.
But I still think something like this might actually work very well if done right (only problem again would be how to adjust TC).
Martin Sedlak
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: UCI pondering done right

Post by hgm »

mar wrote: Mon Dec 17, 2018 5:09 pmthe advantage is that you even save CPU resources this way
If this is to be considered an advantage, I know a far better and far simpler ponder implementation. And the beautiful thing is that most GUIs already support it! Just never let the GUI send go-ponder or ponderhit. Saves even more CPU resources!

On most GUIs this mode of pondering is available under the name "ponder off".
abulmo2
Posts: 433
Joined: Fri Dec 16, 2016 11:04 am
Location: France
Full name: Richard Delorme

Re: UCI pondering done right

Post by abulmo2 »

lucasart wrote: Sun Dec 16, 2018 1:06 am I find the UCI pondering spec truly horrible. It violate both UCI key principles, to the point that it feels like a piece of Winboard grafted on UCI:
(1) statelessness.
(2) simplicity for engine developers.
I wonder how you can say that. Assertions (1) and (2) are both wrong:
- UCI pondering does not break statelessness.
- UCI pondering is simple to implement: about 10 line of codes in Amoeba.
I give a quick look at Demolito's code. You just need to change the way you handle your time management and to delay the output of the bestmove until ponderhit/stop is received. Adding a few variables to control pondering should not be that difficult.

Richard
Richard Delorme
mar
Posts: 2555
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: UCI pondering done right

Post by mar »

hgm wrote: Mon Dec 17, 2018 8:03 pm
mar wrote: Mon Dec 17, 2018 5:09 pmthe advantage is that you even save CPU resources this way
If this is to be considered an advantage, I know a far better and far simpler ponder implementation. And the beautiful thing is that most GUIs already support it! Just never let the GUI send go-ponder or ponderhit. Saves even more CPU resources!

On most GUIs this mode of pondering is available under the name "ponder off".
:D
Yes, this is one of the advantages of lazy pondering if you can think faster than your opponent!
But you can save even more resources by not playing any games at all - you don't even need a GUI for that.

Of course, there's one protocol that gets pondering right and gives you way more control by letting you to implement all the logic yourself.
You simply receive "hard" from the GUI, perhaps meaning that it won't be that easy to implement. But freedom comes at a price :)

UCI users are forced to ponder on one move, but that's for sissies. You can be much more creative with xboard protocol - why not ponder on all moves at once, multipv all and the opponent will be under time pressure all the time - all that is up to you :D
Martin Sedlak
Fulvio
Posts: 395
Joined: Fri Aug 12, 2016 8:43 pm

Re: UCI pondering done right

Post by Fulvio »

lucasart wrote: Sun Dec 16, 2018 1:06 am I find the UCI pondering spec truly horrible. It violate both UCI key principles, to the point that it feels like a piece of Winboard grafted on UCI:
(1) statelessness.
The UCI protocol is not stateless:
https://en.wikipedia.org/wiki/Stateless_protocol

For example when the engine receives a "position" command it should change its internal state "current position".
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: UCI pondering done right

Post by hgm »

Actually the UCI specs explicitly allow you to do anything you want after go-ponder too; the ponder move is just advise, and following it up is not mandatory. As long as you don't produce thinking output that would confuse the GUI.

But seriously: a ponder implementation that does not use all the time the opponent is thinking (unless there is really nothing to think about) should be considered broken. It cannot be excused by the fact that pondering is a less-efficient use of CPU time; under many conditions you would save the resources just to waste them (e.g. OTB or on-line games).

A major design flaw of UCI is that you have to provide the clock times already with the go-ponder command (when opponent clock time is not known yet) rather than with the ponderhit command. It would indeed have been much better to always use go-infinite, and allow a ponderhit-wtime-btime command to turn that into a normal search. Or to make all TC a separate command, and make any 'go' command imply go-infinite, and follow it up by a stop-wtime-btime command that would request a time-management-mediated termination of the current search rather than an instant one. (Out goes the 'ponderhit' command...)

Of course the fact that there is a 'searchmoves' qualifier rather than a 'banmoves' qualifier to 'go' is also pretty bad: it forces the GUI to generate all legal moves (and thus know the game rules) when the user has only indicated the move he wants to suppress.

I could go on and on...
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: UCI pondering done right

Post by hgm »

Fulvio wrote: Tue Dec 18, 2018 11:57 amThe UCI protocol is not stateless:
https://en.wikipedia.org/wiki/Stateless_protocol

For example when the engine receives a "position" command it should change its internal state "current position".
Indeed, this so-called statelessness is just a much-hyped half-truth. A more accurate description would be 'partially amnesic'.

* The 'go' command destroys the game state and TC info after its execution.
* There is no state w.r.t. what side it is playing, so the engine will never move automatically.
mar
Posts: 2555
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: UCI pondering done right

Post by mar »

hgm wrote: Tue Dec 18, 2018 11:58 am A major design flaw of UCI is that you have to provide the clock times already with the go-ponder command (when opponent clock time is not known yet) rather than with the ponderhit command. It would indeed have been much better to always use go-infinite, and allow a ponderhit-wtime-btime command to turn that into a normal search. Or to make all TC a separate command, and make any 'go' command imply go-infinite, and follow it up by a stop-wtime-btime command that would request a time-management-mediated termination of the current search rather than an instant one. (Out goes the 'ponderhit' command...)
Yes, this is actually a very elegant idea, I like it. But I'm afraid it's too late to fix UCI now.
Martin Sedlak
Ras
Posts: 2487
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: UCI pondering done right

Post by Ras »

The go with the times is exactly right with UCI because you just allocate the normal move time and abort search when either stop arrives, or both ponderhit AND time elapse. Besides, it's actually a big plus with UCI that it doesn't get "fixed" all the time.
Rasmus Althoff
https://www.ct800.net
Michel
Posts: 2272
Joined: Mon Sep 29, 2008 1:50 am

Re: UCI pondering done right

Post by Michel »

Fulvio wrote: Tue Dec 18, 2018 11:57 am
lucasart wrote: Sun Dec 16, 2018 1:06 am I find the UCI pondering spec truly horrible. It violate both UCI key principles, to the point that it feels like a piece of Winboard grafted on UCI:
(1) statelessness.
The UCI protocol is not stateless:
https://en.wikipedia.org/wiki/Stateless_protocol

For example when the engine receives a "position" command it should change its internal state "current position".
It's not strictly stateless but the state is short lived.
Ideas=science. Simplification=engineering.
Without ideas there is nothing to simplify.