Difference between revisions of "Perft"

From Chessprogramming wiki
Jump to: navigation, search
(Created page with "'''Home * Board Representation * Move Generation * Perft''' '''Perft''', ('''perf'''ormance '''t'''est, move path enumeration)<br/> a debugging function...")
 
Line 183: Line 183:
 
* [http://brausch.org/home/chess/index.html Chess Engine OliThink - New Move Generator OliPerft (Pre OliThink 5)] by [[Oliver Brausch]] » [[OliThink]]
 
* [http://brausch.org/home/chess/index.html Chess Engine OliThink - New Move Generator OliPerft (Pre OliThink 5)] by [[Oliver Brausch]] » [[OliThink]]
 
* [http://www.craftychess.com/documentation/craftydoc.html Crafty Command Documentation] by [[Robert Hyatt]], see perft <depth> » [[Crafty]]
 
* [http://www.craftychess.com/documentation/craftydoc.html Crafty Command Documentation] by [[Robert Hyatt]], see perft <depth> » [[Crafty]]
 +
* [https://github.com/abulmo/hqperft hqperft: Chess move generation based on (H)yperbola (Q)uintessence & range attacks] by [[Richard Delorme]] » [[Hyperbola Quintessence]]
 
* [http://www.rocechess.ch/perft.html perft, divide, debugging a move generator] from [[ROCE]] by [[Roman Hartmann]]
 
* [http://www.rocechess.ch/perft.html perft, divide, debugging a move generator] from [[ROCE]] by [[Roman Hartmann]]
 
* [http://marcelk.net/rookie/nostalgia/v3/perft-random.epd perft-random.epd] by [[Marcel van Kervinck]] » [[Rookie]]
 
* [http://marcelk.net/rookie/nostalgia/v3/perft-random.epd perft-random.epd] by [[Marcel van Kervinck]] » [[Rookie]]

Revision as of 14:03, 31 October 2018

Home * Board Representation * Move Generation * Perft

Perft, (performance test, move path enumeration)
a debugging function to walk the move generation tree of strictly legal moves to count all the leaf nodes of a certain depth, which can be compared to predetermined values and used to isolate bugs. In perft, nodes are only counted at the end after the last makemove. Thus "higher" terminal nodes (e.g. mate or stalemate) are not counted, instead the number of move paths of a certain depth. Perft ignores draws by repetition, by the fifty-move rule and by insufficient material. By recording the amount of time taken for each iteration, it's possible to compare the performance of different move generators or the same generator on different machines, though this must be done with caution since there are variations to perft.

Perft function

A simple perft function in C looks as follows:

typedef unsigned long long u64;

u64 Perft(int depth)
{
    MOVE move_list[256];
    int n_moves, i;
    u64 nodes = 0;

    if (depth == 0) return 1;

    n_moves = GenerateLegalMoves(move_list);
    for (i = 0; i < n_moves; i++) {
        MakeMove(move_list[i]);
        nodes += Perft(depth - 1);
        UndoMove(move_list[i]);
    }
    return nodes;
}

Bulk-counting

Instead of counting nodes at "depth 0", legal move generators can take advantage of the fact that the number of moves generated at "depth 1" represents the accurate perft value for that branch. Therefore they can skip the last makemove/undomove, which gives much faster results and is a better indicator of the raw move generator speed (versus move generator + make/unmake). However, this can cause some confusion when comparing perft values. Assuming the above code used a legal move generator, it would only need the following modification:

...
//__/* DELETE: if (depth == 0) return 1; */__//

n_moves = GenerateMoves(move_list);

__if (depth == 1) return n_moves;__
...

Hashing

Perft can receive another speed boost by hashing node counts, with a small chance for inaccurate results. Sometimes this is used as a sanity check to make sure the hash table and keys are working correctly.

Perft function with pseudo move generator

To generate legal moves some programs have to make moves first, call the function IsIncheck and then undo those moves. That makes above Perft function to make and undo moves twice for all moves. Bellow code can avoid that problem and run much faster:

typedef unsigned long long u64;

u64 Perft(int depth)
{
    MOVE move_list[256];
    int n_moves, i;
    u64 nodes = 0;

    if (depth == 0) return 1;

    n_moves = GenerateMoves(move_list);
    for (i = 0; i < n_moves; i++) {
        MakeMove(move_list[i]);
        if (!IsIncheck())
            nodes += Perft(depth - 1);
        UndoMove(move_list[i]);
    }
    return nodes;
}

Perft History

Supposably, perft was first implemented within the Cobol program RSCE-1 by R.C. Smith, submitted to the USCF for evaluation, and subject of an 1978 Computerworld article [1] . RSCE-1's purpose was not to play chess games, but position analysis, to find forced mates, and to perform a move path enumeration of up to three plies, with the perft(3) result of 8,902 from the initial position already mentioned [2] . Ken Thompson may have calculated perft(3) and perft(4) earlier than this date with Belle. Steven Edwards was the first to compute perft(5) through perft(9), and has since been actively involved in Perft computations.

In December 2003, Albert Bertilsson started a distributed project [3] to calculate perft(11) of the initial position, taking over a week to calculate [4] . Exact Perft numbers have been computed and verified up to a depth of 13 by Edwards and are now available in the On-Line Encyclopedia of Integer Sequences [5] , and are given under Initial Position Summary. A so far unverified claim for perft(14) of 61,885,021,521,585,529,237 was given by Peter Österlund in April 2013 [6], while Daniel Shawul proposed Perft estimation applying Monte carlo methods [7] [8]. In August 2017, Ankan Banerjee, who already confirmed Peter Österlund's perft(14) in September 2016 [9], computed perft(15) of 2,015,099,950,053,364,471,960 with his GPU perft program [10], running it several days two times with different zobrist keys on a cluster of Nvidia DGX-1 server systems [11]. His program starts exploring the tree in depth first manner on CPU. When a certain depth is reached a GPU function (kernel) is launched to compute perft of the subtree in breadth first manner [12]. Ankan Banerjee dedicated his computations in honor to Steven Edwards - whose tireless efforts for verifying perft(14) encouraged him to verify perft(14) and take up the challenge to compute perft(15) [13].

Divide

The Divide command is often implemented as a variation of perft, listing all moves and for each move, the perft of the decremented depth. However, some programs already give "divided" output for perft.

See also

Publications

Perft in other Games

Forum Posts

[15]

2000 ...

2005 ...

2010 ...

2011

2012

2013

Re: Perft(14) estimates thread by Peter Österlund, CCC, April 02, 2013 » 61,885,021,521,585,529,237
MC methods by Daniel Shawul, CCC, April 11, 2013 » Monte-Carlo Tree Search
Re: MC methods by Daniel Shawul, CCC, April 13, 2013

2014

2015 ...

2016

Re: yet another attempt on Perft(14) by Ankan Banerjee, CCC, September 09, 2016

2017

Re: perft(15) by Ankan Banerjee, CCC, August 25, 2017
Re: Perft(15): comparison of estimates with Ankan's result by Ankan Banerjee, CCC, August 26, 2017

External Links

Implementations

Video Tutorial

References

Up one level