Endgame bitbases

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

Re: Endgame bitbases

Postby Joachim Rang » 16 Jul 2005, 11:27

Fabien Letouzey wrote:Hi Dann,
Dann Corbit wrote:This is a paper on tablebase compression that looks interesting:
http://www.daimi.au.dk/~doktoren/master_thesis/

Indeed, but could you send a compressed version to me? It must fit in a floppy disk ...

Thanks,

Fabien.


hm, I think a compression algorithm to get this on a floppy must be yet developed ;-) - at least I was not able to educe it enough with Acobat Distiller 7.0.

I made a rar-archive in two parts which should fit on two floppys:

http://iwanuschka.de/schutthalde/report.part1.rar

http://iwanuschka.de/schutthalde/report.part2.rar

regards Joachim
Joachim Rang
 
Posts: 69
Joined: 26 Sep 2004, 22:00

Re: Endgame bitbases

Postby Fabien Letouzey » 17 Jul 2005, 09:10

Hi Joachim,

Joachim Rang wrote:hm, I think a compression algorithm to get this on a floppy must be yet developed ;-) - at least I was not able to educe it enough with Acobat Distiller 7.0.


I assumed Dann would understand. PostScript is in fact a text language and therefore compresses very well with good tool (like bzip2). Nobody should ever make uncompressed PS available like he did ... Furthermore it's possible to remove unnecessary figures when needed.

Joachim Rang wrote:I made a rar-archive in two parts which should fit on two floppys:


Thanks, I got them.

Fabien.
Fabien Letouzey
 
Posts: 110
Joined: 03 Dec 2004, 10:17
Location: France

Re: Endgame bitbases

Postby Dann Corbit » 18 Jul 2005, 19:05

I was lazy to put the postscript pages on my site in that way.

Perhaps I shall compress them all so that download will be faster.

Sometimes I get complaints from people who do not understand the .gz or .bz2 extensions on compressed files (they only know about zip) but you can't please everybody.
Dann Corbit
 

Re: Endgame bitbases

Postby Dann Corbit » 18 Jul 2005, 19:16

I compressed the pdf and ps files that were not yet compressed.
Dann Corbit
 

Re: Endgame bitbases

Postby diepeveen » 21 Jul 2005, 16:11

Hello Allessandro,

Your idea gets used already for years in the Diep EGTBs. I'm not using zip. Far superior to Zip is Kadatch compressor, just ship him an email.

Most 6 men EGTBs Diep can compress to a factor 100-1000 smaller in this way. Extreme cases of 6 men give 5000 times reduction.

Prediction code you can also use in a SEARCH. That increases prediction rate CONSIDERABLE. The only disadvantage is that it takes real long to convert 6 men to compressed EGTBs.

Diep uses its own indexing format that needs a tad more entries than Nalimov does do.

4 men and 5 men really aren't very interesting. It's the 6 men that are interesting for this, not to mention the 7 men.

A single 7 man in Diep format can be hundreds of gigabytes uncompressed.

Generating EGTBs goes a LOT faster than rewriting them to a compressable format. The advantage of rewriting them is that you can do it even at small tiny systems and if i just look in this room i have about 9 cpu's to my avail in total.

Vincent

Alessandro Scotti wrote:Hi Dieter,
I don't use a special indexing scheme because there's so much going on at the moment that I can't possibly manage another level of complexity. Code is designed so that it can be put in at a later time though.
At some time Kiwi sources will be released under the GPL and I can't use EGTB probing code, so I must score positions (a la Heinz) and also embed my own bitbases in the engine, or at least make them as small a download as possible. That's why I'm interested in compression.
The method I'm using now is performing reasonably well in practice, but requires some work to be done for each bitbase. It takes three steps to compress a bitbase:
- a "predictor" function that predicts the outcome of each position;
- preliminary RLE compression (optional);
- ZIP compression.
Let me present an example with KBPK, strong side on move. In its raw form the bitbase would take 64*64*48*64 / 2 bits or 768K. Since KBP almost always win, actually 97.22% of those bits will have the same value (assuming invalid positions are properly set). This compress very well of course and actually zips to about 18K. I've found that in such cases adding a preliminary layer of RLE compression helps a lot, and here it will take the final size to 15K, that's more than 15% smaller.
So far so good. Now the problem is: can we improve the 97.22% figure? Yes, and here enters the predictor. This function encodes the bitbase by guessing the value of each position, then replacing the bitbase entry with a 0 if the guess was correct, or 1 if it was wrong. In the KBPK predictor I've put this simple line:

Code: Select all
                    if( FileOfSquare(wp) == 0 && ! is_light_square(wb) ) {
                        if( distance( bk, A8 ) < (distance( wk, A8 )-1) && distance(bk,A8) < distance( wp,A8) ) {
                            predicted_value = 0;
                        }
                    }


This says that when the weak king is closer to the promotion square of a rook pawn and the bishop cannot control that square, the position is draw. It doesn't have to be 100% accurate, all that's matter is that it's right more than it's wrong! :-)
With this one liner we now have 97.63% zero's in the bitbase, and it compresses to 14K.
That's the idea... very similar to what you said about KBNK: your code knews most positions but not all. So it wasn't a perfect recognizer, but it will probably make for an extremely good predictor, allowing for great compression of the corresponding bitbase.
In my code I take advantage of existing bitbases too, so I use KPK in the KPPK predictor, here's the full code:

Code: Select all
int bbAdjustKPPK( PackedArray * pa, int wtm, int op )
{
    printf( "Adjusting KPPK/%d...", wtm );

    // Predictions are based on the KPK bitbases, get them
    PackedArray * kpk_wtm = getBitBase( bb_KPK, bb_WtM );
    PackedArray * kpk_btm = getBitBase( bb_KPK, bb_BtM );

    if( kpk_wtm == 0 || kpk_btm == 0 ) {
        printf( "*** Warning: KPPK adjuster can't find KPK bitbase\n" );
        return -1;
    }

    // Use also the KPPK table with black to move
    PackedArray * kppk_btm = 0;
   
    if( wtm ) {
        kppk_btm = getBitBase( bb_KPPK, bb_BtM );
    }

    PositionEnumerator posEnum;

    posEnum.addPiece( WhitePawn );
    posEnum.addPiece( WhitePawn );

    unsigned good_predictions = 0;

    while( posEnum.hasMorePositions() ) {
        if( FileOfSquare( posEnum.getWhiteKingPos() ) >= 4 ) {
            // Skip this position (simmetry)
            posEnum.gotoNextPosition();
            continue;
        }

        if( ! posEnum.isValidPosition( wtm ? true : false ) ) {
            good_predictions++;
            posEnum.gotoNextPosition();
            continue;
        }

        int index = getBitBaseIndex( bb_KPPK, posEnum );

        // Predict and fix the bitbase
        int wk = posEnum.getWhiteKingPos();
        int bk = posEnum.getBlackKingPos();
        int p1 = posEnum.getPiecePos( 2 );
        int p2 = posEnum.getPiecePos( 3 );

        if( p1 > p2 ) {
            int x = p1;
            p1 = p2;
            p2 = x;
        }

        unsigned predicted_value =
            kpk_wtm->get( getBitBaseIndex(bb_KPK,wk,bk,p1) ) |
            kpk_wtm->get( getBitBaseIndex(bb_KPK,wk,bk,p2) ) |
            kpk_btm->get( getBitBaseIndex(bb_KPK,wk,bk,p1) ) |
            kpk_btm->get( getBitBaseIndex(bb_KPK,wk,bk,p2) );

        if( RankOfSquare(p1) == 1 || RankOfSquare(p2) == 1 ) {
            predicted_value = 1;
        }

        if( FileOfSquare(p1) < 7 && p2 == (p1+1) ) predicted_value = 1;
        if( FileOfSquare(p1) < 6 && p2 == (p1+2) ) predicted_value = 1;
        if( FileOfSquare(p1) < 5 && p2 == (p1+3) ) predicted_value = 1;

        if( kppk_btm != 0 ) {
            predicted_value |= kppk_btm->get(index);
        }

        if( predicted_value == pa->get(index) ) {
            good_predictions++;
        }

        pa->set( index, pa->get(index) ^ predicted_value );

        posEnum.gotoNextPosition();
    }

    printf( " done, accuracy = %05.2f\n", (good_predictions * 100.0) / getBitBaseIndexRange(bb_KPPK) );

    return 0;
}


This was easy and fun to write, and made KPPK compress to 9K.
The bitbases for the weaker side do not compress so well, so I'm a bit concerned about those, but if it is actually possible to use bitbases for only one side then probably the few hundreds K target is feasible.
diepeveen
 
Posts: 116
Joined: 28 Jun 2005, 01:09
Location: Netherlands

Previous

Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 26 guests