Debugging a transposition table

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
Ronald
Posts: 160
Joined: Tue Jan 23, 2018 10:18 am
Location: Rotterdam
Full name: Ronald Friederich

Re: Debugging a transposition table

Post by Ronald »

I did another test by also disabling the return score after a hashhit. When i disable it then my output looks a lot like your current output.

So maybe you should check if you really have returns in your search:

Code: Select all

   if (h.depth >= depth && !PV) {
            if (h.bound == tt::LOWER && score >= beta) return score;
            if (h.bound == tt::UPPER && score <= alpha) return score;
            if (h.bound == tt::EXACT) return score;
        }
Does the !PV work correctly?
Joost Buijs
Posts: 1563
Joined: Thu Jul 16, 2009 10:47 am
Location: Almere, The Netherlands

Re: Debugging a transposition table

Post by Joost Buijs »

Repetition detection has a big influence on this type of positions as well, when I turn this off it clearly takes more time before my engine finds the correct move, so it may be that there is something wrong with that. The engine that I'm testing this with has besides the TT move and history heuristic nothing else, no extra pruning (only a >= b) and no LMR, basically a clean search without any extra's. I can turn the history heuristic off as well, but I don't think this will make a significant difference.
konsolas
Posts: 182
Joined: Sun Jun 12, 2016 5:44 pm
Location: London
Full name: Vincent

Re: Debugging a transposition table

Post by konsolas »

Ronald wrote: Fri Jun 01, 2018 1:36 pm I did another test by also disabling the return score after a hashhit. When i disable it then my output looks a lot like your current output.

So maybe you should check if you really have returns in your search:

Code: Select all

   if (h.depth >= depth && !PV) {
            if (h.bound == tt::LOWER && score >= beta) return score;
            if (h.bound == tt::UPPER && score <= alpha) return score;
            if (h.bound == tt::EXACT) return score;
        }
Does the !PV work correctly?
This seems to be a good point; I'm only getting cuts on ~1.5% of the nodes which have a hash table entry when searching fine#70.
Could you find out your hash cut rate (i.e. number of hash cutoffs / number of hash hits)?

EDIT: It turns out that you're absolutely right: removing !PV means that my engine reaches the required depth in less than a second.
Now I suppose I need to figure out where I'm setting PV to true incorrectly. Thank you for your help!
Joost Buijs
Posts: 1563
Joined: Thu Jul 16, 2009 10:47 am
Location: Almere, The Netherlands

Re: Debugging a transposition table

Post by Joost Buijs »

I don't see any reason why you should not use the TT in the PV, maybe because stockfish does it this way, but that doesn't mean it is a necessity.
User avatar
Ronald
Posts: 160
Joined: Tue Jan 23, 2018 10:18 am
Location: Rotterdam
Full name: Ronald Friederich

Re: Debugging a transposition table

Post by Ronald »

Great that was the problem. After you found out why PV node was not set correctly, you should test if you want to use it in the hashtest at all, like Joost says. If you retrieve your PV from the hash, you might get a longer PV when not using the hash in pv nodes, I understand that is why some engines are doing it, but it doesn't seem logic to not use it, you want to try to finish your search as fast as possible. My engine performs better if I use the hash in pv nodes also.
konsolas
Posts: 182
Joined: Sun Jun 12, 2016 5:44 pm
Location: London
Full name: Vincent

Re: Debugging a transposition table

Post by konsolas »

What's extremely weird is that, even though it's now reaching higher depths, my engine doesn't report a correct PV:

Code: Select all

info depth 34 score cp 168 time 2433 nodes 6199096 nps 2546000 hashfull 622364 hashhitrate 0.804551 hashcutrate 0.598365 mbf 1.92747 betacutoff 0.917953 pv a1b1 a7b7 b1c2 b7b8 c2d3 b8c7 d3c4 c7b6 c4d3 b6b7 d3c4 b7a6 c4d3 a6b6 d3c4 b6a6 c4d3 a6b6 d3e3 b6c7 e3f3 c7d7 f3g3 d7e7 g3h4 e7f6 h4h5 f6f7 h5h6 f7f6 h6h7 f6f7 h7h8 f7f6
It gets the third move wrong, b1c2 instead of b1c1, resulting in a draw when I put it in a game.
Joost Buijs
Posts: 1563
Joined: Thu Jul 16, 2009 10:47 am
Location: Almere, The Netherlands

Re: Debugging a transposition table

Post by Joost Buijs »

Indeed, for analysis it is a bit cumbersome these truncated PV's but for gameplay it scores somewhat better, at least for my engine is this the case. The nicest is to store the PV separately, or to use a small 2nd hash table for the PV only (I think Crafty does this).
Joost Buijs
Posts: 1563
Joined: Thu Jul 16, 2009 10:47 am
Location: Almere, The Netherlands

Re: Debugging a transposition table

Post by Joost Buijs »

konsolas wrote: Fri Jun 01, 2018 2:49 pm What's extremely weird is that, even though it's now reaching higher depths, my engine doesn't report a correct PV:

Code: Select all

info depth 34 score cp 168 time 2433 nodes 6199096 nps 2546000 hashfull 622364 hashhitrate 0.804551 hashcutrate 0.598365 mbf 1.92747 betacutoff 0.917953 pv a1b1 a7b7 b1c2 b7b8 c2d3 b8c7 d3c4 c7b6 c4d3 b6b7 d3c4 b7a6 c4d3 a6b6 d3c4 b6a6 c4d3 a6b6 d3e3 b6c7 e3f3 c7d7 f3g3 d7e7 g3h4 e7f6 h4h5 f6f7 h5h6 f7f6 h6h7 f6f7 h7h8 f7f6
It gets the third move wrong, b1c2 instead of b1c1, resulting in a draw when I put it in a game.
It could be a problem with repetition detection, when I disable this I get almost the same behaviour.
konsolas
Posts: 182
Joined: Sun Jun 12, 2016 5:44 pm
Location: London
Full name: Vincent

Re: Debugging a transposition table

Post by konsolas »

Joost Buijs wrote: Fri Jun 01, 2018 2:59 pm
konsolas wrote: Fri Jun 01, 2018 2:49 pm What's extremely weird is that, even though it's now reaching higher depths, my engine doesn't report a correct PV:

Code: Select all

info depth 34 score cp 168 time 2433 nodes 6199096 nps 2546000 hashfull 622364 hashhitrate 0.804551 hashcutrate 0.598365 mbf 1.92747 betacutoff 0.917953 pv a1b1 a7b7 b1c2 b7b8 c2d3 b8c7 d3c4 c7b6 c4d3 b6b7 d3c4 b7a6 c4d3 a6b6 d3c4 b6a6 c4d3 a6b6 d3e3 b6c7 e3f3 c7d7 f3g3 d7e7 g3h4 e7f6 h4h5 f6f7 h5h6 f7f6 h6h7 f6f7 h7h8 f7f6
It gets the third move wrong, b1c2 instead of b1c1, resulting in a draw when I put it in a game.
It could be a problem with repetition detection, when I disable this I get almost the same behaviour.
Right again; there was an integer underflow bug that prevented repetition detection from working.

Seems like there's one last issue in my transposition table which is correctly handling mate scores. Even after promoting, the mate scores seem to jump around randomly.
User avatar
Ronald
Posts: 160
Joined: Tue Jan 23, 2018 10:18 am
Location: Rotterdam
Full name: Ronald Friederich

Re: Debugging a transposition table

Post by Ronald »

Great again.!
I think your mating problem has to do with correcting the matescore when you put it into the hashtable (and when you get it out). In your source you don't do that will probably be the problem. When you get a matescore for your position you correct the matevalue with the ply you are in. If you store that value in the hash and retrieve it later at another plydepth you will not have the correct matevalue. The best thing to do is correct the matevalue with the current plydepth before storing it in the hash, and correct the value again after retrieving it from the hash.

When storing the hash entry I first do the following correction to the score sc

Code: Select all

void putHashTableEntry(U64 hk, moveStruct mv, eval sc, int8_t d, U8 n, U8 ply) {
    if (sc >= MINCHECKMATE) sc += ply;
    else if (sc <= -MINCHECKMATE) sc -= ply;
    ..
    
After retrieving the hash entry from hash I first make the following correction before using the entry:

Code: Select all

     if (hashEntry.score >= MINCHECKMATE) hashEntry.score -= ply;
        else if (hashEntry.score <= -MINCHECKMATE) hashEntry.score += ply;
   
MINCHECKMATE is the lowest possible value which is a checkmate:
MINCHECKMATE = CHECKMATEVALUE - MAXDEPTH