UCI pondering done right

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Ras
Posts: 2487
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: UCI pondering done right

Post by Ras »

Michel wrote: Sat Dec 22, 2018 4:09 pmFunny that you say this. The SF maintainers will argue that a crash is a perfectly valid and even desirable reaction to an illegal command since otherwise writing an UCI parser is too complicated...
I think that no matter how malformed the input is, it must never crash the engine. Refusing to move is OK, and giving some kind of useful error message desirable. It also helps other developers (of GUIs or adaptors) to decide whether there's a bug in their software or in the engine. Validating input is not complicated, IMO that's just a cheap pretext for sloppy programming.
Rasmus Althoff
https://www.ct800.net
User avatar
hgm
Posts: 27787
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: UCI pondering done right

Post by hgm »

And in this case the command of course isn't illegal. It is just a bit under-specified what exactly 'not affecting the search' means. But ambiguous semantics isn't the same as 'anything flies' (out of your nose and such...). E.g. should the obligation to not terminate the search spontaneously that the 'infinite' qualifier imposes be considered an effect on the search, so that you would be released from this obligation ('not affecting the search') if the 'infinite' is not there? I guess that interpretation would remove possible conflicts between qualifiers. E.g. even "go infinite depth 10" would make sense, because it tells you to stop thinking after d=10 is reached, but not print the search result until you receive a 'stop'.

This 'never stop' is actually one of the most annoying things for developers of UCI engines, BTW. It requires explicit code to handle, after a search naturally terminates (e.g. because of mate, EGT probing, a depth or nodes limit was reached during ponder...), where you would need to go into a loop that waits for 'stop''/'ponderhit', but doesn't forget to reply to 'isready' in the mean time. It seems a pointless requirement, as the GUI could have done this (backlogging unexpected 'bestmove' commands, and releasing them instead of sending 'stop') just as easily, simplifying the engines.
Ras
Posts: 2487
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: UCI pondering done right

Post by Ras »

hgm wrote: Sat Dec 22, 2018 4:51 pmBut ambiguous semantics isn't the same as 'anything flies' (out of your nose and such...).
Exactly. Even if the behaviour were completely unspecified, it would be better to choose a reasonable implementation. I guess that after years of C/C++ programming, people find this nonsense normal, but actually, it's already bad in C/C++ because most of that undefined behaviour should have been implementation defined anyway. It's certainly no justification to transfer this way of thinking to application level.
E.g. even "go infinite depth 10" would make sense, because it tells you to stop thinking after d=10 is reached, but not print the search result until you receive a 'stop'.
That's how Shredder implements this case, and I've done it the same way.
This 'never stop' is actually one of the most annoying things for developers of UCI engines, BTW.
It has a good rationale. Many engines, mine included, will return right after finding any mate in search without caring whether it is the shortest. If this mate was found in some selective extension, then chances are that there is a shorter one once the base depth reaches this level. In analysis mode, you want to let the engine run longer to see whether it can find the shorter mate. Or, when there is only one legal move, many engines will just do it and return, which is also not what you want in analysis mode.

I can't confirm that it's one of the most annoying or even complicated things when developing a UCI engine. It's like 6 lines of code at the end of the searcher. OK, actually a bit more because that includes a function call, but only because I print search info once per second along with NPS=0 to show the user than no search is happening anymore (Shredder doesn't do this). I could also get away with just waiting infinitely on the abort event to arrive, that would be two lines of code.

Listening to isready in between is not an issue as this has to be handled in parallel to the search anyway, usually in a separate thread.
Rasmus Althoff
https://www.ct800.net