diff options
Diffstat (limited to 'src/solvers/h48/distribution_h48.h')
| -rw-r--r-- | src/solvers/h48/distribution_h48.h | 78 |
1 files changed, 78 insertions, 0 deletions
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 | } | ||
