diff --git a/.gitignore b/.gitignore index 93c3eb9..adf8864 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ build/* .vscode/* .idea/* cmake-build-debug/* +*.o +*.d +*.gcda diff --git a/build/makefile b/build/makefile index 05d19ca..d0ee4a4 100644 --- a/build/makefile +++ b/build/makefile @@ -1,49 +1,92 @@ EXE = seer -SRC = ../src/seer.cc ../syzygy/tbprobe.c ../src/search/*.cc ../src/chess/*.cc ../src/engine/*.cc -CC = g++ -EVALFILE = weights/0xddf7a131.bin +CC = gcc +CXX = g++ -OPSLIMIT = 1000000000 CXXSTANDARD = 17 +CSTANDARD = 17 + +EVALFILE = weights/0xddf7a131.bin +OPSLIMIT = 1000000000 + +CXXSRC += $(wildcard ../src/*.cc ) +CXXSRC += $(wildcard ../src/search/*.cc) +CXXSRC += $(wildcard ../src/chess/*.cc) +CXXSRC += $(wildcard ../src/engine/*.cc) + +CSRC := ../syzygy/tbprobe.c INCLUDE = ../include INCBIN = ../incbin SYZYGY = ../syzygy CXXFLAGS += -std=c++$(CXXSTANDARD) -CXXFLAGS += -O3 -g -DNDEBUG -march=native -mtune=native -fopenmp -flto -fwhole-program -CXXFLAGS += -Wall -Wextra +CXXFLAGS += -O3 -g -DNDEBUG -march=native -mtune=native -fopenmp +CXXFLAGS += -Wall -Wextra -pedantic CXXFLAGS += -fconstexpr-ops-limit=$(OPSLIMIT) -CXXFLAGS += -I$(INCLUDE) -I$(INCBIN) -I$(SYZYGY) CXXFLAGS += -DEVALFILE=\"$(EVALFILE)\" -THREADSANFLAGS += $(CXXFLAGS) -fsanitize=thread -ADDRESSSANFLAGS += $(CXXFLAGS) -fsanitize=address -UBSANFLAGS += $(CXXFLAGS) -fsanitize=undefined -TUNEFLAGS += $(CXXFLAGS) -DTUNE +CFLAGS += -std=c$(CSTANDARD) +CFLAGS += -O3 -g -DNDEBUG -march=native -mtune=native -fopenmp +CFLAGS += -Wall -Wextra -pedantic +CPPFLAGS += -MMD +CPPFLAGS += -I$(INCLUDE) +CPPFLAGS += -I$(INCBIN) +CPPFLAGS += -I$(SYZYGY) -LIBS = -lpthread +LDFLAGS = -lpthread -default: - $(CC) $(SRC) $(CXXFLAGS) $(LIBS) -o $(EXE) +COBJECTS += $(CSRC:%.c=%.o) +CDEPENDS += $(CSRC:%.c=%.d) +CXXOBJECTS += $(CXXSRC:%.cc=%.o) +CXXDEPENDS += $(CXXSRC:%.cc=%.d) + +.PHONY: default +default: flto + +.PHONY: pgo pgo: - rm -f *.gcda - $(CC) -fprofile-generate $(SRC) $(CXXFLAGS) $(LIBS) -o $(EXE) + $(MAKE) clean + $(MAKE) profileclean + $(MAKE) profilegenerate EXE=$(EXE) CC=$(CC) CXX=$(CXX) EVALFILE=$(EVALFILE) ./$(EXE) bench - $(CC) -fprofile-use $(SRC) $(CXXFLAGS) $(LIBS) -o $(EXE) - rm -f *.gcda + $(MAKE) clean + $(MAKE) profileuse EXE=$(EXE) CC=$(CC) CXX=$(CXX) EVALFILE=$(EVALFILE) + $(MAKE) profileclean + +.PHONY: profilegenerate +profilegenerate: CXXFLAGS += -fprofile-generate +profilegenerate: CFLAGS += -fprofile-generate +profilegenerate: flto + +.PHONY: profileuse +profileuse: CXXFLAGS += -fprofile-use +profileuse: CFLAGS += -fprofile-use +profileuse: flto + +.PHONY: flto +flto: CXXFLAGS += -flto -fwhole-program +flto: CFLAGS += -flto -fwhole-program +flto: binary + +.PHONY: plain +flto: binary + +.PHONY: binary +binary: $(CXXOBJECTS) $(COBJECTS) + +$(CXX) $(CXXFLAGS) -o $(EXE) $^ $(LDFLAGS) -threadsan: - $(CC) $(SRC) $(THREADSANFLAGS) $(LIBS) -o $(EXE) +.PHONY: clean +clean: + rm -f $(CXXOBJECTS) $(CXXDEPENDS) + rm -f $(COBJECTS) $(CDEPENDS) -addresssan: - $(CC) $(SRC) $(ADDRESSSANFLAGS) $(LIBS) -o $(EXE) +.PHONY: profileclean +profileclean: + rm -f $(CSRC:%.c=%.gcda) + rm -f $(CXXSRC:%.cc=%.gcda) -ubsan: - $(CC) $(SRC) $(UBSANFLAGS) $(LIBS) -o $(EXE) -tune: - $(CC) $(SRC) $(TUNEFLAGS) $(LIBS) -o $(EXE) +-include $(CXXDEPENDS) $(CDEPENDS) diff --git a/build/makefile-clang b/build/makefile-clang deleted file mode 100644 index 4f31891..0000000 --- a/build/makefile-clang +++ /dev/null @@ -1,48 +0,0 @@ -EXE = seer -SRC = ../src/seer.cc ../syzygy/tbprobe.c ../src/search/*.cc ../src/chess/*.cc ../src/engine/*.cc -CC = clang++ - -EVALFILE = weights/0xddf7a131.bin - -OPSLIMIT = 1000000000 -CXXSTANDARD = 17 - -INCLUDE = ../include -INCBIN = ../incbin -SYZYGY = ../syzygy - -CXXFLAGS += -std=c++$(CXXSTANDARD) -CXXFLAGS += -O3 -g -DNDEBUG -march=native -mtune=native -fopenmp -flto -CXXFLAGS += -Wall -Wextra -Wpedantic -CXXFLAGS += -fconstexpr-steps=$(OPSLIMIT) -CXXFLAGS += -I$(INCLUDE) -I$(INCBIN) -I$(SYZYGY) -CXXFLAGS += -DEVALFILE=\"$(EVALFILE)\" - -THREADSANFLAGS += $(CXXFLAGS) -fsanitize=thread -ADDRESSSANFLAGS += $(CXXFLAGS) -fsanitize=address -UBSANFLAGS += $(CXXFLAGS) -fsanitize=undefined - -LIBS = -lpthread - -PROFRAW = data.profraw -PROFDATA = data.profdata - -default: - $(CC) $(SRC) $(CXXFLAGS) $(LIBS) -o $(EXE) - -pgo: - rm -f $(PROFRAW) $(PROFDATA) - $(CC) -fprofile-instr-generate=$(PROFRAW) $(SRC) $(CXXFLAGS) $(LIBS) -o $(EXE) - ./$(EXE) bench - llvm-profdata merge -output=$(PROFDATA) $(PROFRAW) - $(CC) -fprofile-instr-use=$(PROFDATA) $(SRC) $(CXXFLAGS) $(LIBS) -o $(EXE) - rm -f $(PROFRAW) $(PROFDATA) - -threadsan: - $(CC) $(SRC) $(THREADSANFLAGS) $(LIBS) -o $(EXE) - -addresssan: - $(CC) $(SRC) $(ADDRESSSANFLAGS) $(LIBS) -o $(EXE) - -ubsan: - $(CC) $(SRC) $(UBSANFLAGS) $(LIBS) -o $(EXE) diff --git a/include/chess/square.h b/include/chess/square.h index ff400de..18f1e06 100644 --- a/include/chess/square.h +++ b/include/chess/square.h @@ -89,11 +89,10 @@ template inline constexpr bool is_square_v = std::is_same_v || std::is_same_v; struct square_set_iterator { - using difference_type = long; using value_type = square; using pointer = const square*; using reference = const square&; - using iterator_category = std::output_iterator_tag; + using iterator_category = std::input_iterator_tag; square::data_type remaining; diff --git a/include/search/history_heuristic.h b/include/search/history_heuristic.h index 7c135aa..690bcb9 100644 --- a/include/search/history_heuristic.h +++ b/include/search/history_heuristic.h @@ -37,7 +37,7 @@ namespace constants { inline constexpr std::size_t num_squares = 64; inline constexpr std::size_t num_pieces = 6; -}; // namespace constants +} // namespace constants struct context { chess::move follow; diff --git a/syzygy/tbchess.c b/syzygy/tbchess.c index f0b703d..3b84040 100644 --- a/syzygy/tbchess.c +++ b/syzygy/tbchess.c @@ -303,15 +303,15 @@ static const uint64_t anti2board_table[15] = 0x0001020408102040ull, }; -static inline std::size_t diag2index(uint64_t b) +static inline size_t diag2index(uint64_t b) { b *= 0x0101010101010101ull; b >>= 56; b >>= 1; - return (std::size_t)b; + return (size_t)b; } -static inline std::size_t anti2index(uint64_t b) +static inline size_t anti2index(uint64_t b) { return diag2index(b); } @@ -327,8 +327,8 @@ static uint64_t bishop_attacks(unsigned sq, uint64_t occ) unsigned d = diag(sq), a = anti(sq); uint64_t d_occ = occ & (diag2board(d) & ~BOARD_EDGE); uint64_t a_occ = occ & (anti2board(a) & ~BOARD_EDGE); - std::size_t d_idx = diag2index(d_occ); - std::size_t a_idx = anti2index(a_occ); + size_t d_idx = diag2index(d_occ); + size_t a_idx = anti2index(a_occ); uint64_t d_attacks = diag_attacks_table[sq][d_idx]; uint64_t a_attacks = anti_attacks_table[sq][a_idx]; return d_attacks | a_attacks; @@ -399,20 +399,20 @@ static void bishop_attacks_init(void) static uint64_t rank_attacks_table[64][64]; static uint64_t file_attacks_table[64][64]; -static inline std::size_t rank2index(uint64_t b, unsigned r) +static inline size_t rank2index(uint64_t b, unsigned r) { b >>= (8 * r); b >>= 1; - return (std::size_t)b; + return (size_t)b; } -static inline std::size_t file2index(uint64_t b, unsigned f) +static inline size_t file2index(uint64_t b, unsigned f) { b >>= f; b *= 0x0102040810204080ull; b >>= 56; b >>= 1; - return (std::size_t)b; + return (size_t)b; } #define rank2board(r) (0xFFull << (8 * (r))) @@ -424,8 +424,8 @@ static uint64_t rook_attacks(unsigned sq, uint64_t occ) unsigned r = rank(sq), f = file(sq); uint64_t r_occ = occ & (rank2board(r) & ~BOARD_RANK_EDGE); uint64_t f_occ = occ & (file2board(f) & ~BOARD_FILE_EDGE); - std::size_t r_idx = rank2index(r_occ, r); - std::size_t f_idx = file2index(f_occ, f); + size_t r_idx = rank2index(r_occ, r); + size_t f_idx = file2index(f_occ, f); uint64_t r_attacks = rank_attacks_table[sq][r_idx]; uint64_t f_attacks = file_attacks_table[sq][f_idx]; return r_attacks | f_attacks; diff --git a/syzygy/tbprobe.c b/syzygy/tbprobe.c index 4bcd6ca..4bfa446 100644 --- a/syzygy/tbprobe.c +++ b/syzygy/tbprobe.c @@ -57,7 +57,7 @@ using namespace std; #define SEP_CHAR ':' #define FD int #define FD_ERR -1 -typedef std::size_t map_t; +typedef size_t map_t; #else #ifndef NOMINMAX #define NOMINMAX @@ -257,13 +257,13 @@ inline static uint16_t read_le_u16(void *p) return from_le_u16(*(uint16_t *)p); } -static std::size_t file_size(FD fd) { +static size_t file_size(FD fd) { #ifdef _WIN32 LARGE_INTEGER fileSize; if (GetFileSizeEx(fd, &fileSize)==0) { return 0; } - return (std::size_t)fileSize.QuadPart; + return (size_t)fileSize.QuadPart; #else struct stat buf; if (fstat(fd,&buf)) { @@ -304,7 +304,7 @@ static FD open_tb(const char *str, const char *suffix) #else #ifdef _UNICODE wchar_t ucode_name[4096]; - std::size_t len; + size_t len; mbstowcs_s(&len, ucode_name, 4096, file, _TRUNCATE); fd = CreateFile(ucode_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -421,7 +421,7 @@ struct PairsData { struct EncInfo { struct PairsData *precomp; - std::size_t factor[TB_PIECES]; + size_t factor[TB_PIECES]; uint8_t pieces[TB_PIECES]; uint8_t norm[TB_PIECES]; }; @@ -667,7 +667,7 @@ static bool test_tb(const char *str, const char *suffix) { FD fd = open_tb(str, suffix); if (fd != FD_ERR) { - std::size_t size = file_size(fd); + size_t size = file_size(fd); close_tb(fd); if ((size & 63) != 16) { fprintf(stderr, "Incomplete tablebase file %s.%s\n", str, suffix); @@ -913,7 +913,7 @@ bool tb_init(const char *path) } // 6- and 7-piece TBs make sense only with a 64-bit address space - if (sizeof(std::size_t) < 8 || TB_PIECES < 6) + if (sizeof(size_t) < 8 || TB_PIECES < 6) goto finished; for (i = 0; i < 5; i++) @@ -1171,10 +1171,10 @@ static const uint8_t FileToFile[] = { 0, 1, 2, 3, 3, 2, 1, 0 }; static const int WdlToMap[5] = { 1, 3, 0, 2, 0 }; static const uint8_t PAFlags[5] = { 8, 0, 0, 0, 4 }; -static std::size_t Binomial[7][64]; -static std::size_t PawnIdx[2][6][24]; -static std::size_t PawnFactorFile[6][4]; -static std::size_t PawnFactorRank[6][6]; +static size_t Binomial[7][64]; +static size_t PawnIdx[2][6][24]; +static size_t PawnFactorFile[6][4]; +static size_t PawnFactorRank[6][6]; static void init_indices(void) { @@ -1183,8 +1183,8 @@ static void init_indices(void) // Binomial[k][n] = Bin(n, k) for (i = 0; i < 7; i++) for (j = 0; j < 64; j++) { - std::size_t f = 1; - std::size_t l = 1; + size_t f = 1; + size_t l = 1; for (k = 0; k < i; k++) { f *= (j - k); l *= (k + 1); @@ -1193,7 +1193,7 @@ static void init_indices(void) } for (i = 0; i < 6; i++) { - std::size_t s = 0; + size_t s = 0; for (j = 0; j < 24; j++) { PawnIdx[0][i][j] = s; s += Binomial[i][PawnTwist[0][(1 + (j % 6)) * 8 + (j / 6)]]; @@ -1205,7 +1205,7 @@ static void init_indices(void) } for (i = 0; i < 6; i++) { - std::size_t s = 0; + size_t s = 0; for (j = 0; j < 24; j++) { PawnIdx[1][i][j] = s; s += Binomial[i][PawnTwist[1][(1 + (j / 4)) * 8 + (j % 4)]]; @@ -1226,11 +1226,11 @@ int leading_pawn(int *p, struct BaseEntry *be, const int enc) return enc == FILE_ENC ? FileToFile[p[0] & 7] : (p[0] - 8) >> 3; } -std::size_t encode(int *p, struct EncInfo *ei, struct BaseEntry *be, +size_t encode(int *p, struct EncInfo *ei, struct BaseEntry *be, const int enc) { int n = be->num; - std::size_t idx; + size_t idx; int k; if (p[0] & 0x04) @@ -1286,7 +1286,7 @@ std::size_t encode(int *p, struct EncInfo *ei, struct BaseEntry *be, for (int i = k; i < t; i++) for (int j = i + 1; j < t; j++) if (p[i] > p[j]) Swap(p[i], p[j]); - std::size_t s = 0; + size_t s = 0; for (int i = k; i < t; i++) { int sq = p[i]; int skips = 0; @@ -1304,7 +1304,7 @@ std::size_t encode(int *p, struct EncInfo *ei, struct BaseEntry *be, for (int i = k; i < t; i++) for (int j = i + 1; j < t; j++) if (p[i] > p[j]) Swap(p[i], p[j]); - std::size_t s = 0; + size_t s = 0; for (int i = k; i < t; i++) { int sq = p[i]; int skips = 0; @@ -1319,27 +1319,27 @@ std::size_t encode(int *p, struct EncInfo *ei, struct BaseEntry *be, return idx; } -static std::size_t encode_piece(int *p, struct EncInfo *ei, struct BaseEntry *be) +static size_t encode_piece(int *p, struct EncInfo *ei, struct BaseEntry *be) { return encode(p, ei, be, PIECE_ENC); } -static std::size_t encode_pawn_f(int *p, struct EncInfo *ei, struct BaseEntry *be) +static size_t encode_pawn_f(int *p, struct EncInfo *ei, struct BaseEntry *be) { return encode(p, ei, be, FILE_ENC); } -static std::size_t encode_pawn_r(int *p, struct EncInfo *ei, struct BaseEntry *be) +static size_t encode_pawn_r(int *p, struct EncInfo *ei, struct BaseEntry *be) { return encode(p, ei, be, RANK_ENC); } // Count number of placements of k like pieces on n squares -static std::size_t subfactor(std::size_t k, std::size_t n) +static size_t subfactor(size_t k, size_t n) { - std::size_t f = n; - std::size_t l = 1; - for (std::size_t i = 1; i < k; i++) { + size_t f = n; + size_t l = 1; + for (size_t i = 1; i < k; i++) { f *= n - i; l *= i + 1; } @@ -1347,7 +1347,7 @@ static std::size_t subfactor(std::size_t k, std::size_t n) return f / l; } -static std::size_t init_enc_info(struct EncInfo *ei, struct BaseEntry *be, +static size_t init_enc_info(struct EncInfo *ei, struct BaseEntry *be, uint8_t *tb, int shift, int t, const int enc) { bool morePawns = enc != PIECE_ENC && be->pawns[1] > 0; @@ -1373,7 +1373,7 @@ static std::size_t init_enc_info(struct EncInfo *ei, struct BaseEntry *be, ei->norm[i]++; int n = 64 - k; - std::size_t f = 1; + size_t f = 1; for (int i = 0; k < be->num || i == order || i == order2; i++) { if (i == order) { @@ -1410,8 +1410,8 @@ static void calc_symLen(struct PairsData *d, uint32_t s, char *tmp) tmp[s] = 1; } -static struct PairsData *setup_pairs(uint8_t **ptr, std::size_t tb_size, - std::size_t *size, uint8_t *flags, int type) +static struct PairsData *setup_pairs(uint8_t **ptr, size_t tb_size, + size_t *size, uint8_t *flags, int type) { struct PairsData *d; uint8_t *data = *ptr; @@ -1444,10 +1444,10 @@ static struct PairsData *setup_pairs(uint8_t **ptr, std::size_t tb_size, d->minLen = minLen; *ptr = &data[12 + 2 * h + 3 * numSyms + (numSyms & 1)]; - std::size_t num_indices = (tb_size + (1ULL << idxBits) - 1) >> idxBits; + size_t num_indices = (tb_size + (1ULL << idxBits) - 1) >> idxBits; size[0] = 6ULL * num_indices; size[1] = 2ULL * numBlocks; - size[2] = (std::size_t)realNumBlocks << blockSize; + size[2] = (size_t)realNumBlocks << blockSize; assert(numSyms < TB_MAX_SYMS); char tmp[TB_MAX_SYMS]; @@ -1490,7 +1490,7 @@ static bool init_table(struct BaseEntry *be, const char *str, int type) data += 5; - std::size_t tb_size[6][2]; + size_t tb_size[6][2]; int num = num_tables(be, type); struct EncInfo *ei = first_ei(be, type); int enc = !be->hasPawns ? PIECE_ENC : type != DTM ? FILE_ENC : RANK_ENC; @@ -1503,7 +1503,7 @@ static bool init_table(struct BaseEntry *be, const char *str, int type) } data += (uintptr_t)data & 1; - std::size_t size[6][2][3]; + size_t size[6][2][3]; for (int t = 0; t < num; t++) { uint8_t flags; ei[t].precomp = setup_pairs(&data, tb_size[t][0], size[t][0], &flags, type); @@ -1600,13 +1600,13 @@ static bool init_table(struct BaseEntry *be, const char *str, int type) return true; } -static uint8_t *decompress_pairs(struct PairsData *d, std::size_t idx) +static uint8_t *decompress_pairs(struct PairsData *d, size_t idx) { if (!d->idxBits) return d->constValue; uint32_t mainIdx = (uint32_t)(idx >> d->idxBits); - int litIdx = (idx & (((std::size_t)1 << d->idxBits) - 1)) - ((std::size_t)1 << (d->idxBits - 1)); + int litIdx = (idx & (((size_t)1 << d->idxBits) - 1)) - ((size_t)1 << (d->idxBits - 1)); uint32_t block; memcpy(&block, d->indexTable + 6 * mainIdx, sizeof(block)); block = from_le_u32(block); @@ -1621,7 +1621,7 @@ static uint8_t *decompress_pairs(struct PairsData *d, std::size_t idx) while (litIdx > d->sizeTable[block]) litIdx -= d->sizeTable[block++] + 1; - uint32_t *ptr = (uint32_t *)(d->data + ((std::size_t)block << d->blockSize)); + uint32_t *ptr = (uint32_t *)(d->data + ((size_t)block << d->blockSize)); int m = d->minLen; uint16_t *offset = d->offset; @@ -1765,7 +1765,7 @@ int probe_table(const Pos *pos, int s, int *success, const int type) struct EncInfo *ei = first_ei(be, type); int p[TB_PIECES]; - std::size_t idx; + size_t idx; int t = 0; uint8_t flags = 0; // initialize to fix GCC warning @@ -2476,8 +2476,8 @@ static uint16_t probe_root(Pos *pos, int *score, unsigned *results) uint16_t moves0[MAX_MOVES]; uint16_t *moves = moves0; uint16_t *end = gen_moves(pos, moves); - std::size_t len = end - moves; - std::size_t num_draw = 0; + size_t len = end - moves; + size_t num_draw = 0; unsigned j = 0; for (unsigned i = 0; i < len; i++) { @@ -2571,7 +2571,7 @@ static uint16_t probe_root(Pos *pos, int *score, unsigned *results) // Select a "random" move that preserves the draw. // Uses calc_key as the PRNG. - std::size_t count = calc_key(pos, !pos->turn) % num_draw; + size_t count = calc_key(pos, !pos->turn) % num_draw; for (unsigned i = 0; i < len; i++) { int v = scores[i];