Multi-session time control: how to design the WB protocol?

Discussions about Winboard/Xboard. News about engines or programs to use with these GUIs (e.g. tournament managers or adapters) belong in this sub forum.

Moderator: Andres Valverde

Should WB send a new command "mlevel" to realize multi-session time control?

No, change "level" to accept more parameters.
2
12%
Yes, keep "level" for current time control and add "mlevel" for new feature.
14
82%
I don't know what's better.
0
No votes
I have a different proposal.
0
No votes
I don't care about this a lot.
1
6%
 
Total votes : 17

Re: Multi-session time control: how to design the WB protoco

Postby Pradu » 06 Jan 2009, 13:20

H.G.Muller wrote:The code I gave supposes the next line is read into inbuf, null-terminated, as usually happens at the top of the command-parsing loop. No special treatment of newlines is needed, as the command is not multiline, and sscanf does never read beyond a null character. Your code only looks shorter because you failed to include the code for AddLevel(), which is 90% of my code. In modular format, my code would look:

[code]if(!strcmp(command,"level"))
{ char *p = line+7;
resetLevel();
while(addLevel(p)) p = skip3(p);
}
Ok but I can gurantee your addLevel will be conseriably more complex and you need an extra skip3(p) <you just moved this convoluted code over to addLevel and and skip3(p)>. If you would like we have a competition on submitting an implementation with a single level command only and with level/mlevel and mine would be more robust (no protocol limitation on number of TCs at all) and simpler. If you solve problems by trying to apply new-line support in a single level command support your code would get very hairy guaranteed.

I don't think that code like that is such an insurmountable obstacle that it should have any impact on protocol design. If people do not know how to skip 3 numbers in a string, they should not take up Chess programming...
True, but why make it harder when it can be made simpler as good programmers will try to do? Imagine continuing this process and adding more harder to parse commands, the probability that such a protocol will suck is high.

Well, if I am going to break compatibility with existing multi-level commands, I would prefer

level 40 40+25/15+5 1

to signify 40/40+25/15+5+1, which in the existing format would have been

level 40 40 0 25 15 0 0 5 1
Last edited by Pradu on 06 Jan 2009, 13:49, edited 1 time in total.
User avatar
Pradu
 
Posts: 343
Joined: 12 Jan 2005, 19:17
Location: Chandler, Arizona, USA

Re: Multi-session time control: how to design the WB protoco

Postby Pradu » 06 Jan 2009, 13:29

If you would like we have a competition on submitting an implementation with a single level command only and with level/mlevel and mine would be more robust (no protocol limitation on number of TCs at all) and simpler.



Let us assume a typical chess program that reads in one line at a time and goes through if...else if... else... to handle commands and uses sscanf and the following two facilities: resetLevel(); addLevel(seconds, mps, inc); "line" is line read and "command" is the command part of the line.

Code: Select all
void addLevelString(char* buf)
{
    int min, inc, sec, mps;
    if(sscanf(buf, "%d %d:%d %d", &mps, &min, &sec, &inc)!=4)
    {
        sec = 0;
        sscanf(buf, "%d %d %d",&mps, &min, &inc);
    }
    addLevel(min*60+sec,mps,inc);
}

..

if(!strcmp(command,"level"))
{
    resetLevel();
    addLevelString(line+6);
}
else if(!strcmp(command,"mlevel")) addLevelString(line+7);
Lets see if your full implementation for level command given these facilities can generate the same functionality being either semantically shorter (not initializing a variable within an if condition for example), simpler, easier to read, or more robust (can handle many time controls). I bet your implementation with a single level command (with perhaps support for new lines; <try adding some logic for skipping 3 within a newline in between line reads>) will fail in most if not all categories.
User avatar
Pradu
 
Posts: 343
Joined: 12 Jan 2005, 19:17
Location: Chandler, Arizona, USA

Re: Multi-session time control: how to design the WB protoco

Postby Sven Schüle » 07 Jan 2009, 00:11

First of all, as you can see I quit from quitting ...

As a preliminary summary, I enjoy noticing that the discussion continues and that there are also new ideas.

Possible efficient/elegant/robust/short/powerful/bug-free implementations of the engine code that's necessary to handle "level"/"mlevel" are now being discussed intensively, and this is one important aspect of the whole issue. Here I fully agree with Pradu who said that
A lot of effort will be replicated by many people when implementing the protocol. Also taking into account that engines far exceed the number of GUIs, the protocol must be made to make engine programming the simplest.

Here I would like to add another statement that is partially similar to the one above:

The implementation should follow the requirements, not vice versa.

Here, requirements come from engine programmers mostly.

One of my main points was, and still is, that defining a new WB command for a new feature would allow engine programmers who want to upgrade their existing engine with the new feature to do the following, at least as a first step before possibly rewriting their "level" [or "mlevel"] handling code:

- Keep their whole code that recognizes the "level" command 100% untouched, and therefore still working reliably.

- Only add new code that recognizes the new command keyword (e.g. "mlevel") and handles it appropriately.

This would be an intermediate strategy since the required data structures to store N time control "sessions" are different from the flat "moves/seconds/increment" triple that is sufficient currently. But it is kind of defensive since any possible bugs in the new code would not affect the operation of the engine in traditional time control mode.

Once the new code would work, the engine programmer could do internal refactoring by choosing one common data structure that is filled and cleared with something like addLevel() and resetLevel() in the way Pradu suggested.

For me, this possibility of separating the working code that implements the existing protocol definition of "level" from new code that implements something new is really an important issue on behalf of the engine programmers.

Also I like Pradu's proposal of sending "level" once as before but followed optionally by one or more "mlevel" commands when multiple TC sessions are requested. The two points that are convincing me most compared to the original idea of sending (in case multi TC is requested) "mlevel" once with 3*N arguments are
- logfile readability and
- robustness with respect to possible buffer overflows.

While the former is kind of a nice service (and I would hate it to read a command with 9, 12, 15 parameters in a logfile) but not essential, the latter is an absolute "must have". To allow for an arbitrary number of parameters in an input string (I mean a really arbitrary number since we obviously don't want to define any artificial limit for the max. allowed number of TC sessions) strongly requires a self-growing string with dynamic memory allocation. It is not really difficult to do this but in the real world we cannot expect that many programmers would like to do this in their engine. But without self-growing, programmers would stick with the "char inputBuffer[256]" style, possibly just increasing the size, but still horribly unsafe.

Note that this issue is not about the exact way of parsing the input string but about a more general design question of a program.

This leads me to one more thought that I would like to point out. While code fragments showing how this or that could be done in detail are clearly a nice thing to discuss about, we should not forget that the "higher level" aspects of some possible alternative decisions should get more weight in the current situation. Concrete implementation details can be left for later.

This completes my list of thoughts I wanted to add to the discussion. I hope we can keep an eye on all, or most, of these somehow and do not dissipate our energies by diving too deep into only one of them.

The next steps should perhaps be
- to really clarify the requirements for "multi-session time control" and possibly other new ways of defining time control for WB engine play, and
- to discuss pros and cons of different ways to realize *these* requirements on the WB protocol level (but not yet too much on the level of the C/C++ bits).

Sven
User avatar
Sven Schüle
 
Posts: 240
Joined: 26 Sep 2004, 20:19
Location: Berlin, Germany

Re: Multi-session time control: how to design the WB protoco

Postby Zach Wegner » 07 Jan 2009, 02:28

Just for fun (and since ZCT was brought up by Pradu ;)) I made a simple implementation of both protocol versions.

Original ZCT code, only one time control supported (but refactored to make the other implementations clearer):
Code: Select all
void cmd_level(void)
{
    if (cmd_input.arg_count != 4)
    {
        print("Usage: level moves base increment\n");
        return;
    }
    level(cmd_input.arg[1], cmd_input.arg[2], cmd_input.arg[3]);
}

void level(char *a, char *b, char *c)
{
    int moves;
    int base;
    int inc;

    moves = atoi(a);
    base = atoi(b) * 60000;
    if (strchr(b, ':'))
        base += atoi(strchr(b, ':')) * 1000;
    inc = atoi(c) * 1000;
    set_time_control(moves, base, inc);
}


H.G. protover:
Code: Select all
void cmd_level1(void)
{
    int x;

    if (cmd_input.arg_count < 4 ||
        (cmd_input.arg_count - 1) % 3 != 0)
    {
        print("Usage: level moves base increment...\n");
        return;
    }
    time_control_reset();
    for (x = 1; x < cmd_input.arg_count; x += 3)
        level(cmd_input.arg[x], cmd_input.arg[x + 1], cmd_input.arg[x + 2]);
}


Pradu protover:
Code: Select all
void cmd_level2(void)
{
    int moves;
    int base;
    int inc;

    if (cmd_input.arg_count != 4)
    {
        print("Usage: %s moves base increment\n", cmd_input.arg[0]);
        return;
    }
    if (!strcmp(cmd_input.arg[0], "level"))
        time_control_reset();
    level(cmd_input.arg[1], cmd_input.arg[2], cmd_input.arg[3]);
}


I made the Pradu version so that both level and mlevel are supported by the same function. I don't think either implementation is particularly pretty, but I'd say the Pradu version is a bit easier to read.

While the former is kind of a nice service (and I would hate it to read a command with 9, 12, 15 parameters in a logfile) but not essential, the latter is an absolute "must have". To allow for an arbitrary number of parameters in an input string (I mean a really arbitrary number since we obviously don't want to define any artificial limit for the max. allowed number of TC sessions) strongly requires a self-growing string with dynamic memory allocation. It is not really difficult to do this but in the real world we cannot expect that many programmers would like to do this in their engine. But without self-growing, programmers would stick with the "char inputBuffer[256]" style, possibly just increasing the size, but still horribly unsafe.
This is an important point too. I'd say most programmers don't use a dynamic string, even Fruit, the "archetypal" open source engine. I am one of the few that have dynamic sizing of strings, but this is because of UCI support. I don't like having some artificial limit of string sizes in my program for aesthetic reasons, but neither do I like having a protocol imposing this belief on all programmers. I only was motivated to write the string code because I discovered ZCT was crashing after 20 or so moves while in UCI mode. UCI screwed this part up, let's not repeat it.
User avatar
Zach Wegner
 
Posts: 182
Joined: 26 Sep 2004, 22:02
Location: Austin, Texas, USA

Re: Multi-session time control: how to design the WB protoco

Postby H.G.Muller » 07 Jan 2009, 10:53

Tim Mann's original sefinition of the multi-session level command allowed the engine to set a maximum to the number of sessions, through feature level=N. With N=1 this would indicate only the old level command is understood, with larger N WB would only sent parameters for the sessions up to the specified number.

But I don't really see any need for WinBoard to distinguish the N>2 case from the N=2 case: It serves no purpose other than being pedantic for engines to check extra parameters beyond those they care to understand; once they know there can be more than one session, they can simply read the number of sessions they can handle, and ignore the rest of the line. So there is no reason for WB to suppress these. And N=0 would break the engine anyway. So there really are only 2 cases, and they could be indicated by a Boolean feature, rather than an integer feature.

The "truly arbitrary number of sessions" argument is a bit acdemic. Suppose some idiot wout want to specify a TC with 1000 sessions. Each session contains at least a single move. Why would your engine be interested in readng the session parameters beyond the 200th sesion? Do you expect the game will last more than 200 moves? I would say these parameters have zero impact on how I would allocate my time, I would not start worrying about them before move 160... It would be very counter-productive to ever pay attention to anything but the first 100 sesions. This requires an input buffer of less than 1KB, and anything that spills over that can be safely cut off. Are we saying now that engines cannot afford a 1KB input buffer?

I can add that the buffers that WB uses have a limited size (MSG_SIZ, which, I think, is set to 256 in the current version), and exits once a game reaches 500 moves. So users that would specify ridicuous numbers of session would crash WinBoard, and the engines would never hve to deal with the hypothetcal level command this would have generated.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Multi-session time control: how to design the WB protoco

Postby xinix » 07 Jan 2009, 11:18

H.G.Muller wrote:I see, so now we are pretending now that this is a democracy, eh? :shock:

Let me tell you how it really works: If one or two people disagreed with me, I would assume that it was just a matter of them having a different personal preference.

If 90% of all people would disagree with me, I would assume that they needed to be educated. :D

Only if 99% would disagree with me, I might start wondering if I had properly weighted the various pros and cons.

The main weakness of democracy is that it gives the power to people that might not be aware of all the issues, or in fact not aware of any, or just misunderstand what the issue is about. For instance, are any of the voters that voted for anothe keyword than level aware of the fact that Tim Mann himself proposed long time ago to use the same keyword (i.e. level) with arguments for multiple sessions? And that there exist WB engines that actually implement this command already, such as BlackBishop?

How am I to weight the opinion of people that were not aware of that? How am I to weigth the opinion of people from which I do not know if they were aware of that?

The problem is further compounded by the fact that the interest of engine authors does not fully coincide with that of GUI and protocol developers. This is similar to putting it up for voting if one person in the room has to give up his money to all the others. I expect many authors to vote for a new command, just so it is guaranteed they can ignore the changes / extensions. (Even withouth first investigating if the changes would hurt them.) And having people ignore the extensions is not in the interest of the future development of WinBoard protocol...


You are absolutely right. If you let everybody have a say it becomes a mess with 2 consequences.
1) You can clean it up
2) The messmakers will go somewhere else.

Arguments for changing:
1) It doesn't change anything for current implementations (actually only important if current implementation is "wrong")
2) It gives the possibility to change parameters. fe sending the "moves to go", current movenumber etc.

Sending the same as to the level command just to correct wrong implementations seems pretty useless indeed.

Tony
xinix
 
Posts: 22
Joined: 28 Aug 2008, 21:42

Re: Multi-session time control: how to design the WB protoco

Postby Sven Schüle » 07 Jan 2009, 14:38

xinix wrote:Arguments for changing:
1) It doesn't change anything for current implementations (actually only important if current implementation is "wrong")
2) It gives the possibility to change parameters. fe sending the "moves to go", current movenumber etc.

Sending the same as to the level command just to correct wrong implementations seems pretty useless indeed.

Just to clarify for me: what do you vote for? What do you mean exactly by "changing"?
User avatar
Sven Schüle
 
Posts: 240
Joined: 26 Sep 2004, 20:19
Location: Berlin, Germany

Re: Multi-session time control: how to design the WB protoco

Postby Pradu » 07 Jan 2009, 14:52

H.G.Muller wrote:The "truly arbitrary number of sessions" argument is a bit acdemic. Suppose some idiot wout want to specify a TC with 1000 sessions.
Regardless, if there is an approach that can provide "truly arbitrary number of sessions" with all the advantages of the variant approach and is better in every other way, why not use it? It would be idiotic not to (unless you are arguing for the sake of argument and the desire to be "always right"). In addition, it is silly to impose limitations how to use game information when it is trivial to remove this limitation regardless of whether in the future someone finds a way to take advantage of it or not.

Each session contains at least a single move. Why would your engine be interested in readng the session parameters beyond the 200th sesion? Do you expect the game will last more than 200 moves? I would say these parameters have zero impact on how I would allocate my time, I would not start worrying about them before move 160... It would be very counter-productive to ever pay attention to anything but the first 100 sesions.
All of this is your current analysis for your program. What if someone found a way to use this feature in the future? It would probably be less likely to find a good use of this feature if it never existed in the first place... Regardless of whether it will be useful or not, adding flexibility without any corresponding tradeoff is a good thing.

This requires an input buffer of less than 1KB, and anything that spills over that can be safely cut off. Are we saying now that engines cannot afford a 1KB input buffer?
This is yet again another place you impose a limitation which can easily be avoided without any corresponding tradeoff.
User avatar
Pradu
 
Posts: 343
Joined: 12 Jan 2005, 19:17
Location: Chandler, Arizona, USA

Re: Multi-session time control: how to design the WB protoco

Postby Sven Schüle » 07 Jan 2009, 15:14

Pradu wrote:
H.G.Muller wrote:The "truly arbitrary number of sessions" argument is a bit acdemic. Suppose some idiot wout want to specify a TC with 1000 sessions.
Regardless, if there is an approach that can provide "truly arbitrary number of sessions" with all the advantages of the variant approach and is better in every other way, why not use it? It would be idiotic not to (unless you are arguing for the sake of argument and the desire to be "always right"). In addition, it is silly to impose limitations how to use game information when it is trivial to remove this limitation regardless of whether in the future someone finds a way to take advantage of it or not.

Each session contains at least a single move. Why would your engine be interested in readng the session parameters beyond the 200th sesion? Do you expect the game will last more than 200 moves? I would say these parameters have zero impact on how I would allocate my time, I would not start worrying about them before move 160... It would be very counter-productive to ever pay attention to anything but the first 100 sesions.
All of this is your current analysis for your program. What if someone found a way to use this feature in the future? It would probably be less likely to find a good use of this feature if it never existed in the first place... Regardless of whether it will be useful or not, adding flexibility without any corresponding tradeoff is a good thing.

This requires an input buffer of less than 1KB, and anything that spills over that can be safely cut off. Are we saying now that engines cannot afford a 1KB input buffer?
This is yet again another place you impose a limitation which can easily be avoided without any corresponding tradeoff.

Fully agreed. If I could support more than 100% of this I would do it.
Sven
User avatar
Sven Schüle
 
Posts: 240
Joined: 26 Sep 2004, 20:19
Location: Berlin, Germany

Re: Multi-session time control: how to design the WB protoco

Postby H.G.Muller » 07 Jan 2009, 16:56

Personally I dislike continuation lines, but if we want to have a protocol that limits the number of parameters to 3, and sent a full specification of the TC in advance, I would prefer to do it simply through multiple level commands. So 40/40+25/15+5+1 would be sent as:

level 40 40 0
level 25 15 0
level 0 5 1


The semantics of the level command would always be that of AddLevel(), and the ResetLevel() would be done by the new command. The engine could specify how many of these level commands it could handle through feature level=N, N=1 being the default. If N was not sufficiently large to let the engine see all sessions up front, the list would be re-sent at the beginning of the next session, omitting the sessions that already have been completed. This would continue until the engine has seen all sessions. So for N=2 the same example would produce:

level 40 40 0
level 25 15 0

...
40 moves played
...
level 25 15 0
level 0 5 1

...
25 moves played
...
remainder of moves played in incremental TC

With N=1 it would lead to

level 40 40 0
...
40 moves played
...
level 25 15 0
...
25 moves played
...
level 0 5 1
...
remainder of moves played in incremental TC

which has a fair chance to work as a kludge on existing engines. If not the accumulateTC option gives you another shot at those engines.
User avatar
H.G.Muller
 
Posts: 3453
Joined: 16 Nov 2005, 12:02
Location: Diemen, NL

Re: Multi-session time control: how to design the WB protoco

Postby Pradu » 09 Jan 2009, 06:59

H.G.Muller wrote:Personally I dislike continuation lines, but if we want to have a protocol that limits the number of parameters to 3, and sent a full specification of the TC in advance, I would prefer to do it simply through multiple level commands. So 40/40+25/15+5+1 would be sent as:

level 40 40 0
level 25 15 0
level 0 5 1


The semantics of the level command would always be that of AddLevel(), and the ResetLevel() would be done by the new command. The engine could specify how many of these level commands it could handle through feature level=N, N=1 being the default. If N was not sufficiently large to let the engine see all sessions up front, the list would be re-sent at the beginning of the next session, omitting the sessions that already have been completed. This would continue until the engine has seen all sessions. So for N=2 the same example would produce:

level 40 40 0
level 25 15 0

...
40 moves played
...
level 25 15 0
level 0 5 1

...
25 moves played
...
remainder of moves played in incremental TC

With N=1 it would lead to

level 40 40 0
...
40 moves played
...
level 25 15 0
...
25 moves played
...
level 0 5 1
...
remainder of moves played in incremental TC

which has a fair chance to work as a kludge on existing engines. If not the accumulateTC option gives you another shot at those engines.


Combining both approaches is a good idea. For people who like a single set of TC setting commands for the whole game and the proposed approach allows this by setting N=0 (perhaps representing infinity). For people who want multiple TC commands through the game, they can have that too.

I think using level in conjunction with mlevel is easier than multiple level commands because the state an engine is in is very clear and it is easy to reset the timecontrol anywhere. Say you were doing an analysis on a game and you wished to play the engine from some position in the game with some new TC. If you used new to reset the level for the engine, then the board would go back to the initial position and you'll have to send all of the moves of the game again to the engine up to the position the user wants to play from. The problem also occurs when using a FEN position where the approach of sending new then playing some moves to the current position won't work. Therefore, both setboard and edit will also have to reset the TC after they run. So if you did setboard then played a few moves and wanted the engine to start playing from that position, you'd have to do setboard then start sending mulitple level commands. I think it would be simpler if a level command was used in conjunction with subsequent mlevel commands. The engine author may then be confident that implementing the time-control reset in the level command will then correctly do a reset whenever a new TC needs to be sent to the engine. In addition, the GUI will not have to send the entire game to the engine from the starting position again if the user suddenly wanted to play from a position (this is not a huge performance problem practically but it may make reading debug files easier).

How about changing the approach to do

Code: Select all
For N=0
level
mlevel
mlevel
....
none for rest of game

N=2
level
mlevel

... some moves to next TC ...

level
mlevel

...
User avatar
Pradu
 
Posts: 343
Joined: 12 Jan 2005, 19:17
Location: Chandler, Arizona, USA

Re: Multi-session time control: how to design the WB protoco

Postby xinix » 09 Jan 2009, 09:49

Sven Schüle wrote:
xinix wrote:Arguments for changing:
1) It doesn't change anything for current implementations (actually only important if current implementation is "wrong")
2) It gives the possibility to change parameters. fe sending the "moves to go", current movenumber etc.

Sending the same as to the level command just to correct wrong implementations seems pretty useless indeed.

Just to clarify for me: what do you vote for? What do you mean exactly by "changing"?


Changing the meaning of the command level It is able to handle all of this so you don't need a new command. If however you lift part of the level command to a new command, then that only seems usefull if you put sommething more in it.

otoh I also like the "level gives first time control", "mlevel gives next" approach.

Tony
xinix
 
Posts: 22
Joined: 28 Aug 2008, 21:42

Previous

Return to Winboard and related Topics

Who is online

Users browsing this forum: No registered users and 17 guests