UCI ponder confusion

Discussion of chess software programming and technical issues.

Moderator: Ras

TonyJH
Posts: 183
Joined: Tue Jun 20, 2006 4:41 am
Location: USA

Re: UCI ponder confusion

Post by TonyJH »

Sven Schüle wrote:
TonyJH wrote:Ok, I could be wrong here. But in this case, I think the bestmove should always be interpreted correctly by polyglot as being from the obsolete search, because the new search request hasn't even been sent to the engine yet. Polyglot is trying to send it, but the engine isn't accepting it yet, and the engine shouldn't be buffering input.
Am I missing something or does this sound right?
Will Polyglot block until the engine accepts input when it is "trying to send something"? If it will then you are right. Otherwise I think that Polyglot will already change its internal state such that it does not expect the next "bestmove" to belong to the obsolete ponder search.

If both sides of the pipe (I think we have a pipe here in this case, don't we?) are doing unbuffered output resp. input then maybe Polyglot will indeed block.

Sven
I think polyglot will block until the engine accepts the input, but I'm not 100% sure.
User avatar
Roman Hartmann
Posts: 295
Joined: Wed Mar 08, 2006 8:29 pm

Re: UCI ponder confusion

Post by Roman Hartmann »

Hi,
I'm one of those who needs to set the option Syncstop to true to make my engine work under Polyglot.
When I implemented the UCI-protocol I even had a quick look at that part of the code of fruit to see how this should be done properly. But I missed the point that there is (almost) no delay between stopping a ponder-search and starting a new one.

Anyway, it seems that polyglot is the only GUI that follows the UCI-standard so close because other GUIs are a bit more tolerant and will put a delay between sending the "stop" command and the new position.

That's what happening if your engine gets stuck after a pondermiss:

Polyglot sends "stop" to the engine and (almost) without a delay it will also send "position fen ...." and then start a new search but that might be missed by the engine as it's either still unwinding the old search or in the process of sending a "bestmove ..". In any case the new position is missed.

I'm aware of this fault in my engine for quite some time but still did not fix it yet. It would mean to mess around with some part of the code I dislike most.

best regards
Roman
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: UCI ponder confusion

Post by Sven »

Roman Hartmann wrote:Hi,
I'm one of those who needs to set the option Syncstop to true to make my engine work under Polyglot.
When I implemented the UCI-protocol I even had a quick look at that part of the code of fruit to see how this should be done properly. But I missed the point that there is (almost) no delay between stopping a ponder-search and starting a new one.

Anyway, it seems that polyglot is the only GUI that follows the UCI-standard so close because other GUIs are a bit more tolerant and will put a delay between sending the "stop" command and the new position.

That's what happening if your engine gets stuck after a pondermiss:

Polyglot sends "stop" to the engine and (almost) without a delay it will also send "position fen ...." and then start a new search but that might be missed by the engine as it's either still unwinding the old search or in the process of sending a "bestmove ..". In any case the new position is missed.

I'm aware of this fault in my engine for quite some time but still did not fix it yet. It would mean to mess around with some part of the code I dislike most.

best regards
Roman
Hi Roman,
thanks for your clarification which might help a lot. Still there is one point I do not understand. When you say: "it seems that polyglot is the only GUI that follows the UCI-standard so close", why does this match the UCI specification that says that the engine shall always send "bestmove" when it receives "stop", considering also that Polyglot by default does not wait for that "bestmove" before launching the new search.

I'm sorry, perhaps I am too silly for that stuff ... but either the UCI side (here Polyglot) waits for "bestmove" in order to discard it, or it does not wait for it and starts the new search, then it can't discard the "bestmove" that comes in later. Without SyncStop=true, Polyglot does not wait, so it would not work with any engine, which is contradictory.

Where is my fault, what am I missing? I guess Polyglot has more intelligence in the default case than I currently see in the source ...

Sven
User avatar
Roman Hartmann
Posts: 295
Joined: Wed Mar 08, 2006 8:29 pm

Re: UCI ponder confusion

Post by Roman Hartmann »

Hi Sven,
the critical part in the UCI-protocol is imo the following part:
* the engine must always be able to process input from stdin, even while thinking.
The protocol does also say that the engine has always to send a "bestmove ..." even when in ponder mode but it doesn't say that the GUI has to wait for the engine to send the bestmove [after a pondermiss] before sending a new position. So in any case it's not polyglots fault although when I implemented the UCI-protocol I too assumed that the GUI would wait for the "bestmove ..." from the engine before sending the new position after a pondermiss but according to the standard it doesn't have to.

I shouldn't have written that polylgot does follow the standard more closely than other GUIs but rather that polyglot doesn't violate the standard although it looks like.

I too wouldn't mind, of course, if every GUI would just wait for the "bestmove ..." [after a pondermiss] from the engine before sending a new position and starting a new search.

best regards
Roman
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: UCI ponder confusion

Post by Sven »

TonyJH wrote:
Sven Schüle wrote:
TonyJH wrote:Ok, I could be wrong here. But in this case, I think the bestmove should always be interpreted correctly by polyglot as being from the obsolete search, because the new search request hasn't even been sent to the engine yet. Polyglot is trying to send it, but the engine isn't accepting it yet, and the engine shouldn't be buffering input.
Am I missing something or does this sound right?
Will Polyglot block until the engine accepts input when it is "trying to send something"? If it will then you are right. Otherwise I think that Polyglot will already change its internal state such that it does not expect the next "bestmove" to belong to the obsolete ponder search.

If both sides of the pipe (I think we have a pipe here in this case, don't we?) are doing unbuffered output resp. input then maybe Polyglot will indeed block.

Sven
I think polyglot will block until the engine accepts the input, but I'm not 100% sure.
Things seem to be different in contrast to what my initial thoughts were on your statement about "Polyglot trying to send". According to wikipedia and other sources, and according to what I learned about pipes, a pipe is buffered itself, with a buffer size of 4k or 8k IIRC. And that buffer is independent from the buffered or unbuffered I/O settings of the processes connected with the pipe. I checked it with a small test program, if you like I can post it.

So in our case this would mean that Polyglot does _not_ block when sending even if the engine were not yet ready for reading input. So Polyglot writes "stop", then changes its internal state somehow, then continues immediately with sending the position to search now, all independent from what the engine does - provided the engine is still alive.

That's how I currently think it works. But that does not mean that I fully understand why only few engines require the SyncStop setting.

Sven
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: UCI ponder confusion

Post by Sven »

Now I got it, I think I found the "intelligence" in the Polyglot code, it is related to the pending_nb counter:

Code: Select all

int uci_parse(uci_t * uci, const char string[]) {

    // ...

      } else if (my_string_equal(command,"bestmove")) {

         // search end

         ASSERT(uci->pending_nb>0);

         if (uci->searching && uci->pending_nb == 1) {

            // current search

            uci->searching = false;
            uci->pending_nb--;

            event = parse_bestmove(uci,argument); // updates uci->best_move and uci->ponder_move

         } else {

            // obsolete search

            if (uci->pending_nb > 0) {
               uci->pending_nb--;
               if (uci->pending_nb == 0) event = EVENT_STOP;
            }
         }
This means that, although Polyglot has already launched a new search, it will still be able to recognize that the "bestmove" reply to "stop" belongs to the obsolete search, since after calling stop_search() the pending_nb counter was still >= 1 and was even incremented to >= 2 when launching the new search, so Polyglot knows that it may discard this "bestmove".

That's what I was searching for, now I have understood and keep quiet :-)

So my conclusion is that the problems requiring to use the SyncStop workaround are really on the engine side and not on the Polyglot side. What exactly causes these engine problems and how most of the UCI engines avoid them is another point, here I currently have no idea.

Sven
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: UCI ponder confusion

Post by Sven »

O.k., you're right, the pending_nb counter solves it as you have described.

Sorry, I had missed that part in the uci_parse() function that handles the "bestmove" coming from an obsolete search.

Sven
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: UCI ponder confusion

Post by Sven »

Hi Roman,

yes, Polyglot does not have to wait for "bestmove" after ponder miss, by default it doesn't, and nevertheless - as I now know - it is able to discard the "bestmove" from the obsolete search that comes in later. So everything is o.k., except for a few engines that are confused by the new search that is already launched ...

It took a while for me to get it, though.

Sven
BubbaTough
Posts: 1154
Joined: Fri Jun 23, 2006 5:18 am

Re: UCI ponder confusion

Post by BubbaTough »

O.k., you're right, the pending_nb counter solves it as you have described.
OK Cool, unless I hear otherwise I will take that as the definitive word (assuming polyglot is single threaded). Knowing this will help me fix things on my end assuming I ever get around to it.

-Sam
User avatar
xsadar
Posts: 147
Joined: Wed Jun 06, 2007 10:01 am
Location: United States
Full name: Mike Leany

Re: UCI ponder confusion

Post by xsadar »

BubbaTough wrote:Hey, I have a question for all you gurus.

I am confused about what I am supposed to do on a ponder miss. When I use Arena, it sends a stop, then waits for me to send a move, then sends the new position for me to look at. Fine, easy enough. But when I use polyglot, it sends a stop, then immediately sends the new position...so if I send a move and it arrives after the new position was sent, things get confused because the receiver thinks the move is for the new position instead of being left over from the ponder (and thus should be discarded). The question is, how do I stay compatible with both?

I have been using some SyncStop option to make polyglot act more like Arena, but the instructions for SyncStop basically says only idiots have to use this option, and it may later be discontinued. Fair enough, but it makes me wonder how all you non-idiots address this issue?

-Sam
It sounds like it's not polyglot getting confused about receiving "bestmove" when its already begun a new search, but your engine getting confused about receiving a new search before it's sent bestmove. Of course, I couldn't know for sure without seeing exactly what's happening, but this (quoted previously by Sven) supports the idea (emphasis mine):
When a ponder miss occurs, Polyglot interrupts the engine and
IMMEDIATELY launches a new search. While there should be no problem
with this, some engines seem confused and corrupt their search board.
"SyncStop" forces PolyGlot to wait for the (now useless) ponder search
to finish before launching the new search.
I think a simple solution to that would be, as suggested previously, when you receive "stop", don't read any more input until you've sent "bestmove".