Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated Huffman code #16

Draft
wants to merge 14 commits into
base: tools
Choose a base branch
from
Draft

Updated Huffman code #16

wants to merge 14 commits into from

Conversation

dpldgr
Copy link

@dpldgr dpldgr commented Apr 20, 2024

Updated to support 26 piece types.

@dpldgr dpldgr marked this pull request as ready for review April 20, 2024 12:48
@ianfab
Copy link
Member

ianfab commented Apr 20, 2024

Thanks. It would be good to also update the dataSize estimation in on_variant_change as well, to consider 9 bit instead of 5 per piece when piece types >= 16 since this should likely consider the worst case to be safe. Also it would be nice to have a corresponding PR for the parsing in the trainer, although that isn't that urgent considering it is almost backwards-compatible.

@dpldgr
Copy link
Author

dpldgr commented Apr 20, 2024

Thanks. It would be good to also update the dataSize estimation in on_variant_change as well, to consider 9 bit instead of 5 per piece when piece types >= 16 since this should likely consider the worst case to be safe. Also it would be nice to have a corresponding PR for the parsing in the trainer, although that isn't that urgent considering it is almost backwards-compatible.

Ahhh yes, it presumes that it's always 5 bits. If someone specifies something like customPiece1 and then customPiece20 in variants.ini, would that use 9 bits for customPiece20, or does the parser skip empty slots?

I am planning to do a PR for the trainer too, I just need to check the end loop condition won't be an issue as it references an enum value rather than using a literal to terminate.

@ianfab
Copy link
Member

ianfab commented Apr 20, 2024

The NNUE piece index only depends on the order, not the value of the enum of the pieces types (and the trainer therefore can't even know which types these actually are), see

for (PieceSet ps = pieceTypes; ps;)
{
// Make sure that the nnueKing type gets the last index, since the NNUE architecture relies on that
PieceType pt = lsb(ps != piece_set(nnueKing) ? ps & ~piece_set(nnueKing) : ps);
ps ^= pt;
assert(pt != nnueKing || !ps);
pieceIndex[pt] = i;

So only the count of used types is what matters, and the 16th type and later will consume 9 bit then, i.e., it might even apply for built-in types if you use enough of them.

const int dataSize = (v->maxFile + 1) * (v->maxRank + 1) + v->nnueMaxPieces * 5
+ popcount(v->pieceTypes) * 2 * 5 + 50 > 512 ? 1024 : 512;
+ typeCount5bits * 2 * 5 + typeCount9bits * 2 * 9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are the bits for the pocket counts, see https://github.com/fairy-stockfish/variant-nnue-pytorch/wiki/Technical-details#training-data-format, the v->nnueMaxPieces * 5 is the one for the pieces on the board. It could e.g. be v->nnueMaxPieces * (typeCount > 15 ? 9 : 5). I think using worst case estimates here (all pieces are of the last type) is reasonable in order to be safe.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I should have picked that one up, I broke a long-standing rule to not code just before bed! 😴

Copy link
Member

@ianfab ianfab Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. The other change should be reverted though, since the 5 bit for the pockets are counts per type (5 bit = [0, 31]), i.e., they are fixed size and not related to the huffman encoding. However, it is using 7 bit when using the bigger data size, see

for(auto c: Colors)
for (PieceSet ps = pos.piece_types(); ps;)
stream.write_n_bit(pos.count_in_hand(c, pop_lsb(ps)), DATA_SIZE > 512 ? 7 : 5);

but that does not need to be considered here. It could just be added as an additional criterion, but this isn't really related to this PR, so no need to add it here unless you would like to.

Edit: I just realized this formula requires tons of knowledge about the code base to decipher, so I should have added a comment explaining each term. I might add that later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if there might have been a misunderstanding. The changes regarding the bits for the pieces in hand still needs to be reverted. The comments on this formula I will add once this PR is merged to avoid merge conflicts.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, there was a misunderstanding it seems, but I have also been busy preparing to move house so haven't gotten around to fixing this yet. I'll make it a draft again for the moment until I have some time to revert the pieces in hand.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, ok. There is no rush of course, so take your time. Or if you want I could also push the changes to the PR from my side.

@dpldgr dpldgr marked this pull request as draft April 28, 2024 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants