What move to pick from aborted search?

Discussion of chess software programming and technical issues.

Moderator: Ras

thomasahle
Posts: 94
Joined: Thu Feb 27, 2014 8:19 pm

What move to pick from aborted search?

Post by thomasahle »

Is it better to return the last move that was fully searched, or the most recent, but perhaps not accurate current move?

In sunfish the main iterative deepening loop looks something like this:

Code: Select all

        gamma = 0
        for depth in range(1, 1000):
            # Inv: lower <= score <= upper
            lower, upper = -MATE_LOWER, MATE_LOWER
            while lower < upper:
                score = self.bound(pos, gamma, depth)
                if score >= gamma:
                    lower = score
                if score < gamma:
                    upper = score
                # Option 2: Yield inside binary search
                yield depth, self.tt_move.get(pos), score
                gamma = (lower + upper + 1) // 2
            # Option 1: Yield after depth completed
            yield depth, self.tt_move.get(pos), gamma
This is MTD-bi / SSS / C*, but I think a similar "double loop" structure is usually present in PV-search with Aspiration Windows.

The dictionary self.tt_move is the last move that failed-high at the root position.
(Let's assume for now that this was not overwritten by anything other than the outermost call to bound.)

The question is: If I run out of time in the inner loop, it means that I haven't finished searching the given depth, but only have an upper and lower bound on the score.
I could thus fall back to returning what was the best move after fully searching the previous depth (Option 2), or I could pick whatever is the tt_move when I run out of time.

Option 2 will produce a move that has been searched to a greater depth, but Option 1 will produce a move that didn't just randomly fail high because gamma was set way too low.

I'm tempted to use Option 1 because it seems safer. But in testing Option 2 was much stronger.

I've also considered counting how many codes each move has actually visited, trying to mimic Leela's search.
I couldn't find any discussion of this in the MTD paper or on the chess programming wiki.
Has anyone put more thought into it?
What do people use with Aspiration Windows?
User avatar
Ras
Posts: 2696
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: What move to pick from aborted search?

Post by Ras »

thomasahle wrote: Sat Dec 31, 2022 1:56 pmIs it better to return the last move that was fully searched, or the most recent, but perhaps not accurate current move?
You can sort your root moves by putting the best move from the previous iteration to the top if it isn't already there and shifting down the others by one. That ensures that with an incomplete search where you get a different best move, this must be better than the one from the previous iteration because that has been searched first.
Rasmus Althoff
https://www.ct800.net
thomasahle
Posts: 94
Joined: Thu Feb 27, 2014 8:19 pm

Re: What move to pick from aborted search?

Post by thomasahle »

Great point! And this is just normal TT move sorting.
syzygy
Posts: 5695
Joined: Tue Feb 28, 2012 11:56 pm

Re: What move to pick from aborted search?

Post by syzygy »

thomasahle wrote: Sat Dec 31, 2022 1:56 pm Is it better to return the last move that was fully searched, or the most recent, but perhaps not accurate current move?
I understand from the rest of your post that you are searching all root moves simultaneously, and you are faced with the choice between the best move from the previous full iteration and the move that is now the best move according to the hash table.

If you make sure that the search of the root node only replaces the tt move for the root position if the old tt move did not fail high but the new tt move does, then it should be safe (and better) to play the new tt move.

If a zero-window search of the root fails low, I assume the tt move is not replaced. (Doing otherwise is a bug.)
What do people use with Aspiration Windows?
Typically you have a current best move which you search first as a PV node, and you search the rest with a zero-window search as a non-PV node. A move that fails high should typically not be played before a PV-research confirms that it is the new best move, because PV nodes are searched with more extensions/less reductions.

With MTD there are no PV nodes, so the siutation is different.