UCI protocol experience needed

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

CRoberson
Posts: 2056
Joined: Mon Mar 13, 2006 2:31 am
Location: North Carolina, USA

UCI protocol experience needed

Post by CRoberson »

I implemented the UCI protocol to cohabitat with the Xboard protocol
last night.

It seems to work well except for one thing. None of the commands
are received during the search. The code I have to detect input
works fine when using the Xboard protocol. According to log file
data the code reaches the checkpoint to check for input but input
is never detected when running in UCI mode.

Is there something special about detecting input when using UCI?
All other uci commands seem to work as they are before or after the
search.

I am using Arena and MS Windows XP.
Alessandro Scotti

Re: UCI protocol experience needed

Post by Alessandro Scotti »

Indeed if it works with Winboard it should work with UCI too.
Dann Corbit
Posts: 12541
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: UCI protocol experience needed

Post by Dann Corbit »

CRoberson wrote:I implemented the UCI protocol to cohabitat with the Xboard protocol
last night.

It seems to work well except for one thing. None of the commands
are received during the search. The code I have to detect input
works fine when using the Xboard protocol. According to log file
data the code reaches the checkpoint to check for input but input
is never detected when running in UCI mode.

Is there something special about detecting input when using UCI?
All other uci commands seem to work as they are before or after the
search.

I am using Arena and MS Windows XP.

How are you collecting the UCI input?
IOW, are you using a separate thread or polling or ...?
CRoberson
Posts: 2056
Joined: Mon Mar 13, 2006 2:31 am
Location: North Carolina, USA

Re: UCI protocol experience needed

Post by CRoberson »

I am polling.

Every so many nodes, I check to see if there is input.
In Unix, I use select.
In MS, I use PeekNamedPipe.
Alessandro Scotti

Re: UCI protocol experience needed

Post by Alessandro Scotti »

I think you can enable protocol debugging in Arena, but I've never used it personally.
Like I said before, if it works with Winboard it must work with UCI so probably the problem is not in the mechanism itself but it is used.
I would say post your code but it's past midnight around here and I'll be dreaming about a 2800 Hamsters very soon! :-)
Dann Corbit
Posts: 12541
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: UCI protocol experience needed

Post by Dann Corbit »

CRoberson wrote:I am polling.

Every so many nodes, I check to see if there is input.
In Unix, I use select.
In MS, I use PeekNamedPipe.
Is buffering turned off for UCI in the same way as you have it turned off for Winboard? IOW, the path that initiates Winboard I/O probably has something like:
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
to turn off cache of input and output.

Does the same thing occur in your UCI startup path?
CRoberson
Posts: 2056
Joined: Mon Mar 13, 2006 2:31 am
Location: North Carolina, USA

Re: UCI protocol experience needed

Post by CRoberson »

Interesting idea. At 4am this morning, I decided it didn't matter
that the UCI execution path didn't include
signal(SIGINT,SIG_IGN).

I just fixed that but it didn't change things.

I've never had the setvbuff commands in it. I'll try those.
CRoberson
Posts: 2056
Joined: Mon Mar 13, 2006 2:31 am
Location: North Carolina, USA

Re: UCI protocol experience needed

Post by CRoberson »

No Change. I wonder if the issue is Arena 1.1?

Nah, other UCI engines work.
Dann Corbit
Posts: 12541
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: UCI protocol experience needed

Post by Dann Corbit »

This is rather strange.
Can you trace it and see what happens when an incoming UCI command arrives while it is thinking?
User avatar
Daniel Mehrmann
Posts: 858
Joined: Wed Mar 08, 2006 9:24 pm
Location: Germany
Full name: Daniel Mehrmann

Re: UCI protocol experience needed

Post by Daniel Mehrmann »

CRoberson wrote:No Change. I wonder if the issue is Arena 1.1?

Nah, other UCI engines work.
Maybe try some sort of logging in your engine while search. I do something like in Homer:

Code: Select all

BOOL
CheckInPut(void)
{
/* Windows */
#if defined WIN32
    static BOOL init = FALSE, pipe;
    static HANDLE StdinHandle;
    DWORD value, LastError;

    /* MS: CRT file handles */
    if (init && stdin->_cnt > 0)
        return TRUE;

    if (!init) {
        init = TRUE;
        StdinHandle = GetStdHandle(STD_INPUT_HANDLE);

        if (StdinHandle == NULL || StdinHandle == INVALID_HANDLE_VALUE) {
            #ifdef _WIN32 /* >= Win2000 */
                LastError = GetLastError();
                MessageHandle("GetStdHandle() failed" , (int)LastError);
            #else
                MessageHandle("GetStdHandle() failed" , 0);
            #endif
        }
        pipe = !GetConsoleMode(StdinHandle, &value);
        if (!pipe) {
            SetConsoleMode(StdinHandle,value &~ (ENABLE_MOUSE_INPUT|ENABLE_WINDOW_INPUT));
            FlushConsoleInputBuffer(StdinHandle);
        }
    }

    if (pipe) {
        if (!PeekNamedPipe(StdinHandle, NULL, 0, NULL, &value, NULL)) {
            #ifdef _WIN32 /* >= Win2000 */
                LastError = GetLastError();
                MessageHandle("PeekNamedPipe stdin failed" , (int)LastError);
            #else
                MessageHandle("PeekNamedPipe stdin failed" , 0);
            #endif

			ExitProgram((int)LastError);
        }
        return value > 0;
   } else {
        GetNumberOfConsoleInputEvents(StdinHandle, &value);
        return value > 1;
   }
   return FALSE;

/* UNIX */
#else
  fd_set rfd;
  struct timeval timeval;
  timeval.tv_sec = timeval.tv_usec = 0;
  FD_ZERO(&rfd);
  FD_SET(0, &rfd);

  return select(1, &rfd, NULL, NULL, &timeval) > 0;
#endif
}
During the search i do

Code: Select all

 if(CheckInPut()) {....read input, do logging }

Code: Select all

BOOL
ReadInPut(char *buffer, int bytes)
{
    if (fgets(buffer, bytes, stdin) != NULL)
        return TRUE;
	else {
		if (feof(stdin)) 
			return FALSE;
		else
			MessageHandle("ReadInput(): Error line not ended", 2);
	}
    return FALSE;
}

Code: Select all


void
ShowBytes(char *buffer, int counter)
{
    while (counter--) {
        if (*buffer < 040 || *&#40;uint8 *&#41;buffer > 0177&#41;
            fprintf&#40;LOG_FILE, "\\%03o", *buffer & 0xff&#41;;
        else
            putc&#40;*buffer, LOG_FILE&#41;;

        buffer++;
    &#125;
    fflush&#40;LOG_FILE&#41;;
&#125;


void
LogInPut&#40;char *message&#41;
&#123;
    if &#40;gameData.Logging&#41; &#123;
        fprintf&#40;LOG_FILE, "--> ");
        ShowBytes&#40;message, strlen&#40;message&#41;);
        fprintf&#40;LOG_FILE, "\n");
        fflush&#40;LOG_FILE&#41;;
    &#125;
&#125;