Problems with implementing UCI analysis mode

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

metax
Posts: 344
Joined: Wed Sep 23, 2009 5:56 pm
Location: Germany

Problems with implementing UCI analysis mode

Post by metax »

I am writing my engine in C. Now that I have mostly implemented UCI, I wanted to implement the analysis mode. However, I have no idea on how to stop analysis when the GUI sends 'stop'.
Before I implemented UCI, I just polled for user input every 30.000 nodes using kbhit(). When it returned true, I aborted the calculation. But kbhit() obviously doesn't work for UCI because the GUI does not really hit a key.
Is there a standard C function for polling for input which immediately returns? How is this solved in other engines?
User avatar
hgm
Posts: 27790
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Problems with implementing UCI analysis mode

Post by hgm »

Unfortunately this depends on if you are running in Windows or Linux. In Windows you would have to use PeekNamedPipe.
Edsel Apostol
Posts: 803
Joined: Mon Jul 17, 2006 5:53 am
Full name: Edsel Apostol

Re: Problems with implementing UCI analysis mode

Post by Edsel Apostol »

metax wrote:I am writing my engine in C. Now that I have mostly implemented UCI, I wanted to implement the analysis mode. However, I have no idea on how to stop analysis when the GUI sends 'stop'.
Before I implemented UCI, I just polled for user input every 30.000 nodes using kbhit(). When it returned true, I aborted the calculation. But kbhit() obviously doesn't work for UCI because the GUI does not really hit a key.
Is there a standard C function for polling for input which immediately returns? How is this solved in other engines?
Here's what most engines are using:

Code: Select all

int biosKey(void) {
    #if defined(_WIN32) || defined(_WIN64)
    /* Windows-version */
    static int init = 0, pipe;
    static HANDLE inh;
    DWORD dw;
    if (stdin->_cnt > 0) return stdin->_cnt;
    if (!init) {
        init = 1;
        inh = GetStdHandle(STD_INPUT_HANDLE);
        pipe = !GetConsoleMode(inh, &dw);
        if (!pipe) {
            SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
            FlushConsoleInputBuffer(inh);
        }
    }
    if (pipe) {
        if (!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) return 1;
        return dw;
    } else {
        GetNumberOfConsoleInputEvents(inh, &dw);
        return dw <= 1 ? 0 &#58; dw;
    &#125;
    #else
    /* Non-windows version */
    fd_set readfds;
    struct timeval timeout;
    FD_ZERO&#40;&readfds&#41;;
    FD_SET&#40;fileno&#40;stdin&#41;, &readfds&#41;;
    /* Set to timeout immediately */
    timeout.tv_sec = 0;
    timeout.tv_usec = 0;
    select&#40;16, &readfds, 0, 0, &timeout&#41;;
    return &#40;FD_ISSET&#40;fileno&#40;stdin&#41;, &readfds&#41;);
    #endif
&#125;
metax
Posts: 344
Joined: Wed Sep 23, 2009 5:56 pm
Location: Germany

Re: Problems with implementing UCI analysis mode

Post by metax »

Thanks a lot! That helped.
User avatar
michiguel
Posts: 6401
Joined: Thu Mar 09, 2006 8:30 pm
Location: Chicago, Illinois, USA

Re: Problems with implementing UCI analysis mode

Post by michiguel »

metax wrote:I am writing my engine in C. Now that I have mostly implemented UCI, I wanted to implement the analysis mode. However, I have no idea on how to stop analysis when the GUI sends 'stop'.
Before I implemented UCI, I just polled for user input every 30.000 nodes using kbhit(). When it returned true, I aborted the calculation. But kbhit() obviously doesn't work for UCI because the GUI does not really hit a key.
Is there a standard C function for polling for input which immediately returns? How is this solved in other engines?
I strongly suggest that you consider using two threads, one deals with all the interface with the user (boss) and the other (worker) is launched/blocked/stopped to search whenever the interface decides. The boss deals with all the mess of the user/GUI interaction and the worker never gets bothered until it needs to be stopped, or it finished its thinking and reports to the boss or make a move etc.

I think that it is even easier to port.

Miguel
metax
Posts: 344
Joined: Wed Sep 23, 2009 5:56 pm
Location: Germany

Re: Problems with implementing UCI analysis mode

Post by metax »

michiguel wrote:
metax wrote:I am writing my engine in C. Now that I have mostly implemented UCI, I wanted to implement the analysis mode. However, I have no idea on how to stop analysis when the GUI sends 'stop'.
Before I implemented UCI, I just polled for user input every 30.000 nodes using kbhit(). When it returned true, I aborted the calculation. But kbhit() obviously doesn't work for UCI because the GUI does not really hit a key.
Is there a standard C function for polling for input which immediately returns? How is this solved in other engines?
I strongly suggest that you consider using two threads, one deals with all the interface with the user (boss) and the other (worker) is launched/blocked/stopped to search whenever the interface decides. The boss deals with all the mess of the user/GUI interaction and the worker never gets bothered until it needs to be stopped, or it finished its thinking and reports to the boss or make a move etc.

I think that it is even easier to port.

Miguel
Unfortunately, I have absolutely no idea on how to realize that in C. :)
User avatar
michiguel
Posts: 6401
Joined: Thu Mar 09, 2006 8:30 pm
Location: Chicago, Illinois, USA

Re: Problems with implementing UCI analysis mode

Post by michiguel »

metax wrote:
michiguel wrote:
metax wrote:I am writing my engine in C. Now that I have mostly implemented UCI, I wanted to implement the analysis mode. However, I have no idea on how to stop analysis when the GUI sends 'stop'.
Before I implemented UCI, I just polled for user input every 30.000 nodes using kbhit(). When it returned true, I aborted the calculation. But kbhit() obviously doesn't work for UCI because the GUI does not really hit a key.
Is there a standard C function for polling for input which immediately returns? How is this solved in other engines?
I strongly suggest that you consider using two threads, one deals with all the interface with the user (boss) and the other (worker) is launched/blocked/stopped to search whenever the interface decides. The boss deals with all the mess of the user/GUI interaction and the worker never gets bothered until it needs to be stopped, or it finished its thinking and reports to the boss or make a move etc.

I think that it is even easier to port.

Miguel
Unfortunately, I have absolutely no idea on how to realize that in C. :)
Great opportunity to learn! In fact, I did not know at all when I decided to do it that way.

When I learned, I checked out a book from the library. Now it is available online
http://www.advancedlinuxprogramming.com/alp-folder

The simple chapter 4 is all you need. There are equivalent functions for windows. If you ever want to do an SMP engine, you have to learn this.

Miguel
Milos
Posts: 4190
Joined: Wed Nov 25, 2009 1:47 am

Re: Problems with implementing UCI analysis mode

Post by Milos »

michiguel wrote:
metax wrote:
michiguel wrote:
metax wrote:I am writing my engine in C. Now that I have mostly implemented UCI, I wanted to implement the analysis mode. However, I have no idea on how to stop analysis when the GUI sends 'stop'.
Before I implemented UCI, I just polled for user input every 30.000 nodes using kbhit(). When it returned true, I aborted the calculation. But kbhit() obviously doesn't work for UCI because the GUI does not really hit a key.
Is there a standard C function for polling for input which immediately returns? How is this solved in other engines?
I strongly suggest that you consider using two threads, one deals with all the interface with the user (boss) and the other (worker) is launched/blocked/stopped to search whenever the interface decides. The boss deals with all the mess of the user/GUI interaction and the worker never gets bothered until it needs to be stopped, or it finished its thinking and reports to the boss or make a move etc.

I think that it is even easier to port.

Miguel
Unfortunately, I have absolutely no idea on how to realize that in C. :)
Great opportunity to learn! In fact, I did not know at all when I decided to do it that way.

When I learned, I checked out a book from the library. Now it is available online
http://www.advancedlinuxprogramming.com/alp-folder

The simple chapter 4 is all you need. There are equivalent functions for windows. If you ever want to do an SMP engine, you have to learn this.
Not a bad advice, especially that the book is free to access.
However, I suggest a more methodical approach. Instead of restricting yourself to a specific implementation of pthreads, a better choice would be to learn fundamentals of concurrent programming. A good book to start might be: http://www.cs.arizona.edu/~greg/mpdbook/.
User avatar
michiguel
Posts: 6401
Joined: Thu Mar 09, 2006 8:30 pm
Location: Chicago, Illinois, USA

Re: Problems with implementing UCI analysis mode

Post by michiguel »

Milos wrote:
michiguel wrote:
metax wrote:
michiguel wrote:
metax wrote:I am writing my engine in C. Now that I have mostly implemented UCI, I wanted to implement the analysis mode. However, I have no idea on how to stop analysis when the GUI sends 'stop'.
Before I implemented UCI, I just polled for user input every 30.000 nodes using kbhit(). When it returned true, I aborted the calculation. But kbhit() obviously doesn't work for UCI because the GUI does not really hit a key.
Is there a standard C function for polling for input which immediately returns? How is this solved in other engines?
I strongly suggest that you consider using two threads, one deals with all the interface with the user (boss) and the other (worker) is launched/blocked/stopped to search whenever the interface decides. The boss deals with all the mess of the user/GUI interaction and the worker never gets bothered until it needs to be stopped, or it finished its thinking and reports to the boss or make a move etc.

I think that it is even easier to port.

Miguel
Unfortunately, I have absolutely no idea on how to realize that in C. :)
Great opportunity to learn! In fact, I did not know at all when I decided to do it that way.

When I learned, I checked out a book from the library. Now it is available online
http://www.advancedlinuxprogramming.com/alp-folder

The simple chapter 4 is all you need. There are equivalent functions for windows. If you ever want to do an SMP engine, you have to learn this.
Not a bad advice, especially that the book is free to access.
However, I suggest a more methodical approach. Instead of restricting yourself to a specific implementation of pthreads, a better choice would be to learn fundamentals of concurrent programming. A good book to start might be: http://www.cs.arizona.edu/~greg/mpdbook/.
Yes, that would be nice but it is overwhelming He does need only two functions: pthread_create and pthread_join. In fact, only a small fraction of the chapter 4 I mention is needed for this simple task.
Those two can be replaced by _beginthreadex and WaitForSingleObject in Windows.
Using a mutex would be nice, but it is not even needed for what Luca needs now. He needs to launch a thread with the iterative deepening search (pthread_create), stop it with a global variable, and wait for the thread to stop (pthread_join). In fact, if the thread is started with a parameter "detached", pthread_join may not even be needed.

Miguel
Milos
Posts: 4190
Joined: Wed Nov 25, 2009 1:47 am

Re: Problems with implementing UCI analysis mode

Post by Milos »

michiguel wrote:Yes, that would be nice but it is overwhelming He does need only two functions: pthread_create and pthread_join. In fact, only a small fraction of the chapter 4 I mention is needed for this simple task.
Those two can be replaced by _beginthreadex and WaitForSingleObject in Windows.
Using a mutex would be nice, but it is not even needed for what Luca needs now. He needs to launch a thread with the iterative deepening search (pthread_create), stop it with a global variable, and wait for the thread to stop (pthread_join). In fact, if the thread is started with a parameter "detached", pthread_join may not even be needed.
I guess from his post that the main problem was _kbhit() that he used and pipe solution of input polling solves his problem.
It would be nice to have a specific thread to deal with I/O stuff and for that he doesn't need more than CreateThread and WaitForSingleObject with a timeout for polling (since he's obviously using windows). But even that is not necessary and polling in the main thread after certain number of nodes works nicely (and it's a bit faster than a separate thread).
However, I had more in mind if he plans in future stuff like implementing SMP. For this he needs really a proper book on concurrent programming.