ComStock 1.0.2 Stockfish with robobases

Discussion about chess-playing software (engines, hosts, opening books, platforms, etc...)
BB+
Posts: 1484
Joined: Thu Jun 10, 2010 4:26 am

Re: ComStock 1.0.2 Stockfish with robobases

Post by BB+ » Tue Jan 11, 2011 9:54 am

OK, now I'm just confused as to why Fruit 2.1 doesn't have this problem. When I use fgets in the "getme.cpp" function, it says that input_available() is false.

BB+
Posts: 1484
Joined: Thu Jun 10, 2010 4:26 am

Re: ComStock 1.0.2 Stockfish with robobases

Post by BB+ » Tue Jan 11, 2011 10:10 am

I figured out why my Fruit simulator failed, as I did not do:

Code: Select all

void util_init() {
   setvbuf(stdin,NULL,_IONBF,0);
   setvbuf(stdout,NULL,_IONBF,0); // _IOLBF breaks on Windows!                  
}
Adding the same to "getme.cpp" (and thus to Stockfish, I presume) solves the problem.

EDIT: Indeed, by putting the above two lines after init_threads() in the main Stockfish function, it now realises that data is still available when "go infinite\nstop\n" is sent and the first "go infinite" has been read by getline(). The only downside is that it takes a full second to actually stop, presumably because the polling is rather slow?! :shock:
Attachments
getme.cpp
Version including setvbuf, and now input_available() returns true, as desired.
(781 Bytes) Downloaded 110 times

Michel Van den Bergh
Posts: 24
Joined: Thu Jun 10, 2010 4:30 pm

Re: ComStock 1.0.2 Stockfish with robobases

Post by Michel Van den Bergh » Tue Jan 11, 2011 11:47 am

I realize that my own explanation why Fruit/Linux doesn't have a problem was somewhat wrong. "select" uses file descriptors
instead of file pointers. So it cannot know about the buffer associated to a file pointer. But as was pointed out Fruit/Linux uses unbuffered I/O. So the only buffer associated with a pipe in this case is the kernel buffer. And of course select knows about that one. But so does PeekNamedPipe. So intrinsically I don't see why Linux and Windows should behave differently.

mcostalba
Posts: 91
Joined: Thu Jun 10, 2010 11:45 pm
Real Name: Marco Costalba

Re: ComStock 1.0.2 Stockfish with robobases

Post by mcostalba » Tue Jan 11, 2011 1:13 pm

BB+ wrote:I think I have a better grasp of the problem.
You have done a lot of tests but still I have not understood if you have tried adding my above suggested code to data_available() .....

BB+
Posts: 1484
Joined: Thu Jun 10, 2010 4:26 am

Re: ComStock 1.0.2 Stockfish with robobases

Post by BB+ » Tue Jan 11, 2011 1:24 pm

You have done a lot of tests but still I have not understood if you have tried adding my above suggested code to data_available()...
No I did not, as it was Windows only, no? At least it is in Fruit, and I don't see how to reference "stdin->_cnt" in Linux in any event.

I think the only fix you need is (as per Fruit) to add something like the following in the Stockfish startup:

Code: Select all

void util_init() {
   setvbuf(stdin,NULL,_IONBF,0);
   setvbuf(stdout,NULL,_IONBF,0); // _IOLBF breaks on Windows!                 
}
Then "stdin" should be unbuffered, and this gets around the problem of the buffers getting the "stop" part of "go infinite\nstop\n", or whatever was happening.

BB+
Posts: 1484
Joined: Thu Jun 10, 2010 4:26 am

Re: ComStock 1.0.2 Stockfish with robobases

Post by BB+ » Tue Jan 11, 2011 2:00 pm

GreKo presumably works correctly (in Unix) due to the setbuf calls on startup:

Code: Select all

void InitInput()
{
        out("init input...\n");

        is_pipe = !isatty (0); 
        if (is_pipe)
        {
                signal(SIGINT, SIG_IGN); 
        }

        setbuf(stdout, NULL);
        setbuf(stdin, NULL);
}
So this is essentially the same as Fruit.
The code in Stockfish is:

Code: Select all

  cout.rdbuf()->pubsetbuf(NULL, 0);
  cin.rdbuf()->pubsetbuf(NULL, 0);
But this doesn't seem to do the job (and I don't really know why -- I tested it in getme.cpp, and data_available() returned 0). Replacing this with setbuf or setvbuf does the trick.

BB+
Posts: 1484
Joined: Thu Jun 10, 2010 4:26 am

Re: ComStock 1.0.2 Stockfish with robobases

Post by BB+ » Tue Jan 11, 2011 2:30 pm

Here's the example stripped down to almost nothing. I attach an archive with "make.sh", "getme.cpp", and "testfunc.c".
The third is the programme that sends "go infinite\nstop\n", the second has a compile switch:

Code: Select all

#ifdef FRUIT // as in Fruit/GreKo                                               
  setvbuf(stdin,NULL,_IONBF,0);
  setvbuf(stdout,NULL,_IONBF,0); // _IOLBF breaks on Windows!                   
  cout << "Using setvbuf [Fruit]" << endl;
#else // as in Stockfish                                                        
  cout.rdbuf()->pubsetbuf(NULL, 0);
  cin.rdbuf()->pubsetbuf(NULL, 0);
  cout << "Using cin.rdbuf()->pubsetbuf [Stockfish]" << endl;
#endif
so that the only difference is how the buffers are set, and the first file (make.sh) simply compiles the programmes and runs them. Here is the output (at least on my machine, Fedora Core 11):

Code: Select all

$ sh make.sh
Using setvbuf [Fruit]
Read input: go infinite
input_available() is 1
Read input: stop
Using cin.rdbuf()->pubsetbuf [Stockfish]
Read input: go infinite
input_available() is 0
Read input: stop
Again, I don't know the ins and outs of this and perhaps it should work either way, but not for me.
Attachments
BUFFERS.7z
7zip archive, 3 files
To demonstrate that cin.rdbuf()->pubsetbuf() and setvbuf() are not the same
(1.25 KiB) Downloaded 131 times

BB+
Posts: 1484
Joined: Thu Jun 10, 2010 4:26 am

Re: ComStock 1.0.2 Stockfish with robobases

Post by BB+ » Tue Jan 11, 2011 2:50 pm

From the lovely C++ standard (emphasis added):
27.6.2.2.2 Buffer management and positioning [streambuf.buffer]
basic_streambuf<char_type,traits>* pubsetbuf(char_type* s, streamsize n);
Returns: setbuf(s, n).
27.6.2.4.2 Buffer management and positioning [streambuf.virt.buffer]
basic_streambuf* setbuf(char_type* s, streamsize n);
Effects: Influences stream buffering in a way that is defined separately for each class derived from basic_streambuf in this Clause (27.8.1.4, 27.9.1.5).
Default behavior: Does nothing. Returns this.
So it might be that "pubsetbuf" is simply doing nothing, or at least it seems to be "implementation-defined", whereas setvbuf seems to be at least well-defined as to the behaviour. However, I could be wrong about something here.

EDIT: Actually, it seems that the more relevant might be
27.9.1.5.12 basic_streambuf* setbuf(char_type* s, streamsize n);
Effects: If setbuf(0,0) is called on a stream before any I/O has occurred on that stream, the stream becomes unbuffered. Otherwise the results are implementation-defined. “Unbuffered” means that pbase() and pptr() always return null and output to the file should appear as soon as possible.
In any event, as select is from a C library in any event, it makes more sense to me to use setvbuf rather than the C++ solution.

mcostalba
Posts: 91
Joined: Thu Jun 10, 2010 11:45 pm
Real Name: Marco Costalba

Re: ComStock 1.0.2 Stockfish with robobases

Post by mcostalba » Tue Jan 11, 2011 7:02 pm

BB+ wrote:I figured out why my Fruit simulator failed, as I did not do:

Code: Select all

void util_init() {
   setvbuf(stdin,NULL,_IONBF,0);
   setvbuf(stdout,NULL,_IONBF,0); // _IOLBF breaks on Windows!                  
}
Adding the same to "getme.cpp" (and thus to Stockfish, I presume) solves the problem.
Thanks ! Patch applied.

User avatar
kingliveson
Posts: 1388
Joined: Thu Jun 10, 2010 1:22 am
Real Name: Franklin Titus
Location: 28°32'1"N 81°22'33"W

Re: ComStock 1.0.2 Stockfish with robobases

Post by kingliveson » Tue Jan 18, 2011 4:52 pm

I tried building this in Windows, but no success -- will try again this coming weekend. No issue with Linux however.
PAWN : Knight >> Bishop >> Rook >>Queen

Post Reply