Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Crafty 25.2 Final
Although it is not our practice to release a new version so soon after a previous release, Bob found a minor bug in the fail-high / fail-low code that we determined made a measurable impact on play - at least 20 ELO maybe more. Crafty is supposed to deal with the case where the first move produces a score, then a later move fails high but then produces a worse score. Crafty is supposed to revert to the better move. An "optimization" made this fail, but it is now fixed. "new" command removed as it is pretty difficult to restore everything once a game has been started. To start a new game, quit crafty and restart. Crafty now notifies xboard/winboard to do this automatically so using those interfaces requires no changes to anything.
  • Loading branch information
MichaelB7 committed Oct 29, 2016
1 parent db25ce0 commit db0e876
Show file tree
Hide file tree
Showing 14 changed files with 239 additions and 137 deletions.
202 changes: 202 additions & 0 deletions src/Makefile-official
@@ -0,0 +1,202 @@
# To build crafty:
#
# You want to set up for maximum optimization, but typically you will
# need to experiment to see which options provide the fastest code. The
# following option descriptions explain each option. To use one or more
# of these options, to the "opt =" line that follows the explanations and
# add the options you want, being careful to stay inside the single quote
# marks.
#
# -DAFFINITY Include code to set processor/thread affinity on Unix
# systems. Note this will not work on Apple OS X as it does
# not support any sort of processor affinity mechanism.
# WARNING: know what you are doing before using this. If
# you test multiple copies of Crafty (each copy using just
# one thread) you can have bogus results because if compiled
# with -DAFFINITY, even a single-cpu execution will lock led
# itself onto processor zero (since it only has thread #0)
# which is probably NOT what you want. This is intended to
# be used when you run Crafty using a complete dedicated
# machine with nothing else running at the same time.
# -DBOOKDIR Path to the directory containing the book binary files.
# The default for all such path values is "." if you don't
# specify a path with this macro definition.
# -DCPUS=n Defines the maximum number of CPUS Crafty will be able
# to use in a SMP system. Note that this is the max you
# will be able to use. You need to use the smpmt=n command
# to make crafty use more than the default 1 process.
# -DDEBUG This is used for testing changes. Enabling this option
# greatly slows Crafty down, but every time a move is made,
# the corresponding position is checked to make sure all of
# the bitboards are set correctly.
# -DEPD If you want full EPD support built in.
# -DLOGDIR Path to the directory where Crafty puts the log.nnn and
# game.nnn files.
# -DNODES This enables the sn=x command. Crafty will search until
# exactly X nodes have been searched, then the search
# terminates as if time ran out.
# -DPOSITIONS Causes Crafty to emit FEN strings, one per book line, as
# it creates a book. I use this to create positions to use
# for cluster testing.
# -DRCDIR Path to the directory where we look for the .craftyrc or
# crafty.rc (windows) file.
# -DSKILL Enables the "skill" command which allows you to arbitrarily
# lower Crafty's playing skill so it does not seem so
# invincible to non-GM-level players.
# -DSYZYGY This enables syzygy endgame tables (both WDL and DTC)
# -DTBDIR Path to the directory where the endgame tablebase files
# are found. default = "./TB"
# -DTEST Displays evaluation table after each move (in the logfile)
# -DTRACE This enables the "trace" command so that the search tree
# can be dumped while running.
# -DUNIX This identifies the target O/S as being Unix-based, if this
# option is omitted, windows is assumed.
#
# Note: If you compile on a machine with the hardware popcnt
# instruction, you should use the -mpopcnt compiler option
# to make the built-in intrinsic use the hardware rather than
# the "folding" approach. That is the default in this
# Makefile so if you do NOT have hardware popcnt, remove all
# of the -mpopcnt strings in the Makefile lines below.
#
default:
$(MAKE) -j unix-clang
help:
@echo "You must specify the system which you want to compile for:"
@echo ""
@echo "make unix-clang Unix w/clang compiler (MacOS usually)"
@echo "make unix-gcc Unix w/gcc compiler"
@echo "make unix-icc Unix w/icc compiler"
@echo "make profile profile-guided-optimizations"
@echo " (edit Makefile to make the profile"
@echo " option use the right compiler)"
@echo ""


quick:
$(MAKE) target=UNIX \
CC=clang \
opt='-DSYZYGY -DTEST -DTRACE -DCPUS=4' \
CFLAGS='-mpopcnt -Wall -Wno-array-bounds -pipe -O3' \
LDFLAGS='$(LDFLAGS) -lstdc++' \
crafty-make

unix-gcc:
$(MAKE) -j target=UNIX \
CC=gcc \
opt='-DSYZYGY -DTEST -DCPUS=4' \
CFLAGS='-Wall -Wno-array-bounds -pipe -O3 -fprofile-use \
-mpopcnt -fprofile-correction -pthread' \
LDFLAGS='$(LDFLAGS) -fprofile-use -pthread -lstdc++' \
crafty-make

unix-gcc-profile:
$(MAKE) -j target=UNIX \
CC=gcc \
opt='-DSYZYGY -DTEST -DCPUS=4' \
CFLAGS='-Wall -Wno-array-bounds -pipe -O3 -fprofile-arcs \
-mpopcnt -pthread' \
LDFLAGS='$(LDFLAGS) -fprofile-arcs -pthread -lstdc++ ' \
crafty-make

unix-clang:
@/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/llvm-profdata merge -output=crafty.profdata *.profraw
$(MAKE) -j target=UNIX \
CC=clang \
opt='-DSYZYGY -DTEST -DCPUS=4' \
CFLAGS='-Wall -Wno-array-bounds -pipe -O3 \
-mpopcnt -fprofile-instr-use=crafty.profdata' \
LDFLAGS='$(LDFLAGS) -fprofile-use -lstdc++' \
crafty-make

unix-clang-profile:
$(MAKE) -j target=UNIX \
CC=clang \
opt='-DSYZYGY -DTEST -DCPUS=4' \
CFLAGS='-Wall -Wno-array-bounds -pipe -O3 \
-mpopcnt -fprofile-instr-generate' \
LDFLAGS='$(LDFLAGS) -fprofile-instr-generate -lstdc++ ' \
crafty-make

unix-icc:
$(MAKE) -j target=UNIX \
CC=icc \
opt='-DSYZYGY -DTEST -DCPUS=4' \
CFLAGS='-Wall -w -O2 -prof_use -prof_dir ./prof -fno-alias \
-mpopcnt -pthread' \
LDFLAGS='$(LDFLAGS) -pthread -lstdc++' \
crafty-make

unix-icc-profile:
$(MAKE) -j target=UNIX \
CC=icc \
opt='-DSYZYGY -DTEST -DCPUS=4' \
CFLAGS='-Wall -w -O2 -prof_gen -prof_dir ./prof -fno-alias \
-mpopcnt -pthread' \
LDFLAGS='$(LDFLAGS) -pthread -lstdc++ ' \
crafty-make

profile:
@rm -rf *.o
@rm -rf log.*
@rm -rf game.*
@rm -rf prof
@rm -rf *.gcda
@mkdir prof
@touch *.c *.h
$(MAKE) -j unix-clang-profile
@echo "#!/bin/csh" > runprof
@echo "./crafty <<EOF" >>runprof
@echo "bench" >>runprof
@echo "mt=0" >>runprof
@echo "quit" >>runprof
@echo "EOF" >>runprof
@chmod +x runprof
@./runprof
@rm runprof
@touch *.c *.h
$(MAKE) -j unix-clang


#
# one of the two following definitions for "objects" should be used. The
# default is to compile everything separately. However, if you use the
# definition that refers to crafty.o, that will compile using the file crafty.c
# which #includes every source file into one large glob. This gives the
# compiler max opportunity to inline functions as appropriate. You should try
# compiling both ways to see which way produces the fastest code.
#

#objects = main.o iterate.o time.o search.o quiesce.o evaluate.o thread.o \
repeat.o hash.o next.o history.o movgen.o make.o unmake.o attacks.o \
see.o tbprobe.o boolean.o utility.o book.o drawn.o epd.o \
epdglue.o init.o input.o autotune.o interrupt.o option.o output.o \
ponder.o resign.o root.o learn.o setboard.o test.o validate.o \
annotate.o analyze.o evtest.o bench.o edit.o data.o

objects = crafty.o

# Do not change anything below this line!

opts = $(opt) -D$(target)

crafty-make:
@$(MAKE) opt='$(opt)' CFLAGS='$(CFLAGS)' crafty

crafty.o: *.c *.h

crafty: $(objects)
$(CC) $(LDFLAGS) -g -o crafty $(objects) -lm $(LIBS)

evaluate.o: evaluate.h

clean:
-rm -f *.o crafty

$(objects): chess.h data.h

.c.o:
$(CC) $(CFLAGS) $(opts) -c $*.c

.s.o:
$(AS) $(AFLAGS) -o $*.o $*.s
2 changes: 1 addition & 1 deletion src/bench.c
Expand Up @@ -215,6 +215,6 @@ int Bench(int increase, int autotune) {
smp_max_threads = Max(0, old_mt);
books_file = old_books;
book_file = old_book;
NewGame(0);
InitializeChessBoard(tree);
return total_time_used;
}
14 changes: 7 additions & 7 deletions src/book.c
Expand Up @@ -924,7 +924,7 @@ void Bookup(TREE * RESTRICT tree, int nargs, char **args) {
static char schar[2] = { "." };
int result = 0, played, i, mask_word, total_moves;
int move, move_num, wtm, book_positions, major, minor;
int cluster, max_cluster, discarded = 0, discarded_mp = 0, discarded_lose =
int cluster, max_cluster, ignored = 0, ignored_mp = 0, ignored_lose =
0;
int errors, data_read;
int start_elapsed_time, ply, max_ply = 256;
Expand Down Expand Up @@ -1132,7 +1132,7 @@ void Bookup(TREE * RESTRICT tree, int nargs, char **args) {
move = ReadNextMove(tree, buffer, 2, wtm);
else {
move = 0;
discarded++;
ignored++;
}
if (move) {
ply++;
Expand Down Expand Up @@ -1314,9 +1314,9 @@ void Bookup(TREE * RESTRICT tree, int nargs, char **args) {
if (stat != 1)
Print(4095, "ERROR! write failed, disk probably full.\n");
} else if (played < min_played)
discarded_mp++;
ignored_mp++;
else
discarded_lose++;
ignored_lose++;
if (last != (int) (next.position >> 49)) {
next_cluster = ftell(book_file);
fseek(book_file, cluster_seek, SEEK_SET);
Expand Down Expand Up @@ -1373,10 +1373,10 @@ void Bookup(TREE * RESTRICT tree, int nargs, char **args) {
Print(4095, "\n\nparsed %d moves (%d games).\n", total_moves,
games_parsed);
Print(4095, "found %d errors during parsing.\n", errors);
Print(4095, "discarded %d moves (maxply=%d).\n", discarded, max_ply);
Print(4095, "discarded %d moves (minplayed=%d).\n", discarded_mp,
Print(4095, "ignored %d moves (maxply=%d).\n", ignored, max_ply);
Print(4095, "ignored %d moves (minplayed=%d).\n", ignored_mp,
min_played);
Print(4095, "discarded %d moves (win/lose=%.1f%%).\n", discarded_lose,
Print(4095, "ignored %d moves (win/lose=%.1f%%).\n", ignored_lose,
wl_percent * 100);
Print(4095, "book contains %d unique positions.\n", book_positions);
Print(4095, "deepest book line was %d plies.\n", max_search_depth);
Expand Down
1 change: 0 additions & 1 deletion src/chess.h
Expand Up @@ -446,7 +446,6 @@ void MakeMove(TREE *RESTRICT, int, int, int);
void MakeMoveRoot(TREE *RESTRICT, int, int);
int Mated(TREE *RESTRICT, int, int);
int RootMoveEGTB(int);
void NewGame(int);
int NextMove(TREE *RESTRICT, int, int, int, int);
int NextRootMove(TREE *RESTRICT, TREE *RESTRICT, int);
int NextRootMoveParallel(void);
Expand Down
3 changes: 1 addition & 2 deletions src/data.c
Expand Up @@ -442,7 +442,7 @@ const int OOOsqs[2][3] = {{E8, D8, C8}, {E1, D1, C1}};
const int OOfrom[2] = {E8, E1};
const int OOto[2] = {G8, G1};
const int OOOto[2] = {C8, C1};
#define VERSION "25.1"
#define VERSION "25.2"
char version[8] = {VERSION};
PLAYING_MODE mode = normal_mode;
int batch_mode = 0; /* no asynch reads */
Expand Down Expand Up @@ -489,7 +489,6 @@ int xboard = 0;
int xboard_done = 0;
int pong = 0;
int early_exit = 99;
int new_game = 0;
char book_path[128] = {BOOKDIR};
char log_path[128] = {LOGDIR};
char tb_path[128] = {TBDIR};
Expand Down
1 change: 0 additions & 1 deletion src/data.h
Expand Up @@ -15,7 +15,6 @@ extern int allow_cores;
extern int allow_memory;
extern int initialized;
extern int early_exit;
extern int new_game;
extern char *AK_list[128];
extern char *GM_list[128];
extern char *IM_list[128];
Expand Down
4 changes: 2 additions & 2 deletions src/evaluate.h
Expand Up @@ -25,8 +25,8 @@ const int passed_pawn_candidate[2][8] = {
{ 0, 5, 5, 11, 27, 65, 0, 0 } /* [eg][rank] */
};
const int pawn_doubled[2][8] = {
{ 7, 8, 9, 9, 9, 9, 8, 7},//{ 5, 8, 9, 9, 9, 9, 8, 5}
{22, 19, 19, 19, 19, 19, 19, 22}//{17, 19, 19, 19, 19, 19, 19, 17}
{ 7, 8, 9, 9, 9, 9, 8, 7},
{22, 19, 19, 19, 19, 19, 19, 22}
};
const int pawn_isolated[2][8] = {
{14, 21, 23, 23, 23, 23, 21, 14},
Expand Down
7 changes: 5 additions & 2 deletions src/init.c
Expand Up @@ -19,7 +19,10 @@
*/
void Initialize() {
TREE *tree;
int i, j, v, major, id, node;
int j, v, major, id;
#if defined(UNIX)
int i, node;
#endif

tree = block[0];
for (j = 1; j <= MAX_BLOCKS; j++)
Expand Down Expand Up @@ -64,7 +67,7 @@ void Initialize() {
book_path);
if (book_file) {
int maj_min;
fseek(book_file, -sizeof(int), SEEK_END);
fseek(book_file, - (long) sizeof(int), SEEK_END);
v = fread(&maj_min, 4, 1, book_file);
if (v <= 0)
perror("Initialize() fread error: ");
Expand Down
2 changes: 1 addition & 1 deletion src/iterate.c
Expand Up @@ -48,7 +48,7 @@ int Iterate(int wtm, int search_type, int root_list_done) {
int value = 0, twtm, correct, correct_count, npc, cpl, max;
unsigned int idle_time;
char buff[32];
#if (CPUS > 1)
#if (CPUS > 1) && defined(UNIX)
pthread_t pt;
#endif

Expand Down
1 change: 0 additions & 1 deletion src/lock.h
Expand Up @@ -15,7 +15,6 @@
extern pthread_t NumaStartThread(void *func, void *args);

# include <windows.h>
# pragma intrinsic (_InterlockedExchange)
typedef volatile LONG lock_t[1];

# define LockInit(v) ((v)[0] = 0)
Expand Down
13 changes: 10 additions & 3 deletions src/main.c
Expand Up @@ -4236,6 +4236,16 @@
* ends which will also overwrite the current exact match and update *
* the age as well. Suggested by J. Wesley Cleveland on CCC. *
* *
* 25.2 Minor bug in the fail-high / fail-low code. Crafty is supposed *
* to deal with the case where the first move produces a score, then *
* a later move fails high but then produces a worse score. We are *
* supposed to revert to the better move. An "optimization" made *
* this fail, but it has been fixed here. "new" command removed as *
* it is pretty difficult to restore everything once a game has been *
* started. To start a new game, quit crafty and restart. Crafty *
* now notifies xboard/winboard to do this automatically so using *
* those interfaces requires no changes to anything. *
* *
*******************************************************************************
*/
int main(int argc, char **argv) {
Expand Down Expand Up @@ -4423,7 +4433,6 @@ int main(int argc, char **argv) {
if (hardware_processors > 0)
Print(32, "machine has %d processors\n\n", hardware_processors);

NewGame(1);
/*
************************************************************
* *
Expand Down Expand Up @@ -4501,8 +4510,6 @@ int main(int argc, char **argv) {
while (1) {
presult = 0;
do {
if (new_game)
NewGame(0);
opponent_start_time = ReadClock();
input_status = 0;
display = tree->position;
Expand Down

0 comments on commit db0e876

Please sign in to comment.