diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/solvers/dispatch.h | 2 | ||||
| -rw-r--r-- | src/solvers/distribution.h | 6 | ||||
| -rw-r--r-- | src/solvers/h48/checkdata.h | 2 | ||||
| -rw-r--r-- | src/solvers/h48/distribution_h48.h | 78 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_h48.h | 71 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_types_macros.h | 19 | ||||
| -rw-r--r-- | src/solvers/h48/h48.h | 1 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 30 | ||||
| -rw-r--r-- | src/solvers/h48/utils.h | 3 |
9 files changed, 178 insertions, 34 deletions
diff --git a/src/solvers/dispatch.h b/src/solvers/dispatch.h index 7e647ce..1bec0e2 100644 --- a/src/solvers/dispatch.h +++ b/src/solvers/dispatch.h | |||
| @@ -43,7 +43,7 @@ solver_dispatch_t solver_dispatchers[] = { | |||
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | const char *solver_aliases[][2] = { | 45 | const char *solver_aliases[][2] = { |
| 46 | { "optimal", "h48h7k2" }, | 46 | { "optimal", "h48h7i" }, |
| 47 | { "eofb", "coord_EO_UF" }, | 47 | { "eofb", "coord_EO_UF" }, |
| 48 | { "eorl", "coord_EO_UR" }, | 48 | { "eorl", "coord_EO_UR" }, |
| 49 | { "eoud", "coord_EO_FD" }, | 49 | { "eoud", "coord_EO_FD" }, |
diff --git a/src/solvers/distribution.h b/src/solvers/distribution.h index 4cb7157..e9302da 100644 --- a/src/solvers/distribution.h +++ b/src/solvers/distribution.h | |||
| @@ -95,12 +95,6 @@ distribution_equal( | |||
| 95 | ": expected %" PRIu64 ", found %" PRIu64 "\n", | 95 | ": expected %" PRIu64 ", found %" PRIu64 "\n", |
| 96 | i, expected[i], actual[i]); | 96 | i, expected[i], actual[i]); |
| 97 | } | 97 | } |
| 98 | /* | ||
| 99 | else { | ||
| 100 | LOG("[checkdata] Value for depth %" PRIu8 | ||
| 101 | " is correct (%" PRIu64 ")\n", i, actual[i]); | ||
| 102 | } | ||
| 103 | */ | ||
| 104 | } | 98 | } |
| 105 | 99 | ||
| 106 | return wrong == 0; | 100 | return wrong == 0; |
diff --git a/src/solvers/h48/checkdata.h b/src/solvers/h48/checkdata.h index af0499d..608c4d8 100644 --- a/src/solvers/h48/checkdata.h +++ b/src/solvers/h48/checkdata.h | |||
| @@ -219,7 +219,7 @@ checkdata_h48( | |||
| 219 | 219 | ||
| 220 | LOG("[checkdata] Checking distribution for '%s' from " | 220 | LOG("[checkdata] Checking distribution for '%s' from " |
| 221 | "actual table\n", info.solver); | 221 | "actual table\n", info.solver); |
| 222 | getdistribution(table, actual_distribution, &info); | 222 | getdistribution_h48(table, actual_distribution, &info); |
| 223 | if (!distribution_equal(ed, actual_distribution, em)) { | 223 | if (!distribution_equal(ed, actual_distribution, em)) { |
| 224 | LOG("[checkdata] Distribution from the actual table " | 224 | LOG("[checkdata] Distribution from the actual table " |
| 225 | "does not match the expected one\n"); | 225 | "does not match the expected one\n"); |
diff --git a/src/solvers/h48/distribution_h48.h b/src/solvers/h48/distribution_h48.h new file mode 100644 index 0000000..8b66c06 --- /dev/null +++ b/src/solvers/h48/distribution_h48.h | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* | ||
| 2 | This file is very similar to ../distibution.h, but some adaptations are | ||
| 3 | needed for H48 because of the intertwined fallback table, and it is easier | ||
| 4 | to have some duplication than to make these functions needlessly generic. | ||
| 5 | */ | ||
| 6 | |||
| 7 | STATIC void *getdistribution_h48_runthread(void *); | ||
| 8 | STATIC void getdistribution_h48(const unsigned char *, | ||
| 9 | uint64_t [static INFO_DISTRIBUTION_LEN], const tableinfo_t [static 1]); | ||
| 10 | |||
| 11 | STATIC void * | ||
| 12 | getdistribution_h48_runthread(void *arg) | ||
| 13 | { | ||
| 14 | getdistribution_data_t *data = (getdistribution_data_t *)arg; | ||
| 15 | const unsigned char *table; | ||
| 16 | uint8_t j, k, m; | ||
| 17 | uint64_t line, d; | ||
| 18 | unsigned char t; | ||
| 19 | |||
| 20 | memset(data->distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); | ||
| 21 | |||
| 22 | k = data->bits; | ||
| 23 | table = data->table; | ||
| 24 | m = TABLE_MASK(0, k); | ||
| 25 | for (line = data->min; line < data->max; line++) { | ||
| 26 | for (d = 0; d < H48_LINE_BYTES; d++) { | ||
| 27 | t = table[d + line * H48_LINE_BYTES]; | ||
| 28 | for (j = 0; j < ENTRIES_PER_BYTE(k); j++) | ||
| 29 | data->distr[(t & (m << (j*k))) >> (j*k)]++; | ||
| 30 | } | ||
| 31 | t = table[(line+1) * H48_LINE_BYTES - 1]; | ||
| 32 | data->distr[(t & (m << (2*k))) >> (2*k)]--; | ||
| 33 | data->distr[(t & (m << (3*k))) >> (3*k)]--; | ||
| 34 | } | ||
| 35 | |||
| 36 | return NULL; | ||
| 37 | } | ||
| 38 | |||
| 39 | STATIC void | ||
| 40 | getdistribution_h48( | ||
| 41 | const unsigned char *table, | ||
| 42 | uint64_t distr[static INFO_DISTRIBUTION_LEN], | ||
| 43 | const tableinfo_t info[static 1] | ||
| 44 | ) { | ||
| 45 | getdistribution_data_t targ[THREADS]; | ||
| 46 | wrapthread_define_var_thread_t(thread[THREADS]); | ||
| 47 | uint8_t pval, k; | ||
| 48 | uint64_t local_distr[THREADS][INFO_DISTRIBUTION_LEN]; | ||
| 49 | uint64_t i, j, lines, lines_per_thread, c, cc; | ||
| 50 | |||
| 51 | k = info->bits; | ||
| 52 | lines = H48_LINES(info->h48h); | ||
| 53 | lines_per_thread = DIV_ROUND_UP(lines, THREADS); | ||
| 54 | |||
| 55 | for (i = 0; i < THREADS; i++) { | ||
| 56 | targ[i] = (getdistribution_data_t) { | ||
| 57 | .min = i * lines_per_thread, | ||
| 58 | .max = MIN((i+1) * lines_per_thread, lines), | ||
| 59 | .bits = k, | ||
| 60 | .distr = local_distr[i], | ||
| 61 | .table = table, | ||
| 62 | }; | ||
| 63 | wrapthread_create(&thread[i], NULL, | ||
| 64 | getdistribution_h48_runthread, &targ[i]); | ||
| 65 | } | ||
| 66 | |||
| 67 | for (i = 0; i < THREADS; i++) | ||
| 68 | wrapthread_join(thread[i], NULL); | ||
| 69 | |||
| 70 | memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); | ||
| 71 | for (i = 0; i < THREADS; i++) | ||
| 72 | for (j = 0; j < INFO_DISTRIBUTION_LEN; j++) | ||
| 73 | distr[j] += local_distr[i][j]; | ||
| 74 | |||
| 75 | /* Clean up excess values */ | ||
| 76 | c = H48_LINE_EXT(H48_COORDMAX(info->h48h)) % H48_LINE_ALLCOORDS; | ||
| 77 | distr[3] -= H48_LINE_COORDS - c; | ||
| 78 | } | ||
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index 7ccadd6..8470b2f 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h | |||
| @@ -20,6 +20,10 @@ STATIC const unsigned char *get_h48data_constptr(const unsigned char *); | |||
| 20 | 20 | ||
| 21 | STATIC_INLINE uint8_t get_h48_pval(const unsigned char *, uint64_t, uint8_t); | 21 | STATIC_INLINE uint8_t get_h48_pval(const unsigned char *, uint64_t, uint8_t); |
| 22 | STATIC_INLINE void set_h48_pval(unsigned char *, uint64_t, uint8_t, uint8_t); | 22 | STATIC_INLINE void set_h48_pval(unsigned char *, uint64_t, uint8_t, uint8_t); |
| 23 | STATIC_INLINE uint8_t get_h48_pvalmin( | ||
| 24 | const unsigned char *, uint64_t, uint8_t); | ||
| 25 | STATIC_INLINE void set_h48_pvalmin( | ||
| 26 | unsigned char *, uint64_t, uint8_t, uint8_t); | ||
| 23 | STATIC_INLINE uint8_t get_h48_pval_atomic( | 27 | STATIC_INLINE uint8_t get_h48_pval_atomic( |
| 24 | wrapthread_atomic const unsigned char *, uint64_t, uint8_t); | 28 | wrapthread_atomic const unsigned char *, uint64_t, uint8_t); |
| 25 | STATIC_INLINE void set_h48_pval_atomic( | 29 | STATIC_INLINE void set_h48_pval_atomic( |
| @@ -300,6 +304,7 @@ gendata_h48h0k4_runthread(void *arg) | |||
| 300 | .depth = bfsarg->depth, | 304 | .depth = bfsarg->depth, |
| 301 | .h = 0, | 305 | .h = 0, |
| 302 | .k = 4, | 306 | .k = 4, |
| 307 | .base = 0, /* Unused */ | ||
| 303 | .cocsepdata = bfsarg->cocsepdata, | 308 | .cocsepdata = bfsarg->cocsepdata, |
| 304 | .selfsim = bfsarg->selfsim, | 309 | .selfsim = bfsarg->selfsim, |
| 305 | .table_atomic = bfsarg->table, | 310 | .table_atomic = bfsarg->table, |
| @@ -343,10 +348,6 @@ gendata_h48h0k4_runthread(void *arg) | |||
| 343 | STATIC void | 348 | STATIC void |
| 344 | gendata_h48k2(gendata_h48_arg_t arg[static 1]) | 349 | gendata_h48k2(gendata_h48_arg_t arg[static 1]) |
| 345 | { | 350 | { |
| 346 | static const uint8_t shortdepth = 8; | ||
| 347 | static const uint64_t capacity = 10000019; | ||
| 348 | static const uint64_t randomizer = 10000079; | ||
| 349 | |||
| 350 | /* | 351 | /* |
| 351 | * A good base value for the k=2 tables have few positions with value | 352 | * A good base value for the k=2 tables have few positions with value |
| 352 | * 0, because those are treated as lower bound 0 and require a second | 353 | * 0, because those are treated as lower bound 0 and require a second |
| @@ -391,6 +392,10 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1]) | |||
| 391 | [11] = 10 | 392 | [11] = 10 |
| 392 | }; | 393 | }; |
| 393 | 394 | ||
| 395 | static const uint8_t shortdepth = 8; | ||
| 396 | static const uint64_t capacity = 10000019; | ||
| 397 | static const uint64_t randomizer = 10000079; | ||
| 398 | |||
| 394 | uint8_t t; | 399 | uint8_t t; |
| 395 | int sleeptime; | 400 | int sleeptime; |
| 396 | unsigned char *table; | 401 | unsigned char *table; |
| @@ -481,10 +486,7 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1]) | |||
| 481 | 486 | ||
| 482 | h48map_destroy(&shortcubes); | 487 | h48map_destroy(&shortcubes); |
| 483 | 488 | ||
| 484 | for (j = 0; j < H48_COORDMAX(arg->h); j++) { | 489 | getdistribution_h48(table, arg->info.distribution, &arg->info); |
| 485 | t = get_h48_pval(table, j, 2); | ||
| 486 | arg->info.distribution[t]++; | ||
| 487 | } | ||
| 488 | 490 | ||
| 489 | bufsize = arg->buf_size - COCSEP_FULLSIZE; | 491 | bufsize = arg->buf_size - COCSEP_FULLSIZE; |
| 490 | writetableinfo(&arg->info, bufsize, (unsigned char *)arg->h48buf); | 492 | writetableinfo(&arg->info, bufsize, (unsigned char *)arg->h48buf); |
| @@ -493,7 +495,7 @@ gendata_h48k2(gendata_h48_arg_t arg[static 1]) | |||
| 493 | STATIC void * | 495 | STATIC void * |
| 494 | gendata_h48k2_runthread(void *arg) | 496 | gendata_h48k2_runthread(void *arg) |
| 495 | { | 497 | { |
| 496 | uint64_t coord; | 498 | uint64_t coord, coordext, coordmin; |
| 497 | kvpair_t kv; | 499 | kvpair_t kv; |
| 498 | h48k2_dfs_arg_t *dfsarg; | 500 | h48k2_dfs_arg_t *dfsarg; |
| 499 | wrapthread_define_if_threads(uint64_t, mutex); | 501 | wrapthread_define_if_threads(uint64_t, mutex); |
| @@ -513,9 +515,13 @@ gendata_h48k2_runthread(void *arg) | |||
| 513 | 515 | ||
| 514 | if (kv.val < dfsarg->shortdepth) { | 516 | if (kv.val < dfsarg->shortdepth) { |
| 515 | coord = kv.key >> (uint64_t)(11 - dfsarg->h); | 517 | coord = kv.key >> (uint64_t)(11 - dfsarg->h); |
| 516 | mutex = H48_INDEX(coord, dfsarg->k) % CHUNKS; | 518 | coordext = H48_LINE_EXT(coord); |
| 519 | coordmin = H48_LINE_MIN(coord); | ||
| 520 | |||
| 521 | mutex = H48_LINE(coord) % CHUNKS; | ||
| 517 | wrapthread_mutex_lock(dfsarg->table_mutex[mutex]); | 522 | wrapthread_mutex_lock(dfsarg->table_mutex[mutex]); |
| 518 | set_h48_pval(dfsarg->table, coord, dfsarg->k, 0); | 523 | set_h48_pval(dfsarg->table, coordext, dfsarg->k, 0); |
| 524 | set_h48_pvalmin(dfsarg->table, coordmin, dfsarg->k, kv.val); | ||
| 519 | wrapthread_mutex_unlock(dfsarg->table_mutex[mutex]); | 525 | wrapthread_mutex_unlock(dfsarg->table_mutex[mutex]); |
| 520 | } else { | 526 | } else { |
| 521 | dfsarg->cube = invcoord_h48(kv.key, dfsarg->crep, 11); | 527 | dfsarg->cube = invcoord_h48(kv.key, dfsarg->crep, 11); |
| @@ -537,6 +543,7 @@ gendata_h48k2_dfs(h48k2_dfs_arg_t arg[static 1]) | |||
| 537 | markarg = (gendata_h48_mark_t) { | 543 | markarg = (gendata_h48_mark_t) { |
| 538 | .h = arg->h, | 544 | .h = arg->h, |
| 539 | .k = arg->k, | 545 | .k = arg->k, |
| 546 | .base = arg->base, | ||
| 540 | .cocsepdata = arg->cocsepdata, | 547 | .cocsepdata = arg->cocsepdata, |
| 541 | .selfsim = arg->selfsim, | 548 | .selfsim = arg->selfsim, |
| 542 | .table = arg->table, | 549 | .table = arg->table, |
| @@ -629,17 +636,23 @@ gendata_h48_mark_atomic(gendata_h48_mark_t arg[static 1]) | |||
| 629 | STATIC_INLINE void | 636 | STATIC_INLINE void |
| 630 | gendata_h48_mark(gendata_h48_mark_t arg[static 1]) | 637 | gendata_h48_mark(gendata_h48_mark_t arg[static 1]) |
| 631 | { | 638 | { |
| 632 | uint8_t oldval, newval; | 639 | uint8_t oldval, newval, v; |
| 633 | uint64_t coord; | 640 | uint64_t coord, coordext, coordmin; |
| 634 | wrapthread_define_if_threads(uint64_t, mutex); | 641 | wrapthread_define_if_threads(uint64_t, mutex); |
| 635 | 642 | ||
| 636 | FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim, | 643 | FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim, |
| 637 | coord = coord_h48(arg->cube, arg->cocsepdata, arg->h); | 644 | coord = coord_h48(arg->cube, arg->cocsepdata, arg->h); |
| 638 | mutex = H48_INDEX(coord, arg->k) % CHUNKS; | 645 | coordext = H48_LINE_EXT(coord); |
| 646 | coordmin = H48_LINE_MIN(coord); | ||
| 647 | |||
| 648 | mutex = H48_LINE(coord) % CHUNKS; | ||
| 639 | wrapthread_mutex_lock(arg->table_mutex[mutex]); | 649 | wrapthread_mutex_lock(arg->table_mutex[mutex]); |
| 640 | oldval = get_h48_pval(arg->table, coord, arg->k); | 650 | oldval = get_h48_pval(arg->table, coordext, arg->k); |
| 641 | newval = (uint8_t)MAX(arg->depth, 0); | 651 | newval = (uint8_t)MAX(arg->depth, 0); |
| 642 | set_h48_pval(arg->table, coord, arg->k, MIN(newval, oldval)); | 652 | v = MIN(newval, oldval); |
| 653 | set_h48_pval(arg->table, coordext, arg->k, v); | ||
| 654 | v = arg->depth + arg->base; | ||
| 655 | set_h48_pvalmin(arg->table, coordmin, arg->k, v); | ||
| 643 | wrapthread_mutex_unlock(arg->table_mutex[mutex]); | 656 | wrapthread_mutex_unlock(arg->table_mutex[mutex]); |
| 644 | ) | 657 | ) |
| 645 | } | 658 | } |
| @@ -648,7 +661,7 @@ STATIC_INLINE bool | |||
| 648 | gendata_h48k2_dfs_stop(cube_t cube, int8_t d, h48k2_dfs_arg_t arg[static 1]) | 661 | gendata_h48k2_dfs_stop(cube_t cube, int8_t d, h48k2_dfs_arg_t arg[static 1]) |
| 649 | { | 662 | { |
| 650 | uint64_t val; | 663 | uint64_t val; |
| 651 | uint64_t coord; | 664 | uint64_t coord, coordext; |
| 652 | wrapthread_define_if_threads(uint64_t, mutex); | 665 | wrapthread_define_if_threads(uint64_t, mutex); |
| 653 | int8_t oldval; | 666 | int8_t oldval; |
| 654 | 667 | ||
| @@ -656,9 +669,10 @@ gendata_h48k2_dfs_stop(cube_t cube, int8_t d, h48k2_dfs_arg_t arg[static 1]) | |||
| 656 | /* We are in the "real coordinate" case, we can stop | 669 | /* We are in the "real coordinate" case, we can stop |
| 657 | if this coordinate has already been visited */ | 670 | if this coordinate has already been visited */ |
| 658 | coord = coord_h48(cube, arg->cocsepdata, arg->h); | 671 | coord = coord_h48(cube, arg->cocsepdata, arg->h); |
| 659 | mutex = H48_INDEX(coord, arg->k) % CHUNKS; | 672 | coordext = H48_LINE_EXT(coord); |
| 673 | mutex = H48_LINE(coord) % CHUNKS; | ||
| 660 | wrapthread_mutex_lock(arg->table_mutex[mutex]); | 674 | wrapthread_mutex_lock(arg->table_mutex[mutex]); |
| 661 | oldval = get_h48_pval(arg->table, coord, arg->k); | 675 | oldval = get_h48_pval(arg->table, coordext, arg->k); |
| 662 | wrapthread_mutex_unlock(arg->table_mutex[mutex]); | 676 | wrapthread_mutex_unlock(arg->table_mutex[mutex]); |
| 663 | return oldval <= d; | 677 | return oldval <= d; |
| 664 | } else { | 678 | } else { |
| @@ -682,7 +696,7 @@ makeinfo_h48k2(gendata_h48_arg_t arg[static 1]) | |||
| 682 | .infosize = INFOSIZE, | 696 | .infosize = INFOSIZE, |
| 683 | .fullsize = H48_TABLESIZE(arg->h, 2) + INFOSIZE, | 697 | .fullsize = H48_TABLESIZE(arg->h, 2) + INFOSIZE, |
| 684 | .hash = 0, | 698 | .hash = 0, |
| 685 | .entries = H48_COORDMAX(arg->h), | 699 | .entries = H48_COORDMAX(arg->h) + 2 * H48_LINES(arg->h), |
| 686 | .classes = 0, | 700 | .classes = 0, |
| 687 | .h48h = arg->h, | 701 | .h48h = arg->h, |
| 688 | .bits = 2, | 702 | .bits = 2, |
| @@ -716,6 +730,13 @@ get_h48_pval(const unsigned char *table, uint64_t i, uint8_t k) | |||
| 716 | } | 730 | } |
| 717 | 731 | ||
| 718 | STATIC_INLINE uint8_t | 732 | STATIC_INLINE uint8_t |
| 733 | get_h48_pvalmin(const unsigned char *table, uint64_t i, uint8_t k) | ||
| 734 | { | ||
| 735 | return (get_h48_pval(table, i, k) << UINT8_C(2)) + | ||
| 736 | get_h48_pval(table, i+UINT64_C(1), k); | ||
| 737 | } | ||
| 738 | |||
| 739 | STATIC_INLINE uint8_t | ||
| 719 | get_h48_pval_atomic( | 740 | get_h48_pval_atomic( |
| 720 | wrapthread_atomic const unsigned char *table, | 741 | wrapthread_atomic const unsigned char *table, |
| 721 | uint64_t i, | 742 | uint64_t i, |
| @@ -733,6 +754,16 @@ set_h48_pval(unsigned char *table, uint64_t i, uint8_t k, uint8_t val) | |||
| 733 | } | 754 | } |
| 734 | 755 | ||
| 735 | STATIC_INLINE void | 756 | STATIC_INLINE void |
| 757 | set_h48_pvalmin(unsigned char *table, uint64_t i, uint8_t k, uint8_t val) | ||
| 758 | { | ||
| 759 | uint8_t v; | ||
| 760 | |||
| 761 | v = MIN(val, get_h48_pvalmin(table, i, k)); | ||
| 762 | set_h48_pval(table, i, k, v >> UINT8_C(2)); | ||
| 763 | set_h48_pval(table, i+UINT64_C(1), k, v % UINT8_C(4)); | ||
| 764 | } | ||
| 765 | |||
| 766 | STATIC_INLINE void | ||
| 736 | set_h48_pval_atomic( | 767 | set_h48_pval_atomic( |
| 737 | wrapthread_atomic unsigned char *table, | 768 | wrapthread_atomic unsigned char *table, |
| 738 | uint64_t i, | 769 | uint64_t i, |
diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h index e66dedb..62a661d 100644 --- a/src/solvers/h48/gendata_types_macros.h +++ b/src/solvers/h48/gendata_types_macros.h | |||
| @@ -21,14 +21,28 @@ | |||
| 21 | #define H48_COORDMAX_NOEO (COCSEP_CLASSES * ESEP_MAX) | 21 | #define H48_COORDMAX_NOEO (COCSEP_CLASSES * ESEP_MAX) |
| 22 | #define H48_COORDMAX(h) (H48_COORDMAX_NOEO << (uint64_t)(h)) | 22 | #define H48_COORDMAX(h) (H48_COORDMAX_NOEO << (uint64_t)(h)) |
| 23 | #define H48_DIV(k) ((size_t)8 / (size_t)(k)) | 23 | #define H48_DIV(k) ((size_t)8 / (size_t)(k)) |
| 24 | #define H48_TABLESIZE(h, k) DIV_ROUND_UP((size_t)H48_COORDMAX((h)), H48_DIV(k)) | 24 | #define H48_TABLESIZE_K4(h) DIV_ROUND_UP((size_t)H48_COORDMAX(h), H48_DIV(4)) |
| 25 | 25 | ||
| 26 | #define H48_COEFF(k) (UINT64_C(8) / (uint64_t)(k)) | 26 | #define H48_COEFF(k) (UINT64_C(8) / (uint64_t)(k)) |
| 27 | #define H48_INDEX(i, k) ((i) / H48_COEFF(k)) | 27 | #define H48_INDEX(i, k) ((i) / H48_COEFF(k)) |
| 28 | #define H48_SHIFT(i, k) ((uint8_t)(k) * (uint8_t)((i) % H48_COEFF(k))) | 28 | #define H48_SHIFT(i, k) ((uint8_t)(k) * (uint8_t)((i) % H48_COEFF(k))) |
| 29 | #define H48_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << H48_SHIFT(i, k)) | 29 | #define H48_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << H48_SHIFT(i, k)) |
| 30 | 30 | ||
| 31 | #define CHUNKS COCSEP_CLASSES | 31 | #define H48_LINE_BITS UINT64_C(512) |
| 32 | #define H48_LINE_BYTES (H48_LINE_BITS >> UINT64_C(3)) | ||
| 33 | #define H48_LINE_ALLCOORDS (H48_LINE_BITS / UINT64_C(2)) | ||
| 34 | #define H48_LINE_COORDS ((H48_LINE_BITS - UINT64_C(4)) / UINT64_C(2)) | ||
| 35 | #define H48_LINE(i) ((i) / H48_LINE_COORDS) | ||
| 36 | #define H48_LINE_EXT(i) ((i) + UINT64_C(2) * H48_LINE(i)) | ||
| 37 | #define H48_LINE_MIN(i) \ | ||
| 38 | ((H48_LINE(i) + UINT64_C(1)) * H48_LINE_ALLCOORDS - UINT64_C(2)) | ||
| 39 | #define H48_LINES(h) DIV_ROUND_UP(H48_COORDMAX(h), H48_LINE_COORDS) | ||
| 40 | #define H48_TABLESIZE_K2(h) ((size_t)(H48_LINE_BYTES * H48_LINES(h))) | ||
| 41 | |||
| 42 | #define H48_TABLESIZE(h, k) \ | ||
| 43 | ((k) == 4 ? H48_TABLESIZE_K4(h) : H48_TABLESIZE_K2(h)) | ||
| 44 | |||
| 45 | #define CHUNKS 2000 | ||
| 32 | 46 | ||
| 33 | /* | 47 | /* |
| 34 | TODO: This loop over similar h48 coordinates can be improved by only | 48 | TODO: This loop over similar h48 coordinates can be improved by only |
| @@ -115,6 +129,7 @@ typedef struct { | |||
| 115 | int8_t depth; | 129 | int8_t depth; |
| 116 | uint8_t h; | 130 | uint8_t h; |
| 117 | uint8_t k; | 131 | uint8_t k; |
| 132 | uint8_t base; | ||
| 118 | uint32_t *cocsepdata; | 133 | uint32_t *cocsepdata; |
| 119 | uint64_t *selfsim; | 134 | uint64_t *selfsim; |
| 120 | unsigned char *table; | 135 | unsigned char *table; |
diff --git a/src/solvers/h48/h48.h b/src/solvers/h48/h48.h index 44fdb59..f7ba8b7 100644 --- a/src/solvers/h48/h48.h +++ b/src/solvers/h48/h48.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include "map.h" | 6 | #include "map.h" |
| 7 | #include "gendata_cocsep.h" | 7 | #include "gendata_cocsep.h" |
| 8 | #include "gendata_eoesep.h" | 8 | #include "gendata_eoesep.h" |
| 9 | #include "distribution_h48.h" | ||
| 9 | #include "gendata_h48.h" | 10 | #include "gendata_h48.h" |
| 10 | #include "checkdata.h" | 11 | #include "checkdata.h" |
| 11 | #include "solve.h" | 12 | #include "solve.h" |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index ad66fd4..6fb359d 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -110,7 +110,7 @@ STATIC_INLINE bool | |||
| 110 | solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) | 110 | solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) |
| 111 | { | 111 | { |
| 112 | uint32_t data, data_inv; | 112 | uint32_t data, data_inv; |
| 113 | int64_t coord; | 113 | int64_t coord, coordext, coordmin; |
| 114 | int8_t target, nh, n; | 114 | int8_t target, nh, n; |
| 115 | uint8_t pval_cocsep, pval_eoesep; | 115 | uint8_t pval_cocsep, pval_eoesep; |
| 116 | 116 | ||
| @@ -142,17 +142,29 @@ solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) | |||
| 142 | if (!arg->use_lb_inverse) { | 142 | if (!arg->use_lb_inverse) { |
| 143 | coord = coord_h48_edges( | 143 | coord = coord_h48_edges( |
| 144 | arg->inverse, COCLASS(data_inv), TTREP(data_inv), arg->h); | 144 | arg->inverse, COCLASS(data_inv), TTREP(data_inv), arg->h); |
| 145 | arg->lb_inverse = get_h48_pval(arg->h48data, coord, arg->k); | 145 | coordext = H48_LINE_EXT(coord); |
| 146 | arg->lb_inverse = get_h48_pval(arg->h48data, coordext, arg->k); | ||
| 146 | arg->table_lookups++; | 147 | arg->table_lookups++; |
| 147 | 148 | ||
| 148 | if (arg->k == 2 && arg->lb_inverse == 0) { | 149 | if (arg->k == 2 && arg->lb_inverse == 0) { |
| 149 | arg->table_fallbacks++; | 150 | arg->table_fallbacks++; |
| 150 | 151 | ||
| 152 | /* | ||
| 151 | pval_cocsep = get_h48_pval( | 153 | pval_cocsep = get_h48_pval( |
| 152 | arg->h48data_fallback_h0k4, coord >> arg->h, 4); | 154 | arg->h48data_fallback_h0k4, coord >> arg->h, 4); |
| 155 | */ | ||
| 156 | #if 1 | ||
| 157 | coordmin = H48_LINE_MIN(coord); | ||
| 158 | pval_cocsep = get_h48_pvalmin( | ||
| 159 | arg->h48data, coordmin, arg->k); | ||
| 153 | pval_eoesep = get_eoesep_pval_cube( | 160 | pval_eoesep = get_eoesep_pval_cube( |
| 154 | arg->h48data_fallback_eoesep, arg->inverse); | 161 | arg->h48data_fallback_eoesep, arg->inverse); |
| 155 | arg->lb_inverse = MAX(pval_cocsep, pval_eoesep); | 162 | arg->lb_inverse = MAX(pval_cocsep, pval_eoesep); |
| 163 | #else | ||
| 164 | coordmin = H48_LINE_MIN(coord); | ||
| 165 | arg->lb_inverse = get_h48_pvalmin( | ||
| 166 | arg->h48data, coordmin, arg->k); | ||
| 167 | #endif | ||
| 156 | } else { | 168 | } else { |
| 157 | arg->lb_inverse += arg->base; | 169 | arg->lb_inverse += arg->base; |
| 158 | } | 170 | } |
| @@ -170,17 +182,29 @@ solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) | |||
| 170 | if (!arg->use_lb_normal) { | 182 | if (!arg->use_lb_normal) { |
| 171 | coord = coord_h48_edges( | 183 | coord = coord_h48_edges( |
| 172 | arg->cube, COCLASS(data), TTREP(data), arg->h); | 184 | arg->cube, COCLASS(data), TTREP(data), arg->h); |
| 173 | arg->lb_normal = get_h48_pval(arg->h48data, coord, arg->k); | 185 | coordext = H48_LINE_EXT(coord); |
| 186 | arg->lb_normal = get_h48_pval(arg->h48data, coordext, arg->k); | ||
| 174 | arg->table_lookups++; | 187 | arg->table_lookups++; |
| 175 | 188 | ||
| 176 | if (arg->k == 2 && arg->lb_normal == 0) { | 189 | if (arg->k == 2 && arg->lb_normal == 0) { |
| 177 | arg->table_fallbacks++; | 190 | arg->table_fallbacks++; |
| 178 | 191 | ||
| 192 | /* | ||
| 179 | pval_cocsep = get_h48_pval( | 193 | pval_cocsep = get_h48_pval( |
| 180 | arg->h48data_fallback_h0k4, coord >> arg->h, 4); | 194 | arg->h48data_fallback_h0k4, coord >> arg->h, 4); |
| 195 | */ | ||
| 196 | #if 1 | ||
| 197 | coordmin = H48_LINE_MIN(coord); | ||
| 198 | pval_cocsep = get_h48_pval( | ||
| 199 | arg->h48data, coordmin, arg->k); | ||
| 181 | pval_eoesep = get_eoesep_pval_cube( | 200 | pval_eoesep = get_eoesep_pval_cube( |
| 182 | arg->h48data_fallback_eoesep, arg->cube); | 201 | arg->h48data_fallback_eoesep, arg->cube); |
| 183 | arg->lb_normal = MAX(pval_cocsep, pval_eoesep); | 202 | arg->lb_normal = MAX(pval_cocsep, pval_eoesep); |
| 203 | #else | ||
| 204 | coordmin = H48_LINE_MIN(coord); | ||
| 205 | arg->lb_normal = get_h48_pval( | ||
| 206 | arg->h48data, coordmin, arg->k); | ||
| 207 | #endif | ||
| 184 | } else { | 208 | } else { |
| 185 | arg->lb_normal += arg->base; | 209 | arg->lb_normal += arg->base; |
| 186 | } | 210 | } |
diff --git a/src/solvers/h48/utils.h b/src/solvers/h48/utils.h index aa2ddde..17f1c94 100644 --- a/src/solvers/h48/utils.h +++ b/src/solvers/h48/utils.h | |||
| @@ -68,6 +68,7 @@ dataid_h48(const char *hk, char buf[static NISSY_SIZE_DATAID]) | |||
| 68 | if (err < 0) | 68 | if (err < 0) |
| 69 | return err; | 69 | return err; |
| 70 | 70 | ||
| 71 | sprintf(buf, "h48h%" PRIu8 "k%" PRIu8, h, k); | 71 | sprintf(buf, "h48h%" PRIu8 "k%" PRIu8 "%s", h, k, |
| 72 | k == 2 ? "i" : ""); | ||
| 72 | return NISSY_OK; | 73 | return NISSY_OK; |
| 73 | } | 74 | } |
