Formalizing the Universal Chess Interface

Discussion of chess software programming and technical issues.

Moderator: Ras

Fulvio
Posts: 396
Joined: Fri Aug 12, 2016 8:43 pm

Re: Formalizing the Universal Chess Interface

Post by Fulvio »

syzygy wrote: Tue Jan 03, 2023 3:11 am It seems to me that the requirement that "go infinite" must wait for "stop" before ending the search only complicates the implementation of the engine with zero benefit for the engine author.
I don't understand why this is so complicate.
If the engine finish early, it just have to do a blocking readline until it receives "stop":

Code: Select all

if infinite or ponder:
    repeat:
        line = readline
        if line == "stop": break
        if line == "ponderhit" AND NOT infinite: break;
        if line == "isready": send "readyok"
        
send "bestmove"
syzygy wrote: Tue Jan 03, 2023 3:11 am I agree that ignoring unknown/unexpected tokens in the "go" command (and in the other direction in the "info" command) makes sense, and most engines probably do this. A non-trivial question would be whether a "fixed" UCI spec should allow the GUI to add non-standard parameters to the "go" command. I would tend to say "no".
Ignoring unknown tokens is a common method to allow future expansions without breaking compatibility (for example https://developers.google.com/protocol- ... 3#unknowns).
However the problem with UCI is that it uses a varible number of tokens (for example "infinite" is single, "depth" is composed of 2 tokens and "wdl" of 4 tokens). It is difficult to be sure that all the tokens of a new field would be correctly ignored.
In my opinion it is better to continue to use options like UCI_showWDL to advertise new capabilities.
User avatar
Ras
Posts: 2696
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: Formalizing the Universal Chess Interface

Post by Ras »

syzygy wrote: Tue Jan 03, 2023 3:11 amStockfish had some race conditions here which were finally solved by adding an ugly busy wait.
I use an event driven blocking wait in search with go infinite that also wakes up once per second to print the status. That way, I avoid busy waiting and burning CPU cycles for nothing.
Of course it is now too late to change this part of the protocol, since GUIs probably depend on this behaviour in analysis mode.
That's entirely possible.
A non-trivial question would be whether a "fixed" UCI spec should allow the GUI to add non-standard parameters to the "go" command. I would tend to say "no".
Same for new stuff in the info part. Existing tournament software relies on the score for adjudication, and that would break with score wdl value or even worse, several values. That would require a wdl-engine to also transmit a cp score, at which point it can just stick with that anyway.

IMO, the stability of the ecosystem is not considered as much as it should (read: number 1 priority) because that's a core feature of UCI - not making things nice on the line where nobody really cares that much. The only thing that can be fixed is clearing up some parts, but only in line with the existing common understanding. Otherwise, the cost of breaking the ecosystem is too high for little to no added value.
Fulvio wrote: Tue Jan 03, 2023 9:21 amI don't understand why this is so complicate.
Because you're only looking at go infinite. The other go parameters will not work like that because you cannot output the final search result in the same place where you also do a blocking wait on stdin. So your approach would work for go infinite only and require handing over the search result from the search to the input thread, but only for go infinite. Most authors want a uniform control flow because that means bugs are less probable.
Rasmus Althoff
https://www.ct800.net
User avatar
hgm
Posts: 28353
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Formalizing the Universal Chess Interface

Post by hgm »

Of course using a separate input thread is just asking for trouble. For one it completely defeats the purpose of 'isready' during search, namely to probe whether the engine is still alive. The input thread automatically and stupidly answers this always with 'readyok', even if the search is completely dead.

A much better design would have the main search thread periodically poll for timeout or pending input. And then deal with the input if there is any (i.e. reply to 'isready', set its own abortFlag on 'stop', calculate its stopping time after 'ponderhit', adjust the debugFlag on 'debug', and ignore everything else).
User avatar
Ras
Posts: 2696
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: Formalizing the Universal Chess Interface

Post by Ras »

hgm wrote: Tue Jan 03, 2023 8:58 pmA much better design would have the main search thread periodically poll for timeout or pending input.
Isn't that how that super ugly peeknamedpipe-hack came around? And also, the polling idea doesn't mean that the engine isn't hanging. It only means that it's not hanging in an area that doesn't include the polling.
Rasmus Althoff
https://www.ct800.net
syzygy
Posts: 5695
Joined: Tue Feb 28, 2012 11:56 pm

Re: Formalizing the Universal Chess Interface

Post by syzygy »

Fulvio wrote: Tue Jan 03, 2023 9:21 am
syzygy wrote: Tue Jan 03, 2023 3:11 am It seems to me that the requirement that "go infinite" must wait for "stop" before ending the search only complicates the implementation of the engine with zero benefit for the engine author.
I don't understand why this is so complicate.
If the engine finish early, it just have to do a blocking readline until it receives "stop":
But there will usually be an I/O thread doing the reading. So you need interthread synchronisation to get it right. This is possible but my point is that it needlessly complicates the life of the engine programmer, which is against the UCI philosophy.

(Maybe there is a good reason for requiring that after "go infinite" the engine sends the bestmove only after receiving "stop", but I don't see it. It seems to me the GUI could simply save the received "bestmove" line until it needs it, or discard it if it has no use for it. If this complicates the life of the GUI programmer, then that is the point of UCI.)
syzygy wrote: Tue Jan 03, 2023 3:11 am I agree that ignoring unknown/unexpected tokens in the "go" command (and in the other direction in the "info" command) makes sense, and most engines probably do this. A non-trivial question would be whether a "fixed" UCI spec should allow the GUI to add non-standard parameters to the "go" command. I would tend to say "no".
Ignoring unknown tokens is a common method to allow future expansions without breaking compatibility (for example https://developers.google.com/protocol- ... 3#unknowns).
If UCI is meant to allow future expansions, it should fully specify the mechanism for doing this. The UCI spec does not do that. Half-baked solutions are not solutions and should not have a place in the specification.

This does not mean that one could not later define an UCIv2 that is mostly compatible with UCI and which will only be used between engines and GUIs which agree on it. (E.g. the engine could list a "UCI_v2" option, and the GUI could enable UCIv2 by triggering UCI_v2.)
However the problem with UCI is that it uses a varible number of tokens (for example "infinite" is single, "depth" is composed of 2 tokens and "wdl" of 4 tokens). It is difficult to be sure that all the tokens of a new field would be correctly ignored.
In my opinion it is better to continue to use options like UCI_showWDL to advertise new capabilities.
Indeed.

However, unknown tokens sent by the engine to the GUI in an "info" line seems less problematic than unknown tokens in the "go" command. The "info" line does not affect chess play, the "go" command does. It looks bad if an UCI-compliant engine loses on time because the GUI uses a non-standard token to set the time limit (e.g. when the player has selected a particular GUI menu option).

To parse "info" with unknown tokens, the GUI can discard tokens, including numbers and other symbols, until it recognises a token such as "depth". This only goes wrong if an unknown token is followed by the "depth" token or some other known token as a parameter to that unknown token, and that should be something that is relatively easy to avoid.
syzygy
Posts: 5695
Joined: Tue Feb 28, 2012 11:56 pm

Re: Formalizing the Universal Chess Interface

Post by syzygy »

Ras wrote: Tue Jan 03, 2023 5:54 pmSame for new stuff in the info part. Existing tournament software relies on the score for adjudication, and that would break with score wdl value or even worse, several values. That would require a wdl-engine to also transmit a cp score, at which point it can just stick with that anyway.
This is a good refutation of what I just wrote in response to Fulvio. Indeed the "info" lines can affect chess play if the GUI adjudicates based on the reported scores.
IMO, the stability of the ecosystem is not considered as much as it should (read: number 1 priority) because that's a core feature of UCI - not making things nice on the line where nobody really cares that much. The only thing that can be fixed is clearing up some parts, but only in line with the existing common understanding. Otherwise, the cost of breaking the ecosystem is too high for little to no added value.
We agree.
expositor
Posts: 60
Joined: Sat Dec 11, 2021 5:03 am
Full name: expositor

Re: Formalizing the Universal Chess Interface

Post by expositor »

Old clients with new engines will break the score display and / or adjudication.
It's already the case that engines need to choose to send `score cp` in order for e.g. autoresignation to work with a particular GUI; nothing requires engines to send this field. Specifying a format in which WDL information can be given (if an engine wants to give WDL information) would be unrelated.

In general, the draft leaves the interpretation of search info to be implementation-defined.* Given that this is merely a protocol, the semantics of each message are left for clients and engines to decide. (However, recommendations for interpretation are given as comments.)

*Almost necessarily, in most cases. For example, no two engines' centipawn units are identically scaled, and for example, it would be difficult to define depth or seldepth in a way that is comparable across all search algorithms and implementations (indeed, some engines may not even have searches). And the internal representations of engines are something I think a protocol specification oughtn't concern itself with (even if the choices made in a protocol's design are entirely made with the ease of engine implementation in mind).
Duh?
I meant the question of whether to name this UCI version 2 or something, as opposed to some unrelated, brand-new name.

> Truthfully, I'm not sure what to do about the naming.
> On one hand, it seems right to give it a separate name so that we can talk about HMK vs "NCI". On other hand, this is pretty obviously just a flavor of UCI, not a brand-new protocol.
> [... E]veryone considers [these] to be UCI engines. They are in fact "NCI" engines! This suggests that, in actual usage, whatever the term UCI refers to very much includes "NCI". And in light of that observation, a name like UCI version 2 seems perfectly reasonable.
This does not mean that one could not later define an UCIv2 that is mostly compatible with UCI and which will only be used between engines and GUIs which agree on it. (E.g. the engine could list a "UCI_v2" option, and the GUI could enable UCIv2 by triggering UCI_v2.)
This is more or less what I'm proposing (hence the `protocol` remark that the draft introduces).
User avatar
hgm
Posts: 28353
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Formalizing the Universal Chess Interface

Post by hgm »

Ras wrote: Tue Jan 03, 2023 9:59 pm
hgm wrote: Tue Jan 03, 2023 8:58 pmA much better design would have the main search thread periodically poll for timeout or pending input.
Isn't that how that super ugly peeknamedpipe-hack came around? And also, the polling idea doesn't mean that the engine isn't hanging. It only means that it's not hanging in an area that doesn't include the polling.
And how much good is that going to do you? You would still have to wait out the entire game for a bestmove which would never come. The chances that an input thread ever crashes are virtually non-existent, so by implementing 'isready' this way you have made its use during search completely pointless.

A proper implementation of 'isready' should check whether the search is still running. E.g. by having the search store the time it last checked the clock, and comparing whether that is not too long before the moment the 'isready' was received.

And what is so hacky about 'PeekNamedPipe'? It is just a system call for testing in a simple way whether there is input waiting that you can read without blocking. Of course you can use an event-driven design, which uses a 'select' to wait for both timer and input events, whichever comes first, instead of polling to get immediate notification. But that is way more complex, and in practice you can poll frequently enough without significantly slowing down the engine so that the poll delay is insignificant.
User avatar
hgm
Posts: 28353
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Formalizing the Universal Chess Interface

Post by hgm »

expositor wrote: Wed Jan 04, 2023 1:59 amAnd in light of that observation, a name like UCI version 2 seems perfectly reasonable.
As long as you make it clear that it is version 2 of the protocol, and not version 2 of the specification. Perhaps you could start the document with a sentence like:

"Those who do not mind that their engine might not work on every UCI GUI can built it to the following specifications."
expositor
Posts: 60
Joined: Sat Dec 11, 2021 5:03 am
Full name: expositor

Re: Formalizing the Universal Chess Interface

Post by expositor »

As long as you make it clear that it is version 2 of the protocol, and not version 2 of the specification. Perhaps you could start the document with a sentence like: "Those who do not mind that their engine might not work on every UCI GUI can built it to the following specifications."
Ah, that's a nice distinction! I'll add something to that effect.