[llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/Game.h LICENSE.txt Makefile SearchGame.c TransGame.h inputs inputs_large

Chris Lattner lattner at cs.uiuc.edu
Mon Feb 13 22:08:46 PST 2006



Changes in directory llvm-test/MultiSource/Benchmarks/Fhourstones-3.1:

Game.h added (r1.1)
LICENSE.txt added (r1.1)
Makefile added (r1.1)
SearchGame.c added (r1.1)
TransGame.h added (r1.1)
inputs added (r1.1)
inputs_large added (r1.1)
---
Log message:

New tasty version of fhourstones: 3.1!

This one even includes a LARGE_PROBLEM_SIZE input! :)


---
Diffs of the changes:  (+484 -0)

 Game.h       |  122 ++++++++++++++++++++++++++++++++++++
 LICENSE.txt  |   11 +++
 Makefile     |   16 ++++
 SearchGame.c |  197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 TransGame.h  |  133 +++++++++++++++++++++++++++++++++++++++
 inputs       |    2 
 inputs_large |    3 
 7 files changed, 484 insertions(+)


Index: llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/Game.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/Game.h:1.1
*** /dev/null	Tue Feb 14 00:08:44 2006
--- llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/Game.h	Tue Feb 14 00:08:34 2006
***************
*** 0 ****
--- 1,122 ----
+ // Fhourstones 3.0 Board Logic
+ // (http://www.cwi.nl/~tromp/c4/fhour.html)
+ //
+ // implementation of the well-known game
+ // usually played on a vertical board of 7 columns by 6 rows,
+ // where 2 players take turns in dropping counters in a column.
+ // the first player to get four of his counters
+ // in a horizontal, vertical or diagonal row, wins the game.
+ // if neither player has won after 42 moves, then the game is drawn.
+ //
+ // This software is copyright (c) 1996-2005 by
+ //      John Tromp
+ //      Insulindeweg 908
+ //      1095 DX Amsterdam
+ //      Netherlands
+ // E-mail: tromp at cwi.nl
+ //
+ // This notice must not be removed.
+ // This software must not be sold for profit.
+ // You may redistribute if your distributees have the
+ // same rights and restrictions.
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #define WIDTH 7
+ #define HEIGHT 6
+ // bitmask corresponds to board as follows in 7x6 case:
+ //  .  .  .  .  .  .  .  TOP
+ //  5 12 19 26 33 40 47
+ //  4 11 18 25 32 39 46
+ //  3 10 17 24 31 38 45
+ //  2  9 16 23 30 37 44
+ //  1  8 15 22 29 36 43
+ //  0  7 14 21 28 35 42  BOTTOM
+ #define H1 (HEIGHT+1)
+ #define H2 (HEIGHT+2)
+ #define SIZE (HEIGHT*WIDTH)
+ #define SIZE1 (H1*WIDTH)
+ #define ALL1 (((uint64)1<<SIZE1)-(uint64)1) // assumes SIZE1 < 63
+ #define COL1 (((uint64)1<<H1)-(uint64)1)
+ #define BOTTOM (ALL1 / COL1) // has bits i*H1 set
+ #define TOP (BOTTOM << HEIGHT)
+ 
+ #include <sys/types.h>
+ typedef u_int64_t uint64;
+ typedef int64_t int64;
+ 
+ uint64 color[2];  // black and white bitboard
+ int moves[SIZE],nplies;
+ char height[WIDTH]; // holds bit index of lowest free square
+   
+ void reset()
+ {
+   int i;
+   nplies = 0;
+   color[0] = color[1] = 0;
+   for (i=0; i<WIDTH; i++)
+     height[i] = (char)(H1*i);
+ }
+ 
+ uint64 positioncode()
+ {
+   return color[nplies&1] + color[0] + color[1] + BOTTOM;
+ // color[0] + color[1] + BOTTOM forms bitmap of heights
+ // so that positioncode() is a complete board encoding
+ }
+ 
+ void printMoves()
+ {
+   int i;
+  
+   for (i=0; i<nplies; i++)
+     printf("%d", 1+moves[i]);
+ }
+ 
+ // return whether newboard lacks overflowing column
+ int islegal(uint64 newboard)
+ {
+   return (newboard & TOP) == 0;
+ }
+ 
+ // return whether columns col has room
+ int isplayable(int col)
+ {
+   return islegal(color[nplies&1] | ((uint64)1 << height[col]));
+ }
+ 
+ // return whether newboard includes a win
+ int haswon(uint64 newboard)
+ {
+   uint64 y = newboard & (newboard>>HEIGHT);
+   if ((y & (y >> 2*HEIGHT)) != 0) // check \ diagonal
+     return 1;
+   y = newboard & (newboard>>H1);
+   if ((y & (y >> 2*H1)) != 0) // check horizontal -
+     return 1;
+   y = newboard & (newboard>>H2); // check / diagonal
+   if ((y & (y >> 2*H2)) != 0)
+     return 1;
+   y = newboard & (newboard>>1); // check vertical |
+   return (y & (y >> 2)) != 0;
+ }
+ 
+ // return whether newboard is legal and includes a win
+ int islegalhaswon(uint64 newboard)
+ {
+   return islegal(newboard) && haswon(newboard);
+ }
+ 
+ void backmove()
+ {
+   int n;
+ 
+   n = moves[--nplies];
+   color[nplies&1] ^= (uint64)1<<--height[n];
+ }
+ 
+ void makemove(int n) 
+ {
+   color[nplies&1] ^= (uint64)1<<height[n]++;
+   moves[nplies++] = n;
+ }


Index: llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/LICENSE.txt
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/LICENSE.txt:1.1
*** /dev/null	Tue Feb 14 00:08:45 2006
--- llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/LICENSE.txt	Tue Feb 14 00:08:34 2006
***************
*** 0 ****
--- 1,11 ----
+ // This software is copyright (c) 1996-2005 by
+ //      John Tromp
+ //      Insulindeweg 908
+ //      1095 DX Amsterdam
+ //      Netherlands
+ // E-mail: tromp at cwi.nl
+ //
+ // This notice must not be removed.
+ // This software must not be sold for profit.
+ // You may redistribute if your distributees have the
+ // same rights and restrictions.


Index: llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/Makefile
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/Makefile:1.1
*** /dev/null	Tue Feb 14 00:08:45 2006
--- llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/Makefile	Tue Feb 14 00:08:34 2006
***************
*** 0 ****
--- 1,16 ----
+ LEVEL = ../../..
+ 
+ PROG     = fhourstones3.1
+ #CPPFLAGS = -DUNIX
+ # -DTRANSIZE=1050011 -DPROBES=8 -DREPORTPLY=8
+ 
+ #include $(LLVM_OBJ_ROOT)/Makefile.config
+ 
+ # Specify which file provides the contents of stdin for the test run 
+ ifdef LARGE_PROBLEM_SIZE
+ STDIN_FILENAME = $(PROJ_SRC_DIR)/inputs_large
+ else
+ STDIN_FILENAME = $(PROJ_SRC_DIR)/inputs
+ endif
+ 
+ include	../../Makefile.multisrc


Index: llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/SearchGame.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/SearchGame.c:1.1
*** /dev/null	Tue Feb 14 00:08:46 2006
--- llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/SearchGame.c	Tue Feb 14 00:08:34 2006
***************
*** 0 ****
--- 1,197 ----
+ // This software is copyright (c) 1996-2005 by
+ //      John Tromp
+ //      Insulindeweg 908
+ //      1095 DX Amsterdam
+ //      Netherlands
+ // E-mail: tromp at cwi.nl
+ //
+ // This notice must not be removed.
+ // This software must not be sold for profit.
+ // You may redistribute if your distributees have the
+ // same rights and restrictions.
+ 
+ #include "TransGame.h"
+ #include <sys/time.h>
+ #include <sys/resource.h>
+  
+ #define BOOKPLY 0  // full-width search up to this depth
+ #define REPORTPLY -1
+ 
+ uint64 millisecs()
+ {
+   struct rusage rusage;
+   getrusage(RUSAGE_SELF,&rusage);
+   return rusage.ru_utime.tv_sec * 1000 + rusage.ru_utime.tv_usec / 1000;
+ }
+ 
+ int history[2][SIZE1];
+ uint64 nodes, msecs;
+ 
+ int min(int x, int y) { return x<y ? x : y; }
+ int max(int x, int y) { return x>y ? x : y; }
+ 
+ void inithistory()
+ {
+   int side,i,h;
+   for (side=0; side<2; side++)
+     for (i=0; i<(WIDTH+1)/2; i++)
+       for (h=0; h<H1/2; h++)
+         history[side][H1*i+h] = history[side][H1*(WIDTH-1-i)+HEIGHT-1-h] =
+         history[side][H1*i+HEIGHT-1-h] = history[side][H1*(WIDTH-1-i)+h] =
+          4+min(3,i) + max(-1,min(3,h)-max(0,3-i)) + min(3,min(i,h)) + min(3,h);
+ }
+ 
+ int ab(int alpha, int beta)
+ {
+   int besti,i,j,l,v,val,score,ttscore;
+   int winontop,work;
+   int nav,av[WIDTH];
+   uint64 poscnt,newbrd,other;
+   int side,otherside;
+   unsigned int hashindx,hashlock;
+ 
+   nodes++;
+   if (nplies == SIZE-1) // one move left
+     return DRAW; // by assumption, player to move can't win
+   otherside = (side = nplies & 1) ^ 1;
+   other = color[otherside];
+   for (i = nav = 0; i < WIDTH; i++) {
+     newbrd = other | ((uint64)1 << height[i]); // check opponent move
+     if (!islegal(newbrd)) 
+       continue;
+     winontop = islegalhaswon(other | ((uint64)2 << height[i]));
+     if (haswon(newbrd)) { // immediate threat
+       if (winontop) // can't stop double threat
+         return LOSS;
+       nav = 0; // forced move
+       av[nav++] = i;
+       while (++i < WIDTH)
+         if (islegalhaswon(other | ((uint64)1 << height[i])))
+           return LOSS;
+       break;
+     }
+     if (!winontop)
+       av[nav++] = i;
+   }
+   if (nav == 0)
+     return LOSS;
+   if (nplies == SIZE-2) // two moves left
+     return DRAW; // opponent has no win either
+   if (nav == 1) {
+     makemove(av[0]);
+     score = LOSSWIN-ab(LOSSWIN-beta,LOSSWIN-alpha);
+     backmove();
+     return score;
+   }
+   ttscore = transpose();
+   if (ttscore != UNKNOWN) {
+     if (ttscore == DRAWLOSS) {
+       if ((beta = DRAW) <= alpha)
+         return ttscore;
+     } else if (ttscore == DRAWWIN) {
+       if ((alpha = DRAW) >= beta)
+         return ttscore;
+     } else return ttscore; // exact score
+   }
+   hashindx = htindex;
+   hashlock = lock;
+   poscnt = posed;
+   besti=0;
+   score = LOSS;
+   for (i = 0; i < nav; i++) {
+     val = history[side][(int)height[av[l = i]]];
+     for (j = i+1; j < nav; j++) {
+       v = history[side][(int)height[av[j]]];
+       if (v > val) {
+         val = v; l = j;
+       }
+     }
+     for (j = av[l]; l>i; l--)
+       av[l] = av[l-1];
+     makemove(av[i] = j);
+     val = LOSSWIN-ab(LOSSWIN-beta,LOSSWIN-alpha);
+     backmove();
+     if (val > score) {
+       besti = i;
+       if ((score=val) > alpha && nplies >= BOOKPLY && (alpha=val) >= beta) {
+         if (score == DRAW && i < nav-1)
+           score = DRAWWIN;
+         if (besti > 0) {
+           for (i = 0; i < besti; i++)
+             history[side][(int)height[av[i]]]--; // punish bad histories
+           history[side][(int)height[av[besti]]] += besti;
+         }
+         break;
+       }
+     }
+   }
+   if (score == LOSSWIN-ttscore) // combine < and >
+     score = DRAW;
+   poscnt = posed - poscnt;
+   for (work=0; (poscnt>>=1) != 0; work++) ; // work=log #positions stored
+   transtore(hashindx, hashlock, score, work);
+   if (nplies <= REPORTPLY) {
+     printMoves();
+     printf("%c%d\n", "#-<=>+"[score], work);
+   }
+   return score;
+ }
+ 
+ int solve()
+ {
+   int i, side = nplies & 1, otherside = side ^ 1, score;
+ 
+   nodes = 0;
+   msecs = 1L;
+   if (haswon(color[otherside]))
+       return LOSS;
+   for (i = 0; i < WIDTH; i++)
+     if (islegalhaswon(color[side] | ((uint64)1 << height[i])))
+       return WIN;
+   inithistory();
+   msecs = millisecs();
+   score = ab(LOSS, WIN);
+   msecs = 1L + millisecs() - msecs; // prevent division by 0
+   return score;
+ }
+ 
+ int main()
+ {
+   int c, result, work;
+   uint64 poscnt;
+                                                                                 
+   if (sizeof(uint64) != 8) {
+     printf("sizeof(uint64) == %d; please redefine.\n", sizeof(uint64));
+     exit(0);
+   }
+   trans_init();
+   puts("Fhourstones 3.1 (C)");
+   printf("Boardsize = %dx%d\n",WIDTH,HEIGHT);
+   printf("Using %d transposition table entries.\n", TRANSIZE);
+ 
+   for (;;) {
+     reset();
+     while ((c = getchar()) != -1) {
+       if (c >= '1' && c <= '0'+WIDTH)
+         makemove(c - '1');
+       else if (c == '\n')
+         break;
+     }
+     if (c == -1)
+       break;
+     printf("\nSolving %d-ply position after ", nplies);
+     printMoves();
+     puts(" . . .");
+ 
+     emptyTT();
+     result = solve();   // expect score << 6 | work
+     poscnt = posed;
+     for (work=0; (poscnt>>=1) != 0; work++) ; //work = log of #positions stored 
+     printf("score = %d (%c)  work = %d\n",
+       result, "#-<=>+"[result], work);
+     //printf("%llu pos / %llu msec = %.1f Kpos/sec\n",
+     //  nodes, msecs, (double)nodes/msecs);
+     htstat();
+   }
+   return 0;
+ }


Index: llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/TransGame.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/TransGame.h:1.1
*** /dev/null	Tue Feb 14 00:08:46 2006
--- llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/TransGame.h	Tue Feb 14 00:08:34 2006
***************
*** 0 ****
--- 1,133 ----
+ // Java Fhourstones 3.1 Transposition table logic
+ // (http://www.cwi.nl/~tromp/c4/fhour.html)
+ //
+ // implementation of the well-known game
+ // usually played on a vertical board of 7 columns by 6 rows,
+ // where 2 players take turns in dropping counters in a column.
+ // the first player to get four of his counters
+ // in a horizontal, vertical or diagonal row, wins the game.
+ // if neither player has won after 42 moves, then the game is drawn.
+ //
+ // This software is copyright (c) 1996-2005 by
+ //      John Tromp
+ //      Insulindeweg 908
+ //      1095 DX Amsterdam
+ //      Netherlands
+ // E-mail: tromp at cwi.nl
+ //
+ // This notice must not be removed.
+ // This software must not be sold for profit.
+ // You may redistribute if your distributees have the
+ // same rights and restrictions.
+ 
+ #include "Game.h"
+ 
+ #define LOCKSIZE 26
+ #define TRANSIZE 8306069
+   // should be a prime no less than about 2^{SIZE1-LOCKSIZE}
+ #define SYMMREC 10 // symmetry normalize first SYMMREC moves
+ #define UNKNOWN 0
+ #define LOSS 1
+ #define DRAWLOSS 2
+ #define DRAW 3
+ #define DRAWWIN 4
+ #define WIN 5
+ #define LOSSWIN 6
+ 
+ typedef struct {
+   unsigned biglock:LOCKSIZE;
+   unsigned bigwork:6;
+   unsigned newlock:LOCKSIZE;
+   unsigned newscore:3;
+   unsigned bigscore:3;
+ } hashentry;
+ 
+ unsigned int htindex, lock;
+ hashentry *ht;
+   
+ uint64 posed; // counts transtore calls
+   
+ void trans_init()
+ {
+   ht = (hashentry *)calloc(TRANSIZE, sizeof(hashentry));
+ }
+   
+ void emptyTT()
+ {
+   int i;
+ 
+   for (i=0; i<TRANSIZE; i++) {
+     ht[i] = (hashentry){0,0,0,0,0};
+   }
+   posed = 0;
+ }
+   
+ void hash()
+ {
+   uint64 htmp, htemp = positioncode();
+   if (nplies < SYMMREC) { // try symmetry recognition by reversing columns
+     uint64 htemp2 = 0;
+     for (htmp=htemp; htmp!=0; htmp>>=H1)
+       htemp2 = htemp2<<H1 | (htmp & COL1);
+     if (htemp2 < htemp)
+       htemp = htemp2;
+   }
+   lock = (unsigned int)(htemp >> (SIZE1-LOCKSIZE));
+   htindex = (unsigned int)(htemp % TRANSIZE);
+ }
+   
+ int transpose()
+ {
+   hashentry he;
+   int biglock,newlock;
+ 
+   hash();
+   he = ht[htindex];
+   if (he.biglock == lock)
+     return he.bigscore;
+   if (he.newlock == lock)
+     return he.newscore;
+   return UNKNOWN;
+ }
+   
+ void transtore(int x, unsigned int lock, int score, int work)
+ {
+   hashentry he;
+ 
+   posed++;
+   he = ht[x];
+   if (he.biglock == lock || work >= he.bigwork) {
+     he.biglock = lock;
+     he.bigscore = score;
+     he.bigwork = work;
+   } else {
+     he.newlock = lock;
+     he.newscore = score;
+   }
+   ht[x] = he;
+ }
+ 
+ void htstat()      /* some statistics on hash table performance */
+ {
+   int total, i;
+   int typecnt[8];                /* bound type stats */
+   hashentry he;
+  
+   for (i=0; i<8; i++)
+     typecnt[i] = 0;
+   for (i=0; i<TRANSIZE; i++) {
+     he = ht[i];
+     if (he.biglock != 0)
+       typecnt[he.bigscore]++;
+     if (he.newlock != 0)
+       typecnt[he.newscore]++;
+   }
+   for (total=0,i=LOSS; i<=WIN; i++)
+     total += typecnt[i];
+   if (total > 0) {
+     printf("- %5.3f  < %5.3f  = %5.3f  > %5.3f  + %5.3f\n",
+       typecnt[LOSS]/(double)total, typecnt[DRAWLOSS]/(double)total,
+       typecnt[DRAW]/(double)total, typecnt[DRAWWIN]/(double)total,
+       typecnt[WIN]/(double)total);
+   }
+ }


Index: llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/inputs
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/inputs:1.1
*** /dev/null	Tue Feb 14 00:08:46 2006
--- llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/inputs	Tue Feb 14 00:08:34 2006
***************
*** 0 ****
--- 1,2 ----
+ 45461667
+ 35333571


Index: llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/inputs_large
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/inputs_large:1.1
*** /dev/null	Tue Feb 14 00:08:46 2006
--- llvm-test/MultiSource/Benchmarks/Fhourstones-3.1/inputs_large	Tue Feb 14 00:08:34 2006
***************
*** 0 ****
--- 1,3 ----
+ 45461667
+ 35333571
+ 13333111






More information about the llvm-commits mailing list