Skip to content

Commit

Permalink
Merge branch 'main' into l1-1536
Browse files Browse the repository at this point in the history
  • Loading branch information
jhonnold committed Dec 2, 2024
2 parents 78cd2c2 + 8a6282e commit dba2267
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 47 deletions.
22 changes: 18 additions & 4 deletions src/history.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void UpdateHistories(SearchStack* ss,
// Only increase the best move history when it
// wasn't trivial. This idea was first thought of
// by Alayan in Ethereal
if (nQ > 1 || depth > 3) {
if (nQ > 1 || depth > 4) {
AddHistoryHeuristic(&HH(stm, bestMove, board->threatened), inc);
UpdateCH(ss, bestMove, inc);
}
Expand Down Expand Up @@ -87,9 +87,23 @@ void UpdateHistories(SearchStack* ss,
}
}

void UpdatePawnCorrection(int raw, int real, Board* board, ThreadData* thread) {
const int16_t correction = Min(30000, Max(-30000, (real - raw) * PAWN_CORRECTION_GRAIN));
void UpdatePawnCorrection(int raw, int real, int depth, Board* board, ThreadData* thread) {
const int16_t correction = Min(30000, Max(-30000, (real - raw) * CORRECTION_GRAIN));
const int idx = (board->pawnZobrist & PAWN_CORRECTION_MASK);
const int saveDepth = Min(16, depth);

thread->pawnCorrection[idx] = (thread->pawnCorrection[idx] * 255 + correction) / 256;
thread->pawnCorrection[idx] = (thread->pawnCorrection[idx] * (256 - saveDepth) + correction * saveDepth) / 256;
}

void UpdateContCorrection(int raw, int real, int depth, SearchStack* ss, ThreadData* thread) {
const Move m1 = (ss - 1)->move;
const Move m2 = (ss - 2)->move;

if (m1 && m2) {
const int16_t correction = Min(30000, Max(-30000, (real - raw) * CORRECTION_GRAIN));
const int saveDepth = Min(16, depth);

int16_t* contCorrection = &thread->contCorrection[Moving(m1)][To(m1)][Moving(m2)][To(m2)];
*contCorrection = (*contCorrection * (256 - saveDepth) + correction * saveDepth) / 256;
}
}
18 changes: 15 additions & 3 deletions src/history.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ INLINE void AddCounterMove(ThreadData* thread, Move move, Move parent) {
}

INLINE int16_t HistoryBonus(int depth) {
return Min(1896, 4 * depth * depth + 120 * depth - 120);
return Min(1729, 4 * depth * depth + 164 * depth - 113);
}

INLINE void AddHistoryHeuristic(int16_t* entry, int16_t inc) {
Expand All @@ -77,7 +77,18 @@ INLINE void UpdateCH(SearchStack* ss, Move move, int16_t bonus) {
}

INLINE int GetPawnCorrection(Board* board, ThreadData* thread) {
return thread->pawnCorrection[board->pawnZobrist & PAWN_CORRECTION_MASK] / PAWN_CORRECTION_GRAIN;
return thread->pawnCorrection[board->pawnZobrist & PAWN_CORRECTION_MASK] / CORRECTION_GRAIN;
}

INLINE int GetContCorrection(SearchStack* ss, ThreadData* thread) {
const Move m1 = (ss - 1)->move;
const Move m2 = (ss - 2)->move;

if (m1 && m2) {
return thread->contCorrection[Moving(m1)][To(m1)][Moving(m2)][To(m2)] / CORRECTION_GRAIN;
} else {
return 0;
}
}

void UpdateHistories(SearchStack* ss,
Expand All @@ -89,6 +100,7 @@ void UpdateHistories(SearchStack* ss,
Move captures[],
int nC);

void UpdatePawnCorrection(int raw, int real, Board* board, ThreadData* thread);
void UpdatePawnCorrection(int raw, int real, int depth, Board* board, ThreadData* thread);
void UpdateContCorrection(int raw, int real, int depth, SearchStack* ss, ThreadData* thread);

#endif
9 changes: 6 additions & 3 deletions src/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ EXE = berserk
SRC = attacks.c bench.c berserk.c bits.c board.c eval.c history.c move.c movegen.c movepick.c perft.c random.c \
search.c see.c tb.c thread.c transposition.c uci.c util.c zobrist.c nn/accumulator.c nn/evaluate.c pyrrhic/tbprobe.c
CC = clang
VERSION = 20240318
MAIN_NETWORK = berserk-1794ba44a3ac.nn
VERSION = 20241119
MAIN_NETWORK = berserk-d43206fe90e4.nn
EVALFILE = $(MAIN_NETWORK)
DEFS = -DVERSION=\"$(VERSION)\" -DEVALFILE=\"$(EVALFILE)\" -DNDEBUG

Expand Down Expand Up @@ -114,18 +114,21 @@ download-network:
echo "Downloaded network $(EVALFILE) and verified"; \
else \
echo "Downloaded network $(EVALFILE) failed validation"; \
exit 1; \
fi; \
elif hash sha256sum 2>/dev/null; then \
if [ "$(EVALFILE)" = "berserk-"`sha256sum $(EVALFILE) | cut -c1-12`".nn" ]; then \
echo "Downloaded network $(EVALFILE) and verified"; \
else \
echo "Downloaded network $(EVALFILE) failed validation"; \
exit 1; \
fi; \
else \
echo "Downloaded network $(EVALFILE), but unable to verify"; \
fi; \
else \
echo "Unable to downlaod network: $(EVALFILE)"; \
echo "Unable to download network: $(EVALFILE)"; \
exit 1; \
fi; \
elif test -f "$(EVALFILE)"; then \
echo "Using network: $(EVALFILE)"; \
Expand Down
66 changes: 35 additions & 31 deletions src/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,19 @@ int STATIC_PRUNE[2][MAX_SEARCH_PLY];
void InitPruningAndReductionTables() {
for (int depth = 1; depth < MAX_SEARCH_PLY; depth++)
for (int moves = 1; moves < 64; moves++)
LMR[depth][moves] = log(depth) * log(moves) / 2.1872 + 0.2487;
LMR[depth][moves] = log(depth) * log(moves) / 2.0385 + 0.2429;

LMR[0][0] = LMR[0][1] = LMR[1][0] = 0;

for (int depth = 0; depth < MAX_SEARCH_PLY; depth++) {
// LMP has both a improving (more strict) and non-improving evalution
// parameter for lmp. If the evaluation is getting better we want to check
// more
LMP[0][depth] = 1.2973 + 0.3772 * depth * depth;
LMP[1][depth] = 2.7002 + 0.9448 * depth * depth;
LMP[0][depth] = 1.3050 + 0.3503 * depth * depth;
LMP[1][depth] = 2.1885 + 0.9911 * depth * depth;

STATIC_PRUNE[0][depth] = -14.9419 * depth * depth; // quiet move cutoff
STATIC_PRUNE[1][depth] = -103.9379 * depth; // capture cutoff
STATIC_PRUNE[0][depth] = -15.2703 * depth * depth; // quiet move cutoff
STATIC_PRUNE[1][depth] = -94.0617 * depth; // capture cutoff
}
}

Expand Down Expand Up @@ -299,7 +299,7 @@ void Search(ThreadData* thread) {
break;

// delta x 1.25
delta += delta / 4;
delta += 17 * delta / 64;
}

SortRootMoves(thread, 0);
Expand All @@ -326,7 +326,7 @@ void Search(ThreadData* thread) {
if (Limits.timeset && thread->depth >= 5 && !Threads.stopOnPonderHit) {
int sameBestMove = bestMove == previousBestMove; // same move?
searchStability = sameBestMove ? Min(10, searchStability + 1) : 0; // increase how stable our best move is
double stabilityFactor = 1.3658 - 0.0482 * searchStability;
double stabilityFactor = 1.3110 - 0.0533 * searchStability;

Score searchScoreDiff = scores[thread->depth - 3] - bestScore;
Score prevScoreDiff = thread->previousScore - bestScore;
Expand All @@ -335,14 +335,14 @@ void Search(ThreadData* thread) {
if (thread->previousScore == UNKNOWN)
searchScoreDiff *= 2, prevScoreDiff = 0;

double scoreChangeFactor = 0.0995 + //
0.0286 * searchScoreDiff * (searchScoreDiff > 0) + //
double scoreChangeFactor = 0.1127 + //
0.0262 * searchScoreDiff * (searchScoreDiff > 0) + //
0.0261 * prevScoreDiff * (prevScoreDiff > 0);
scoreChangeFactor = Max(0.4843, Min(1.4498, scoreChangeFactor));
scoreChangeFactor = Max(0.5028, Min(1.6561, scoreChangeFactor));

uint64_t bestMoveNodes = thread->rootMoves[0].nodes;
double pctNodesNotBest = 1.0 - (double) bestMoveNodes / thread->nodes;
double nodeCountFactor = Max(0.5464, pctNodesNotBest * 2.1394 + 0.4393);
double nodeCountFactor = Max(0.5630, pctNodesNotBest * 2.2669 + 0.4499);
if (bestScore >= TB_WIN_BOUND)
nodeCountFactor = 0.5;

Expand Down Expand Up @@ -468,7 +468,7 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*
rawEval = ttEval;
if (rawEval == EVAL_UNKNOWN)
rawEval = Evaluate(board, thread);
eval = ss->staticEval = ClampEval(rawEval + GetPawnCorrection(board, thread) / 2);
eval = ss->staticEval = ClampEval(rawEval + GetPawnCorrection(board, thread) / 2 + GetContCorrection(ss, thread));

// correct eval on fmr
eval = AdjustEvalOnFMR(board, eval);
Expand All @@ -477,7 +477,7 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*
eval = ttScore;
} else if (!ss->skip) {
rawEval = Evaluate(board, thread);
eval = ss->staticEval = ClampEval(rawEval + GetPawnCorrection(board, thread) / 2);
eval = ss->staticEval = ClampEval(rawEval + GetPawnCorrection(board, thread) / 2 + GetContCorrection(ss, thread));

// correct eval on fmr
eval = AdjustEvalOnFMR(board, eval);
Expand Down Expand Up @@ -511,16 +511,17 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*
MovePicker mp;
if (!isPV && !inCheck) {
const int opponentHasEasyCapture = !!OpponentsEasyCaptures(board);
const int opponentDeclining = ss->staticEval + (ss - 1)->staticEval > 1;

// Reverse Futility Pruning
// i.e. the static eval is so far above beta we prune
if (depth <= 8 && !ss->skip && eval < TB_WIN_BOUND && eval >= beta &&
eval - 67 * depth + 112 * (improving && !opponentHasEasyCapture) >= beta &&
(!hashMove || GetHistory(ss, thread, hashMove) > 12525))
if (depth <= 9 && !ss->skip && eval < TB_WIN_BOUND && eval >= beta &&
eval - 70 * depth + 118 * (improving && !opponentHasEasyCapture) + 25 * opponentDeclining >= beta &&
(!hashMove || GetHistory(ss, thread, hashMove) > 11800))
return (eval + beta) / 2;

// Razoring
if (depth <= 6 && eval + 252 * depth <= alpha) {
if (depth <= 5 && eval + 214 * depth <= alpha) {
score = Quiesce(alpha, beta, 0, thread, ss);
if (score <= alpha)
return score;
Expand All @@ -532,7 +533,7 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*
// threats)
if (depth >= 4 && (ss - 1)->move != NULL_MOVE && !ss->skip && !opponentHasEasyCapture && eval >= beta &&
HasNonPawn(board, board->stm) && (ss->ply >= thread->nmpMinPly || board->stm != thread->npmColor)) {
int R = 4 + 342 * depth / 1024 + Min(10 * (eval - beta) / 1024, 4);
int R = 4 + 385 * depth / 1024 + Min(10 * (eval - beta) / 1024, 4);

TTPrefetch(KeyAfter(board, NULL_MOVE));
ss->move = NULL_MOVE;
Expand Down Expand Up @@ -565,8 +566,8 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*
// Prob cut
// If a relatively deep search from our TT doesn't say this node is
// less than beta + margin, then we run a shallow search to look
int probBeta = beta + 197;
if (depth >= 5 && !ss->skip && abs(beta) < TB_WIN_BOUND && !(ttHit && ttDepth >= depth - 3 && ttScore < probBeta)) {
int probBeta = beta + 172;
if (depth >= 6 && !ss->skip && abs(beta) < TB_WIN_BOUND && !(ttHit && ttDepth >= depth - 3 && ttScore < probBeta)) {
InitPCMovePicker(&mp, thread, probBeta > eval);
while ((move = NextMove(&mp, board, 1))) {
if (!IsLegal(move, board))
Expand Down Expand Up @@ -625,12 +626,12 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*
if (!IsCap(move) && PromoPT(move) != QUEEN) {
int lmrDepth = Max(1, depth - R);

if (!killerOrCounter && lmrDepth < 7 && history < -2658 * (depth - 1)) {
if (!killerOrCounter && lmrDepth < 5 && history < -2788 * (depth - 1)) {
skipQuiets = 1;
continue;
}

if (!inCheck && lmrDepth < 10 && eval + 87 + 46 * lmrDepth <= alpha)
if (!inCheck && lmrDepth < 10 && eval + 81 + 46 * lmrDepth <= alpha)
skipQuiets = 1;

if (!SEE(board, move, STATIC_PRUNE[0][lmrDepth]))
Expand Down Expand Up @@ -673,10 +674,10 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*

// no score failed above sBeta, so this is singular
if (score < sBeta) {
if (!isPV && score < sBeta - 50 && ss->de <= 6 && !IsCap(move)) {
if (!isPV && score < sBeta - 48 && ss->de <= 6 && !IsCap(move)) {
extension = 3;
ss->de = (ss - 1)->de + 1;
} else if (!isPV && score < sBeta - 17 && ss->de <= 6) {
} else if (!isPV && score < sBeta - 14 && ss->de <= 6) {
extension = 2;
ss->de = (ss - 1)->de + 1;
} else {
Expand Down Expand Up @@ -738,7 +739,7 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*
if (score > alpha && R > 1) {
// Credit to Viz (and lonfom) for the following modification of the zws
// re-search depth. They can be found in SF as doDeeperSearch + doShallowerSearch
newDepth += (score > bestScore + 76);
newDepth += (score > bestScore + 69);
newDepth -= (score < bestScore + newDepth);

if (newDepth - 1 > lmrDepth)
Expand Down Expand Up @@ -798,7 +799,7 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*

// we're failing high
if (alpha >= beta) {
UpdateHistories(ss, thread, move, depth + (bestScore > beta + 78), quiets, numQuiets, captures, numCaptures);
UpdateHistories(ss, thread, move, depth + (bestScore > beta + 77), quiets, numQuiets, captures, numCaptures);
break;
}
}
Expand All @@ -816,8 +817,10 @@ int Negamax(int alpha, int beta, int depth, int cutnode, ThreadData* thread, PV*
if (!ss->skip && !(isRoot && thread->multiPV > 0))
TTPut(tt, board->zobrist, depth, bestScore, bound, bestMove, ss->ply, rawEval, ttPv);

if (!inCheck && !IsCap(bestMove) && (bound & (bestScore >= rawEval ? BOUND_LOWER : BOUND_UPPER)))
UpdatePawnCorrection(rawEval, bestScore, board, thread);
if (!inCheck && !IsCap(bestMove) && (bound & (bestScore >= rawEval ? BOUND_LOWER : BOUND_UPPER))) {
UpdatePawnCorrection(rawEval, bestScore, depth, board, thread);
UpdateContCorrection(rawEval, bestScore, depth, ss, thread);
}

return bestScore;
}
Expand Down Expand Up @@ -872,7 +875,7 @@ int Quiesce(int alpha, int beta, int depth, ThreadData* thread, SearchStack* ss)
rawEval = ttEval;
if (rawEval == EVAL_UNKNOWN)
rawEval = Evaluate(board, thread);
eval = ss->staticEval = ClampEval(rawEval + GetPawnCorrection(board, thread) / 2);
eval = ss->staticEval = ClampEval(rawEval + GetPawnCorrection(board, thread) / 2 + GetContCorrection(ss, thread));

// correct eval on fmr
eval = AdjustEvalOnFMR(board, eval);
Expand All @@ -881,7 +884,7 @@ int Quiesce(int alpha, int beta, int depth, ThreadData* thread, SearchStack* ss)
eval = ttScore;
} else {
rawEval = Evaluate(board, thread);
eval = ss->staticEval = ClampEval(rawEval + GetPawnCorrection(board, thread) / 2);
eval = ss->staticEval = ClampEval(rawEval + GetPawnCorrection(board, thread) / 2 + GetContCorrection(ss, thread));

// correct eval on fmr
eval = AdjustEvalOnFMR(board, eval);
Expand All @@ -898,7 +901,7 @@ int Quiesce(int alpha, int beta, int depth, ThreadData* thread, SearchStack* ss)

bestScore = eval;

futility = bestScore + 60;
futility = bestScore + 63;
}

int numQuiets = 0, numCaptures = 0;
Expand Down Expand Up @@ -1065,6 +1068,7 @@ void SearchClearThread(ThreadData* thread) {
memset(&thread->ch, 0, sizeof(thread->ch));
memset(&thread->caph, 0, sizeof(thread->caph));
memset(&thread->pawnCorrection, 0, sizeof(thread->pawnCorrection));
memset(&thread->contCorrection, 0, sizeof(thread->contCorrection));

thread->board.accumulators = thread->accumulators;
thread->previousScore = UNKNOWN;
Expand Down
4 changes: 3 additions & 1 deletion src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
#define ALIGN_ON 64
#define ALIGN __attribute__((aligned(ALIGN_ON)))

#define PAWN_CORRECTION_GRAIN 256
#define CORRECTION_GRAIN 256

#define PAWN_CORRECTION_SIZE 131072
#define PAWN_CORRECTION_MASK (PAWN_CORRECTION_SIZE - 1)

Expand Down Expand Up @@ -198,6 +199,7 @@ struct ThreadData {
int16_t caph[12][64][2][7]; // capture history (piece - to - defeneded - captured_type)

int16_t pawnCorrection[PAWN_CORRECTION_SIZE];
int16_t contCorrection[12][64][12][64];

int action, calls;
pthread_t nativeThread;
Expand Down
8 changes: 4 additions & 4 deletions src/uci.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ SearchParams Limits;
// this repo: https://github.com/vondele/WLD_model

// Third order polynomial fit of Berserk data
const double as[4] = {-5.83465749, 46.43599644, -58.49798392, 172.62328616};
const double bs[4] = {-7.95320845, 48.50833438, -66.34647240, 56.29169197};
const double as[4] = {-2.02923586, 16.87641200, -27.06230207, 182.53858835};
const double bs[4] = {-6.15230497, 42.37548361, -80.19006222, 77.75994970};

// win% as permilli given score and ply
int WRModel(Score s, int ply) {
Expand Down Expand Up @@ -178,8 +178,8 @@ void ParseGo(char* in, Board* board) {
if (movesToGo == -1) {
int total = Max(1, time + 50 * inc - 50 * MOVE_OVERHEAD);

Limits.alloc = Min(time * 0.3784, total * 0.0570);
Limits.max = Min(time * 0.7776 - MOVE_OVERHEAD, Limits.alloc * 5.8320) - 10;
Limits.alloc = Min(time * 0.4193, total * 0.0575);
Limits.max = Min(time * 0.9221 - MOVE_OVERHEAD, Limits.alloc * 5.9280) - 10;
} else {
int total = Max(1, time + movesToGo * inc - MOVE_OVERHEAD);

Expand Down
2 changes: 1 addition & 1 deletion src/uci.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ extern int CONTEMPT;
extern SearchParams Limits;

// Normalization of a score to 50% WR at 100cp
#define Normalize(s) ((s) / 1.54)
#define Normalize(s) ((s) / 1.70)

int WRModel(Score s, int ply);

Expand Down

0 comments on commit dba2267

Please sign in to comment.