Updated README: Equal sign not required with `--mode` flag.
[sgk-go] / engine / cache.h
CommitLineData
7eeb782e
AT
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
3 * http://www.gnu.org/software/gnugo/ for more information. *
4 * *
5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
6 * 2008 and 2009 by the Free Software Foundation. *
7 * *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation - version 3 or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License in file COPYING for more details. *
17 * *
18 * You should have received a copy of the GNU General Public *
19 * License along with this program; if not, write to the Free *
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
21 * Boston, MA 02111, USA. *
22\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23
24#ifndef _CACHE_H_
25#define _CACHE_H_
26
27#include <stdio.h>
28#include "hash.h"
29
30/*
31 * This file, together with engine/hash.c implements hashing of go positions
32 * using a method known as Zobrist hashing. See the Texinfo documentation
33 * (Reading/Hashing) for more information.
34 */
35
36
37/* Hashnode: a node stored in the transposition table.
38 *
39 * In addition to the position, the hash lock encodes the following data,
40 * all hashed:
41 * komaster
42 * kom_pos
43 * routine
44 * str1
45 * str2
46 * extra hashvalue, optional (e.g. encoding a goal array)
47 *
48 * The data field packs into 32 bits the following
49 * fields:
50 *
51 * RESERVED : 5 bits
52 * value1 : 4 bits
53 * value2 : 4 bits
54 * move : 10 bits
55 * cost : 4 bits
56 * remaining_depth: 5 bits (depth - stackp) NOTE: HN_MAX_REMAINING_DEPTH
57 *
58 * The last 9 bits together give an index for the total costs.
59 */
60typedef struct {
61 Hash_data key;
62 unsigned int data; /* Should be 32 bits, but only wastes 25% if 64 bits. */
63} Hashnode;
64
65#define HN_MAX_REMAINING_DEPTH 31
66
67
68/* Hashentry: an entry, with two nodes of the hash_table
69 */
70typedef struct {
71 Hashnode deepest;
72 Hashnode newest;
73} Hashentry;
74
75/* Hn is for hash node. */
76#define hn_get_value1(hn) ((hn >> 23) & 0x0f)
77#define hn_get_value2(hn) ((hn >> 19) & 0x0f)
78#define hn_get_move(hn) ((hn >> 9) & 0x3ff)
79#define hn_get_cost(hn) ((hn >> 5) & 0x0f)
80#define hn_get_remaining_depth(hn) ((hn >> 0) & 0x1f)
81#define hn_get_total_cost(hn) ((hn >> 0) & 0x1ff)
82
83#define hn_create_data(remaining_depth, value1, value2, move, cost) \
84 ((((value1) & 0x0f) << 23) \
85 | (((value2) & 0x0f) << 19) \
86 | (((move) & 0x3ff) << 9) \
87 | (((cost) & 0x0f) << 5) \
88 | (((remaining_depth & 0x1f) << 0)))
89
90
91/* Transposition_table: transposition table used for caching. */
92typedef struct {
93 unsigned int num_entries;
94 Hashentry *entries;
95 int is_clean;
96} Transposition_table;
97
98extern Transposition_table ttable;
99
100/* Number of cache entries to use by default if no cache memory usage
101 * has been set explicitly.
102 */
103#define DEFAULT_NUMBER_OF_CACHE_ENTRIES 350000
104
105void tt_free(Transposition_table *table);
106int tt_get(Transposition_table *table, enum routine_id routine,
107 int target1, int target2, int remaining_depth,
108 Hash_data *extra_hash,
109 int *value1, int *value2, int *move);
110void tt_update(Transposition_table *table, enum routine_id routine,
111 int target, int target2, int remaining_depth,
112 Hash_data *extra_hash,
113 int value1, int value2, int move);
114
115
116/* ================================================================ */
117
118
119/* Macros used from reading.c, readconnect.c, and owl.c to store and
120 * retrieve read results.
121 */
122
123#if TRACE_READ_RESULTS
124
125#define TRACE_CACHED_RESULT(result, move) \
126 gprintf("%o%s %1m %d %d %1m (cached) ", read_function_name, \
127 q, stackp, result, move); \
128 dump_stack();
129
130#define TRACE_CACHED_RESULT2(result1, result2, move) \
131 gprintf("%o%s %1m %1m %d %d %d %1m (cached) ", read_function_name, \
132 q1, q2, stackp, result1, result2, move); \
133 dump_stack();
134
135
136#define SETUP_TRACE_INFO(name, str) \
137 const char *read_function_name = name; \
138 int q = find_origin(str);
139
140#define SETUP_TRACE_INFO2(name, str1, str2) \
141 const char *read_function_name = name; \
142 int q1 = board[str1] == EMPTY ? str1 : find_origin(str1); \
143 int q2 = board[str2] == EMPTY ? str2 : find_origin(str2);
144
145#else
146
147#define TRACE_CACHED_RESULT(result, move)
148#define TRACE_CACHED_RESULT2(result1, result2, move)
149
150#define SETUP_TRACE_INFO(name, str) \
151 const char *read_function_name = name; \
152 int q = str;
153
154#define SETUP_TRACE_INFO2(name, str1, str2) \
155 const char *read_function_name = name; \
156 int q1 = str1; \
157 int q2 = str2;
158
159#endif
160
161/* Trace messages in decidestring/decidedragon sgf file. */
162void sgf_trace(const char *func, int str, int move, int result,
163 const char *message);
164/* Trace messages in decideconnection sgf file. */
165void sgf_trace2(const char *func, int str1, int str2, int move,
166 const char *result, const char *message);
167/* Trace messages in decidesemeai sgf file. */
168void sgf_trace_semeai(const char *func, int str1, int str2, int move,
169 int result1, int result2, const char *message);
170
171/* Macro to hide the call to sgf_trace(). Notice that a little black
172 * magic is going on here. Before using this macro, SETUP_TRACE_INFO
173 * must have been called to provide the variables read_function_name
174 * and q. These must of course not be used for anything else in
175 * the function.
176 */
177#define SGFTRACE(move, result, message) \
178 if (sgf_dumptree) \
179 sgf_trace(read_function_name, q, move, result, message)
180
181/* Corresponding macro for use in connection or semeai reading, where
182 * two groups are involved.
183 */
184#define SGFTRACE2(move, result, message) \
185 if (sgf_dumptree) \
186 sgf_trace2(read_function_name, q1, q2, move, \
187 result_to_string(result), message)
188
189#define SGFTRACE_SEMEAI(move, result1, result2, message) \
190 if (sgf_dumptree) \
191 sgf_trace_semeai(read_function_name, q1, q2, move, \
192 result1, result2, message)
193
194
195/* ================================================================ */
196
197/*
198 * These macros should be used in all the places where we want to
199 * return a result from a reading function and where we want to
200 * store the result in the hash table at the same time.
201 */
202
203#if !TRACE_READ_RESULTS
204
205#define READ_RETURN0(routine, str, remaining_depth) \
206 do { \
207 tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\
208 0, 0, NO_MOVE);\
209 return 0; \
210 } while (0)
211
212#define READ_RETURN(routine, str, remaining_depth, point, move, value) \
213 do { \
214 tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\
215 value, 0, move);\
216 if ((value) != 0 && (point) != 0) *(point) = (move); \
217 return (value); \
218 } while (0)
219
220#define READ_RETURN_SEMEAI(routine, str1, str2, remaining_depth, point, move, value1, value2) \
221 do { \
222 tt_update(&ttable, routine, str1, str2, remaining_depth, NULL, \
223 value1, value2, move); \
224 if ((value1) != 0 && (point) != 0) *(point) = (move); \
225 return; \
226 } while (0)
227
228#define READ_RETURN_CONN(routine, str1, str2, remaining_depth, point, move, value) \
229 do { \
230 tt_update(&ttable, routine, str1, str2, remaining_depth, NULL,\
231 value, 0, move);\
232 if ((value) != 0 && (point) != 0) *(point) = (move); \
233 return (value); \
234 } while (0)
235
236#define READ_RETURN_HASH(routine, str, remaining_depth, hash, point, move, value) \
237 do { \
238 tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, hash,\
239 value, 0, move);\
240 if ((value) != 0 && (point) != 0) *(point) = (move); \
241 return (value); \
242 } while (0)
243
244#define READ_RETURN2(routine, str, remaining_depth, point, move, value1, value2) \
245 do { \
246 tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\
247 value1, value2, move);\
248 if ((value1) != 0 && (point) != 0) *(point) = (move); \
249 return (value1); \
250 } while (0)
251
252#else /* !TRACE_READ_RESULTS */
253
254#define READ_RETURN0(routine, str, remaining_depth) \
255 do { \
256 tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\
257 0, 0, NO_MOVE);\
258 gprintf("%o%s %1m %d 0 0 ", read_function_name, q, stackp); \
259 dump_stack(); \
260 return 0; \
261 } while (0)
262
263#define READ_RETURN(routine, str, remaining_depth, point, move, value) \
264 do { \
265 tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\
266 value, 0, move);\
267 if ((value) != 0 && (point) != 0) *(point) = (move); \
268 gprintf("%o%s %1m %d %d %1m ", read_function_name, q, stackp, \
269 (value), (move)); \
270 dump_stack(); \
271 return (value); \
272 } while (0)
273
274#define READ_RETURN_SEMEAI(routine, str1, str2, remaining_depth, point, move, value1, value2) \
275 do { \
276 tt_update(&ttable, routine, str1, str2, remaining_depth, NULL, \
277 value1, value2, move); \
278 if ((value1) != 0 && (point) != 0) *(point) = (move); \
279 gprintf("%o%s %1m %1m %d %d %d %1m ", read_function_name, q1, q2, stackp, \
280 (value1), (value2), (move)); \
281 dump_stack(); \
282 return; \
283 } while (0)
284
285#define READ_RETURN_CONN(routine, str1, str2, remaining_depth, point, move, value) \
286 do { \
287 tt_update(&ttable, routine, str1, str2, remaining_depth, NULL,\
288 value, 0, move);\
289 if ((value) != 0 && (point) != 0) *(point) = (move); \
290 gprintf("%o%s %1m %1m %d %d %1m ", read_function_name, q1, q2, stackp, \
291 (value), (move)); \
292 dump_stack(); \
293 return (value); \
294 } while (0)
295
296#define READ_RETURN_HASH(routine, str, remaining_depth, hash, point, move, value) \
297 do { \
298 tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, hash,\
299 value, 0, move);\
300 if ((value) != 0 && (point) != 0) *(point) = (move); \
301 gprintf("%o%s %1m %d %d %1m ", read_function_name, q, stackp, \
302 (value), (move)); \
303 dump_stack(); \
304 return (value); \
305 } while (0)
306
307#define READ_RETURN2(routine, str, remaining_depth, point, move, value1, value2) \
308 do { \
309 tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\
310 value1, value2, move);\
311 if ((value1) != 0 && (point) != 0) *(point) = (move); \
312 gprintf("%o%s %1m %d %d %1m ", read_function_name, q, stackp, \
313 (value1), (move)); \
314 dump_stack(); \
315 return (value1); \
316 } while (0)
317
318#endif
319
320
321/* ================================================================ */
322/* This has actually nothing to do with caching, but is useful in
323 * the same places where the caching is.
324 */
325
326/* Macro to use when saving ko results while continuing to look for an
327 * unconditional result. It's assumed that we have tried the move at
328 * (move) and then called an attack or defense function giving the
329 * result passed in the code parameter.
330 *
331 * In general we prefer not to have to do the first ko threat. Thus a
332 * savecode KO_A is always better than a savecode KO_B. Also we always
333 * prefer to keep the old move if we get the same savecode once more,
334 * on the assumption that the moves have been ordered with the
335 * presumably best one first.
336 *
337 * Notice that the savecode may be either 0 (nothing found so far), KO_B
338 * or KO_A. Occasionally savecode WIN is also used, indicating an effective
339 * but not preferred move, typically because it's either a sacrifice
340 * or a backfilling move. If possible, we prefer making non-sacrifice
341 * and direct moves. Of course savecode WIN is better than KO_A or KO_B.
342 */
343
344#define UPDATE_SAVED_KO_RESULT(savecode, save, code, move) \
345 if (code != 0 && REVERSE_RESULT(code) > savecode) { \
346 save = move; \
347 savecode = REVERSE_RESULT(code); \
348 } \
349
350/* Same as above, except this should be used when there's no
351 * intervening trymove(). Thus we shouldn't reverse the save code.
352 */
353#define UPDATE_SAVED_KO_RESULT_UNREVERSED(savecode, save, code, move) \
354 if (code != WIN && code > savecode) { \
355 save = move; \
356 savecode = code; \
357 }
358
359
360/* This too isn't really related to caching but is convenient to have here.
361 * (Needs to be available in reading.c and persistent.c.)
362 *
363 * Minimum number of nodes for which DEBUG_READING_PERFORMANCE reports
364 * anything.
365 */
366#define MIN_READING_NODES_TO_REPORT 1000
367
368
369#endif /* _CACHE_H_ */
370
371
372/*
373 * Local Variables:
374 * tab-width: 8
375 * c-basic-offset: 2
376 * End:
377 */