aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48/gendata_h48.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/solvers/h48/gendata_h48.h')
-rw-r--r--src/solvers/h48/gendata_h48.h255
1 files changed, 8 insertions, 247 deletions
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
index 8470b2f..e8bb7b2 100644
--- a/src/solvers/h48/gendata_h48.h
+++ b/src/solvers/h48/gendata_h48.h
@@ -2,13 +2,9 @@ STATIC long long gendata_h48_dispatch(
2 const char *, unsigned long long, unsigned char *); 2 const char *, unsigned long long, unsigned char *);
3STATIC uint64_t gendata_h48short(gendata_h48short_arg_t [static 1]); 3STATIC uint64_t gendata_h48short(gendata_h48short_arg_t [static 1]);
4STATIC int64_t gendata_h48(gendata_h48_arg_t [static 1]); 4STATIC int64_t gendata_h48(gendata_h48_arg_t [static 1]);
5STATIC void gendata_h48h0k4(gendata_h48_arg_t [static 1]);
6STATIC void gendata_h48k2(gendata_h48_arg_t [static 1]); 5STATIC void gendata_h48k2(gendata_h48_arg_t [static 1]);
7
8STATIC void *gendata_h48h0k4_runthread(void *);
9STATIC void *gendata_h48k2_runthread(void *); 6STATIC void *gendata_h48k2_runthread(void *);
10 7
11STATIC_INLINE void gendata_h48_mark_atomic(gendata_h48_mark_t [static 1]);
12STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t [static 1]); 8STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t [static 1]);
13STATIC_INLINE bool gendata_h48k2_dfs_stop( 9STATIC_INLINE bool gendata_h48k2_dfs_stop(
14 cube_t, int8_t, h48k2_dfs_arg_t [static 1]); 10 cube_t, int8_t, h48k2_dfs_arg_t [static 1]);
@@ -24,10 +20,6 @@ STATIC_INLINE uint8_t get_h48_pvalmin(
24 const unsigned char *, uint64_t, uint8_t); 20 const unsigned char *, uint64_t, uint8_t);
25STATIC_INLINE void set_h48_pvalmin( 21STATIC_INLINE void set_h48_pvalmin(
26 unsigned char *, uint64_t, uint8_t, uint8_t); 22 unsigned char *, uint64_t, uint8_t, uint8_t);
27STATIC_INLINE uint8_t get_h48_pval_atomic(
28 wrapthread_atomic const unsigned char *, uint64_t, uint8_t);
29STATIC_INLINE void set_h48_pval_atomic(
30 wrapthread_atomic unsigned char *, uint64_t, uint8_t, uint8_t);
31 23
32STATIC long long 24STATIC long long
33gendata_h48_dispatch( 25gendata_h48_dispatch(
@@ -87,23 +79,16 @@ gendata_h48short(gendata_h48short_arg_t arg[static 1])
87STATIC int64_t 79STATIC int64_t
88gendata_h48(gendata_h48_arg_t arg[static 1]) 80gendata_h48(gendata_h48_arg_t arg[static 1])
89{ 81{
90 uint64_t size, cocsepsize, h48size, fallbacksize, fallback2size, of; 82 uint64_t size, cocsepsize, h48size, eoesepsize;
91 long long r; 83 long long r;
92 unsigned char *cocsepdata_offset; 84 unsigned char *cocsepdata_offset;
93 tableinfo_t cocsepinfo, h48info, fallbackinfo; 85 tableinfo_t cocsepinfo, h48info;
94 gendata_h48_arg_t arg_h0k4;
95 86
96 cocsepsize = COCSEP_FULLSIZE; 87 cocsepsize = COCSEP_FULLSIZE;
97 h48size = INFOSIZE + H48_TABLESIZE(arg->h, arg->k); 88 h48size = INFOSIZE + H48_TABLESIZE(arg->h, arg->k);
98 fallbacksize = arg->k == 2 ? INFOSIZE + H48_TABLESIZE(0, 4) : 0; 89 eoesepsize = EOESEP_FULLSIZE;
99 fallback2size = EOESEP_FULLSIZE;
100
101 /* Add padding for 8-bit alignment */
102 h48size = 8 * DIV_ROUND_UP(h48size, 8);
103 fallbacksize = 8 * DIV_ROUND_UP(fallbacksize, 8);
104 fallback2size = 8 * DIV_ROUND_UP(fallback2size, 8);
105 90
106 size = cocsepsize + h48size + fallbacksize + fallback2size; 91 size = cocsepsize + h48size + eoesepsize;
107 92
108 if (arg->buf == NULL) 93 if (arg->buf == NULL)
109 return size; /* Dry-run */ 94 return size; /* Dry-run */
@@ -121,18 +106,11 @@ gendata_h48(gendata_h48_arg_t arg[static 1])
121 arg->cocsepdata = (uint32_t *)cocsepdata_offset; 106 arg->cocsepdata = (uint32_t *)cocsepdata_offset;
122 arg->h48buf = (wrapthread_atomic unsigned char*)arg->buf + cocsepsize; 107 arg->h48buf = (wrapthread_atomic unsigned char*)arg->buf + cocsepsize;
123 108
109/* TODO this can probably be removed now? */
124 arg->base = 99; 110 arg->base = 99;
111/* */
125 112
126 if (arg->h == 0 && arg->k == 4) { 113 gendata_h48k2(arg);
127 gendata_h48h0k4(arg);
128 } else if (arg->k == 2) {
129 gendata_h48k2(arg);
130 } else {
131 LOG("[H48 gendata] Error: cannot generate data for h = %" PRIu8
132 " and k = %" PRIu8 " (not implemented yet)\n",
133 arg->h, arg->k);
134 return NISSY_ERROR_INVALID_SOLVER;
135 }
136 114
137 r = readtableinfo(arg->buf_size, arg->buf, &cocsepinfo); 115 r = readtableinfo(arg->buf_size, arg->buf, &cocsepinfo);
138 if (r != NISSY_OK) { 116 if (r != NISSY_OK) {
@@ -149,25 +127,9 @@ gendata_h48(gendata_h48_arg_t arg[static 1])
149 return NISSY_ERROR_UNKNOWN; 127 return NISSY_ERROR_UNKNOWN;
150 } 128 }
151 129
152 /* Add h0k4 fallback table */
153
154 if (arg->k == 2) {
155 arg_h0k4 = *arg;
156 arg_h0k4.h = 0;
157 arg_h0k4.k = 4;
158 arg_h0k4.base = 0;
159 arg_h0k4.maxdepth = 20;
160 arg_h0k4.buf_size = arg->buf_size - h48size;
161 arg_h0k4.buf = arg->buf + cocsepsize + h48size;
162 arg_h0k4.h48buf = arg->h48buf + h48size;
163
164 gendata_h48h0k4(&arg_h0k4);
165
166 }
167
168 /* Add eoesep fallback table */ 130 /* Add eoesep fallback table */
169 131
170 gendata_eoesep(arg->buf + (size - fallback2size), 20); 132 gendata_eoesep(arg->buf + (size - eoesepsize), 20);
171 133
172 /* Update tableinfo with correct next values */ 134 /* Update tableinfo with correct next values */
173 135
@@ -186,166 +148,10 @@ gendata_h48(gendata_h48_arg_t arg[static 1])
186 return NISSY_ERROR_UNKNOWN; 148 return NISSY_ERROR_UNKNOWN;
187 } 149 }
188 150
189 if (arg->k == 2) {
190 r = readtableinfo_n(arg->buf_size, arg->buf, 3, &fallbackinfo);
191 if (r != NISSY_OK) {
192 LOG("[H48 gendata] Error: could not read info for h48 "
193 "fallback table\n");
194 return NISSY_ERROR_UNKNOWN;
195 }
196
197 of = cocsepsize + h48size;
198 fallbackinfo.next = fallbacksize;
199 r = writetableinfo(
200 &fallbackinfo, arg->buf_size - of, arg->buf + of);
201 if (r != NISSY_OK) {
202 LOG("[H48 gendata] Error: could not write info for "
203 "h48 fallback table\n");
204 return NISSY_ERROR_UNKNOWN;
205 }
206 }
207
208 return size; 151 return size;
209} 152}
210 153
211STATIC void 154STATIC void
212gendata_h48h0k4(gendata_h48_arg_t arg[static 1])
213{
214 wrapthread_atomic unsigned char *table;
215 uint8_t val;
216 uint64_t i, sc, done, d, h48max;
217 uint64_t t, tt, isize, cc, bufsize;
218 h48h0k4_bfs_arg_t bfsarg[THREADS];
219 wrapthread_define_var_thread_t(thread[THREADS]);
220 wrapthread_define_var_mutex_t(table_mutex[CHUNKS]);
221
222 arg->info = (tableinfo_t) {
223 .solver = "h48 solver h = 0, k = 4",
224 .type = TABLETYPE_PRUNING,
225 .infosize = INFOSIZE,
226 .fullsize = H48_TABLESIZE(0, 4) + INFOSIZE,
227 .hash = 0,
228 .entries = H48_COORDMAX(0),
229 .classes = 0,
230 .h48h = 0,
231 .bits = 4,
232 .base = 0,
233 .maxvalue = 0,
234 .next = 0,
235 };
236
237 table = arg->h48buf + INFOSIZE;
238 memset(table, 0xFF, H48_TABLESIZE(0, 4));
239
240 h48max = H48_COORDMAX(0);
241 sc = coord_h48(SOLVED_CUBE, arg->cocsepdata, 0);
242 set_h48_pval_atomic(table, sc, 4, 0);
243 arg->info.distribution[0] = 1;
244
245 isize = h48max / THREADS;
246 isize = (isize / H48_COEFF(arg->k)) * H48_COEFF(arg->k);
247 for (t = 0; t < CHUNKS; t++)
248 wrapthread_mutex_init(&table_mutex[t], NULL);
249 for (t = 0; t < THREADS; t++) {
250 bfsarg[t] = (h48h0k4_bfs_arg_t) {
251 .cocsepdata = arg->cocsepdata,
252 .table = table,
253 .selfsim = arg->selfsim,
254 .crep = arg->crep,
255 .start = isize * t,
256 .end = t == THREADS-1 ? h48max : isize * (t+1),
257 };
258 for (tt = 0; tt < CHUNKS; tt++)
259 bfsarg[t].table_mutex[tt] = &table_mutex[tt];
260 }
261 for (done = 1, d = 1; done < h48max && d <= arg->maxdepth; d++) {
262 LOG("[H48 gendata] Generating depth %" PRIu64 "\n", d);
263
264 for (t = 0; t < THREADS; t++) {
265 bfsarg[t].depth = d;
266 wrapthread_create(&thread[t], NULL,
267 gendata_h48h0k4_runthread, &bfsarg[t]);
268 }
269
270 for (t = 0; t < THREADS; t++)
271 wrapthread_join(thread[t], NULL);
272
273 for (i = 0, cc = 0; i < h48max; i++) {
274 val = get_h48_pval_atomic(table, i, 4);
275 cc += val == d;
276 }
277
278 done += cc;
279 arg->info.distribution[d] = cc;
280
281 LOG("[H48 gendata] Found %" PRIu64 "\n", cc);
282 }
283
284 arg->info.maxvalue = d - 1;
285 bufsize = arg->buf_size - COCSEP_FULLSIZE;
286 writetableinfo(&arg->info, bufsize, (unsigned char *)arg->h48buf);
287}
288
289STATIC void *
290gendata_h48h0k4_runthread(void *arg)
291{
292 static const uint8_t breakpoint = 10; /* Hand-picked optimal */
293
294 uint8_t c, m;
295 uint64_t i;
296 uint64_t j;
297 cube_t cube, moved;
298 gendata_h48_mark_t markarg;
299 h48h0k4_bfs_arg_t *bfsarg;
300
301 bfsarg = (h48h0k4_bfs_arg_t *)arg;
302
303 markarg = (gendata_h48_mark_t) {
304 .depth = bfsarg->depth,
305 .h = 0,
306 .k = 4,
307 .base = 0, /* Unused */
308 .cocsepdata = bfsarg->cocsepdata,
309 .selfsim = bfsarg->selfsim,
310 .table_atomic = bfsarg->table,
311 .table_mutex = bfsarg->table_mutex,
312 };
313
314 /*
315 * If depth < breakpoint, scan all neighbors of coordinates at depth-1.
316 * Otherwise, scan all neighbors of unvisited coordinates.
317 */
318 for (i = bfsarg->start; i < bfsarg->end; i++) {
319 c = get_h48_pval_atomic(bfsarg->table, i, 4);
320
321 if ((bfsarg->depth < breakpoint && c != bfsarg->depth - 1) ||
322 (bfsarg->depth >= breakpoint && c != 0xF))
323 continue;
324
325 cube = invcoord_h48(i, bfsarg->crep, 0);
326 for (m = 0; m < 18; m++) {
327 moved = move(cube, m);
328 j = coord_h48(moved, bfsarg->cocsepdata, 0);
329 c = get_h48_pval_atomic(bfsarg->table, j, 4);
330 if (bfsarg->depth < breakpoint) {
331 if (c <= bfsarg->depth)
332 continue;
333 markarg.cube = moved;
334 gendata_h48_mark_atomic(&markarg);
335 } else {
336 if (c >= bfsarg->depth)
337 continue;
338 markarg.cube = cube;
339 gendata_h48_mark_atomic(&markarg);
340 break; /* Enough to find one, skip the rest */
341 }
342 }
343 }
344
345 return NULL;
346}
347
348STATIC void
349gendata_h48k2(gendata_h48_arg_t arg[static 1]) 155gendata_h48k2(gendata_h48_arg_t arg[static 1])
350{ 156{
351 /* 157 /*
@@ -396,10 +202,8 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
396 static const uint64_t capacity = 10000019; 202 static const uint64_t capacity = 10000019;
397 static const uint64_t randomizer = 10000079; 203 static const uint64_t randomizer = 10000079;
398 204
399 uint8_t t;
400 int sleeptime; 205 int sleeptime;
401 unsigned char *table; 206 unsigned char *table;
402 uint64_t j;
403 wrapthread_atomic uint64_t count; 207 wrapthread_atomic uint64_t count;
404 uint64_t i, ii, inext, bufsize, done, nshort, velocity; 208 uint64_t i, ii, inext, bufsize, done, nshort, velocity;
405 h48map_t shortcubes; 209 h48map_t shortcubes;
@@ -613,27 +417,6 @@ gendata_h48k2_dfs(h48k2_dfs_arg_t arg[static 1])
613} 417}
614 418
615STATIC_INLINE void 419STATIC_INLINE void
616gendata_h48_mark_atomic(gendata_h48_mark_t arg[static 1])
617{
618 uint8_t oldval, newval;
619 uint64_t coord;
620 wrapthread_define_if_threads(uint64_t, mutex);
621
622 FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim,
623 coord = coord_h48(arg->cube, arg->cocsepdata, arg->h);
624 oldval = get_h48_pval_atomic(arg->table_atomic, coord, arg->k);
625 newval = (uint8_t)MAX(arg->depth, 0);
626 if (newval < oldval) {
627 mutex = H48_INDEX(coord, arg->k) % CHUNKS;
628 wrapthread_mutex_lock(arg->table_mutex[mutex]);
629 set_h48_pval_atomic(
630 arg->table_atomic, coord, arg->k, newval);
631 wrapthread_mutex_unlock(arg->table_mutex[mutex]);
632 }
633 )
634}
635
636STATIC_INLINE void
637gendata_h48_mark(gendata_h48_mark_t arg[static 1]) 420gendata_h48_mark(gendata_h48_mark_t arg[static 1])
638{ 421{
639 uint8_t oldval, newval, v; 422 uint8_t oldval, newval, v;
@@ -736,16 +519,6 @@ get_h48_pvalmin(const unsigned char *table, uint64_t i, uint8_t k)
736 get_h48_pval(table, i+UINT64_C(1), k); 519 get_h48_pval(table, i+UINT64_C(1), k);
737} 520}
738 521
739STATIC_INLINE uint8_t
740get_h48_pval_atomic(
741 wrapthread_atomic const unsigned char *table,
742 uint64_t i,
743 uint8_t k
744)
745{
746 return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k);
747}
748
749STATIC_INLINE void 522STATIC_INLINE void
750set_h48_pval(unsigned char *table, uint64_t i, uint8_t k, uint8_t val) 523set_h48_pval(unsigned char *table, uint64_t i, uint8_t k, uint8_t val)
751{ 524{
@@ -762,15 +535,3 @@ set_h48_pvalmin(unsigned char *table, uint64_t i, uint8_t k, uint8_t val)
762 set_h48_pval(table, i, k, v >> UINT8_C(2)); 535 set_h48_pval(table, i, k, v >> UINT8_C(2));
763 set_h48_pval(table, i+UINT64_C(1), k, v % UINT8_C(4)); 536 set_h48_pval(table, i+UINT64_C(1), k, v % UINT8_C(4));
764} 537}
765
766STATIC_INLINE void
767set_h48_pval_atomic(
768 wrapthread_atomic unsigned char *table,
769 uint64_t i,
770 uint8_t k,
771 uint8_t val
772)
773{
774 table[H48_INDEX(i, k)] = (table[H48_INDEX(i, k)] & (~H48_MASK(i, k)))
775 | (val << H48_SHIFT(i, k));
776}

Generated with cgit - Back to sebastiano.tronto.net