aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48/gendata_h48.h
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-12-14 15:12:36 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2025-12-14 16:09:31 +0100
commitbcd52547af58b15868e24f3904e307548d1fd505 (patch)
treecda0a871f65575bb15fb4536c7b103c13caf433e /src/solvers/h48/gendata_h48.h
parent21fdf9697ddfab0a9c082a91ae0a79b1b574774c (diff)
downloadnissy-core-bcd52547af58b15868e24f3904e307548d1fd505.tar.gz
nissy-core-bcd52547af58b15868e24f3904e307548d1fd505.zip
Cleanup, update documentation, fix examples
Diffstat (limited to 'src/solvers/h48/gendata_h48.h')
-rw-r--r--src/solvers/h48/gendata_h48.h121
1 files changed, 57 insertions, 64 deletions
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
index e8bb7b2..68111c8 100644
--- a/src/solvers/h48/gendata_h48.h
+++ b/src/solvers/h48/gendata_h48.h
@@ -2,24 +2,22 @@ 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_h48k2(gendata_h48_arg_t [static 1]); 5STATIC void gendata_h48_maintable(gendata_h48_arg_t [static 1]);
6STATIC void *gendata_h48k2_runthread(void *); 6STATIC void *gendata_h48_runthread(void *);
7 7
8STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t [static 1]); 8STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t [static 1]);
9STATIC_INLINE bool gendata_h48k2_dfs_stop( 9STATIC_INLINE bool gendata_h48_dfs_stop(
10 cube_t, int8_t, h48k2_dfs_arg_t [static 1]); 10 cube_t, int8_t, h48_dfs_arg_t [static 1]);
11STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t [static 1]); 11STATIC void gendata_h48_dfs(h48_dfs_arg_t [static 1]);
12STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t [static 1]); 12STATIC tableinfo_t makeinfo_h48(gendata_h48_arg_t [static 1]);
13 13
14STATIC const uint32_t *get_cocsepdata_constptr(const unsigned char *); 14STATIC const uint32_t *get_cocsepdata_constptr(const unsigned char *);
15STATIC const unsigned char *get_h48data_constptr(const unsigned char *); 15STATIC const unsigned char *get_h48data_constptr(const unsigned char *);
16 16
17STATIC_INLINE uint8_t get_h48_pval(const unsigned char *, uint64_t, uint8_t); 17STATIC_INLINE uint8_t get_h48_pval(const unsigned char *, uint64_t);
18STATIC_INLINE void set_h48_pval(unsigned char *, uint64_t, uint8_t, uint8_t); 18STATIC_INLINE void set_h48_pval(unsigned char *, uint64_t, uint8_t);
19STATIC_INLINE uint8_t get_h48_pvalmin( 19STATIC_INLINE uint8_t get_h48_pvalmin(const unsigned char *, uint64_t);
20 const unsigned char *, uint64_t, uint8_t); 20STATIC_INLINE void set_h48_pvalmin(unsigned char *, uint64_t, uint8_t);
21STATIC_INLINE void set_h48_pvalmin(
22 unsigned char *, uint64_t, uint8_t, uint8_t);
23 21
24STATIC long long 22STATIC long long
25gendata_h48_dispatch( 23gendata_h48_dispatch(
@@ -31,7 +29,7 @@ gendata_h48_dispatch(
31 long long err; 29 long long err;
32 gendata_h48_arg_t arg; 30 gendata_h48_arg_t arg;
33 31
34 err = parse_h48_hk(solver, &arg.h, &arg.k); 32 err = parse_h48h(solver, &arg.h);
35 if (err != NISSY_OK) 33 if (err != NISSY_OK)
36 return err; 34 return err;
37 35
@@ -85,7 +83,7 @@ gendata_h48(gendata_h48_arg_t arg[static 1])
85 tableinfo_t cocsepinfo, h48info; 83 tableinfo_t cocsepinfo, h48info;
86 84
87 cocsepsize = COCSEP_FULLSIZE; 85 cocsepsize = COCSEP_FULLSIZE;
88 h48size = INFOSIZE + H48_TABLESIZE(arg->h, arg->k); 86 h48size = INFOSIZE + H48_TABLESIZE(arg->h);
89 eoesepsize = EOESEP_FULLSIZE; 87 eoesepsize = EOESEP_FULLSIZE;
90 88
91 size = cocsepsize + h48size + eoesepsize; 89 size = cocsepsize + h48size + eoesepsize;
@@ -106,11 +104,8 @@ gendata_h48(gendata_h48_arg_t arg[static 1])
106 arg->cocsepdata = (uint32_t *)cocsepdata_offset; 104 arg->cocsepdata = (uint32_t *)cocsepdata_offset;
107 arg->h48buf = (wrapthread_atomic unsigned char*)arg->buf + cocsepsize; 105 arg->h48buf = (wrapthread_atomic unsigned char*)arg->buf + cocsepsize;
108 106
109/* TODO this can probably be removed now? */ 107 /* Compute the main H48 table with two bits per entry */
110 arg->base = 99; 108 gendata_h48_maintable(arg);
111/* */
112
113 gendata_h48k2(arg);
114 109
115 r = readtableinfo(arg->buf_size, arg->buf, &cocsepinfo); 110 r = readtableinfo(arg->buf_size, arg->buf, &cocsepinfo);
116 if (r != NISSY_OK) { 111 if (r != NISSY_OK) {
@@ -152,10 +147,10 @@ gendata_h48(gendata_h48_arg_t arg[static 1])
152} 147}
153 148
154STATIC void 149STATIC void
155gendata_h48k2(gendata_h48_arg_t arg[static 1]) 150gendata_h48_maintable(gendata_h48_arg_t arg[static 1])
156{ 151{
157 /* 152 /*
158 * A good base value for the k=2 tables have few positions with value 153 * A good base value for the h48 tables have few positions with value
159 * 0, because those are treated as lower bound 0 and require a second 154 * 0, because those are treated as lower bound 0 and require a second
160 * lookup in another table, and at the same time not too many positions 155 * lookup in another table, and at the same time not too many positions
161 * with value 3, because some of those are under-estimates. 156 * with value 3, because some of those are under-estimates.
@@ -208,13 +203,13 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
208 uint64_t i, ii, inext, bufsize, done, nshort, velocity; 203 uint64_t i, ii, inext, bufsize, done, nshort, velocity;
209 h48map_t shortcubes; 204 h48map_t shortcubes;
210 gendata_h48short_arg_t shortarg; 205 gendata_h48short_arg_t shortarg;
211 h48k2_dfs_arg_t dfsarg[THREADS]; 206 h48_dfs_arg_t dfsarg[THREADS];
212 wrapthread_define_var_thread_t(thread[THREADS]); 207 wrapthread_define_var_thread_t(thread[THREADS]);
213 wrapthread_define_var_mutex_t(shortcubes_mutex); 208 wrapthread_define_var_mutex_t(shortcubes_mutex);
214 wrapthread_define_var_mutex_t(table_mutex[CHUNKS]); 209 wrapthread_define_var_mutex_t(table_mutex[CHUNKS]);
215 210
216 table = (unsigned char *)arg->h48buf + INFOSIZE; 211 table = (unsigned char *)arg->h48buf + INFOSIZE;
217 memset(table, 0xFF, H48_TABLESIZE(arg->h, arg->k)); 212 memset(table, 0xFF, H48_TABLESIZE(arg->h));
218 213
219 LOG("[H48 gendata] Computing depth <=%" PRIu8 "\n", shortdepth) 214 LOG("[H48 gendata] Computing depth <=%" PRIu8 "\n", shortdepth)
220 h48map_create(&shortcubes, capacity, randomizer); 215 h48map_create(&shortcubes, capacity, randomizer);
@@ -229,9 +224,8 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
229 nshort = shortarg.map->n; 224 nshort = shortarg.map->n;
230 LOG("[H48 gendata] Computed %" PRIu64 " positions\n", nshort); 225 LOG("[H48 gendata] Computed %" PRIu64 " positions\n", nshort);
231 226
232 if (arg->base >= 20) 227 arg->base = base[arg->h];
233 arg->base = base[arg->h]; 228 arg->info = makeinfo_h48(arg);
234 arg->info = makeinfo_h48k2(arg);
235 229
236 inext = 0; 230 inext = 0;
237 count = 0; 231 count = 0;
@@ -239,9 +233,8 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
239 for (i = 0; i < CHUNKS; i++) 233 for (i = 0; i < CHUNKS; i++)
240 wrapthread_mutex_init(&table_mutex[i], NULL); 234 wrapthread_mutex_init(&table_mutex[i], NULL);
241 for (i = 0; i < THREADS; i++) { 235 for (i = 0; i < THREADS; i++) {
242 dfsarg[i] = (h48k2_dfs_arg_t){ 236 dfsarg[i] = (h48_dfs_arg_t){
243 .h = arg->h, 237 .h = arg->h,
244 .k = arg->k,
245 .base = arg->base, 238 .base = arg->base,
246 .shortdepth = shortdepth, 239 .shortdepth = shortdepth,
247 .cocsepdata = arg->cocsepdata, 240 .cocsepdata = arg->cocsepdata,
@@ -257,12 +250,13 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
257 dfsarg[i].table_mutex[ii] = &table_mutex[ii]; 250 dfsarg[i].table_mutex[ii] = &table_mutex[ii];
258 251
259 wrapthread_create( 252 wrapthread_create(
260 &thread[i], NULL, gendata_h48k2_runthread, &dfsarg[i]); 253 &thread[i], NULL, gendata_h48_runthread, &dfsarg[i]);
261 } 254 }
262 255
263 if (NISSY_CANSLEEP) { 256 if (NISSY_CANSLEEP) {
264 /* Log the progress periodically */ 257 /* Log the progress periodically */
265 LOG("Processing 'short cubes'. This will take a while.\n"); 258 LOG("[H48 gendata] Processing 'short cubes'. "
259 "This will take a while.\n");
266 260
267 /* Estimate velocity by checking how much is done after 1s */ 261 /* Estimate velocity by checking how much is done after 1s */
268 msleep(1000); 262 msleep(1000);
@@ -277,8 +271,8 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
277 wrapthread_mutex_lock(&shortcubes_mutex); 271 wrapthread_mutex_lock(&shortcubes_mutex);
278 done = count; 272 done = count;
279 wrapthread_mutex_unlock(&shortcubes_mutex); 273 wrapthread_mutex_unlock(&shortcubes_mutex);
280 LOG("Processed %" PRIu64 " / %" PRIu64 " cubes\n", 274 LOG("[H48 gendata] Processed %" PRIu64 " / %" PRIu64
281 (done / 1000) * 1000, nshort); 275 " cubes\n", (done / 1000) * 1000, nshort);
282 } 276 }
283 } else { 277 } else {
284 LOG("Status updates won't be available because the sleep() " 278 LOG("Status updates won't be available because the sleep() "
@@ -297,14 +291,14 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1])
297} 291}
298 292
299STATIC void * 293STATIC void *
300gendata_h48k2_runthread(void *arg) 294gendata_h48_runthread(void *arg)
301{ 295{
302 uint64_t coord, coordext, coordmin; 296 uint64_t coord, coordext, coordmin;
303 kvpair_t kv; 297 kvpair_t kv;
304 h48k2_dfs_arg_t *dfsarg; 298 h48_dfs_arg_t *dfsarg;
305 wrapthread_define_if_threads(uint64_t, mutex); 299 wrapthread_define_if_threads(uint64_t, mutex);
306 300
307 dfsarg = (h48k2_dfs_arg_t *)arg; 301 dfsarg = (h48_dfs_arg_t *)arg;
308 302
309 while (true) { 303 while (true) {
310 wrapthread_mutex_lock(dfsarg->shortcubes_mutex); 304 wrapthread_mutex_lock(dfsarg->shortcubes_mutex);
@@ -324,12 +318,12 @@ gendata_h48k2_runthread(void *arg)
324 318
325 mutex = H48_LINE(coord) % CHUNKS; 319 mutex = H48_LINE(coord) % CHUNKS;
326 wrapthread_mutex_lock(dfsarg->table_mutex[mutex]); 320 wrapthread_mutex_lock(dfsarg->table_mutex[mutex]);
327 set_h48_pval(dfsarg->table, coordext, dfsarg->k, 0); 321 set_h48_pval(dfsarg->table, coordext, 0);
328 set_h48_pvalmin(dfsarg->table, coordmin, dfsarg->k, kv.val); 322 set_h48_pvalmin(dfsarg->table, coordmin, kv.val);
329 wrapthread_mutex_unlock(dfsarg->table_mutex[mutex]); 323 wrapthread_mutex_unlock(dfsarg->table_mutex[mutex]);
330 } else { 324 } else {
331 dfsarg->cube = invcoord_h48(kv.key, dfsarg->crep, 11); 325 dfsarg->cube = invcoord_h48(kv.key, dfsarg->crep, 11);
332 gendata_h48k2_dfs(dfsarg); 326 gendata_h48_dfs(dfsarg);
333 } 327 }
334 } 328 }
335 329
@@ -337,7 +331,7 @@ gendata_h48k2_runthread(void *arg)
337} 331}
338 332
339STATIC void 333STATIC void
340gendata_h48k2_dfs(h48k2_dfs_arg_t arg[static 1]) 334gendata_h48_dfs(h48_dfs_arg_t arg[static 1])
341{ 335{
342 int8_t d; 336 int8_t d;
343 uint8_t m[4]; 337 uint8_t m[4];
@@ -346,7 +340,6 @@ gendata_h48k2_dfs(h48k2_dfs_arg_t arg[static 1])
346 340
347 markarg = (gendata_h48_mark_t) { 341 markarg = (gendata_h48_mark_t) {
348 .h = arg->h, 342 .h = arg->h,
349 .k = arg->k,
350 .base = arg->base, 343 .base = arg->base,
351 .cocsepdata = arg->cocsepdata, 344 .cocsepdata = arg->cocsepdata,
352 .selfsim = arg->selfsim, 345 .selfsim = arg->selfsim,
@@ -365,7 +358,7 @@ gendata_h48k2_dfs(h48k2_dfs_arg_t arg[static 1])
365 for (m[0] = 0; m[0] < 18; m[0]++) { 358 for (m[0] = 0; m[0] < 18; m[0]++) {
366 markarg.depth = d+1; 359 markarg.depth = d+1;
367 cube[0] = move(arg->cube, m[0]); 360 cube[0] = move(arg->cube, m[0]);
368 if (gendata_h48k2_dfs_stop(cube[0], d+1, arg)) 361 if (gendata_h48_dfs_stop(cube[0], d+1, arg))
369 continue; 362 continue;
370 markarg.cube = cube[0]; 363 markarg.cube = cube[0];
371 gendata_h48_mark(&markarg); 364 gendata_h48_mark(&markarg);
@@ -378,7 +371,7 @@ gendata_h48k2_dfs(h48k2_dfs_arg_t arg[static 1])
378 continue; 371 continue;
379 } 372 }
380 cube[1] = move(cube[0], m[1]); 373 cube[1] = move(cube[0], m[1]);
381 if (gendata_h48k2_dfs_stop(cube[1], d+2, arg)) 374 if (gendata_h48_dfs_stop(cube[1], d+2, arg))
382 continue; 375 continue;
383 markarg.cube = cube[1]; 376 markarg.cube = cube[1];
384 gendata_h48_mark(&markarg); 377 gendata_h48_mark(&markarg);
@@ -393,7 +386,7 @@ gendata_h48k2_dfs(h48k2_dfs_arg_t arg[static 1])
393 continue; 386 continue;
394 } 387 }
395 cube[2] = move(cube[1], m[2]); 388 cube[2] = move(cube[1], m[2]);
396 if (gendata_h48k2_dfs_stop(cube[2], d+3, arg)) 389 if (gendata_h48_dfs_stop(cube[2], d+3, arg))
397 continue; 390 continue;
398 markarg.cube = cube[2]; 391 markarg.cube = cube[2];
399 gendata_h48_mark(&markarg); 392 gendata_h48_mark(&markarg);
@@ -430,18 +423,18 @@ gendata_h48_mark(gendata_h48_mark_t arg[static 1])
430 423
431 mutex = H48_LINE(coord) % CHUNKS; 424 mutex = H48_LINE(coord) % CHUNKS;
432 wrapthread_mutex_lock(arg->table_mutex[mutex]); 425 wrapthread_mutex_lock(arg->table_mutex[mutex]);
433 oldval = get_h48_pval(arg->table, coordext, arg->k); 426 oldval = get_h48_pval(arg->table, coordext);
434 newval = (uint8_t)MAX(arg->depth, 0); 427 newval = (uint8_t)MAX(arg->depth, 0);
435 v = MIN(newval, oldval); 428 v = MIN(newval, oldval);
436 set_h48_pval(arg->table, coordext, arg->k, v); 429 set_h48_pval(arg->table, coordext, v);
437 v = arg->depth + arg->base; 430 v = arg->depth + arg->base;
438 set_h48_pvalmin(arg->table, coordmin, arg->k, v); 431 set_h48_pvalmin(arg->table, coordmin, v);
439 wrapthread_mutex_unlock(arg->table_mutex[mutex]); 432 wrapthread_mutex_unlock(arg->table_mutex[mutex]);
440 ) 433 )
441} 434}
442 435
443STATIC_INLINE bool 436STATIC_INLINE bool
444gendata_h48k2_dfs_stop(cube_t cube, int8_t d, h48k2_dfs_arg_t arg[static 1]) 437gendata_h48_dfs_stop(cube_t cube, int8_t d, h48_dfs_arg_t arg[static 1])
445{ 438{
446 uint64_t val; 439 uint64_t val;
447 uint64_t coord, coordext; 440 uint64_t coord, coordext;
@@ -455,11 +448,11 @@ gendata_h48k2_dfs_stop(cube_t cube, int8_t d, h48k2_dfs_arg_t arg[static 1])
455 coordext = H48_LINE_EXT(coord); 448 coordext = H48_LINE_EXT(coord);
456 mutex = H48_LINE(coord) % CHUNKS; 449 mutex = H48_LINE(coord) % CHUNKS;
457 wrapthread_mutex_lock(arg->table_mutex[mutex]); 450 wrapthread_mutex_lock(arg->table_mutex[mutex]);
458 oldval = get_h48_pval(arg->table, coordext, arg->k); 451 oldval = get_h48_pval(arg->table, coordext);
459 wrapthread_mutex_unlock(arg->table_mutex[mutex]); 452 wrapthread_mutex_unlock(arg->table_mutex[mutex]);
460 return oldval <= d; 453 return oldval <= d;
461 } else { 454 } else {
462 /* With 0 < k < 11 we do not have a "real coordinate". 455 /* With 0 < h < 11 we do not have a "real coordinate".
463 The best we can do is checking if we backtracked to 456 The best we can do is checking if we backtracked to
464 one of the "short cubes". */ 457 one of the "short cubes". */
465 coord = coord_h48(cube, arg->cocsepdata, 11); 458 coord = coord_h48(cube, arg->cocsepdata, 11);
@@ -469,15 +462,15 @@ gendata_h48k2_dfs_stop(cube_t cube, int8_t d, h48k2_dfs_arg_t arg[static 1])
469} 462}
470 463
471STATIC tableinfo_t 464STATIC tableinfo_t
472makeinfo_h48k2(gendata_h48_arg_t arg[static 1]) 465makeinfo_h48(gendata_h48_arg_t arg[static 1])
473{ 466{
474 tableinfo_t info; 467 tableinfo_t info;
475 468
476 info = (tableinfo_t) { 469 info = (tableinfo_t) {
477 .solver = "h48 solver h = , k = 2", 470 .solver = "h48 solver h = ",
478 .type = TABLETYPE_PRUNING, 471 .type = TABLETYPE_PRUNING,
479 .infosize = INFOSIZE, 472 .infosize = INFOSIZE,
480 .fullsize = H48_TABLESIZE(arg->h, 2) + INFOSIZE, 473 .fullsize = H48_TABLESIZE(arg->h) + INFOSIZE,
481 .hash = 0, 474 .hash = 0,
482 .entries = H48_COORDMAX(arg->h) + 2 * H48_LINES(arg->h), 475 .entries = H48_COORDMAX(arg->h) + 2 * H48_LINES(arg->h),
483 .classes = 0, 476 .classes = 0,
@@ -507,31 +500,31 @@ get_h48data_constptr(const unsigned char *data)
507} 500}
508 501
509STATIC_INLINE uint8_t 502STATIC_INLINE uint8_t
510get_h48_pval(const unsigned char *table, uint64_t i, uint8_t k) 503get_h48_pval(const unsigned char *table, uint64_t i)
511{ 504{
512 return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k); 505 return (table[H48_INDEX(i)] & H48_MASK(i)) >> H48_SHIFT(i);
513} 506}
514 507
515STATIC_INLINE uint8_t 508STATIC_INLINE uint8_t
516get_h48_pvalmin(const unsigned char *table, uint64_t i, uint8_t k) 509get_h48_pvalmin(const unsigned char *table, uint64_t i)
517{ 510{
518 return (get_h48_pval(table, i, k) << UINT8_C(2)) + 511 return (get_h48_pval(table, i) << UINT8_C(2)) +
519 get_h48_pval(table, i+UINT64_C(1), k); 512 get_h48_pval(table, i+UINT64_C(1));
520} 513}
521 514
522STATIC_INLINE void 515STATIC_INLINE void
523set_h48_pval(unsigned char *table, uint64_t i, uint8_t k, uint8_t val) 516set_h48_pval(unsigned char *table, uint64_t i, uint8_t val)
524{ 517{
525 table[H48_INDEX(i, k)] = (table[H48_INDEX(i, k)] & (~H48_MASK(i, k))) 518 table[H48_INDEX(i)] = (table[H48_INDEX(i)] & (~H48_MASK(i)))
526 | (val << H48_SHIFT(i, k)); 519 | (val << H48_SHIFT(i));
527} 520}
528 521
529STATIC_INLINE void 522STATIC_INLINE void
530set_h48_pvalmin(unsigned char *table, uint64_t i, uint8_t k, uint8_t val) 523set_h48_pvalmin(unsigned char *table, uint64_t i, uint8_t val)
531{ 524{
532 uint8_t v; 525 uint8_t v;
533 526
534 v = MIN(val, get_h48_pvalmin(table, i, k)); 527 v = MIN(val, get_h48_pvalmin(table, i));
535 set_h48_pval(table, i, k, v >> UINT8_C(2)); 528 set_h48_pval(table, i, v >> UINT8_C(2));
536 set_h48_pval(table, i+UINT64_C(1), k, v % UINT8_C(4)); 529 set_h48_pval(table, i+UINT64_C(1), v % UINT8_C(4));
537} 530}

Generated with cgit - Back to sebastiano.tronto.net