Skip to content

Commit

Permalink
mm: infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
lemonsqueeze committed Jul 18, 2018
1 parent 3ff0b86 commit ca33969
Show file tree
Hide file tree
Showing 34 changed files with 1,111 additions and 517 deletions.
3 changes: 3 additions & 0 deletions CREDITS
Expand Up @@ -3,6 +3,9 @@ Pachi stands on the research shoulders of giants:
Move Evaluation in Go using Deep Convolutional Neural Networks
Chris J. Maddison, Aja Huang, Ilya Sutskever & David Silver

Computing Elo Ratings of Move Patterns in the Game of Go
Rémi Coulom

Modification of UCT with Patterns in Monte-Carlo Go
Sylvain Gelly, Yizao Wang, Remi Munos & Olivier Teytaud

Expand Down
64 changes: 5 additions & 59 deletions HACKING
Expand Up @@ -58,11 +58,11 @@ Pachi consists of the following components:
several UCT engines on different computers
engines/ other engines:
dcnn.c example "dcnn move generator" engine
patternplay.c example "large patterns move generator" engine
patternplay.c example "mm patterns move generator" engine
random.c example "random move generator" engine
replay.c example "playout move generator" engine
montecarlo.c simple treeless Monte Carlo engine, quite bitrotten
patternscan.c auxiliary engine for harvesting patterns from existing games
patternscan.c auxiliary engine for mm patterns training pipeline
joseki.c auxiliary engine for generating joseki patterns

* "playout" policy is asked to generate moves to play during the Monte Carlo
Expand Down Expand Up @@ -176,63 +176,9 @@ support.
General Pattern Matcher
=======================

Pachi has in-development general pattern matcher that can match various
sets of features (spatial and others), inspired by the CrazyStone and
van der Werf - de Groot - Stern pattern model. Please see pattern.h
for detailed description of the pattern concept and recognized features.

To harvest patterns, use 'pachi -e patternscan' (see patternscan/patternscan.c
for available options). The output of the pattern scanner are two data
structures: The matched patterns

(feature1:payload feature2:payload ...)

and spatial dictionary. "Spatial" feature represents a particular
configuration of stones in a circle around the move-to-play; each
configuration has its own record in the dictionary and the spatial
feature references only the id in the dictionary; so you need to keep
both the patterns and the "patterns.spat" file. Normally, 'patternscan'
will only match already existing dictionary entries, but you
can pass it "gen_spat_dict" so that it appends all newly found spatial
features to the dictionary - use "spat_threshold" to limit recording
only to frequently occuring spatial features; to start the dictionary
from scratch, simply remove any existing "patterns.spat" file.

There are few pre-made scripts to make the initialization of the pattern
matcher easy:

* tools/pattern_byplayer.sh: Sorts out patterns from given SGF collection
by player names, one player per file in a dedicated directory. This is
useful if you want to use the patterns to e.g. recognize games of a
player by characteristic patterns. Spatial dictionary is autogenerated
in full.

* tools/pattern_spatial_gen.sh: Initializes spatial dictionary by spatial
features found at least N times in given SGF collection. This is useful
for further gathering of general pattern statistics while keeping
the amount of spatial features manageable.

* tools/pattern_spatial_show.pl ID: Shows spatial pattern of given id
in 2D plane.

* tools/pattern_bayes_gen.sh: Generates a Bayesian probability table
for each pattern in a SGF collection. The computed number is the empiric
probability of playing a given pattern when it is available on board.

* tools/pattern_bayes_merge.sh: Merges Bayesian probability tables
of patterns. This is useful for parallel pattern mining - run multiple
pattern_bayes_gen (perhaps remove the counts >= 2 test) and then merge
the generated tables.

* tools/pattern_getdrops.pl: Processes game logs to determine moves that
lead to large drop in Pachi's evaluation and extracts patterns that
represent these moves. This might allow Pachi to "learn from its past
mistakes" and recognize these moves in the future. A full pipeline
for this might be:

cat kgsGtp.log | tools/kgslog2gtp.pl |
tools/pattern_getdrops.pl | tools/pattern_bayes_gen.sh - |
tools/pattern_bayes_merge.sh patterns.prob - >patterns.prob2
Pachi has a general pattern matcher that can match various sets of features
(spatial and others). See pattern/README for description of the pattern
matcher and training pipeline.


Plugin API
Expand Down
43 changes: 24 additions & 19 deletions README.md
Expand Up @@ -72,14 +72,14 @@ section at the top of the Makefile.
## DCNN support

Pachi can use a neural network as source of good moves to consider.
This makes it about 1 stone stronger and makes the games
more pretty. With dcnn support Pachi can also run on modest hardware
with very few playouts, or even no playouts at all using the raw dcnn
engine (not recommended for actual play, pachi won't know when to pass
or resign !).
With dcnn support Pachi can play at dan level strength on modest hardware.
For large number of playouts this makes it about 1 stone stronger, and
tends to make the games more pretty. A raw dcnn engine is available for
pure dcnn play (not recommended for actual games, pachi won't know when to
pass or resign !).

One drawback however is that pondering and dcnn can't be used at the same
time right now (you should get a warning on startup).
Currently dcnn is used for root node only, and pondering and dcnn can't be
used together (you should get a warning on startup).

To build Pachi with DCNN support:
- Install [Caffe](http://caffe.berkeleyvision.org)
Expand All @@ -99,6 +99,17 @@ dcnn.c to accomodate it. Pachi will check for `golast19.prototxt` and
playing on 19x19.


## MM Patterns

MM Patterns have replaced large patterns database used in previous versions.
No need to download anything extra, they're enabled by default as long as Pachi
can find its data files.

Patterns load instantly now, take up very little memory and prediction rate is
better in middle game. They also make it possible to fix tactical holes in
Pachi by adding corresponding features. See pattern/README for details.


## How to run

By default Pachi will run on all cores, using up to 200Mb of memory for tree
Expand Down Expand Up @@ -128,31 +139,25 @@ Will make Pachi use 20s per move.
./pachi -t =5000:15000 threads=4,max_tree_size=100

This will make Pachi play with max 15000 playouts per move on 4 threads,
taking up to 100Mb of memory (+ several tens MiB as a constant overhead).
It should be about 2d with dcnn and large patterns setup.
taking up to 100Mb of memory (+ several tens Mb as a constant overhead).
It should be about 2d with dcnn and mm patterns.

./pachi -t _1200 --no-dcnn threads=8,max_tree_size=3072,pondering
./pachi -t _1200 --nodcnn threads=8,max_tree_size=3072,pondering

This will make Pachi play without dcnn with time settings 20:00 S.D. with 8 threads,
taking up to 3GiB of memory, and thinking during the opponent's turn as well.
taking up to 3Gb of memory, and thinking during the opponent's turn as well.

**Logs**

Pachi logs details of its activity on stderr, which can be viewed via
`Tools->GTP Shell` in gogui. Tons of details about winrates, memory usage,
`Tools -> GTP Shell` in gogui. Tons of details about winrates, memory usage,
score estimate etc can be found here. Even though most of it available through
other means in gogui, it's always a good place to look in case something
unexpected happens.

`-d <log_level>` changes the amount of logging (-d0 suppresses everything)
`-o log_file` logs to a file instead. gogui live-gfx commands won't work though.

**Large patterns**

Pachi can also use a pattern database to improve its playing performance.
You can get it at http://pachi.or.cz/pat/ - you will also find further
instructions there.

**Opening book**

> Mostly useful when running without dcnn (dcnn can deal with fuseki).
Expand Down Expand Up @@ -192,7 +197,7 @@ overridden at runtime by setting `DATA_DIR` environment variable.
## Analyze commands

When running Pachi through GoGui, a number of graphic tools are available
through the `Tools->Analyze commands` window:
through the `Tools -> Analyze commands` window:

- Best moves
- Score estimate
Expand Down
19 changes: 19 additions & 0 deletions board.c
Expand Up @@ -403,6 +403,25 @@ board_print(struct board *board, FILE *f)
board_print_custom(board, f, DEBUGL(6) ? cprint_group : NULL, NULL);
}

static char*
print_target_move_handler(struct board *b, coord_t c, void *data)
{
static char buf[32];
coord_t target_move = (coord_t)data;

if (c == target_move) sprintf(buf, "\e[40;33;1m*\e[0m");
else sprintf(buf, "%c", stone2char(board_at(b, c)));
return buf;
}

void
board_print_target_move(struct board *b, FILE *f, coord_t target_move)
{
assert(!is_pass(target_move));
assert(board_at(b, target_move) == S_NONE);
board_hprint(b, f, print_target_move_handler, (void*)target_move);
}


/* Update board hash with given coordinate. */
static void profiling_noinline
Expand Down
30 changes: 30 additions & 0 deletions board.h
Expand Up @@ -12,6 +12,7 @@
#include "util.h"
#include "stone.h"
#include "move.h"
#include "mq.h"

struct fbook;

Expand Down Expand Up @@ -357,6 +358,8 @@ typedef char *(*board_print_handler)(struct board *b, coord_t c, void *data);
void board_print(struct board *board, FILE *f);
void board_print_custom(struct board *board, FILE *f, board_cprint cprint, void *data);
void board_hprint(struct board *board, FILE *f, board_print_handler handler, void *data);
/* @target_move displayed as '*' (must be empty spot) */
void board_print_target_move(struct board *b, FILE *f, coord_t target_move);

/* Debugging: Compare 2 boards byte by byte. Don't use that for sorting =) */
int board_cmp(struct board *b1, struct board *b2);
Expand Down Expand Up @@ -387,6 +390,8 @@ static bool board_is_valid_move(struct board *b, struct move *m);
static bool board_playing_ko_threat(struct board *b);
/* Returns 0 or ID of neighboring group in atari. */
static group_t board_get_atari_neighbor(struct board *b, coord_t coord, enum stone group_color);
/* Get all neighboring groups in atari */
static void board_get_atari_neighbors(struct board *b, coord_t coord, enum stone group_color, struct move_queue *q);
/* Returns true if the move is not obvious self-atari. */
static bool board_safe_to_play(struct board *b, coord_t coord, enum stone color);

Expand Down Expand Up @@ -630,6 +635,31 @@ board_get_atari_neighbor(struct board *b, coord_t coord, enum stone group_color)
return 0;
}

static inline void
board_get_atari_neighbors(struct board *b, coord_t c, enum stone group_color, struct move_queue *q)
{
q->moves = 0;
foreach_neighbor(b, c, {
group_t g = group_at(b, c);
if (g && board_at(b, c) == group_color && board_group_info(b, g).libs == 1) {
mq_add(q, g, 0);
mq_nodup(q);
}
});
}

#define foreach_atari_neighbor(b, c, group_color) \
do { \
struct move_queue __q; \
board_get_atari_neighbors(b, (c), (group_color), &__q); \
for (unsigned int __i = 0; __i < __q.moves; __i++) { \
group_t g = __q.move[__i];

#define foreach_atari_neighbor_end \
} \
} while (0)


static inline bool
board_safe_to_play(struct board *b, coord_t coord, enum stone color)
{
Expand Down

0 comments on commit ca33969

Please sign in to comment.