From 840202dc0e7f7a89f6b12a10545c6a2c68139a44 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Mon, 17 Jun 2024 07:39:13 +0200 Subject: [PATCH] perft-test.c/common-test.h: add sentinel for temp tests / TT stats --- test/common-test.h | 81 ++++++++++++++--------------- test/perft-test.c | 124 ++++++++++++++++++++++++++------------------- 2 files changed, 114 insertions(+), 91 deletions(-) diff --git a/test/common-test.h b/test/common-test.h index ba01990..6328899 100644 --- a/test/common-test.h +++ b/test/common-test.h @@ -28,29 +28,25 @@ struct fentest { char *comment; char *fen; } fentest[] = { - /******************* TEMP TESTS BELOW *******************/ + /************************************************************ + * TEMP TESTS BELOW - only run them (till sentinel below) * + ************************************************************/ /* - * { __LINE__, MOVEGEN | MOVEDO | PERFT, - * "bug perft TT après 1.b4 f5", - * "1nbqkbn1/ppp1p1pp/8/r1rpPpK1/1P6/8/P1PP1PPP/RNBQ1BNR w - f6 0 2" + * { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, + * "startpos + 1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4", + * "r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 1 4" + * }, + * { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, + * "", + * "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1" * }, */ - /* - * { __LINE__, MOVEGEN | MOVEDO | PERFT, - * "bug perft TT après 1.b4", - * "1nbqkbn1/ppp1pppp/8/r1rpP1K1/1P6/8/P1PP1PPP/RNBQ1BNR b - - 0 1", - * }, - */ - - { __LINE__, MOVEGEN | MOVEDO | PERFT, - "bug perft TT", - "1nbqkbn1/ppp1pppp/8/r1rpP1K1/8/8/PPPP1PPP/RNBQ1BNR w - d6 0 1", - }, - - /* ***************** END of TEMP TESTS ******************/ - /* below line ignored if first test */ + /****************************************************************** + * DO NOT DELETE NEXT LINE - sentinel entry for temp tests above. * + * ignored if first array entry. * + ******************************************************************/ { __LINE__, 0, NULL, NULL }, { __LINE__, MOVEGEN | MOVEDO | PERFT, @@ -154,40 +150,45 @@ struct fentest { "checker: h4", "4k3/8/8/8/7b/8/8/4K3 w - - 0 1" }, + /* + * { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, + * "1.e3 - perft bug", + * "rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq - 0 1" + * }, + * { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT | PERFT, + * "1.e3 Nc6 - perft bug", + * "r1bqkbnr/pppppppp/2n5/8/8/4P3/PPPP1PPP/RNBQKBNR w KQkq - 1 2" + * }, + * { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT | PERFT, + * "1.e3 Nc6 2.Ke2 - perft bug", + * "r1bqkbnr/pppppppp/2n5/8/8/4P3/PPPPKPPP/RNBQ1BNR b kq - 2 2" + * }, + * { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, + * "1.e3 Nc6 2.Ke2 Nd4+ - perft bug", + * "r1bqkbnr/pppppppp/8/8/3n4/4P3/PPPPKPPP/RNBQ1BNR w kq - 3 3" + * }, + */ // First game moves { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, "startpos", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" }, - //{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, - // "1.e3 - perft bug", - // "rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq - 0 1" - //}, - //{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT | PERFT, - // "1.e3 Nc6 - perft bug", - // "r1bqkbnr/pppppppp/2n5/8/8/4P3/PPPP1PPP/RNBQKBNR w KQkq - 1 2" - //}, - //{ __LINE__, FEN | MOVEGEN | MOVEDO | PERFT | PERFT, - // "1.e3 Nc6 2.Ke2 - perft bug", - // "r1bqkbnr/pppppppp/2n5/8/8/4P3/PPPPKPPP/RNBQ1BNR b kq - 2 2" - //}, { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, - "1.e3 Nc6 2.Ke2 Nd4+ - perft bug", - "r1bqkbnr/pppppppp/8/8/3n4/4P3/PPPPKPPP/RNBQ1BNR w kq - 3 3" - }, - { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, - "1.e4", + "startpos + 1.e4", "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1" }, { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, - "1.Nh3", - "rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq - 1 1" + "startpos + 1.e4 e5 2.Nf3", + "rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2" }, { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, - "1.e4 e5 2.Nf3 Nc6", - "r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 0 1" + "startpos + 1.e4 e5 2.Nf3 Nc6", + "r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3" + }, + { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, + "startpos + 1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4", + "r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 1 4" }, - // castling test // both can castle queen only { __LINE__, FEN | MOVEGEN | MOVEDO | PERFT, diff --git a/test/perft-test.c b/test/perft-test.c index ef476f6..8db151d 100644 --- a/test/perft-test.c +++ b/test/perft-test.c @@ -255,21 +255,29 @@ static __unused void compare_moves(movelist_t *fish, movelist_t *me) static int usage(char *prg) { - fprintf(stderr, "Usage: %s [-cmv][-d depth] [-p perft-version] \n", prg); - fprintf(stderr, "\t-c/m: print comments/moves, -n: no SF check, -d: depth, -p: 1-3, \n"); + fprintf(stderr, "Usage: %s [-cms][-d depth] [-p version] [-t size:\n", prg); + fprintf(stderr, "\t-c: do *not* print FEN comments\n"); + fprintf(stderr, "\t-d depth: perft depth (default: 6)"); + fprintf(stderr, "\t-m: print moves details\n"); + fprintf(stderr, "\t-s: use Stockfish to validate perft result\n"); + fprintf(stderr, "\t-t size: Transposition Table size (Mb). Default: 32\n"); + fprintf(stderr, + "\t-p flavor: perft flavor, 1:perft, 2:perft_alt 3:both, default:1\n"); return 1; } int main(int ac, char**av) { - int test_line; + int curtest = 0; u64 sf_count = 0, my_count; - bool comment = false; + bool comment = true, sf_run = false, moves_output = false; char *fen; pos_t *pos = NULL, *fenpos; pos_t *fishpos = pos_new(); movelist_t fishmoves; FILE *outfd = NULL; + s64 ms, lps; + int opt, depth = 6, run = 3, tt = 32, newtt = 32; struct { s64 count, ms; s64 minlps, maxlps; @@ -279,54 +287,73 @@ int main(int ac, char**av) { .minlps=LONG_MAX }, { .minlps=LONG_MAX }, }; - s64 ms, lps; - int opt, depth = 6, run = 3; - bool sf_run = true, perft_output = false; - - while ((opt = getopt(ac, av, "cmnd:p:")) != -1) { + while ((opt = getopt(ac, av, "cd:mp:st:")) != -1) { switch (opt) { case 'c': - comment = true; + comment = false; break; case 'd': depth = atoi(optarg); - break; - case 'p': /* 1 or 2 or 3 for both */ - run = atoi(optarg); - break; - case 'n': - sf_run = false; + if (depth <= 0) + depth = 6; break; case 'm': - perft_output = true; + moves_output = false; + break; + case 'p': + run = atoi(optarg); + break; + case 's': + sf_run = true; + break; + case 't': + newtt = atoi(optarg); break; default: return usage(*av); } } - printf("perft: depth = %d run = %x stockfish = %s\n", - depth, run, sf_run? "true": "false"); + if (!run) { + printf("Nothing to do, exiting\n"); + exit(0); + } init_all(); + if (newtt != 32 && newtt > 1) { + printf("changing TT size from %d to %d\n", tt, newtt); + tt_create(newtt); + tt = newtt; + } + printf("%s: depth:%d tt_size:%d run:%x SF:%s\n", + *av, + depth, newtt, run, + sf_run? "yes": "no"); - if (!run) - exit(0); + tt_info(); + printf("\n"); + + printf("move_t size:%lu\n", sizeof(move_t)); if (sf_run) outfd = open_stockfish(); CLOCK_DEFINE(clock, CLOCK_MONOTONIC); while ((fen = next_fen(PERFT | MOVEDO))) { - if (comment) - printf("%s\n", *cur_comment()? cur_comment(): ""); - test_line = cur_line(); - tt_clear(); if (!(fenpos = fen2pos(pos, fen))) { - printf("wrong fen line = %d: [%s]\n", test_line, fen); + printf("wrong fen line:%d fen:%s\n\n", cur_line(), fen); continue; } + curtest++; + printf("test:%d line:%d", curtest, cur_line()); + if (comment) + printf(" comment:%s\n", + *cur_comment()? cur_comment(): "no test desc"); + printf("\t%s\n", fen); + + tt_clear(); + pos = fenpos; if (sf_run) { stockfish_fen(outfd, fen); @@ -345,15 +372,13 @@ int main(int ac, char**av) if (lps < res[2].minlps) res[2].minlps = lps; } - printf("SF : line=%3d perft=%'lu %'ldms lps=%'lu \"%s\"\n", - test_line, sf_count, ms, - lps, - fen); + printf("Stockfish : perft:%'lu ms:%'ld lps:%'lu\n", + sf_count, ms, lps); } if (run & 1) { clock_start(&clock); - my_count = perft(pos, depth, 1, perft_output); + my_count = perft(pos, depth, 1, moves_output); ms = clock_elapsed_ms(&clock); if (!ms) { res[0].skipped++; @@ -369,20 +394,17 @@ int main(int ac, char**av) } if (!sf_run || sf_count == my_count) { - printf("pt1 OK : line=%3d perft=%'lu %'ldms lps=%'lu \"%s\"\n", - test_line, my_count, ms, - lps, - fen); + printf("perft : perft:%'lu ms:%'ld lps:%'lu ", + my_count, ms, lps); + tt_stats(); } else { - printf("pt1 ERR: line=%3d sf=%'lu me=%'lu \"%s\"\n", - test_line, sf_count, my_count, fen); + printf("perft : perft:%'lu ***ERROR***\n", my_count); } - tt_stats(); } if (run & 2) { clock_start(&clock); - my_count = perft_alt(pos, depth, 1, perft_output); + my_count = perft_alt(pos, depth, 1, moves_output); ms = clock_elapsed_ms(&clock); if (!ms) { res[1].skipped++; @@ -398,13 +420,10 @@ int main(int ac, char**av) } if (!sf_run || sf_count == my_count) { - printf("pt2 OK : line=%3d perft=%'lu %'ldms lps=%'lu \"%s\"\n", - test_line, my_count, ms, - lps, - fen); + printf("perft_alt : perft:%'lu ms:%'ld lps:%'lu\n", + my_count, ms, lps); } else { - printf("pt2 ERR: line=%3d sf=%'lu me=%'lu \"%s\"\n", - test_line, sf_count, my_count, fen); + printf("perft_alt : perft:%'lu ***ERROR***\n", my_count); } } printf("\n"); @@ -413,29 +432,32 @@ int main(int ac, char**av) if (sf_run) { if (!res[2].ms) res[2].ms = 1; - printf("total SF %'lums %'lums lps=%'lu min=%'lu max=%'lu (skipped %d)\n", + printf("total Stockfish : perft:%'lums ms:%'lums lps:%'lu min:%'lu max:%'lu " + "(skipped %d/%d)\n", res[2].count, res[2].ms, res[2].count * 1000l / res[2].ms, res[2].minlps, res[2].maxlps, - res[2].skipped); + res[0].skipped, curtest); } if (run & 1) { if (!res[0].ms) res[0].ms = 1; - printf("total perft %'lums %'lums lps=%'lu min=%'lu max=%'lu (skipped %d)\n", + printf("total perft : perft:%'lums ms:%'lums lps:%'lu min:%'lu max:%'lu " + "(skipped %d/%d)\n", res[0].count, res[0].ms, res[0].count * 1000l / res[0].ms, res[0].minlps, res[0].maxlps, - res[0].skipped); + res[0].skipped, curtest); } if (run & 2) { if (!res[1].ms) res[1].ms = 1; - printf("total perft2 %'lums %'lums lps=%'lu min=%'lu max=%'lu (skipped %d)\n", + printf("total perft_alt : perft:%'lums ms:%'lums lps:%'lu min:%'lu max:%'lu " + "(skipped %d/%d)\n", res[1].count, res[1].ms, res[1].count * 1000l / res[1].ms, res[1].minlps, res[1].maxlps, - res[1].skipped); + res[0].skipped, curtest); } return 0; }