Compiling qperft as c++ code

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Compiling qperft as C++ code (bug report).

Post by Sven »

hgm wrote:
Ajedrecista wrote:Good catch! I also spotted a bug in qperft which people said it was due to hashing.
Note that when it is due to hashing, it is not necessarily a bug. The hashing is intrinsically unreliable, because you can get key collisions.
Your last statement that I could find regarding the problem Jesus reported in his post linked to above was this:
hgm wrote:I did not make a new version yet, but invalidating the key by just adding something to it in NextPromoPiece() did produce the correct perft(7).
appearing here.
The version I downloaded from your site looks different from the one that Jesus tested back in 2012 since it does not even have a function like NextPromoPiece(), but it still does not seem to produce the correct perft(7) for the position he quoted. Am I missing something? Did I use the wrong version? Is there a version where the problem mentioned above has already been fixed?
User avatar
Ajedrecista
Posts: 1969
Joined: Wed Jul 13, 2011 9:04 pm
Location: Madrid, Spain.

Re: JetChess bug report.

Post by Ajedrecista »

Hello Paul:
ibid wrote:Not sure if this is a known bug or not, but JetChess has a related issue:

[d]rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq - 0 6

It sees 7 moves here, missing the double check...

-paul
Great! Thomas Zipproth is registered in TalkChess so he can be reached via PM. It is curious that I computed perft(11) of 1.- f3, f6 a while ago (more than 1.15e+15 leaf nodes if I remember well) and I got the same result than Steven's in his way to compute Perft(13) from initial position.

I got the same error with:

[d]rnbqkbnr/ppp5/3Npppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq - 0 6

When perft(1) is reported as 7 again instead of 1.

Regards from Spain.

Ajedrecista.
zullil
Posts: 6442
Joined: Tue Jan 09, 2007 12:31 am
Location: PA USA
Full name: Louis Zulli

Re: Compiling qperft as C++ code (bug report).

Post by zullil »

stegemma wrote:
I've completed yesterday the new move generator of satana, it seems to be up to 2 times faster than the previous one. Here's my perft for this position:

Code: Select all

FEN: rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq
perft 1 Nodes: 2, Time: 0 ms, Nodes/s: 2000
perft 2 Nodes: 70, Time: 0 ms, Nodes/s: 70000
perft 3 Nodes: 1454, Time: 0 ms, Nodes/s: 1454000
perft 4 Nodes: 51654, Time: 2 ms, Nodes/s: 17218000
perft 5 Nodes: 1171698, Time: 56 ms, Nodes/s: 20556105
perft 6 Nodes: 42212557, Time: 1565 ms, Nodes/s: 26955655
perft 7 Nodes: 1029536265, Time: 44194 ms, Nodes/s: 23295310
Mine seems faster, which is hard to believe. Are you bulk counting at leaf nodes?

Code: Select all

ProcyonLeo: ~/Documents/Chess/Kirby] ./perft
FEN string = rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq
Depth = 7
Leaf nodes = 1029536265
Time taken = 36940 ms
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Compiling qperft as c++ code

Post by hgm »

It seems the fix of the problem reported by Jesus never made it to my website. :oops:

I pushed a fixed version now that adapts the hash key on under-promotions, and does test for contact checks. If there are any, it fakes that the last move was with this piece.

I guess this might give invalid output for impossible positions with multiple contact checks: the move generator would only recognize one, and allow capture of that checker, even though that would not solve the other contact check(s).

Code: Select all

C:\cygwin\home\perft>a 7 H24 "rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b
KQkq - 0 6"
Hash-table size = ffffff, Starts at b4b040,section = 1fffff
 - - - - - - - - - - - -
 - - - - - - - - - - - -
 - - r n b q k b n r - -
 - - p p N . . . . . - -
 - - . . . p p p p p - -
 - - . . . . . . . . - -
 - - B . . . P . . . - -
 - - . . . . . . . . - -
 - - P P P P . P P P - -
 - - R . B Q K . N R - -
 - - - - - - - - - - - -
 - - - - - - - - - - - -

Quick Perft by H.G. Muller
Perft mode: Hash-table size = 256MB, bulk counting in horizon nodes

perft( 1)=            2 ( 0.000 sec)
perft( 2)=           70 ( 0.000 sec)
perft( 3)=         1454 ( 0.001 sec)
perft( 4)=        51654 ( 0.000 sec)
perft( 5)=      1171698 ( 0.019 sec)
perft( 6)=     42212557 ( 0.232 sec)
perft( 7)=   1029536265 ( 4.919 sec)

C:\cygwin\home\perft>a 7 "rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq
 - 0 6"
 - - - - - - - - - - - -
 - - - - - - - - - - - -
 - - r n b q k b n r - -
 - - p p N . . . . . - -
 - - . . . p p p p p - -
 - - . . . . . . . . - -
 - - B . . . P . . . - -
 - - . . . . . . . . - -
 - - P P P P . P P P - -
 - - R . B Q K . N R - -
 - - - - - - - - - - - -
 - - - - - - - - - - - -

Quick Perft by H.G. Muller
Perft mode: No hashing, bulk counting in horizon nodes

perft( 1)=            2 ( 0.000 sec)
perft( 2)=           70 ( 0.000 sec)
perft( 3)=         1454 ( 0.000 sec)
perft( 4)=        51654 ( 0.001 sec)
perft( 5)=      1171698 ( 0.019 sec)
perft( 6)=     42212557 ( 0.437 sec)
perft( 7)=   1029536265 (15.455 sec)
Weird thing is that it got 30% slower, though, on perft(6) from the opening position. Which does not execute any of the new code (which is all in the UnMake for promotions, and there aren't any promotions in perft(6)).

I have seen that before, where deleting some lines of unreachable code gave such a slowdown. I guess the solution would be to use a better compiler; I am using a very old gcc version.
User avatar
stegemma
Posts: 859
Joined: Mon Aug 10, 2009 10:05 pm
Location: Italy
Full name: Stefano Gemma

Re: Compiling qperft as c++ code

Post by stegemma »

hgm wrote:It seems the fix of the problem reported by Jesus never made it to my website. :oops:

I pushed a fixed version now that adapts the hash key on under-promotions, and does test for contact checks. If there are any, it fakes that the last move was with this piece.

I guess this might give invalid output for impossible positions with multiple contact checks: the move generator would only recognize one, and allow capture of that checker, even though that would not solve the other contact check(s).[...]
I have seen that before, where deleting some lines of unreachable code gave such a slowdown. I guess the solution would be to use a better compiler; I am using a very old gcc version.
You can compile with Visual C++ with minor changes, as reported in the other my posts. For the patch, of course you take care of the case when a sliding piece do contact check while discovering a check from another sliding piece? This could happens moving a bishop that is two squares away from the king, on the same row as the king and a far rook/queen, for sample:

K.b....r
User avatar
stegemma
Posts: 859
Joined: Mon Aug 10, 2009 10:05 pm
Location: Italy
Full name: Stefano Gemma

Re: Compiling qperft as C++ code (bug report).

Post by stegemma »

zullil wrote:
stegemma wrote:
I've completed yesterday the new move generator of satana, it seems to be up to 2 times faster than the previous one. Here's my perft for this position:

Code: Select all

FEN: rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq
perft 1 Nodes: 2, Time: 0 ms, Nodes/s: 2000
perft 2 Nodes: 70, Time: 0 ms, Nodes/s: 70000
perft 3 Nodes: 1454, Time: 0 ms, Nodes/s: 1454000
perft 4 Nodes: 51654, Time: 2 ms, Nodes/s: 17218000
perft 5 Nodes: 1171698, Time: 56 ms, Nodes/s: 20556105
perft 6 Nodes: 42212557, Time: 1565 ms, Nodes/s: 26955655
perft 7 Nodes: 1029536265, Time: 44194 ms, Nodes/s: 23295310
Mine seems faster, which is hard to believe. Are you bulk counting at leaf nodes?

Code: Select all

ProcyonLeo: ~/Documents/Chess/Kirby] ./perft
FEN string = rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq
Depth = 7
Leaf nodes = 1029536265
Time taken = 36940 ms
I don't use bitboards nor hash tables... and sincerely (i'm not joking) i don't know what is bulk counting. I execute any move and test for legality right after the execution even on leaf nodes, without any special optimization. I could get a better performance without executing moves on leaves (i already have a function "isInCheckAftermove" in some older versions of satana that test for check without executing the move) but i'm satisfied of this results, for now.

You should take care of the cpu used, of course, to compare results. Mine is an intel E6700 dual core dated 2011, windows 7 64 bit.
zullil
Posts: 6442
Joined: Tue Jan 09, 2007 12:31 am
Location: PA USA
Full name: Louis Zulli

Re: Compiling qperft as C++ code (bug report).

Post by zullil »

stegemma wrote:
zullil wrote:
stegemma wrote:
I've completed yesterday the new move generator of satana, it seems to be up to 2 times faster than the previous one. Here's my perft for this position:

Code: Select all

FEN: rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq
perft 1 Nodes: 2, Time: 0 ms, Nodes/s: 2000
perft 2 Nodes: 70, Time: 0 ms, Nodes/s: 70000
perft 3 Nodes: 1454, Time: 0 ms, Nodes/s: 1454000
perft 4 Nodes: 51654, Time: 2 ms, Nodes/s: 17218000
perft 5 Nodes: 1171698, Time: 56 ms, Nodes/s: 20556105
perft 6 Nodes: 42212557, Time: 1565 ms, Nodes/s: 26955655
perft 7 Nodes: 1029536265, Time: 44194 ms, Nodes/s: 23295310
Mine seems faster, which is hard to believe. Are you bulk counting at leaf nodes?

Code: Select all

ProcyonLeo: ~/Documents/Chess/Kirby] ./perft
FEN string = rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq
Depth = 7
Leaf nodes = 1029536265
Time taken = 36940 ms
I don't use bitboards nor hash tables... and sincerely (i'm not joking) i don't know what is bulk counting. I execute any move and test for legality right after the execution even on leaf nodes, without any special optimization. I could get a better performance without executing moves on leaves (i already have a function "isInCheckAftermove" in some older versions of satana that test for check without executing the move) but i'm satisfied of this results, for now.

You should take care of the cpu used, of course, to compare results. Mine is an intel E6700 dual core dated 2011, windows 7 64 bit.
I don't use bitboards or a hash table either. But I only generate legal moves, so I don't need to make the moves leading to the leaf nodes to test for legality. That's why mine is faster here. My result was obtained on a 2 GHz Core 2 Duo on a 2007 MacBook running OS X 10.7.
User avatar
stegemma
Posts: 859
Joined: Mon Aug 10, 2009 10:05 pm
Location: Italy
Full name: Stefano Gemma

Re: Compiling qperft as C++ code (bug report).

Post by stegemma »

zullil wrote:[...]
I don't use bitboards or a hash table either. But I only generate legal moves, so I don't need to make the moves leading to the leaf nodes to test for legality. That's why mine is faster here. My result was obtained on a 2 GHz Core 2 Duo on a 2007 MacBook running OS X 10.7.
So your perft is not just faster than mine... but _really_ faster! :)

What method do you use, to generate legal moves?
User avatar
hgm
Posts: 27796
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Compiling qperft as c++ code

Post by hgm »

I don't have Visual C++. But the difference seems to be that I used gcc -O2, and that -O3 makes it faster. (For my engines this usually doesn't help.) So I now updated the perft.exe on my download page to the -O3 compile. This takes 27 sec for perft(7) without hashing, while the previous -O2 compile took 35 sec.
ibid
Posts: 89
Joined: Mon Jun 13, 2011 12:09 pm

Re: JetChess bug report.

Post by ibid »

Ajedrecista wrote:Hello Paul:
ibid wrote:Not sure if this is a known bug or not, but JetChess has a related issue:

[d]rnbqkbnr/ppN5/3ppppp/8/B3P3/8/PPPP1PPP/R1BQK1NR b KQkq - 0 6

It sees 7 moves here, missing the double check...

-paul
Great! Thomas Zipproth is registered in TalkChess so he can be reached via PM. It is curious that I computed perft(11) of 1.- f3, f6 a while ago (more than 1.15e+15 leaf nodes if I remember well) and I got the same result than Steven's in his way to compute Perft(13) from initial position.
I suspect the bug is not too serious. In gperft information about checking piece
location(s) is computed in MakeMove() for convenience since at that point I have
already extracted information about the move (to, from, piece moving, etc). Of
course doing it that way means you need a special routine to determine the check
status of a new position when it is loaded. I have to suspect JetChess has a similar
issue since there is no way it could get deep perfts correct without knowing what a
double check is on internal nodes.

gperft's numbers match what others found here (1 thread, no hash tables)
1 2 0.000
2 70 0.000
3 1454 0.000
4 51654 0.008
5 1171698 0.014
6 42212557 0.089
7 1029536265 2.023
8 37522643900 48.706

-paul