Proposed User Guide for Oscar's operft utility

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Proposed User Guide for Oscar's operft utility

Post by sje »

Proposed User Guide for Oscar's operft command line utility:
User Guide: operft Revised 2014-09-16


Building operft:

cc -O3 -Wall -pipe -o operft Oscar.c operf.c


Usage:

(1) operft
(2) operft [-nsvz] [-q <Q>] -d <depth> -p <quoted-FEN-string>
(3) operft [-nsvz] [-q <Q>] -d <depth> -f <FEN-input-file> -o <FEN-output-file>
(4) operft [-nsvz] [-q <Q>] -d <depth> -w <work-unit-input-file> -o <work-unit-output-file>

Mode 1: Print program identification, program usage, then exit.

Mode 2: Perform perft() to the given depth for the position given by the quoted FEN string.

Mode 3: Perform perft() to the given depth for every FEN position, one per line, in the FEN input file and write the results to the FEN output file.

More 4: Perform perft() to the given depth for every FEN position, one per line, in the work unit input file and write the results to the work unit output file.


Options:

-n No bulk counting.
-q <Q> Set transposititon table entry count to 2^Q; 8<=Q<=29; default Q=24.
-s Skip transposition table assistance.
-v Verbose operation.
-z Emit ply zero subtotals, one per move.


File formats:

Each line in a FEN input file has one FEN position record: six fields separated by one or more spaces and terminated with a newline.

Each line in a FEN output file has one FEN position record and a perft() count: seven fields separated by one or more spaces and terminated with a newline.

Each line in a work unit input file has one FEN position record and an integer giving the occurrence count: seven fields separated by one or more spaces and terminated with a newline.

Each line in a work unit output file has one FEN position record, an integer giving the occurrence count, the perft, and the product (the occurence count times the perft): nine fields separated by one or more spaces and terminated with a newline.


Other:

Verbose output is written to the standard output file.
Diagnostics are written to the standard error file.
A perft() calculation attempted using an invalid FEN returns a zero result.
Perft values are represented using 64 bit unsigned integers; overflow is not detected.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Using the C library routine getopt()

Post by sje »

Using the C library routine getopt()

I've avoided using the getopt() library routine mostly because I've preferred to write my own command line parameter processors. But I've grown lazy over the years and have become more willing to accept free code if it does what it says and if what it says will fill the need.

Question: Is the getopt() provided by OpenBSD (Mac OS/X) functionally equivalent to the getopt() provided by GNU (Linux)? I need to program to the most restrictive subset because of the need for portability. Although Oscar doesn't use any C library functions in OpenCL mode, Oscar's driving programs operft and operftocl do use such functions.

Also, while I don't use Windows, it may be the case that some who do might want to port Oscar and its drivers and I don't want to introduce unnecessary difficulties for them.

Up until now I've been making source changes and recompiling operft when changing option values like transposition table size, enabling bulk counting, etc. But this is no good for a deliverable product, so a generalized parameter processor has to go in soon.

--------

From our friend wc:

Code: Select all

gail&#58;OscarSource sje$ wc -l Oscar.c Oscar.h operft.c
    5310 Oscar.c
     906 Oscar.h
     539 operft.c
    6755 total
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Code snippet: getopt()

Post by sje »

A first attempt with getopt() from operft:

Code: Select all

  bool doamov = false;
  bool dobulk = false;
  bool doply0 = false;
  bool dotran = false;
  bool dovdmp = false;
  
  const char *fenstr = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
  ui depth = 1;
  ui ptqlen = 24;
  
  int optc;
  
  while (&#40;optc = getopt&#40;argc, argv, "abd&#58;f&#58;pq&#58;tv")) != -1&#41;
  &#123;
    switch &#40;optc&#41;
    &#123;
      case 'a'&#58;  // Enable ASCII movie
        doamov = true;
        break;
        
      case 'b'&#58;  // Enable bulk counting
        dobulk = true;
        break;
        
      case 'd'&#58;  // Override default depth value
        depth = atoi&#40;optarg&#41;;
        break;
        
      case 'f'&#58;  // Override default FEN string
        fenstr = optarg;
        break;

      case 'p'&#58;  // Enable ply zero move subtotal output
        doply0 = true;
        break;

      case 'q'&#58;  // Override default transpotion table log2 length
        ptqlen = atoi&#40;optarg&#41;;
        break;

      case 't'&#58;  // Enable transposition table assistance
        dotran = true;
        break;

      case 'v'&#58;  // Enable variation dump
        dovdmp = true;
        break;
      
      default&#58;
        fprintf&#40;stderr, "%c?\n", optc&#41;;
        break;
    &#125;;
  &#125;;
From the console:

Code: Select all

gail&#58;tmp sje$ ./operft -bt -d1
20   0.00 MHz
gail&#58;tmp sje$ ./operft -bt -d2
400   0.00 MHz
gail&#58;tmp sje$ ./operft -bt -d3
8902   0.02 MHz
gail&#58;tmp sje$ ./operft -bt -d4
197281   0.34 MHz
gail&#58;tmp sje$ ./operft -bt -d5
4865609   7.25 MHz
gail&#58;tmp sje$ ./operft -bt -d6
119060324   55.42 MHz
gail&#58;tmp sje$ ./operft -bt -d7
3195901860   165.82 MHz
gail&#58;tmp sje$ ./operft -bt -d8
84998978956   336.08 MHz
gail&#58;tmp sje$ ./operft -bt -d9
2439530234167   609.68 MHz
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

More examples

Post by sje »

Varying the transposition table size:

Code: Select all

gail&#58;tmp sje$ ./operft -f "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" -bt -d7 -q19
287188994746   122.98 MHz
gail&#58;tmp sje$ ./operft -f "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" -bt -d7 -q20
287188994746   150.64 MHz
gail&#58;tmp sje$ ./operft -f "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" -bt -d7 -q21
287188994746   172.33 MHz
gail&#58;tmp sje$ ./operft -f "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" -bt -d7 -q22
287188994746   192.31 MHz
gail&#58;tmp sje$ ./operft -f "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" -bt -d7 -q23
287188994746   220.38 MHz
gail&#58;tmp sje$ ./operft -f "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" -bt -d7 -q24
287188994746   253.26 MHz
gail&#58;tmp sje$ ./operft -f "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" -bt -d7 -q25
287188994746   284.53 MHz
gail&#58;tmp sje$ ./operft -f "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" -bt -d7 -q26
287188994746   297.98 MHz
gail&#58;tmp sje$ ./operft -f "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10" -bt -d7 -q27
287188994746   303.15 MHz