syzygy implementation

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

syzygy implementation

Post by Desperado »

Hello,

yesterday i managed to implement syzygy in quick and dirty way. As base i used the sources from https://github.com/jdart1/Fathom.

It wasn't simply to plug in with Visual Studio 2019. There are some settings to do for the project.
Especially for me, but that might be the same for others, i had to update the code base because of many duplicate names (e.g. Piece type values).
At the same time it was necessary to handle Visual Studio related compiler warnings (error level). So, all in all, i guess it was one or two hours of work until it compiled successfully. I am reporting this because there might be some people who want to know if it works with VS 2019. Yes, just put in some work into code-arrangement, compiler-warnings, naming issues.

Now one of my first questions is, what is the main difference compared to Ethereal/src/pyrrhic/ implementation content wise?

My second question related to the probing wdl call.

Code: Select all


        ...
        
        int pcnt = Bit::popcnt(Pos::occupied(pos));

        if(TB_LARGEST >= pcnt)
        {
            int result = tb_probe_wdl(
                pos->bb[WHITE],
                pos->bb[BLACK],
                Pos::kings(pos),
                Pos::queens(pos),
                Pos::rooks(pos),
                Pos::bishops(pos),
                Pos::knights(pos),
                Pos::pawns(pos),
                pos->r50,              /* R50 needs to be Zero otherwise the probing function will fail */
                pos->oo,
                pos->ep != INVALID_SQ ? pos->ep : 0,
                FlipColor(pos->stm));
                
                ....
         }
The probing function looks like that

Code: Select all

    static inline unsigned tb_probe_wdl(
        uint64_t _white,
        uint64_t _black,
        uint64_t _kings,
        uint64_t _queens,
        uint64_t _rooks,
        uint64_t _bishops,
        uint64_t _knights,
        uint64_t _pawns,
        unsigned _rule50,
        unsigned _castling,
        unsigned _ep,
        bool     _turn)
    {
        if(_castling != 0)
            return TB_RESULT_FAILED;
        if(_rule50 != 0)
            return TB_RESULT_FAILED;
        return tb_probe_wdl_impl(_white, _black, _kings, _queens, _rooks,
                                 _bishops, _knights, _pawns, _ep, _turn);
    }
Now TB_LARGEST will be set to 5 when you have installed the 5-Men.

What is the point to limit the probe when the 50 move counter is 0 (having a capture or pawn move) ?

That way, a position with 5-Men (no pawns, TB_LARGEST = 5) will never be tested, because a capture is required,
which then reduces the position to 4-Men setup. That can be hacked of course by using 0 instead of the 50 move counter.
So, what is the idea and must it be combined with TB_LARGEST = 6 to lookup 5-Men.
User avatar
MartinBryant
Posts: 69
Joined: Thu Nov 21, 2013 12:37 am
Location: Manchester, UK
Full name: Martin Bryant

Re: syzygy implementation

Post by MartinBryant »

Coincidentally I changed Colossus to use SYZYGY from Nalimov yesterday too... and I also use Visual Studio! What fun! But well worth it as they are sooooo much faster than Nalimov.

My understanding is that if you have <= 5 pieces at the root you are meant to use tb_probe_root as mentioned in his README.md
And if you have >= 6 pieces at the root you will probe the EGTBs after a capture with tb_probe_wdl and the 50-move counter will be zero.
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: syzygy implementation

Post by Desperado »

MartinBryant wrote: Sun May 23, 2021 10:28 am Coincidentally I changed Colossus to use SYZYGY from Nalimov yesterday too... and I also use Visual Studio! What fun! But well worth it as they are sooooo much faster than Nalimov.

My understanding is that if you have <= 5 pieces at the root you are meant to use tb_probe_root as mentioned in his README.md
And if you have >= 6 pieces at the root you will probe the EGTBs after a capture with tb_probe_wdl and the 50-move counter will be zero.
Hello Martin,

thx for your reply. Well, i am not talking about the root and i already understood that the 50-move counter will be zero after the capture or pawn move.
  • I would like to know why this is only done with a counter equal to zero?
The other point is, that the Variable TB_LARGEST is set to 5 in tb_init(const char*) (if you have installed 5-men)
If the counter needs to be 0, then a capture is required (e.g. KBBKN no pawns) which results in a 4 Men position (e.g. KBKN) that will be probed.
So, the database includes information (KBBKN) which will not be probed that way. Maybe there is an explanation,
otherwise it simply looks like a bug to me.
  • Either the variable TB_LARGEST must be 6, so that after a capture move a check for 5 pieces will be done or the condition that the counter must be 0 is omitted, then 5 pieces are also checked.
And what code base would you suggest and why ?
  • github.com/jdart1/Fathom
  • Ethereal/src/pyrrhic/
User avatar
MartinBryant
Posts: 69
Joined: Thu Nov 21, 2013 12:37 am
Location: Manchester, UK
Full name: Martin Bryant

Re: syzygy implementation

Post by MartinBryant »

Hmmm... apologies if I'm being thick on this grey Sunday morning but I don't see a problem.

Assuming you have >=6 pieces at the root, how could you arrive at a 5-piece position in the tree where the 50-move counter wasn't zero? As you would already have checked the EGTB some ply earlier immediately after the capture that took you down to 5 pieces where it was zero and you would have got the EGTB result and terminated the branch.
I suppose he just included the test as a sanity check because it shouldn't happen?
Of course you can just pass a zero into his function anyway but I don't see how you would ever call tb_probe_wdl when the 50-move counter wasn't zero.

The variable TB_LARGEST is just to be used to test whether you should query the EGTB...
if (pieceCountNow <= TB_LARGEST)
{
//Probe the EGTB
}
User avatar
MartinBryant
Posts: 69
Joined: Thu Nov 21, 2013 12:37 am
Location: Manchester, UK
Full name: Martin Bryant

Re: syzygy implementation

Post by MartinBryant »

P.S. I used the github codebase you linked to originally.
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: syzygy implementation

Post by Desperado »

MartinBryant wrote: Sun May 23, 2021 11:31 am ...

Assuming you have >=6 pieces at the root, how could you arrive at a 5-piece position in the tree where the 50-move counter wasn't zero?

...

I suppose he just included the test as a sanity check because it shouldn't happen?

...
Ok, i was confused, now it makes sense. Yesterday i put in FENs which were already 5-Men. (Without having probe_root() at that point, so indeed a sanity check). And because it is not the probe_root function (which has a different behaviour in this context), the probe in the inner tree will query 4-Men. And yes, normally you want to return from the search branch immediately.

Everything makes sense now, sorry for the confusion.

Thank you.
AndrewGrant
Posts: 1766
Joined: Tue Apr 19, 2016 6:08 am
Location: U.S.A
Full name: Andrew Grant

Re: syzygy implementation

Post by AndrewGrant »

Pyrrhic has all of the safety guards deleted, and has a slightly more efficient implementation of the mini-chess wrapper that powered Fathom. It also has a cleaner namespace.

However, it will crash if you send it bad stuff. It will crash if you swap white and black. It will crash if you don't give it your own bitboard generation functions. It will crash if you cannot define some bitutils for them.

I'de suggest using Fathom if you are just starting. Pyrrhic if you care to get some more speed and maybe save yourself some annoyance with inane #defines polluting the global namespace.
#WeAreAllDraude #JusticeForDraude #RememberDraude #LeptirBigUltra
"Those who can't do, clone instead" - Eduard ( A real life friend, not this forum's Eduard )
User avatar
Desperado
Posts: 879
Joined: Mon Dec 15, 2008 11:45 am

Re: syzygy implementation

Post by Desperado »

AndrewGrant wrote: Sun May 23, 2021 2:38 pm Pyrrhic has all of the safety guards deleted, and has a slightly more efficient implementation of the mini-chess wrapper that powered Fathom. It also has a cleaner namespace.

However, it will crash if you send it bad stuff. It will crash if you swap white and black. It will crash if you don't give it your own bitboard generation functions. It will crash if you cannot define some bitutils for them.

I'de suggest using Fathom if you are just starting. Pyrrhic if you care to get some more speed and maybe save yourself some annoyance with inane #defines polluting the global namespace.
Hallo Andrew,

thanks for your feedback too.

I think i have all the ressources available to use your solution. Speed is not an issue at the moment.
But it seems like there is no fundamental difference, so i can go with fathom. Maybe i will make my own lightweight version out of it at some point.