diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-18 08:48:13 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-05-18 08:48:13 +0200 |
| commit | 8b94d135429a9f3253cc7f25a1453b412065c4a0 (patch) | |
| tree | 4a31d6def5421e95fb98505a2bc2653c18fca330 /src | |
| parent | 30b43f08955158d4f2066f4b50fe8d1241b3177b (diff) | |
| download | nissy-core-8b94d135429a9f3253cc7f25a1453b412065c4a0.tar.gz nissy-core-8b94d135429a9f3253cc7f25a1453b412065c4a0.zip | |
Refactor solver dispatch and checkdata
Diffstat (limited to 'src')
| -rw-r--r-- | src/nissy.c | 143 | ||||
| -rw-r--r-- | src/solvers/coord/gendata.h | 35 | ||||
| -rw-r--r-- | src/solvers/coord/solve.h | 35 | ||||
| -rw-r--r-- | src/solvers/coord/utils.h | 12 | ||||
| -rw-r--r-- | src/solvers/dispatch.h | 49 | ||||
| -rw-r--r-- | src/solvers/distribution.h | 77 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_cocsep.h | 16 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_h48.h | 86 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_types_macros.h | 8 | ||||
| -rw-r--r-- | src/solvers/h48/h48.h | 1 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 34 | ||||
| -rw-r--r-- | src/solvers/h48/utils.h | 66 | ||||
| -rw-r--r-- | src/solvers/solvers.h | 2 |
13 files changed, 318 insertions, 246 deletions
diff --git a/src/nissy.c b/src/nissy.c index acf6ebe..1f929c0 100644 --- a/src/nissy.c +++ b/src/nissy.c | |||
| @@ -12,13 +12,10 @@ | |||
| 12 | #include "core/core.h" | 12 | #include "core/core.h" |
| 13 | #include "solvers/solvers.h" | 13 | #include "solvers/solvers.h" |
| 14 | 14 | ||
| 15 | long long parse_h48_solver( | ||
| 16 | const char *, uint8_t [static 1], uint8_t [static 1]); | ||
| 17 | STATIC bool checkdata(const unsigned char *, const tableinfo_t [static 1]); | 15 | STATIC bool checkdata(const unsigned char *, const tableinfo_t [static 1]); |
| 18 | STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN], | 16 | STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN], |
| 19 | const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t); | 17 | const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t); |
| 20 | STATIC long long write_result(oriented_cube_t, char [static NISSY_SIZE_CUBE]); | 18 | STATIC long long write_result(oriented_cube_t, char [static NISSY_SIZE_CUBE]); |
| 21 | STATIC size_t my_strnlen(const char *, size_t); | ||
| 22 | STATIC long long nissy_dataid(const char *, char [static NISSY_SIZE_DATAID]); | 19 | STATIC long long nissy_dataid(const char *, char [static NISSY_SIZE_DATAID]); |
| 23 | STATIC long long nissy_gendata_unsafe( | 20 | STATIC long long nissy_gendata_unsafe( |
| 24 | const char *, unsigned long long, unsigned char *); | 21 | const char *, unsigned long long, unsigned char *); |
| @@ -33,67 +30,20 @@ struct { | |||
| 33 | GETCUBE_OPTIONS(NULL, NULL) | 30 | GETCUBE_OPTIONS(NULL, NULL) |
| 34 | }; | 31 | }; |
| 35 | 32 | ||
| 36 | long long | ||
| 37 | parse_h48_solver(const char *buf, uint8_t h[static 1], uint8_t k[static 1]) | ||
| 38 | { | ||
| 39 | const char *fullbuf = buf; | ||
| 40 | |||
| 41 | buf += 3; | ||
| 42 | |||
| 43 | if (*buf != 'h') | ||
| 44 | goto parse_h48_solver_error; | ||
| 45 | buf++; | ||
| 46 | |||
| 47 | *h = atoi(buf); | ||
| 48 | |||
| 49 | for ( ; *buf >= 0 + '0' && *buf <= 9 + '0'; buf++) | ||
| 50 | if (*buf == 0) | ||
| 51 | goto parse_h48_solver_error; | ||
| 52 | |||
| 53 | if (*buf != 'k') | ||
| 54 | goto parse_h48_solver_error; | ||
| 55 | buf++; | ||
| 56 | |||
| 57 | *k = atoi(buf); | ||
| 58 | |||
| 59 | return *h < 12 && (*k == 2 || (*k == 4 && *h == 0)) ? 0 : 1; | ||
| 60 | |||
| 61 | parse_h48_solver_error: | ||
| 62 | *h = 0; | ||
| 63 | *k = 0; | ||
| 64 | LOG("Error parsing H48 solver: must be in \"h48h*k*\" format," | ||
| 65 | " but got %s\n", fullbuf); | ||
| 66 | return NISSY_ERROR_INVALID_SOLVER; | ||
| 67 | } | ||
| 68 | |||
| 69 | STATIC bool | 33 | STATIC bool |
| 70 | checkdata(const unsigned char *buf, const tableinfo_t info[static 1]) | 34 | checkdata(const unsigned char *buf, const tableinfo_t info[static 1]) |
| 71 | { | 35 | { |
| 72 | uint64_t distr[INFO_DISTRIBUTION_LEN]; | 36 | uint64_t distr[INFO_DISTRIBUTION_LEN]; |
| 73 | 37 | ||
| 74 | if (my_strnlen(info->solver, INFO_SOLVER_STRLEN) | 38 | if (info->type == TABLETYPE_PRUNING) { |
| 75 | == INFO_SOLVER_STRLEN) { | 39 | getdistribution(buf + INFOSIZE, distr, info); |
| 76 | LOG("[checkdata] Error reading table info\n"); | 40 | LOG("\n[checkdata] Checking distribution for %s\n", info->solver); |
| 77 | return false; | 41 | return distribution_equal(info->distribution, distr, info->maxvalue); |
| 78 | } else if (!strncmp(info->solver, "cocsep", 6)) { | ||
| 79 | getdistribution_cocsep( | ||
| 80 | (uint32_t *)((char *)buf + INFOSIZE), distr); | ||
| 81 | } else if (!strncmp(info->solver, "h48", 3)) { | ||
| 82 | getdistribution_h48(buf + INFOSIZE, distr, | ||
| 83 | info->h48h, info->bits); | ||
| 84 | } else if (!strncmp(info->solver, "coordinate solver for ", 22)) { | ||
| 85 | getdistribution_coord(buf + INFOSIZE, | ||
| 86 | info->solver + 22, distr); | ||
| 87 | } else if (!strncmp(info->solver, "eoesep data for h48", 19)) { | ||
| 88 | return true; | ||
| 89 | } else if (!strncmp(info->solver, "coord helper table for ", 23)) { | ||
| 90 | return true; | ||
| 91 | } else { | 42 | } else { |
| 92 | LOG("[checkdata] unknown solver %s\n", info->solver); | 43 | LOG("\n[checkdata] Skipping distribution check for " |
| 93 | return false; | 44 | "special table %s\n", info->solver); |
| 45 | return true; | ||
| 94 | } | 46 | } |
| 95 | |||
| 96 | return distribution_equal(info->distribution, distr, info->maxvalue); | ||
| 97 | } | 47 | } |
| 98 | 48 | ||
| 99 | STATIC bool | 49 | STATIC bool |
| @@ -109,8 +59,12 @@ distribution_equal( | |||
| 109 | for (i = 0, wrong = 0; i <= MIN(maxvalue, 20); i++) { | 59 | for (i = 0, wrong = 0; i <= MIN(maxvalue, 20); i++) { |
| 110 | if (expected[i] != actual[i]) { | 60 | if (expected[i] != actual[i]) { |
| 111 | wrong++; | 61 | wrong++; |
| 112 | LOG("Value %" PRIu8 ": expected %" PRIu64 ", found %" | 62 | LOG("[checkdata] Value for depth %" PRIu8 |
| 113 | PRIu64 "\n", i, expected[i], actual[i]); | 63 | ": expected %" PRIu64 ", found %" PRIu64 "\n", |
| 64 | i, expected[i], actual[i]); | ||
| 65 | } else { | ||
| 66 | LOG("[checkdata] Value for depth %" PRIu8 | ||
| 67 | " is correct (%" PRIu64 ")\n", i, actual[i]); | ||
| 114 | } | 68 | } |
| 115 | } | 69 | } |
| 116 | 70 | ||
| @@ -130,18 +84,6 @@ write_result(oriented_cube_t cube, char result[static NISSY_SIZE_CUBE]) | |||
| 130 | return NISSY_OK; | 84 | return NISSY_OK; |
| 131 | } | 85 | } |
| 132 | 86 | ||
| 133 | STATIC size_t | ||
| 134 | my_strnlen(const char *str, size_t maxlen) | ||
| 135 | { | ||
| 136 | size_t i; | ||
| 137 | |||
| 138 | for (i = 0; i < maxlen; i++) | ||
| 139 | if (str[i] == '\0') | ||
| 140 | return i; | ||
| 141 | |||
| 142 | return maxlen; | ||
| 143 | } | ||
| 144 | |||
| 145 | long long | 87 | long long |
| 146 | nissy_inverse( | 88 | nissy_inverse( |
| 147 | const char cube[static NISSY_SIZE_CUBE], | 89 | const char cube[static NISSY_SIZE_CUBE], |
| @@ -337,22 +279,15 @@ nissy_datainfo( | |||
| 337 | STATIC long long | 279 | STATIC long long |
| 338 | nissy_dataid(const char *solver, char dataid[static NISSY_SIZE_DATAID]) | 280 | nissy_dataid(const char *solver, char dataid[static NISSY_SIZE_DATAID]) |
| 339 | { | 281 | { |
| 340 | if (!strncmp(solver, "h48", 3)) { | 282 | solver_dispatch_t *dispatch; |
| 341 | uint8_t h, k; | 283 | |
| 342 | long long err; | 284 | dispatch = match_solver(solver); |
| 343 | if ((err = parse_h48_solver(solver, &h, &k)) != NISSY_OK) | 285 | if (dispatch == NULL) { |
| 344 | return err; | 286 | LOG("[dataid] Unknown solver %s\n", solver); |
| 345 | /* TODO: also check that h and k are admissible */ | ||
| 346 | else strcpy(dataid, solver); | ||
| 347 | return err; | ||
| 348 | /* TODO: do this when moved parser */ | ||
| 349 | /* return dataid_h48(solver, dataid); */ | ||
| 350 | } else if (!strncmp(solver, "coord_", 6)) { | ||
| 351 | return dataid_coord(solver+6, dataid); | ||
| 352 | } else { | ||
| 353 | LOG("[gendata] Unknown solver %s\n", solver); | ||
| 354 | return NISSY_ERROR_INVALID_SOLVER; | 287 | return NISSY_ERROR_INVALID_SOLVER; |
| 355 | } | 288 | } |
| 289 | |||
| 290 | return dispatch->dataid(solver, dataid); | ||
| 356 | } | 291 | } |
| 357 | 292 | ||
| 358 | long long | 293 | long long |
| @@ -386,8 +321,7 @@ nissy_gendata_unsafe( | |||
| 386 | unsigned char *data | 321 | unsigned char *data |
| 387 | ) | 322 | ) |
| 388 | { | 323 | { |
| 389 | long long parse_ret; | 324 | solver_dispatch_t *dispatch; |
| 390 | gendata_h48_arg_t arg; | ||
| 391 | 325 | ||
| 392 | if (solver == NULL) { | 326 | if (solver == NULL) { |
| 393 | LOG("[gendata] Error: 'solver' argument is NULL\n"); | 327 | LOG("[gendata] Error: 'solver' argument is NULL\n"); |
| @@ -399,20 +333,13 @@ nissy_gendata_unsafe( | |||
| 399 | return NISSY_ERROR_DATA; | 333 | return NISSY_ERROR_DATA; |
| 400 | } | 334 | } |
| 401 | 335 | ||
| 402 | if (!strncmp(solver, "h48", 3)) { | 336 | dispatch = match_solver(solver); |
| 403 | arg.buf_size = data_size; | 337 | if (dispatch == NULL) { |
| 404 | arg.buf = data; | ||
| 405 | parse_ret = parse_h48_solver(solver, &arg.h, &arg.k); | ||
| 406 | arg.maxdepth = 20; | ||
| 407 | if (parse_ret != NISSY_OK) | ||
| 408 | return parse_ret; | ||
| 409 | return gendata_h48(&arg); | ||
| 410 | } else if (!strncmp(solver, "coord_", 6)) { | ||
| 411 | return gendata_coord_dispatch(solver+6, data); | ||
| 412 | } else { | ||
| 413 | LOG("[gendata] Unknown solver %s\n", solver); | 338 | LOG("[gendata] Unknown solver %s\n", solver); |
| 414 | return NISSY_ERROR_INVALID_SOLVER; | 339 | return NISSY_ERROR_INVALID_SOLVER; |
| 415 | } | 340 | } |
| 341 | |||
| 342 | return dispatch->gendata(solver, data_size, data); | ||
| 416 | } | 343 | } |
| 417 | 344 | ||
| 418 | long long | 345 | long long |
| @@ -466,9 +393,8 @@ nissy_solve( | |||
| 466 | ) | 393 | ) |
| 467 | { | 394 | { |
| 468 | oriented_cube_t oc; | 395 | oriented_cube_t oc; |
| 469 | long long parse_ret; | ||
| 470 | uint8_t h, k; | ||
| 471 | int t; | 396 | int t; |
| 397 | solver_dispatch_t *dispatch; | ||
| 472 | 398 | ||
| 473 | if (solver == NULL) { | 399 | if (solver == NULL) { |
| 474 | LOG("[solve] Error: 'solver' argument is NULL\n"); | 400 | LOG("[solve] Error: 'solver' argument is NULL\n"); |
| @@ -511,21 +437,14 @@ nissy_solve( | |||
| 511 | return NISSY_ERROR_DATA; | 437 | return NISSY_ERROR_DATA; |
| 512 | } | 438 | } |
| 513 | 439 | ||
| 514 | if (!strncmp(solver, "h48", 3)) { | 440 | dispatch = match_solver(solver); |
| 515 | parse_ret = parse_h48_solver(solver, &h, &k); | 441 | if (dispatch == NULL) { |
| 516 | if (parse_ret != NISSY_OK) | ||
| 517 | return parse_ret; | ||
| 518 | return solve_h48(oc, minmoves, maxmoves, maxsols, | ||
| 519 | optimal, t, data_size, data, sols_size, sols, stats, | ||
| 520 | poll_status, poll_status_data); | ||
| 521 | } else if (!strncmp(solver, "coord_", 6)) { | ||
| 522 | return solve_coord_dispatch(oc, solver + 6, nissflag, | ||
| 523 | minmoves, maxmoves, maxsols, optimal, t, data_size, data, | ||
| 524 | sols_size, sols, poll_status, poll_status_data); | ||
| 525 | } else { | ||
| 526 | LOG("[solve] Error: unknown solver '%s'\n", solver); | 442 | LOG("[solve] Error: unknown solver '%s'\n", solver); |
| 527 | return NISSY_ERROR_INVALID_SOLVER; | 443 | return NISSY_ERROR_INVALID_SOLVER; |
| 528 | } | 444 | } |
| 445 | return dispatch->solve(oc, solver, nissflag, minmoves, maxmoves, | ||
| 446 | maxsols, optimal, t, data_size, data, sols_size, sols, stats, | ||
| 447 | poll_status, poll_status_data); | ||
| 529 | } | 448 | } |
| 530 | 449 | ||
| 531 | long long | 450 | long long |
diff --git a/src/solvers/coord/gendata.h b/src/solvers/coord/gendata.h index 7a974f8..1b65f49 100644 --- a/src/solvers/coord/gendata.h +++ b/src/solvers/coord/gendata.h | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | STATIC size_t gendata_coord(const coord_t [static 1], unsigned char *); | 1 | STATIC size_t gendata_coord(const coord_t [static 1], unsigned char *); |
| 2 | STATIC int64_t gendata_coord_dispatch(const char *, unsigned char *); | 2 | STATIC long long gendata_coord_dispatch(const char *, unsigned long long, |
| 3 | unsigned char *); | ||
| 3 | STATIC tableinfo_t genptable_coord( | 4 | STATIC tableinfo_t genptable_coord( |
| 4 | const coord_t [static 1], const unsigned char *, unsigned char *); | 5 | const coord_t [static 1], const unsigned char *, unsigned char *); |
| 5 | STATIC bool switch_to_fromnew(uint64_t, uint64_t, uint64_t); | 6 | STATIC bool switch_to_fromnew(uint64_t, uint64_t, uint64_t); |
| @@ -7,15 +8,17 @@ STATIC uint64_t genptable_coord_fillneighbors(const coord_t [static 1], | |||
| 7 | const unsigned char *, uint64_t, uint8_t, unsigned char *); | 8 | const unsigned char *, uint64_t, uint8_t, unsigned char *); |
| 8 | STATIC uint64_t genptable_coord_fillfromnew(const coord_t [static 1], | 9 | STATIC uint64_t genptable_coord_fillfromnew(const coord_t [static 1], |
| 9 | const unsigned char *, uint64_t, uint8_t, unsigned char *); | 10 | const unsigned char *, uint64_t, uint8_t, unsigned char *); |
| 10 | STATIC void getdistribution_coord(const unsigned char *, const char *, | ||
| 11 | uint64_t [static INFO_DISTRIBUTION_LEN]); | ||
| 12 | STATIC uint8_t get_coord_pval( | 11 | STATIC uint8_t get_coord_pval( |
| 13 | const coord_t [static 1], const unsigned char *, uint64_t); | 12 | const coord_t [static 1], const unsigned char *, uint64_t); |
| 14 | STATIC void set_coord_pval( | 13 | STATIC void set_coord_pval( |
| 15 | const coord_t [static 1], unsigned char *, uint64_t, uint8_t); | 14 | const coord_t [static 1], unsigned char *, uint64_t, uint8_t); |
| 16 | 15 | ||
| 17 | STATIC int64_t | 16 | STATIC long long |
| 18 | gendata_coord_dispatch(const char *coordstr, unsigned char *buf) | 17 | gendata_coord_dispatch( |
| 18 | const char *coordstr, | ||
| 19 | unsigned long long bufsize, | ||
| 20 | unsigned char *buf | ||
| 21 | ) | ||
| 19 | { | 22 | { |
| 20 | coord_t *coord; | 23 | coord_t *coord; |
| 21 | 24 | ||
| @@ -249,28 +252,6 @@ genptable_coord_fillfromnew( | |||
| 249 | return tot; | 252 | return tot; |
| 250 | } | 253 | } |
| 251 | 254 | ||
| 252 | STATIC void | ||
| 253 | getdistribution_coord( | ||
| 254 | const unsigned char *table, | ||
| 255 | const char *coord, | ||
| 256 | uint64_t distr[static INFO_DISTRIBUTION_LEN] | ||
| 257 | ) | ||
| 258 | { | ||
| 259 | uint8_t v; | ||
| 260 | uint64_t i; | ||
| 261 | coord_t *c; | ||
| 262 | |||
| 263 | memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); | ||
| 264 | |||
| 265 | if((c = parse_coord(strlen(coord), coord)) == NULL) | ||
| 266 | return; | ||
| 267 | |||
| 268 | for (i = 0; i < c->max; i++) { | ||
| 269 | v = get_coord_pval(c, table, i); | ||
| 270 | distr[v]++; | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | STATIC uint8_t | 255 | STATIC uint8_t |
| 275 | get_coord_pval( | 256 | get_coord_pval( |
| 276 | const coord_t coord[static 1], | 257 | const coord_t coord[static 1], |
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h index 8eb3e9d..df0f6ff 100644 --- a/src/solvers/coord/solve.h +++ b/src/solvers/coord/solve.h | |||
| @@ -13,11 +13,13 @@ typedef struct { | |||
| 13 | } dfsarg_solve_coord_t; | 13 | } dfsarg_solve_coord_t; |
| 14 | 14 | ||
| 15 | STATIC int64_t solve_coord(oriented_cube_t, coord_t [static 1], uint8_t, | 15 | STATIC int64_t solve_coord(oriented_cube_t, coord_t [static 1], uint8_t, |
| 16 | uint8_t, uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t, | 16 | uint8_t, uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t n, |
| 17 | const unsigned char *, size_t n, char [n], int (*)(void *), void *); | 17 | const unsigned char [n], size_t m, char [m], int (*)(void *), void *); |
| 18 | STATIC int64_t solve_coord_dispatch(oriented_cube_t, const char *, uint8_t, | 18 | STATIC long long solve_coord_dispatch(oriented_cube_t, const char *, unsigned, |
| 19 | uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t, | 19 | unsigned, unsigned, unsigned, unsigned, unsigned, unsigned long long n, |
| 20 | const unsigned char *, size_t n, char [n], int (*)(void *), void *); | 20 | const unsigned char [n], unsigned m, char [m], |
| 21 | long long [static NISSY_SIZE_SOLVE_STATS], | ||
| 22 | int (*)(void *), void *); | ||
| 21 | STATIC bool coord_solution_admissible(const dfsarg_solve_coord_t [static 1]); | 23 | STATIC bool coord_solution_admissible(const dfsarg_solve_coord_t [static 1]); |
| 22 | STATIC bool solve_coord_dfs_stop(const dfsarg_solve_coord_t [static 1]); | 24 | STATIC bool solve_coord_dfs_stop(const dfsarg_solve_coord_t [static 1]); |
| 23 | STATIC bool coord_continue_onnormal(const dfsarg_solve_coord_t [static 1]); | 25 | STATIC bool coord_continue_onnormal(const dfsarg_solve_coord_t [static 1]); |
| @@ -198,20 +200,21 @@ solve_coord_dfs(dfsarg_solve_coord_t arg[static 1]) | |||
| 198 | return ret; | 200 | return ret; |
| 199 | } | 201 | } |
| 200 | 202 | ||
| 201 | STATIC int64_t | 203 | STATIC long long |
| 202 | solve_coord_dispatch( | 204 | solve_coord_dispatch( |
| 203 | oriented_cube_t oc, | 205 | oriented_cube_t oc, |
| 204 | const char *coord_and_axis, | 206 | const char *coord_and_axis, |
| 205 | uint8_t nissflag, | 207 | unsigned nissflag, |
| 206 | uint8_t minmoves, | 208 | unsigned minmoves, |
| 207 | uint8_t maxmoves, | 209 | unsigned maxmoves, |
| 208 | uint64_t maxsolutions, | 210 | unsigned maxsolutions, |
| 209 | uint8_t optimal, | 211 | unsigned optimal, |
| 210 | uint8_t threads, | 212 | unsigned threads, |
| 211 | uint64_t data_size, | 213 | unsigned long long data_size, |
| 212 | const unsigned char *data, | 214 | const unsigned char data[data_size], |
| 213 | size_t solutions_size, | 215 | unsigned solutions_size, |
| 214 | char sols[solutions_size], | 216 | char sols[solutions_size], |
| 217 | long long stats[static NISSY_SIZE_SOLVE_STATS], | ||
| 215 | int (*poll_status)(void *), | 218 | int (*poll_status)(void *), |
| 216 | void *poll_status_data | 219 | void *poll_status_data |
| 217 | ) | 220 | ) |
| @@ -250,7 +253,7 @@ solve_coord( | |||
| 250 | uint8_t optimal, | 253 | uint8_t optimal, |
| 251 | uint8_t threads, | 254 | uint8_t threads, |
| 252 | uint64_t data_size, | 255 | uint64_t data_size, |
| 253 | const unsigned char *data, | 256 | const unsigned char data[data_size], |
| 254 | size_t solutions_size, | 257 | size_t solutions_size, |
| 255 | char sols[solutions_size], | 258 | char sols[solutions_size], |
| 256 | int (*poll_status)(void *), | 259 | int (*poll_status)(void *), |
diff --git a/src/solvers/coord/utils.h b/src/solvers/coord/utils.h index ef3f817..aa4d74c 100644 --- a/src/solvers/coord/utils.h +++ b/src/solvers/coord/utils.h | |||
| @@ -2,7 +2,7 @@ STATIC coord_t *parse_coord(size_t n, const char [n]); | |||
| 2 | STATIC uint8_t parse_axis(size_t n, const char [n]); | 2 | STATIC uint8_t parse_axis(size_t n, const char [n]); |
| 3 | STATIC void parse_coord_and_axis( | 3 | STATIC void parse_coord_and_axis( |
| 4 | size_t n, const char [n], coord_t **, uint8_t *); | 4 | size_t n, const char [n], coord_t **, uint8_t *); |
| 5 | STATIC int64_t dataid_coord(const char *, char [static NISSY_SIZE_DATAID]); | 5 | STATIC long long dataid_coord(const char *, char [static NISSY_SIZE_DATAID]); |
| 6 | 6 | ||
| 7 | STATIC coord_t * | 7 | STATIC coord_t * |
| 8 | parse_coord(size_t n, const char coord[n]) | 8 | parse_coord(size_t n, const char coord[n]) |
| @@ -38,20 +38,22 @@ parse_coord_and_axis( | |||
| 38 | uint8_t *axis | 38 | uint8_t *axis |
| 39 | ) | 39 | ) |
| 40 | { | 40 | { |
| 41 | const char *s; | ||
| 41 | size_t i; | 42 | size_t i; |
| 42 | 43 | ||
| 44 | s = str + 6; | ||
| 43 | for (i = 0; i < n; i++) | 45 | for (i = 0; i < n; i++) |
| 44 | if (str[i] == '_') | 46 | if (s[i] == '_') |
| 45 | break; | 47 | break; |
| 46 | 48 | ||
| 47 | if (coord != NULL) | 49 | if (coord != NULL) |
| 48 | *coord = parse_coord(i, str); | 50 | *coord = parse_coord(i, s); |
| 49 | 51 | ||
| 50 | if (axis != NULL) | 52 | if (axis != NULL) |
| 51 | *axis = i == n ? UINT8_ERROR : parse_axis(n-i-1, str+i+1); | 53 | *axis = i == n ? UINT8_ERROR : parse_axis(n-i-1, s+i+1); |
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | STATIC int64_t | 56 | STATIC long long |
| 55 | dataid_coord(const char *ca, char dataid[static NISSY_SIZE_DATAID]) | 57 | dataid_coord(const char *ca, char dataid[static NISSY_SIZE_DATAID]) |
| 56 | { | 58 | { |
| 57 | coord_t *c; | 59 | coord_t *c; |
diff --git a/src/solvers/dispatch.h b/src/solvers/dispatch.h new file mode 100644 index 0000000..0cfbc3b --- /dev/null +++ b/src/solvers/dispatch.h | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | typedef struct { | ||
| 2 | const char *prefix; | ||
| 3 | long long (*dataid)(const char *, char [static NISSY_SIZE_DATAID]); | ||
| 4 | long long (*gendata)( | ||
| 5 | const char *, unsigned long long, unsigned char *); | ||
| 6 | long long (*solve)(oriented_cube_t, const char *, unsigned, unsigned, | ||
| 7 | unsigned, unsigned, unsigned, unsigned, unsigned long long, | ||
| 8 | const unsigned char *, unsigned, char *, | ||
| 9 | long long [static NISSY_SIZE_SOLVE_STATS], | ||
| 10 | int (*)(void *), void *); | ||
| 11 | } solver_dispatch_t; | ||
| 12 | |||
| 13 | STATIC solver_dispatch_t *match_solver(const char *); | ||
| 14 | |||
| 15 | solver_dispatch_t solver_dispatchers[] = { | ||
| 16 | { | ||
| 17 | .prefix = "h48", | ||
| 18 | .dataid = dataid_h48, | ||
| 19 | .gendata = gendata_h48_dispatch, | ||
| 20 | .solve = solve_h48_dispatch, | ||
| 21 | }, | ||
| 22 | { | ||
| 23 | .prefix = "coord_", | ||
| 24 | .dataid = dataid_coord, | ||
| 25 | .gendata = gendata_coord_dispatch, | ||
| 26 | .solve = solve_coord_dispatch, | ||
| 27 | }, | ||
| 28 | { | ||
| 29 | .prefix = NULL | ||
| 30 | } | ||
| 31 | }; | ||
| 32 | |||
| 33 | STATIC solver_dispatch_t * | ||
| 34 | match_solver(const char *name) | ||
| 35 | { | ||
| 36 | const char *prefix; | ||
| 37 | int i; | ||
| 38 | |||
| 39 | if (name == NULL) | ||
| 40 | return NULL; | ||
| 41 | |||
| 42 | for (i = 0; solver_dispatchers[i].prefix != NULL; i++) { | ||
| 43 | prefix = solver_dispatchers[i].prefix; | ||
| 44 | if (!strncmp(name, prefix, strlen(prefix))) | ||
| 45 | return &solver_dispatchers[i]; | ||
| 46 | } | ||
| 47 | |||
| 48 | return NULL; | ||
| 49 | } | ||
diff --git a/src/solvers/distribution.h b/src/solvers/distribution.h new file mode 100644 index 0000000..1a3719c --- /dev/null +++ b/src/solvers/distribution.h | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | #define ENTRIES_PER_BYTE(k) (UINT64_C(8) / (uint64_t)(k)) | ||
| 2 | #define TABLE_SHIFT(i, k) ((uint8_t)(k) * (uint8_t)((i) % ENTRIES_PER_BYTE(k))) | ||
| 3 | #define TABLE_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << TABLE_SHIFT(i, k)) | ||
| 4 | |||
| 5 | typedef struct { | ||
| 6 | uint64_t min; | ||
| 7 | uint64_t max; | ||
| 8 | uint8_t bits; | ||
| 9 | uint64_t *distr; | ||
| 10 | const unsigned char *table; | ||
| 11 | } getdistribution_data_t; | ||
| 12 | |||
| 13 | STATIC void *getdistribution_runthread(void *); | ||
| 14 | STATIC void getdistribution(const unsigned char *, | ||
| 15 | uint64_t [static INFO_DISTRIBUTION_LEN], const tableinfo_t [static 1]); | ||
| 16 | |||
| 17 | STATIC void * | ||
| 18 | getdistribution_runthread(void *arg) | ||
| 19 | { | ||
| 20 | getdistribution_data_t *data = (getdistribution_data_t *)arg; | ||
| 21 | const unsigned char *table; | ||
| 22 | uint8_t j, k, m; | ||
| 23 | uint64_t i; | ||
| 24 | |||
| 25 | memset(data->distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); | ||
| 26 | |||
| 27 | k = data->bits; | ||
| 28 | table = data->table; | ||
| 29 | m = TABLE_MASK(0, k); | ||
| 30 | for (i = data->min; i < data->max; i++) | ||
| 31 | for (j = 0; j < ENTRIES_PER_BYTE(k); j++) | ||
| 32 | data->distr[(table[i] & (m << (j*k))) >> (j*k)]++; | ||
| 33 | |||
| 34 | return NULL; | ||
| 35 | } | ||
| 36 | |||
| 37 | STATIC void | ||
| 38 | getdistribution( | ||
| 39 | const unsigned char *table, | ||
| 40 | uint64_t distr[static INFO_DISTRIBUTION_LEN], | ||
| 41 | const tableinfo_t info[static 1] | ||
| 42 | ) { | ||
| 43 | getdistribution_data_t targ[THREADS]; | ||
| 44 | pthread_t thread[THREADS]; | ||
| 45 | uint8_t pval, k; | ||
| 46 | uint64_t local_distr[THREADS][INFO_DISTRIBUTION_LEN]; | ||
| 47 | uint64_t i, j, nbytes, sz, epb; | ||
| 48 | |||
| 49 | k = info->bits; | ||
| 50 | epb = ENTRIES_PER_BYTE(k); | ||
| 51 | nbytes = info->entries / epb; | ||
| 52 | sz = nbytes / THREADS; | ||
| 53 | for (i = 0; i < THREADS; i++) { | ||
| 54 | targ[i] = (getdistribution_data_t) { | ||
| 55 | .min = i * sz, | ||
| 56 | .max = i == THREADS - 1 ? nbytes : (i+1) * sz, | ||
| 57 | .bits = k, | ||
| 58 | .distr = local_distr[i], | ||
| 59 | .table = table, | ||
| 60 | }; | ||
| 61 | pthread_create(&thread[i], NULL, | ||
| 62 | getdistribution_runthread, &targ[i]); | ||
| 63 | } | ||
| 64 | |||
| 65 | for (i = 0; i < THREADS; i++) | ||
| 66 | pthread_join(thread[i], NULL); | ||
| 67 | |||
| 68 | memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); | ||
| 69 | for (i = 0; i < THREADS; i++) | ||
| 70 | for (j = 0; j < INFO_DISTRIBUTION_LEN; j++) | ||
| 71 | distr[j] += local_distr[i][j]; | ||
| 72 | |||
| 73 | for (i = nbytes * epb; i < info->entries; i++) { | ||
| 74 | pval = (table[i/epb] & TABLE_MASK(i, k)) >> TABLE_SHIFT(i, k); | ||
| 75 | distr[pval]++; | ||
| 76 | } | ||
| 77 | } | ||
diff --git a/src/solvers/h48/gendata_cocsep.h b/src/solvers/h48/gendata_cocsep.h index 2eac383..3117a8e 100644 --- a/src/solvers/h48/gendata_cocsep.h +++ b/src/solvers/h48/gendata_cocsep.h | |||
| @@ -1,7 +1,5 @@ | |||
| 1 | STATIC size_t gendata_cocsep(unsigned char *, uint64_t *, cube_t *); | 1 | STATIC size_t gendata_cocsep(unsigned char *, uint64_t *, cube_t *); |
| 2 | STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t [static 1]); | 2 | STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t [static 1]); |
| 3 | STATIC void getdistribution_cocsep( | ||
| 4 | const uint32_t [static COCSEP_TABLESIZE], uint64_t [static 21]); | ||
| 5 | 3 | ||
| 6 | STATIC_INLINE bool gendata_cocsep_get_visited( | 4 | STATIC_INLINE bool gendata_cocsep_get_visited( |
| 7 | const uint8_t [static COCSEP_VISITEDSIZE], int64_t); | 5 | const uint8_t [static COCSEP_VISITEDSIZE], int64_t); |
| @@ -136,20 +134,6 @@ gendata_cocsep_dfs(cocsep_dfs_arg_t arg[static 1]) | |||
| 136 | return cc; | 134 | return cc; |
| 137 | } | 135 | } |
| 138 | 136 | ||
| 139 | STATIC void | ||
| 140 | getdistribution_cocsep( | ||
| 141 | const uint32_t table[static COCSEP_TABLESIZE], | ||
| 142 | uint64_t distr[static 21] | ||
| 143 | ) | ||
| 144 | { | ||
| 145 | size_t i; | ||
| 146 | |||
| 147 | memset(distr, 0, 21 * sizeof(uint64_t)); | ||
| 148 | |||
| 149 | for (i = 0; i < COCSEP_TABLESIZE; i++) | ||
| 150 | distr[CBOUND(table[i])]++; | ||
| 151 | } | ||
| 152 | |||
| 153 | STATIC_INLINE bool | 137 | STATIC_INLINE bool |
| 154 | gendata_cocsep_get_visited( | 138 | gendata_cocsep_get_visited( |
| 155 | const uint8_t a[static COCSEP_VISITEDSIZE], | 139 | const uint8_t a[static COCSEP_VISITEDSIZE], |
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index c1a9ced..644ddc2 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | STATIC long long gendata_h48_dispatch( | ||
| 2 | const char *, unsigned long long, unsigned char *); | ||
| 1 | STATIC uint64_t gendata_h48short(gendata_h48short_arg_t [static 1]); | 3 | STATIC uint64_t gendata_h48short(gendata_h48short_arg_t [static 1]); |
| 2 | STATIC int64_t gendata_h48(gendata_h48_arg_t [static 1]); | 4 | STATIC int64_t gendata_h48(gendata_h48_arg_t [static 1]); |
| 3 | STATIC void gendata_h48h0k4(gendata_h48_arg_t [static 1]); | 5 | STATIC void gendata_h48h0k4(gendata_h48_arg_t [static 1]); |
| @@ -12,9 +14,6 @@ STATIC_INLINE bool gendata_h48k2_dfs_stop( | |||
| 12 | cube_t, int8_t, h48k2_dfs_arg_t [static 1]); | 14 | cube_t, int8_t, h48k2_dfs_arg_t [static 1]); |
| 13 | STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t [static 1]); | 15 | STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t [static 1]); |
| 14 | STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t [static 1]); | 16 | STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t [static 1]); |
| 15 | STATIC void *getdistribution_h48_runthread(void *); | ||
| 16 | STATIC void getdistribution_h48(const unsigned char *, | ||
| 17 | uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t); | ||
| 18 | 17 | ||
| 19 | STATIC const uint32_t *get_cocsepdata_constptr(const unsigned char *); | 18 | STATIC const uint32_t *get_cocsepdata_constptr(const unsigned char *); |
| 20 | STATIC const unsigned char *get_h48data_constptr(const unsigned char *); | 19 | STATIC const unsigned char *get_h48data_constptr(const unsigned char *); |
| @@ -28,6 +27,27 @@ STATIC_INLINE void set_h48_pval_atomic( | |||
| 28 | 27 | ||
| 29 | size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *); | 28 | size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *); |
| 30 | 29 | ||
| 30 | STATIC long long | ||
| 31 | gendata_h48_dispatch( | ||
| 32 | const char *solver, | ||
| 33 | unsigned long long data_size, | ||
| 34 | unsigned char *data | ||
| 35 | ) | ||
| 36 | { | ||
| 37 | long long err; | ||
| 38 | gendata_h48_arg_t arg; | ||
| 39 | |||
| 40 | err = parse_h48_hk(solver, &arg.h, &arg.k); | ||
| 41 | if (err != NISSY_OK) | ||
| 42 | return err; | ||
| 43 | |||
| 44 | arg.buf_size = data_size; | ||
| 45 | arg.buf = data; | ||
| 46 | arg.maxdepth = 20; | ||
| 47 | |||
| 48 | return gendata_h48(&arg); | ||
| 49 | } | ||
| 50 | |||
| 31 | STATIC uint64_t | 51 | STATIC uint64_t |
| 32 | gendata_h48short(gendata_h48short_arg_t arg[static 1]) | 52 | gendata_h48short(gendata_h48short_arg_t arg[static 1]) |
| 33 | { | 53 | { |
| @@ -649,64 +669,6 @@ makeinfo_h48k2(gendata_h48_arg_t arg[static 1]) | |||
| 649 | return info; | 669 | return info; |
| 650 | } | 670 | } |
| 651 | 671 | ||
| 652 | STATIC void * | ||
| 653 | getdistribution_h48_runthread(void *arg) | ||
| 654 | { | ||
| 655 | getdistribution_h48_data_t *data = (getdistribution_h48_data_t *)arg; | ||
| 656 | const unsigned char *table; | ||
| 657 | uint8_t j, k, m; | ||
| 658 | int64_t i; | ||
| 659 | |||
| 660 | memset(data->distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); | ||
| 661 | |||
| 662 | k = data->k; | ||
| 663 | table = data->table; | ||
| 664 | m = H48_MASK(0, k); | ||
| 665 | for (i = data->min; i < data->max; i++) | ||
| 666 | for (j = 0; j < H48_DIV(k); j++) | ||
| 667 | data->distr[(table[i] & (m << (j*k))) >> (j*k)]++; | ||
| 668 | |||
| 669 | return NULL; | ||
| 670 | } | ||
| 671 | |||
| 672 | STATIC void | ||
| 673 | getdistribution_h48( | ||
| 674 | const unsigned char *table, | ||
| 675 | uint64_t distr[static INFO_DISTRIBUTION_LEN], | ||
| 676 | uint8_t h, | ||
| 677 | uint8_t k | ||
| 678 | ) { | ||
| 679 | getdistribution_h48_data_t targ[THREADS]; | ||
| 680 | pthread_t thread[THREADS]; | ||
| 681 | uint64_t local_distr[THREADS][INFO_DISTRIBUTION_LEN]; | ||
| 682 | int64_t i, j, nbytes, sz; | ||
| 683 | |||
| 684 | nbytes = H48_COORDMAX(h) / H48_DIV(k); | ||
| 685 | sz = nbytes / THREADS; | ||
| 686 | for (i = 0; i < THREADS; i++) { | ||
| 687 | targ[i] = (getdistribution_h48_data_t) { | ||
| 688 | .min = i * sz, | ||
| 689 | .max = i == THREADS - 1 ? nbytes : (i+1) * sz, | ||
| 690 | .k = k, | ||
| 691 | .distr = local_distr[i], | ||
| 692 | .table = table, | ||
| 693 | }; | ||
| 694 | pthread_create(&thread[i], NULL, | ||
| 695 | getdistribution_h48_runthread, &targ[i]); | ||
| 696 | } | ||
| 697 | |||
| 698 | for (i = 0; i < THREADS; i++) | ||
| 699 | pthread_join(thread[i], NULL); | ||
| 700 | |||
| 701 | memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); | ||
| 702 | for (i = 0; i < THREADS; i++) | ||
| 703 | for (j = 0; j < INFO_DISTRIBUTION_LEN; j++) | ||
| 704 | distr[j] += local_distr[i][j]; | ||
| 705 | |||
| 706 | for (i = nbytes * H48_DIV(k); i < H48_COORDMAX(h); i++) | ||
| 707 | distr[get_h48_pval(table, i, k)]++; | ||
| 708 | } | ||
| 709 | |||
| 710 | STATIC const uint32_t * | 672 | STATIC const uint32_t * |
| 711 | get_cocsepdata_constptr(const unsigned char *data) | 673 | get_cocsepdata_constptr(const unsigned char *data) |
| 712 | { | 674 | { |
| @@ -821,7 +783,7 @@ gendata_h48_derive(uint8_t h, const unsigned char *fulltable, unsigned char *buf | |||
| 821 | h48derive, j, arg.k, MIN(val_full, val_derive)); | 783 | h48derive, j, arg.k, MIN(val_full, val_derive)); |
| 822 | } | 784 | } |
| 823 | 785 | ||
| 824 | getdistribution_h48(h48derive, arg.info.distribution, h, arg.k); | 786 | getdistribution(h48derive, arg.info.distribution, &arg.info); |
| 825 | 787 | ||
| 826 | bufsize = arg.buf_size - COCSEP_FULLSIZE - INFOSIZE; | 788 | bufsize = arg.buf_size - COCSEP_FULLSIZE - INFOSIZE; |
| 827 | if (writetableinfo(&arg.info, bufsize, (unsigned char *)arg.h48buf) | 789 | if (writetableinfo(&arg.info, bufsize, (unsigned char *)arg.h48buf) |
diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h index c4b1b5a..b0592c2 100644 --- a/src/solvers/h48/gendata_types_macros.h +++ b/src/solvers/h48/gendata_types_macros.h | |||
| @@ -121,11 +121,3 @@ typedef struct { | |||
| 121 | _Atomic unsigned char *table_atomic; | 121 | _Atomic unsigned char *table_atomic; |
| 122 | pthread_mutex_t **table_mutex; | 122 | pthread_mutex_t **table_mutex; |
| 123 | } gendata_h48_mark_t; | 123 | } gendata_h48_mark_t; |
| 124 | |||
| 125 | typedef struct { | ||
| 126 | int64_t min; | ||
| 127 | int64_t max; | ||
| 128 | uint8_t k; | ||
| 129 | uint64_t *distr; | ||
| 130 | const unsigned char *table; | ||
| 131 | } getdistribution_h48_data_t; | ||
diff --git a/src/solvers/h48/h48.h b/src/solvers/h48/h48.h index 0cfa773..79d2583 100644 --- a/src/solvers/h48/h48.h +++ b/src/solvers/h48/h48.h | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | #include "utils.h" | ||
| 1 | #include "coordinate_types_macros.h" | 2 | #include "coordinate_types_macros.h" |
| 2 | #include "map_types_macros.h" | 3 | #include "map_types_macros.h" |
| 3 | #include "gendata_types_macros.h" | 4 | #include "gendata_types_macros.h" |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index f2967ed..2818c09 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -50,6 +50,10 @@ typedef struct { | |||
| 50 | int8_t *shortest_sol; | 50 | int8_t *shortest_sol; |
| 51 | } dfsarg_solve_h48_maketasks_t; | 51 | } dfsarg_solve_h48_maketasks_t; |
| 52 | 52 | ||
| 53 | STATIC long long solve_h48_dispatch(oriented_cube_t, const char *, unsigned, | ||
| 54 | unsigned, unsigned, unsigned, unsigned, unsigned, unsigned long long n, | ||
| 55 | const unsigned char [n], unsigned m, char [m], | ||
| 56 | long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *); | ||
| 53 | STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]); | 57 | STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]); |
| 54 | STATIC int64_t solve_h48_maketasks( | 58 | STATIC int64_t solve_h48_maketasks( |
| 55 | dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1], | 59 | dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1], |
| @@ -61,6 +65,36 @@ STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, | |||
| 61 | uint8_t, uint64_t, const unsigned char *, size_t n, char [n], | 65 | uint8_t, uint64_t, const unsigned char *, size_t n, char [n], |
| 62 | long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *); | 66 | long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *); |
| 63 | 67 | ||
| 68 | STATIC long long solve_h48_dispatch( | ||
| 69 | oriented_cube_t oc, | ||
| 70 | const char *solver, | ||
| 71 | unsigned nissflag, | ||
| 72 | unsigned minmoves, | ||
| 73 | unsigned maxmoves, | ||
| 74 | unsigned maxsols, | ||
| 75 | unsigned optimal, | ||
| 76 | unsigned threads, | ||
| 77 | unsigned long long data_size, | ||
| 78 | const unsigned char data[data_size], | ||
| 79 | unsigned sols_size, | ||
| 80 | char sols[sols_size], | ||
| 81 | long long stats[static NISSY_SIZE_SOLVE_STATS], | ||
| 82 | int (*poll_status)(void *), | ||
| 83 | void *poll_status_data | ||
| 84 | ) | ||
| 85 | { | ||
| 86 | uint8_t h, k; | ||
| 87 | long long err; | ||
| 88 | |||
| 89 | err = parse_h48_hk(solver, &h, &k); | ||
| 90 | if (err != NISSY_OK) | ||
| 91 | return err; | ||
| 92 | |||
| 93 | return solve_h48(oc, minmoves, maxmoves, maxsols, optimal, threads, | ||
| 94 | data_size, data, sols_size, sols, stats, | ||
| 95 | poll_status, poll_status_data); | ||
| 96 | } | ||
| 97 | |||
| 64 | STATIC_INLINE bool | 98 | STATIC_INLINE bool |
| 65 | solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) | 99 | solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) |
| 66 | { | 100 | { |
diff --git a/src/solvers/h48/utils.h b/src/solvers/h48/utils.h new file mode 100644 index 0000000..b266c66 --- /dev/null +++ b/src/solvers/h48/utils.h | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | long long parse_h48_hk( | ||
| 2 | const char *, uint8_t [static 1], uint8_t [static 1]); | ||
| 3 | STATIC long long dataid_h48(const char *, char [static NISSY_SIZE_DATAID]); | ||
| 4 | |||
| 5 | long long | ||
| 6 | parse_h48_hk(const char *buf, uint8_t h[static 1], uint8_t k[static 1]) | ||
| 7 | { | ||
| 8 | char format_error_msg[100]; | ||
| 9 | sprintf(format_error_msg, "[H48] Error parsing H48 solver: must be in " | ||
| 10 | "'h48h*k*' format, but got '%s'\n", buf); | ||
| 11 | |||
| 12 | buf += 3; | ||
| 13 | |||
| 14 | if (*buf != 'h') { | ||
| 15 | LOG(format_error_msg); | ||
| 16 | goto parse_h48_hk_error; | ||
| 17 | } | ||
| 18 | buf++; | ||
| 19 | |||
| 20 | *h = atoi(buf); | ||
| 21 | if (*h > 11) { | ||
| 22 | LOG("[H48] Invalid value %" PRIu8 " for parameter h\n", *h); | ||
| 23 | goto parse_h48_hk_error; | ||
| 24 | } | ||
| 25 | |||
| 26 | for ( ; *buf >= 0 + '0' && *buf <= 9 + '0'; buf++) { | ||
| 27 | if (*buf == 0) { | ||
| 28 | LOG(format_error_msg); | ||
| 29 | goto parse_h48_hk_error; | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | if (*buf != 'k') { | ||
| 34 | LOG(format_error_msg); | ||
| 35 | goto parse_h48_hk_error; | ||
| 36 | } | ||
| 37 | buf++; | ||
| 38 | |||
| 39 | *k = atoi(buf); | ||
| 40 | if (!(*k == 2 || (*k == 4 && *h == 0))) { | ||
| 41 | LOG("[H48] Invalid combinations of values h=%" PRIu8 " and k=%" | ||
| 42 | PRIu8 " for parameters h and k\n", *h, *k); | ||
| 43 | goto parse_h48_hk_error; | ||
| 44 | } | ||
| 45 | |||
| 46 | return NISSY_OK; | ||
| 47 | |||
| 48 | parse_h48_hk_error: | ||
| 49 | *h = 0; | ||
| 50 | *k = 0; | ||
| 51 | return NISSY_ERROR_INVALID_SOLVER; | ||
| 52 | } | ||
| 53 | |||
| 54 | STATIC long long | ||
| 55 | dataid_h48(const char *hk, char buf[static NISSY_SIZE_DATAID]) | ||
| 56 | { | ||
| 57 | uint8_t h, k; | ||
| 58 | long long err; | ||
| 59 | |||
| 60 | err = parse_h48_hk(hk, &h, &k); | ||
| 61 | if (err < 0) | ||
| 62 | return err; | ||
| 63 | |||
| 64 | sprintf(buf, "h48h%" PRIu8 "k%" PRIu8, h, k); | ||
| 65 | return NISSY_OK; | ||
| 66 | } | ||
diff --git a/src/solvers/solvers.h b/src/solvers/solvers.h index 4d6bbca..27ae627 100644 --- a/src/solvers/solvers.h +++ b/src/solvers/solvers.h | |||
| @@ -2,5 +2,7 @@ | |||
| 2 | #include "solutions.h" | 2 | #include "solutions.h" |
| 3 | #include "tables_types_macros.h" | 3 | #include "tables_types_macros.h" |
| 4 | #include "tables.h" | 4 | #include "tables.h" |
| 5 | #include "distribution.h" | ||
| 5 | #include "h48/h48.h" | 6 | #include "h48/h48.h" |
| 6 | #include "coord/coord.h" | 7 | #include "coord/coord.h" |
| 8 | #include "dispatch.h" | ||
