Daniel Shawul wrote:diep wrote:hgm wrote:I don't think this is theoreticlly possible: the pawn advance is a function in a multi-dimensional spae, and it cannot be mapped by a continuous function on the one-dimensional space of numbers.
BS statement.
I solved that in Diep already in 1994 or so. I was 20 years old and just had started Diep.
Note that the best way to order moves is just using a picksort - i'm using that of course.
But solving just the pawns is so simple....
Note with nowadays bitboards you can solve it in a different manner.
Just enumerate for white the fields a8 as least significant, followed by b8 and h1 as most significant.
Now with a simple bitboard trick you can get out the first pawn.
then you fiddle with that and you got the pawn move.
You know this is highschool math...
It is 1 dimensional math...
But I don't understand why you would need this. Why not simply make a pawn hash table which lists all possible positions, and the name of the file on the HD where you stored the slice, if it is already computed? You can use a hashed perft on positions with Pawns only (and counts of the other pieces, so you know when lane-changing is still possible), starting with a placement step on 2nd rank. Then you can just run through the list to search for not-yet-computed slices that have all successors already computed, and start working on those. If it is not a pure Pawn ending, I don't think you would ever get in a situation where a linear search through the list of Pawn structures would take significant time compared to calculating a single slice.
This also makes it much easier to fully exploit the exchange symmetry of a large number of Pawns.
With pure Pawn endings slices would only be 64 positions, so for the sake of efficiency you would probably combine them to super-slices, e.g. only slice based on white Pawn locations.
On a GPU it makes sense, but he's making a mistake.
He should talk to Joost Buijs how he did do his ordering for nightmare in 90s...
I think you missed why it is difficult to enumerate. The question is given an index (a number) determine the locations of the n-bitbases. I like this approach a lot because it avoids the use of nested loops for each piece added. If I want to generate 10 men my function is still
Code: Select all
for(i=0;i < n_positions;i++) {
sq[0]=f(i) , sq[1] = g(i), ...
}
This is much more difficult than you think. Even enumerating n alike pieces requires some weird math. Look in my other post for a code snippet. Now merging this for two groups of white and black pawns, you see it is a nightmare. Even though I think it may be possible to find an enumeration function it will be difficult.
I know the above code may be a little slower because when you go over inner loops, you still have to generate each square unlike the case shown below. I like the above code for its elegance but it may be slower ..
Code: Select all
for(i=0;i<64;i++) {
sq[0]=i;
for(j=0;j<64;j++)
sq[1]=j;
...
{
if(invalid) continue; //or store invalid value anyway
}
}
Oh comeon diep has its own EGTBs. It's 1 lookup table to remove squares for n of the same pieces, i combine that with kings as the first layer (most significant). That's not for generation, that's the resulting EGTBs.
In the resulting EGTB i try to avoid positions with >= 2 pieces on the same squares (goes here and there wrong for en passant - i don't store castling rights). Nalimov goes further there removing also bunches of positions where the king can't stand legal for side not to move, yet that's white and black dependant - could save you 15% or so max. Read further why i don't do that.
After the up to a couple of hundreds of passes of bitmap generation, you convert the resulting bitmap to win/draw/loss. If you want DTM or something silly like that, then you need to add each bitmap pass to the DTM tables.
Either way, you'll be using 2 or 3 different EGTB formats. A simple bitmap format, if you want DTM or something more silly like correct 50 move rule, you'll need 3 formats. One to generate quickly. the same format for the win in N and then after it's all done you need to convert to the format that's using a better indexation removing more illegals.
DTM is not so clever nor anything similar. it's 1 or 2 bytes. If you use 50 move rule, you have still a 7 bits need an entry. That's way too much.
win/draw/loss compresses up to factor 1000 handsdown and for some even factor 5000+ is not a problem.
With the DTM's you'll get to factor 4 and the 50 move rule tables a tad under factor 4.
So with all 6 men in DTM format you need 1.3TB or so. Uncompressed wdl in Diep format is already 1.05TB (with TB as power of 10, not 1024) and with compression it's far smaller (not operational in Diep yet, maybe soon though might i get some 7 men done - but that's not a priority yet because of price of disks).
It's all about the compression.
So you're forced to WDL or you will need 1TB of SSD's.
Note that if you use WDL you don't need to do extreme effort to get a compact format - only mirroring is important and avoiding pieces on the same square/same pieces. So the big reductions that lose you a factor 2 if you don't do it . Positions where king is in check - that's a 0 in your format anyway - compresses well.
With DTM style format of course you better remove all positions here you can capture the king.
The whole question is: do you want 7 men tables one day?
If so - go WDL - if not, buy expensive SSD's and go get 6 men.
With spinning harddrives you can't use EGTBs in search you know other than what fits in your caches as you'll get too many nps in the first place.
So what fits in RAM or on a SSD, that's what you can use nowadays. Slowing down your nps too much is not gonna be happy.
You'll get 30 ply nominal anyway, so already in openingsposition you start probing EGTBs. That's usually KRPKRP and that's a rather useless EGTB to probe there.
So magnetic disks are too slow for that.
p.s. note biggest diff between generation format and resulting format: storing 5 positions a byte for the last and 1 bit a position for the generation format.