diff options
| -rw-r--r-- | src/solvers/h48/checkdata.h | 4 | ||||
| -rw-r--r-- | src/solvers/h48/distribution_h48.h | 6 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_h48.h | 255 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_types_macros.h | 11 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 61 |
5 files changed, 27 insertions, 310 deletions
diff --git a/src/solvers/h48/checkdata.h b/src/solvers/h48/checkdata.h index 608c4d8..04afd48 100644 --- a/src/solvers/h48/checkdata.h +++ b/src/solvers/h48/checkdata.h | |||
| @@ -171,6 +171,10 @@ struct { | |||
| 171 | }, | 171 | }, |
| 172 | }; | 172 | }; |
| 173 | 173 | ||
| 174 | /* | ||
| 175 | TODO: this function can be simplified, now we support only one h48 table + | ||
| 176 | eoesep. The loop can be just two checks. | ||
| 177 | */ | ||
| 174 | STATIC long long | 178 | STATIC long long |
| 175 | checkdata_h48( | 179 | checkdata_h48( |
| 176 | const char *solver, | 180 | const char *solver, |
diff --git a/src/solvers/h48/distribution_h48.h b/src/solvers/h48/distribution_h48.h index 8b66c06..93a6933 100644 --- a/src/solvers/h48/distribution_h48.h +++ b/src/solvers/h48/distribution_h48.h | |||
| @@ -44,11 +44,9 @@ getdistribution_h48( | |||
| 44 | ) { | 44 | ) { |
| 45 | getdistribution_data_t targ[THREADS]; | 45 | getdistribution_data_t targ[THREADS]; |
| 46 | wrapthread_define_var_thread_t(thread[THREADS]); | 46 | wrapthread_define_var_thread_t(thread[THREADS]); |
| 47 | uint8_t pval, k; | ||
| 48 | uint64_t local_distr[THREADS][INFO_DISTRIBUTION_LEN]; | 47 | uint64_t local_distr[THREADS][INFO_DISTRIBUTION_LEN]; |
| 49 | uint64_t i, j, lines, lines_per_thread, c, cc; | 48 | uint64_t i, j, lines, lines_per_thread, c; |
| 50 | 49 | ||
| 51 | k = info->bits; | ||
| 52 | lines = H48_LINES(info->h48h); | 50 | lines = H48_LINES(info->h48h); |
| 53 | lines_per_thread = DIV_ROUND_UP(lines, THREADS); | 51 | lines_per_thread = DIV_ROUND_UP(lines, THREADS); |
| 54 | 52 | ||
| @@ -56,7 +54,7 @@ getdistribution_h48( | |||
| 56 | targ[i] = (getdistribution_data_t) { | 54 | targ[i] = (getdistribution_data_t) { |
| 57 | .min = i * lines_per_thread, | 55 | .min = i * lines_per_thread, |
| 58 | .max = MIN((i+1) * lines_per_thread, lines), | 56 | .max = MIN((i+1) * lines_per_thread, lines), |
| 59 | .bits = k, | 57 | .bits = info->bits, |
| 60 | .distr = local_distr[i], | 58 | .distr = local_distr[i], |
| 61 | .table = table, | 59 | .table = table, |
| 62 | }; | 60 | }; |
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 *); |
| 3 | STATIC uint64_t gendata_h48short(gendata_h48short_arg_t [static 1]); | 3 | STATIC uint64_t gendata_h48short(gendata_h48short_arg_t [static 1]); |
| 4 | STATIC int64_t gendata_h48(gendata_h48_arg_t [static 1]); | 4 | STATIC int64_t gendata_h48(gendata_h48_arg_t [static 1]); |
| 5 | STATIC void gendata_h48h0k4(gendata_h48_arg_t [static 1]); | ||
| 6 | STATIC void gendata_h48k2(gendata_h48_arg_t [static 1]); | 5 | STATIC void gendata_h48k2(gendata_h48_arg_t [static 1]); |
| 7 | |||
| 8 | STATIC void *gendata_h48h0k4_runthread(void *); | ||
| 9 | STATIC void *gendata_h48k2_runthread(void *); | 6 | STATIC void *gendata_h48k2_runthread(void *); |
| 10 | 7 | ||
| 11 | STATIC_INLINE void gendata_h48_mark_atomic(gendata_h48_mark_t [static 1]); | ||
| 12 | STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t [static 1]); | 8 | STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t [static 1]); |
| 13 | STATIC_INLINE bool gendata_h48k2_dfs_stop( | 9 | STATIC_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); |
| 25 | STATIC_INLINE void set_h48_pvalmin( | 21 | STATIC_INLINE void set_h48_pvalmin( |
| 26 | unsigned char *, uint64_t, uint8_t, uint8_t); | 22 | unsigned char *, uint64_t, uint8_t, uint8_t); |
| 27 | STATIC_INLINE uint8_t get_h48_pval_atomic( | ||
| 28 | wrapthread_atomic const unsigned char *, uint64_t, uint8_t); | ||
| 29 | STATIC_INLINE void set_h48_pval_atomic( | ||
| 30 | wrapthread_atomic unsigned char *, uint64_t, uint8_t, uint8_t); | ||
| 31 | 23 | ||
| 32 | STATIC long long | 24 | STATIC long long |
| 33 | gendata_h48_dispatch( | 25 | gendata_h48_dispatch( |
| @@ -87,23 +79,16 @@ gendata_h48short(gendata_h48short_arg_t arg[static 1]) | |||
| 87 | STATIC int64_t | 79 | STATIC int64_t |
| 88 | gendata_h48(gendata_h48_arg_t arg[static 1]) | 80 | gendata_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 | ||
| 211 | STATIC void | 154 | STATIC void |
| 212 | gendata_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 | |||
| 289 | STATIC void * | ||
| 290 | gendata_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 | |||
| 348 | STATIC void | ||
| 349 | gendata_h48k2(gendata_h48_arg_t arg[static 1]) | 155 | gendata_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 | ||
| 615 | STATIC_INLINE void | 419 | STATIC_INLINE void |
| 616 | gendata_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 | |||
| 636 | STATIC_INLINE void | ||
| 637 | gendata_h48_mark(gendata_h48_mark_t arg[static 1]) | 420 | gendata_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 | ||
| 739 | STATIC_INLINE uint8_t | ||
| 740 | get_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 | |||
| 749 | STATIC_INLINE void | 522 | STATIC_INLINE void |
| 750 | set_h48_pval(unsigned char *table, uint64_t i, uint8_t k, uint8_t val) | 523 | set_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 | |||
| 766 | STATIC_INLINE void | ||
| 767 | set_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 | } | ||
diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h index 62a661d..16f0be3 100644 --- a/src/solvers/h48/gendata_types_macros.h +++ b/src/solvers/h48/gendata_types_macros.h | |||
| @@ -97,17 +97,6 @@ typedef struct { | |||
| 97 | } gendata_h48short_arg_t; | 97 | } gendata_h48short_arg_t; |
| 98 | 98 | ||
| 99 | typedef struct { | 99 | typedef struct { |
| 100 | uint8_t depth; | ||
| 101 | uint32_t *cocsepdata; | ||
| 102 | wrapthread_atomic unsigned char *table; | ||
| 103 | uint64_t *selfsim; | ||
| 104 | cube_t *crep; | ||
| 105 | uint64_t start; | ||
| 106 | uint64_t end; | ||
| 107 | wrapthread_define_struct_mutex_t(*table_mutex[CHUNKS]); | ||
| 108 | } h48h0k4_bfs_arg_t; | ||
| 109 | |||
| 110 | typedef struct { | ||
| 111 | cube_t cube; | 100 | cube_t cube; |
| 112 | uint8_t h; | 101 | uint8_t h; |
| 113 | uint8_t k; | 102 | uint8_t k; |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index 6fb359d..047d13e 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -34,7 +34,6 @@ typedef struct { | |||
| 34 | uint8_t base; | 34 | uint8_t base; |
| 35 | const uint32_t *cocsepdata; | 35 | const uint32_t *cocsepdata; |
| 36 | const unsigned char *h48data; | 36 | const unsigned char *h48data; |
| 37 | const unsigned char *h48data_fallback_h0k4; | ||
| 38 | const unsigned char *h48data_fallback_eoesep; | 37 | const unsigned char *h48data_fallback_eoesep; |
| 39 | uint64_t movemask_normal; | 38 | uint64_t movemask_normal; |
| 40 | uint64_t movemask_inverse; | 39 | uint64_t movemask_inverse; |
| @@ -112,7 +111,7 @@ solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) | |||
| 112 | uint32_t data, data_inv; | 111 | uint32_t data, data_inv; |
| 113 | int64_t coord, coordext, coordmin; | 112 | int64_t coord, coordext, coordmin; |
| 114 | int8_t target, nh, n; | 113 | int8_t target, nh, n; |
| 115 | uint8_t pval_cocsep, pval_eoesep; | 114 | uint8_t pval_min, pval_eoesep; |
| 116 | 115 | ||
| 117 | n = arg->solution_moves->nmoves + arg->solution_moves->npremoves; | 116 | n = arg->solution_moves->nmoves + arg->solution_moves->npremoves; |
| 118 | target = arg->target_depth - n; | 117 | target = arg->target_depth - n; |
| @@ -149,22 +148,12 @@ solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) | |||
| 149 | if (arg->k == 2 && arg->lb_inverse == 0) { | 148 | if (arg->k == 2 && arg->lb_inverse == 0) { |
| 150 | arg->table_fallbacks++; | 149 | arg->table_fallbacks++; |
| 151 | 150 | ||
| 152 | /* | ||
| 153 | pval_cocsep = get_h48_pval( | ||
| 154 | arg->h48data_fallback_h0k4, coord >> arg->h, 4); | ||
| 155 | */ | ||
| 156 | #if 1 | ||
| 157 | coordmin = H48_LINE_MIN(coord); | 151 | coordmin = H48_LINE_MIN(coord); |
| 158 | pval_cocsep = get_h48_pvalmin( | 152 | pval_min = get_h48_pvalmin( |
| 159 | arg->h48data, coordmin, arg->k); | 153 | arg->h48data, coordmin, arg->k); |
| 160 | pval_eoesep = get_eoesep_pval_cube( | 154 | pval_eoesep = get_eoesep_pval_cube( |
| 161 | arg->h48data_fallback_eoesep, arg->inverse); | 155 | arg->h48data_fallback_eoesep, arg->inverse); |
| 162 | arg->lb_inverse = MAX(pval_cocsep, pval_eoesep); | 156 | arg->lb_inverse = MAX(pval_min, 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 | ||
| 168 | } else { | 157 | } else { |
| 169 | arg->lb_inverse += arg->base; | 158 | arg->lb_inverse += arg->base; |
| 170 | } | 159 | } |
| @@ -189,22 +178,12 @@ solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) | |||
| 189 | if (arg->k == 2 && arg->lb_normal == 0) { | 178 | if (arg->k == 2 && arg->lb_normal == 0) { |
| 190 | arg->table_fallbacks++; | 179 | arg->table_fallbacks++; |
| 191 | 180 | ||
| 192 | /* | ||
| 193 | pval_cocsep = get_h48_pval( | ||
| 194 | arg->h48data_fallback_h0k4, coord >> arg->h, 4); | ||
| 195 | */ | ||
| 196 | #if 1 | ||
| 197 | coordmin = H48_LINE_MIN(coord); | 181 | coordmin = H48_LINE_MIN(coord); |
| 198 | pval_cocsep = get_h48_pval( | 182 | pval_min = get_h48_pval( |
| 199 | arg->h48data, coordmin, arg->k); | 183 | arg->h48data, coordmin, arg->k); |
| 200 | pval_eoesep = get_eoesep_pval_cube( | 184 | pval_eoesep = get_eoesep_pval_cube( |
| 201 | arg->h48data_fallback_eoesep, arg->cube); | 185 | arg->h48data_fallback_eoesep, arg->cube); |
| 202 | arg->lb_normal = MAX(pval_cocsep, pval_eoesep); | 186 | arg->lb_normal = MAX(pval_min, 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 | ||
| 208 | } else { | 187 | } else { |
| 209 | arg->lb_normal += arg->base; | 188 | arg->lb_normal += arg->base; |
| 210 | } | 189 | } |
| @@ -482,7 +461,7 @@ solve_h48( | |||
| 482 | void *poll_status_data | 461 | void *poll_status_data |
| 483 | ) | 462 | ) |
| 484 | { | 463 | { |
| 485 | int i, ntasks, eoesep_table_index; | 464 | int i, ntasks; |
| 486 | bool td; | 465 | bool td; |
| 487 | wrapthread_atomic int status, prev_status; | 466 | wrapthread_atomic int status, prev_status; |
| 488 | size_t lastused; | 467 | size_t lastused; |
| @@ -493,10 +472,10 @@ solve_h48( | |||
| 493 | long double fallback_rate, lookups_per_node; | 472 | long double fallback_rate, lookups_per_node; |
| 494 | uint64_t offset; | 473 | uint64_t offset; |
| 495 | uint64_t nodes_visited, table_lookups, table_fallbacks; | 474 | uint64_t nodes_visited, table_lookups, table_fallbacks; |
| 496 | tableinfo_t info, fbinfo, fbinfo2; | 475 | tableinfo_t info, fbinfo2; |
| 497 | const uint32_t *cocsepdata; | 476 | const uint32_t *cocsepdata; |
| 498 | const unsigned char *fallback, *h48data; | 477 | const unsigned char *h48data; |
| 499 | const unsigned char *fallback2; | 478 | const unsigned char *eoesep; |
| 500 | solution_moves_t solution_moves[THREADS]; | 479 | solution_moves_t solution_moves[THREADS]; |
| 501 | solution_settings_t settings; | 480 | solution_settings_t settings; |
| 502 | solution_list_t sollist; | 481 | solution_list_t sollist; |
| @@ -512,29 +491,16 @@ solve_h48( | |||
| 512 | cocsepdata = (uint32_t *)(data + INFOSIZE); | 491 | cocsepdata = (uint32_t *)(data + INFOSIZE); |
| 513 | h48data = data + COCSEP_FULLSIZE + INFOSIZE; | 492 | h48data = data + COCSEP_FULLSIZE + INFOSIZE; |
| 514 | 493 | ||
| 515 | /* Read fallback table(s) */ | 494 | /* Read additional eoesep table */ |
| 516 | fallback = NULL; | ||
| 517 | if (readtableinfo_n(data_size, data, 3, &fbinfo) != NISSY_OK) | ||
| 518 | goto solve_h48_error_data; | ||
| 519 | offset = info.next; | 495 | offset = info.next; |
| 520 | eoesep_table_index = 3; | 496 | if (readtableinfo_n(data_size, data, 3, &fbinfo2) |
| 521 | if (info.bits == 2) { | ||
| 522 | /* We only support h0k4 as fallback table */ | ||
| 523 | if (fbinfo.h48h != 0 || fbinfo.bits != 4) | ||
| 524 | goto solve_h48_error_data; | ||
| 525 | fallback = h48data + offset; | ||
| 526 | offset += fbinfo.next; | ||
| 527 | eoesep_table_index++; | ||
| 528 | } | ||
| 529 | |||
| 530 | if (readtableinfo_n(data_size, data, eoesep_table_index, &fbinfo2) | ||
| 531 | != NISSY_OK) | 497 | != NISSY_OK) |
| 532 | goto solve_h48_error_data; | 498 | goto solve_h48_error_data; |
| 533 | 499 | ||
| 534 | /* Some heuristic check to see that it is eoesep */ | 500 | /* Some heuristic check to see that it is eoesep */ |
| 535 | if (fbinfo2.bits != 4 || fbinfo2.type != TABLETYPE_SPECIAL) | 501 | if (fbinfo2.bits != 4 || fbinfo2.type != TABLETYPE_SPECIAL) |
| 536 | goto solve_h48_error_data; | 502 | goto solve_h48_error_data; |
| 537 | fallback2 = h48data + offset; | 503 | eoesep = h48data + offset; |
| 538 | 504 | ||
| 539 | settings = (solution_settings_t) { | 505 | settings = (solution_settings_t) { |
| 540 | .unniss = true, | 506 | .unniss = true, |
| @@ -553,8 +519,7 @@ solve_h48( | |||
| 553 | .base = info.base, | 519 | .base = info.base, |
| 554 | .cocsepdata = cocsepdata, | 520 | .cocsepdata = cocsepdata, |
| 555 | .h48data = h48data, | 521 | .h48data = h48data, |
| 556 | .h48data_fallback_h0k4 = fallback, | 522 | .h48data_fallback_eoesep = eoesep, |
| 557 | .h48data_fallback_eoesep = fallback2, | ||
| 558 | .solution_moves = &solution_moves[i], | 523 | .solution_moves = &solution_moves[i], |
| 559 | .solution_settings = &settings, | 524 | .solution_settings = &settings, |
| 560 | .solution_list = &sollist, | 525 | .solution_list = &sollist, |
