4 Commits

Author SHA1 Message Date
f8bb5c06e5 comment move_find_in_movelist() limitations 2024-07-10 07:51:29 +02:00
f52454903c cleanup 2024-07-10 07:50:31 +02:00
5401e83db8 Memory allocation: moved to alloc.[ch] 2024-07-10 07:49:44 +02:00
3100504fa2 Makefile: add 'build=' option 2024-07-10 07:47:02 +02:00
13 changed files with 139 additions and 80 deletions

1
.gitignore vendored
View File

@@ -20,3 +20,4 @@ perf.data
valgrind.out valgrind.out
gmon.out gmon.out
compile_commands.json compile_commands.json
.lastbuild

View File

@@ -12,16 +12,6 @@
SHELL := /bin/bash SHELL := /bin/bash
ifeq ($(CC),)
CC = gcc
endif
ifeq ($(CC),cc)
CC = gcc
endif
ifeq ($(BUILD),)
BUILD = dev
endif
BEAR := bear BEAR := bear
TOUCH := touch TOUCH := touch
RM := rm RM := rm
@@ -60,6 +50,38 @@ TARGET := $(addprefix $(BINDIR)/,$(TARGET_FN))
ASMFILES := $(SRC:.c=.s) $(TSTSRC:.c=.s) ASMFILES := $(SRC:.c=.s) $(TSTSRC:.c=.s)
CPPFILES := $(SRC:.c=.i) $(TSTSRC:.c=.i) CPPFILES := $(SRC:.c=.i) $(TSTSRC:.c=.i)
##################################### Check for compiler and requested build
BUILDS := release dev perf debug
# last compilation build
BUILDFILE := .lastbuild
lastbuild := $(file < $(BUILDFILE))
$(info last:$(lastbuild))
# default to gcc
CC ?= cc
ifeq ($(CC),cc)
CC = gcc
endif
# if no build specified, use last one
ifeq ($(build),)
build := $(lastbuild)
endif
# if build is still undefined, set a default
ifeq ($(build),)
build := release
endif
# check for valid build
ifeq ($(filter $(build),$(BUILDS)),)
$(error Error: Unknown build=`$(build)`. Possible builds are: $(BUILDS))
endif
# if new build, rewrite BUILDFILE
ifneq ($(build),$(lastbuild))
$(info New build:`$(build)` (was:$(lastbuild)))
$(file >$(BUILDFILE),$(build))
endif
##################################### set a version string ##################################### set a version string
# inspired from: # inspired from:
# https://eugene-babichenko.github.io/blog/2019/09/28/nightly-versions-makefiles/ # https://eugene-babichenko.github.io/blog/2019/09/28/nightly-versions-makefiles/
@@ -90,11 +112,13 @@ endif
##################################### pre-processor flags ##################################### pre-processor flags
CPPFLAGS := -I$(BRINCDIR) -I$(INCDIR) -DVERSION=\"$(VERSION)\" CPPFLAGS := -I$(BRINCDIR) -I$(INCDIR) -DVERSION=\"$(VERSION)\"
CPPFLAGS += -DDIAGRAM_SYM # UTF8 symbols in diagrams
ifeq ($(BUILD),release) ifeq ($(BUILD),release)
CPPFLAGS += -DNDEBUG # assert (unused) CPPFLAGS += -DNDEBUG # assert (unused)
else # ifeq ($(BUILD),dev) else # ifeq ($(BUILD),dev)
CPPFLAGS += -DWARN_ON # brlib bug.h CPPFLAGS += -DWARN_ON=1 # brlib bug.h
CPPFLAGS += -DBUG_ON # brlib bug.h CPPFLAGS += -DBUG_ON=1 # brlib bug.h
#CPPFLAGS += -DDEBUG # global - unused #CPPFLAGS += -DDEBUG # global - unused
#CPPFLAGS += -DDEBUG_DEBUG # enable log() functions #CPPFLAGS += -DDEBUG_DEBUG # enable log() functions
@@ -115,8 +139,6 @@ else # ifeq ($(BUILD),dev)
#CPPFLAGS += -DDEBUG_SEARCH # move search #CPPFLAGS += -DDEBUG_SEARCH # move search
endif endif
CPPFLAGS += -DDIAGRAM_SYM # UTF8 symbols in diagrams
# remove extraneous spaces (due to spaces before comments) # remove extraneous spaces (due to spaces before comments)
CPPFLAGS := $(strip $(CPPFLAGS)) CPPFLAGS := $(strip $(CPPFLAGS))
@@ -132,8 +154,8 @@ CFLAGS += -march=native
### dev OR release ### dev OR release
ifeq ($(BUILD),release) ifeq ($(BUILD),release)
CFLAGS += -O3 CFLAGS += -O3
CFLAGS += -g #CFLAGS += -g
CFLAGS += -ginline-points # inlined funcs debug info #CFLAGS += -ginline-points # inlined funcs debug info
CFLAGS += -funroll-loops CFLAGS += -funroll-loops
CFLAGS += -flto CFLAGS += -flto
else ifeq ($(BUILD),dev) else ifeq ($(BUILD),dev)
@@ -210,9 +232,9 @@ $(sort all $(MAKECMDGOALS)):
else else
##################################### General targets ##################################### General targets
.PHONY: all release dev perf debug compile clean cleanall .PHONY: all release dev perf debug compile libs clean cleanall
all: testing $(TARGET) all: libs testing $(TARGET)
release: release:
$(MAKE) BUILD=release clean all $(MAKE) BUILD=release clean all
@@ -314,7 +336,7 @@ cleanobjdir: cleanobj
# "normal" ones, but do not imply to rebuild target. # "normal" ones, but do not imply to rebuild target.
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) $(DEPDIR) $(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) $(DEPDIR)
@echo compiling brchess module: $< "->" $@. @echo compiling brchess module: $< "->" $@.
@$(CC) -c $(ALL_CFLAGS) $< -o $@ $(CC) -c $(ALL_CFLAGS) $< -o $@
##################################### brlib libraries ##################################### brlib libraries
.PHONY: cleanbrlib cleanallbrlib brlib .PHONY: cleanbrlib cleanallbrlib brlib
@@ -325,8 +347,10 @@ cleanbrlib:
cleanallbrlib: cleanallbrlib:
$(MAKE) -C $(BRLIB) cleanall $(MAKE) -C $(BRLIB) cleanall
export build
brlib: brlib:
$(MAKE) -C $(BRLIB) libs $(info calling with build=$(build))
$(MAKE) -e -C $(BRLIB) lib-static
##################################### brchess binaries ##################################### brchess binaries
.PHONY: targets cleanbin cleanbindir .PHONY: targets cleanbin cleanbindir
@@ -398,7 +422,7 @@ TEST += movedo-test perft-test tt-test
PIECE_OBJS := piece.o PIECE_OBJS := piece.o
FEN_OBJS := $(PIECE_OBJS) fen.o position.o bitboard.o board.o \ FEN_OBJS := $(PIECE_OBJS) fen.o position.o bitboard.o board.o \
hq.o attack.o hash.o init.o misc.o move.o hq.o attack.o hash.o init.o misc.o alloc.o move.o
BB_OBJS := $(FEN_OBJS) BB_OBJS := $(FEN_OBJS)
MOVEGEN_OBJS := $(BB_OBJS) move-gen.o MOVEGEN_OBJS := $(BB_OBJS) move-gen.o
ATTACK_OBJS := $(MOVEGEN_OBJS) ATTACK_OBJS := $(MOVEGEN_OBJS)

2
brlib

Submodule brlib updated: 553dc6bd07...a48ebf9099

51
src/alloc.c Normal file
View File

@@ -0,0 +1,51 @@
/* alloc.c - various memory allocation helpers
*
* Copyright (C) 2024 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <brlib.h>
#include "chessdefs.h"
#include "alloc.h"
/* force BUG_ON, to get a program abort for failed malloc/free
*/
#pragma push_macro("BUG_ON")
#undef BUG_ON
#define BUG_ON 1
#include <bug.h>
void *safe_alloc(size_t size)
{
void *mem = malloc(size);
bug_on(mem == NULL);
return mem;
}
void *safe_alloc_page_aligned(size_t size)
{
void *mem = malloc(size);
bug_on(mem == NULL);
return mem;
}
void safe_free(void *ptr)
{
bug_on(ptr == NULL);
free(ptr);
}
/* restore BUG_ON
*/
#pragma pop_macro("BUG_ON")

21
src/alloc.h Normal file
View File

@@ -0,0 +1,21 @@
/* alloc.h - various memory allocation helpers
*
* Copyright (C) 2024 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "chessdefs.h"
void *safe_alloc(size_t size);
void *safe_alloc_page_aligned(size_t size);
void safe_free(void *ptr);

View File

@@ -30,7 +30,7 @@ bitboard_t bb_line[64][64];
bitboard_t bb_knight[64], bb_king[64], bb_pawn_attacks[2][64]; bitboard_t bb_knight[64], bb_king[64], bb_pawn_attacks[2][64];
/* vectors are clockwise from N */ /* vectors are clockwise from N */
static int knight_vector[] = { static int knight_vector[8] = {
NORTH_EAST + NORTH, NORTH_EAST + EAST, NORTH_EAST + NORTH, NORTH_EAST + EAST,
SOUTH_EAST + EAST, SOUTH_EAST + SOUTH, SOUTH_EAST + EAST, SOUTH_EAST + SOUTH,
SOUTH_WEST + SOUTH, SOUTH_WEST + WEST, SOUTH_WEST + SOUTH, SOUTH_WEST + WEST,

View File

@@ -21,7 +21,7 @@
#include <bug.h> #include <bug.h>
#include "chessdefs.h" #include "chessdefs.h"
#include "misc.h" #include "alloc.h"
#include "position.h" #include "position.h"
#include "fen.h" #include "fen.h"
@@ -288,7 +288,7 @@ char *pos2fen(const pos_t *pos, char *fen)
int cur = 0; int cur = 0;
if (!fen) if (!fen)
fen = safe_malloc(92); fen = safe_alloc(92);
/* 1) position /* 1) position
*/ */

View File

@@ -18,7 +18,7 @@
#include <bitops.h> #include <bitops.h>
#include "chessdefs.h" #include "chessdefs.h"
#include "misc.h" #include "alloc.h"
#include "position.h" #include "position.h"
#include "piece.h" #include "piece.h"
#include "hash.h" #include "hash.h"
@@ -211,7 +211,7 @@ int tt_create(s32 sizemb)
hash_tt.mask = -1ull >> (64 - nbits); hash_tt.mask = -1ull >> (64 - nbits);
hash_tt.keys = safe_malloc(hash_tt.bytes); hash_tt.keys = safe_alloc(hash_tt.bytes);
//printf("bits=%2d size=%'15lu/%'6d Mb/%'14lu buckets ", //printf("bits=%2d size=%'15lu/%'6d Mb/%'14lu buckets ",
// hash_tt.nbits, hash_tt.bytes, hash_tt.mb, hash_tt.nbuckets); // hash_tt.nbits, hash_tt.bytes, hash_tt.mb, hash_tt.nbuckets);

View File

@@ -56,7 +56,6 @@ void hq_init()
for (int occ = 0; occ < 64; ++occ) { for (int occ = 0; occ < 64; ++occ) {
for (int file = 0; file < 8; ++file) { for (int file = 0; file < 8; ++file) {
int attacks = 0; int attacks = 0;
//int o = mask << 1; /* skip right square */
/* set f left attacks */ /* set f left attacks */
for (int slide = file - 1; slide >= 0; --slide) { for (int slide = file - 1; slide >= 0; --slide) {
@@ -70,17 +69,9 @@ void hq_init()
int b = bb_sq[slide]; int b = bb_sq[slide];
attacks |= b; attacks |= b;
if ((occ << 1) & b) /* piece on b, we stop */ if ((occ << 1) & b) /* piece on b, we stop */
//if ((o & b) == b)
break; break;
} }
bb_rank_attacks[(occ << 3) + file] = attacks; bb_rank_attacks[(occ << 3) + file] = attacks;
//if (((occ << 3) + file) == 171) {
//char str[64], str2[64];
//printf("mask=%x=%s file=%d att=%x=%s\n",
// occ, bitboard_rank_sprint(str, occ), file,
// attacks, bitboard_rank_sprint(str2, attacks));
//}
} }
} }
} }
@@ -100,12 +91,6 @@ bitboard_t hq_rank_moves(bitboard_t occ, square_t sq)
u32 rank = sq & SQ_RANKMASK; u32 rank = sq & SQ_RANKMASK;
u32 file = sq & SQ_FILEMASK; u32 file = sq & SQ_FILEMASK;
u64 o = (occ >> rank) & 0176; /* 01111110 clear bits 0 & 7 */ u64 o = (occ >> rank) & 0176; /* 01111110 clear bits 0 & 7 */
//char zob[128], zob2[128];
//printf("rank_moves: occ=%lx=%s file=%d o=%lx=%s index=%ld=%ld attack=%lx=%s\n", occ,
// bitboard_rank_sprint(zob, occ), file, o,
// bitboard_rank_sprint(zob, o), (o << 2) + file, (o * 4) + file,
// (bitboard_t)bb_rank_attacks[(o << 2) + file] << rank,
// bitboard_rank_sprint(zob2, (bitboard_t)bb_rank_attacks[(o << 2) + file] << rank));
return ((bitboard_t)bb_rank_attacks[(o << 2) + file]) << rank; return ((bitboard_t)bb_rank_attacks[(o << 2) + file]) << rank;
} }

View File

@@ -14,34 +14,5 @@
#ifndef _UTIL_H #ifndef _UTIL_H
#define _UTIL_H #define _UTIL_H
#include <stdio.h>
#include <stdlib.h>
#include "chessdefs.h"
#undef safe_malloc
#undef safe_free
/* force BUG_ON, to get a program abort for failed malloc/free
*/
#pragma push_macro("BUG_ON")
#undef BUG_ON
#define BUG_ON
#include <bug.h>
#define safe_malloc(size) ({ \
void *_ret = malloc(size); \
bug_on(_ret == NULL); \
_ret; \
})
#define safe_free(ptr) do { \
bug_on(ptr == NULL); \
free(ptr); \
} while (0)
/* restore BUG_ON
*/
#pragma pop_macro("BUG_ON")
#endif /* UTIL_H */ #endif /* UTIL_H */

View File

@@ -165,9 +165,14 @@ move_t move_find_in_movelist(move_t target, movelist_t *list)
move_t *move = list->move, *last = move + list->nmoves; move_t *move = list->move, *last = move + list->nmoves;
for (; move < last; ++move) { for (; move < last; ++move) {
if (move_from(target) == move_from(*move) && /* note that we compare promoted piece without checking if the move
move_to(target) == move_to(*move) && * is a promotion. But, in our move representation "promoted Knight"
move_promoted(target) == move_promoted(*move)) * is encoded as zero, same as when there is no promotion. This can
* lead to false match is @target or some @list moves are invalid,
* which we do not consider.
*/
if (move_fromto(target) == move_fromto(*move) &&
move_promoted(target) == move_promoted(*move))
return *move; return *move;
} }
return MOVE_NONE; return MOVE_NONE;
@@ -205,12 +210,13 @@ static int _moves_cmp_bysquare(const void *p1, const void *p2)
square_t t2 = move_to(m2); square_t t2 = move_to(m2);
piece_type_t prom1 = move_promoted(m1); piece_type_t prom1 = move_promoted(m1);
piece_type_t prom2 = move_promoted(m2); piece_type_t prom2 = move_promoted(m2);
/* We compare origin square first */
if (f1 < f2) return -1; if (f1 < f2) return -1;
if (f1 > f2) return 1; if (f1 > f2) return 1;
/* f1 == f2 */ /* f1 == f2, we compare destination squares */
if (t1 < t2) return -1; if (t1 < t2) return -1;
if (t1 > t2) return 1; if (t1 > t2) return 1;
/* t1 == t2 */ /* t1 == t2, we compare promoted piece */
if (prom1 < prom2) return -1; if (prom1 < prom2) return -1;
if (prom1 > prom2) return 1; if (prom1 > prom2) return 1;
return 0; return 0;

View File

@@ -76,7 +76,7 @@ static inline square_t move_to(move_t move)
return (move >> M_OFF_TO) & 077; return (move >> M_OFF_TO) & 077;
} }
static inline square_t move_fromto(move_t move) static inline move_t move_fromto(move_t move)
{ {
return move & 07777; return move & 07777;
} }

View File

@@ -27,7 +27,7 @@
#include "hq.h" #include "hq.h"
#include "fen.h" #include "fen.h"
#include "piece.h" #include "piece.h"
#include "misc.h" #include "alloc.h"
#include "board.h" #include "board.h"
#include "attack.h" #include "attack.h"
#include "hist.h" #include "hist.h"
@@ -42,7 +42,7 @@
*/ */
pos_t *pos_new(void) pos_t *pos_new(void)
{ {
return safe_malloc(sizeof(pos_t)); return safe_alloc(sizeof(pos_t));
} }
/** /**
@@ -57,7 +57,7 @@ pos_t *pos_new(void)
*/ */
pos_t *pos_dup(const pos_t *pos) pos_t *pos_dup(const pos_t *pos)
{ {
pos_t *newpos = safe_malloc(sizeof(pos_t)); pos_t *newpos = safe_alloc(sizeof(pos_t));
*newpos = *pos; *newpos = *pos;
return newpos; return newpos;