13 #include <caffe/caffe.hpp>
14 using namespace caffe
;
24 static shared_ptr
<Net
<float> > net
;
27 using_dcnn(struct board
*b
)
29 return (real_board_size(b
) == 19 && net
);
32 /* Make caffe quiet */
34 dcnn_quiet_caffe(int argc
, char *argv
[])
36 if (DEBUGL(7) || getenv("GLOG_minloglevel"))
39 setenv("GLOG_minloglevel", "2", 1);
40 execvp(argv
[0], argv
); /* Sucks that we have to do this */
50 const char *model_file
= "golast19.prototxt";
51 const char *trained_file
= "golast.trained";
52 if (stat(model_file
, &s
) != 0 || stat(trained_file
, &s
) != 0) {
54 fprintf(stderr
, "No dcnn files found, will not use dcnn code.\n");
58 Caffe::set_mode(Caffe::CPU
);
60 /* Load the network. */
61 net
.reset(new Net
<float>(model_file
, TEST
));
62 net
->CopyTrainedLayersFrom(trained_file
);
65 fprintf(stderr
, "Initialized dcnn.\n");
69 dcnn_get_moves(struct board
*b
, enum stone color
, float result
[])
71 assert(real_board_size(b
) == 19);
74 int dsize
= 13 * size
* size
;
75 float *data
= new float[dsize
];
76 for (int i
= 0; i
< dsize
; i
++)
79 for (int j
= 0; j
< size
; j
++) {
80 for(int k
= 0; k
< size
; k
++) {
82 coord_t c
= coord_xy(b
, j
+1, k
+1);
83 group_t g
= group_at(b
, c
);
84 enum stone bc
= board_at(b
, c
);
85 int libs
= board_group_info(b
, g
).libs
- 1;
86 if (libs
> 3) libs
= 3;
88 data
[8*size
*size
+ p
] = 1.0;
90 data
[(0+libs
)*size
*size
+ p
] = 1.0;
91 else if (bc
== stone_other(color
))
92 data
[(4+libs
)*size
*size
+ p
] = 1.0;
94 if (c
== b
->last_move
.coord
)
95 data
[9*size
*size
+ p
] = 1.0;
96 else if (c
== b
->last_move2
.coord
)
97 data
[10*size
*size
+ p
] = 1.0;
98 else if (c
== b
->last_move3
.coord
)
99 data
[11*size
*size
+ p
] = 1.0;
100 else if (c
== b
->last_move4
.coord
)
101 data
[12*size
*size
+ p
] = 1.0;
106 Blob
<float> *blob
= new Blob
<float>(1,13,size
,size
);
107 blob
->set_cpu_data(data
);
108 vector
<Blob
<float>*> bottom
;
109 bottom
.push_back(blob
);
111 const vector
<Blob
<float>*>& rr
= net
->Forward(bottom
);
113 for (int i
= 0; i
< size
* size
; i
++) {
114 result
[i
] = rr
[0]->cpu_data()[i
];
115 if (result
[i
] < 0.00001)
123 find_dcnn_best_moves(struct board
*b
, float *r
, coord_t
*best
, float *best_r
)
125 for (int i
= 0; i
< DCNN_BEST_N
; i
++)
128 foreach_free_point(b
) {
129 int k
= (coord_x(c
, b
) - 1) * 19 + (coord_y(c
, b
) - 1);
130 for (int i
= 0; i
< DCNN_BEST_N
; i
++)
131 if (r
[k
] > best_r
[i
]) {
132 for (int j
= DCNN_BEST_N
- 1; j
> i
; j
--) { // shift
133 best_r
[j
] = best_r
[j
- 1];
134 best
[j
] = best
[j
- 1];
140 } foreach_free_point_end
;
144 print_dcnn_best_moves(struct tree_node
*node
, struct board
*b
,
145 coord_t
*best
, float *best_r
)
147 fprintf(stderr
, "%.*sprior_dcnn(%s) = [ ",
148 node
->depth
* 4, " ",
149 coord2sstr(node_coord(node
), b
));
150 for (int i
= 0; i
< DCNN_BEST_N
; i
++)
151 fprintf(stderr
, "%s ", coord2sstr(best
[i
], b
));
152 fprintf(stderr
, "] ");
154 fprintf(stderr
, "[ ");
155 for (int i
= 0; i
< DCNN_BEST_N
; i
++)
156 fprintf(stderr
, "%.2f ", best_r
[i
]);
157 fprintf(stderr
, "]\n");
161 dcnn_genmove(struct engine
*e
, struct board
*b
, struct time_info
*ti
, enum stone color
, bool pass_all_alive
)
164 float best_r
[DCNN_BEST_N
] = { 0.0, };
165 coord_t best_moves
[DCNN_BEST_N
];
166 dcnn_get_moves(b
, color
, r
);
167 find_dcnn_best_moves(b
, r
, best_moves
, best_r
);
169 return coord_copy(best_moves
[0]);
173 engine_dcnn_init(char *arg
, struct board
*b
)
177 fprintf(stderr
, "Couldn't initialize dcnn, aborting.\n");
180 //struct patternplay *pp = patternplay_state_init(arg);
181 struct engine
*e
= (engine
*)calloc2(1, sizeof(struct engine
));
182 e
->name
= (char*)"DCNN Engine";
183 e
->comment
= (char*)"I just select dcnn's best move.";
184 e
->genmove
= dcnn_genmove
;
185 //e->evaluate = dcnn_evaluate;