aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-05-18 08:48:13 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-05-18 08:48:13 +0200
commit8b94d135429a9f3253cc7f25a1453b412065c4a0 (patch)
tree4a31d6def5421e95fb98505a2bc2653c18fca330
parent30b43f08955158d4f2066f4b50fe8d1241b3177b (diff)
downloadnissy-core-8b94d135429a9f3253cc7f25a1453b412065c4a0.tar.gz
nissy-core-8b94d135429a9f3253cc7f25a1453b412065c4a0.zip
Refactor solver dispatch and checkdata
Diffstat (limited to '')
-rw-r--r--src/nissy.c143
-rw-r--r--src/solvers/coord/gendata.h35
-rw-r--r--src/solvers/coord/solve.h35
-rw-r--r--src/solvers/coord/utils.h12
-rw-r--r--src/solvers/dispatch.h49
-rw-r--r--src/solvers/distribution.h77
-rw-r--r--src/solvers/h48/gendata_cocsep.h16
-rw-r--r--src/solvers/h48/gendata_h48.h86
-rw-r--r--src/solvers/h48/gendata_types_macros.h8
-rw-r--r--src/solvers/h48/h48.h1
-rw-r--r--src/solvers/h48/solve.h34
-rw-r--r--src/solvers/h48/utils.h66
-rw-r--r--src/solvers/solvers.h2
-rw-r--r--test/120_gendata_eo/gendata_eo_tests.c5
-rw-r--r--tools/000_gendata/gendata.c2
-rw-r--r--tools/expected_distributions.h2
-rw-r--r--tools/nissy_extra.h2
-rw-r--r--tools/tool.h2
18 files changed, 325 insertions, 252 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
15long long parse_h48_solver(
16 const char *, uint8_t [static 1], uint8_t [static 1]);
17STATIC bool checkdata(const unsigned char *, const tableinfo_t [static 1]); 15STATIC bool checkdata(const unsigned char *, const tableinfo_t [static 1]);
18STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN], 16STATIC 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);
20STATIC long long write_result(oriented_cube_t, char [static NISSY_SIZE_CUBE]); 18STATIC long long write_result(oriented_cube_t, char [static NISSY_SIZE_CUBE]);
21STATIC size_t my_strnlen(const char *, size_t);
22STATIC long long nissy_dataid(const char *, char [static NISSY_SIZE_DATAID]); 19STATIC long long nissy_dataid(const char *, char [static NISSY_SIZE_DATAID]);
23STATIC long long nissy_gendata_unsafe( 20STATIC 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
36long long
37parse_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
61parse_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
69STATIC bool 33STATIC bool
70checkdata(const unsigned char *buf, const tableinfo_t info[static 1]) 34checkdata(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
99STATIC bool 49STATIC 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
133STATIC size_t
134my_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
145long long 87long long
146nissy_inverse( 88nissy_inverse(
147 const char cube[static NISSY_SIZE_CUBE], 89 const char cube[static NISSY_SIZE_CUBE],
@@ -337,22 +279,15 @@ nissy_datainfo(
337STATIC long long 279STATIC long long
338nissy_dataid(const char *solver, char dataid[static NISSY_SIZE_DATAID]) 280nissy_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
358long long 293long 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
418long long 345long 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
531long long 450long 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 @@
1STATIC size_t gendata_coord(const coord_t [static 1], unsigned char *); 1STATIC size_t gendata_coord(const coord_t [static 1], unsigned char *);
2STATIC int64_t gendata_coord_dispatch(const char *, unsigned char *); 2STATIC long long gendata_coord_dispatch(const char *, unsigned long long,
3 unsigned char *);
3STATIC tableinfo_t genptable_coord( 4STATIC 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 *);
5STATIC bool switch_to_fromnew(uint64_t, uint64_t, uint64_t); 6STATIC 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 *);
8STATIC uint64_t genptable_coord_fillfromnew(const coord_t [static 1], 9STATIC 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 *);
10STATIC void getdistribution_coord(const unsigned char *, const char *,
11 uint64_t [static INFO_DISTRIBUTION_LEN]);
12STATIC uint8_t get_coord_pval( 11STATIC 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);
14STATIC void set_coord_pval( 13STATIC 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
17STATIC int64_t 16STATIC long long
18gendata_coord_dispatch(const char *coordstr, unsigned char *buf) 17gendata_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
252STATIC void
253getdistribution_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
274STATIC uint8_t 255STATIC uint8_t
275get_coord_pval( 256get_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
15STATIC int64_t solve_coord(oriented_cube_t, coord_t [static 1], uint8_t, 15STATIC 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 *);
18STATIC int64_t solve_coord_dispatch(oriented_cube_t, const char *, uint8_t, 18STATIC 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 *);
21STATIC bool coord_solution_admissible(const dfsarg_solve_coord_t [static 1]); 23STATIC bool coord_solution_admissible(const dfsarg_solve_coord_t [static 1]);
22STATIC bool solve_coord_dfs_stop(const dfsarg_solve_coord_t [static 1]); 24STATIC bool solve_coord_dfs_stop(const dfsarg_solve_coord_t [static 1]);
23STATIC bool coord_continue_onnormal(const dfsarg_solve_coord_t [static 1]); 25STATIC 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
201STATIC int64_t 203STATIC long long
202solve_coord_dispatch( 204solve_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]);
2STATIC uint8_t parse_axis(size_t n, const char [n]); 2STATIC uint8_t parse_axis(size_t n, const char [n]);
3STATIC void parse_coord_and_axis( 3STATIC 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 *);
5STATIC int64_t dataid_coord(const char *, char [static NISSY_SIZE_DATAID]); 5STATIC long long dataid_coord(const char *, char [static NISSY_SIZE_DATAID]);
6 6
7STATIC coord_t * 7STATIC coord_t *
8parse_coord(size_t n, const char coord[n]) 8parse_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
54STATIC int64_t 56STATIC long long
55dataid_coord(const char *ca, char dataid[static NISSY_SIZE_DATAID]) 57dataid_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 @@
1typedef 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
13STATIC solver_dispatch_t *match_solver(const char *);
14
15solver_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
33STATIC solver_dispatch_t *
34match_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
5typedef 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
13STATIC void *getdistribution_runthread(void *);
14STATIC void getdistribution(const unsigned char *,
15 uint64_t [static INFO_DISTRIBUTION_LEN], const tableinfo_t [static 1]);
16
17STATIC void *
18getdistribution_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
37STATIC void
38getdistribution(
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 @@
1STATIC size_t gendata_cocsep(unsigned char *, uint64_t *, cube_t *); 1STATIC size_t gendata_cocsep(unsigned char *, uint64_t *, cube_t *);
2STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t [static 1]); 2STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t [static 1]);
3STATIC void getdistribution_cocsep(
4 const uint32_t [static COCSEP_TABLESIZE], uint64_t [static 21]);
5 3
6STATIC_INLINE bool gendata_cocsep_get_visited( 4STATIC_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
139STATIC void
140getdistribution_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
153STATIC_INLINE bool 137STATIC_INLINE bool
154gendata_cocsep_get_visited( 138gendata_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 @@
1STATIC long long gendata_h48_dispatch(
2 const char *, unsigned long long, unsigned char *);
1STATIC uint64_t gendata_h48short(gendata_h48short_arg_t [static 1]); 3STATIC uint64_t gendata_h48short(gendata_h48short_arg_t [static 1]);
2STATIC int64_t gendata_h48(gendata_h48_arg_t [static 1]); 4STATIC int64_t gendata_h48(gendata_h48_arg_t [static 1]);
3STATIC void gendata_h48h0k4(gendata_h48_arg_t [static 1]); 5STATIC 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]);
13STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t [static 1]); 15STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t [static 1]);
14STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t [static 1]); 16STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t [static 1]);
15STATIC void *getdistribution_h48_runthread(void *);
16STATIC void getdistribution_h48(const unsigned char *,
17 uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t);
18 17
19STATIC const uint32_t *get_cocsepdata_constptr(const unsigned char *); 18STATIC const uint32_t *get_cocsepdata_constptr(const unsigned char *);
20STATIC const unsigned char *get_h48data_constptr(const unsigned char *); 19STATIC const unsigned char *get_h48data_constptr(const unsigned char *);
@@ -28,6 +27,27 @@ STATIC_INLINE void set_h48_pval_atomic(
28 27
29size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *); 28size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *);
30 29
30STATIC long long
31gendata_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
31STATIC uint64_t 51STATIC uint64_t
32gendata_h48short(gendata_h48short_arg_t arg[static 1]) 52gendata_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
652STATIC void *
653getdistribution_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
672STATIC void
673getdistribution_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
710STATIC const uint32_t * 672STATIC const uint32_t *
711get_cocsepdata_constptr(const unsigned char *data) 673get_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
125typedef 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
53STATIC 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 *);
53STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]); 57STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]);
54STATIC int64_t solve_h48_maketasks( 58STATIC 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
68STATIC 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
64STATIC_INLINE bool 98STATIC_INLINE bool
65solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) 99solve_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 @@
1long long parse_h48_hk(
2 const char *, uint8_t [static 1], uint8_t [static 1]);
3STATIC long long dataid_h48(const char *, char [static NISSY_SIZE_DATAID]);
4
5long long
6parse_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
48parse_h48_hk_error:
49 *h = 0;
50 *k = 0;
51 return NISSY_ERROR_INVALID_SOLVER;
52}
53
54STATIC long long
55dataid_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"
diff --git a/test/120_gendata_eo/gendata_eo_tests.c b/test/120_gendata_eo/gendata_eo_tests.c
index ec1fd64..1b985c3 100644
--- a/test/120_gendata_eo/gendata_eo_tests.c
+++ b/test/120_gendata_eo/gendata_eo_tests.c
@@ -17,7 +17,8 @@ Pruning table values (from nissy):
17 17
18unsigned char buf[FULLSIZE]; 18unsigned char buf[FULLSIZE];
19 19
20int64_t gendata_coord_dispatch(const char *, unsigned char *); 20long long gendata_coord_dispatch(
21 const char *, unsigned long long, unsigned char *);
21int64_t readtableinfo(size_t, const unsigned char *, tableinfo_t *); 22int64_t readtableinfo(size_t, const unsigned char *, tableinfo_t *);
22 23
23void run(void) { 24void run(void) {
@@ -25,7 +26,7 @@ void run(void) {
25 size_t result; 26 size_t result;
26 tableinfo_t info; 27 tableinfo_t info;
27 28
28 result = gendata_coord_dispatch("EO", buf); 29 result = gendata_coord_dispatch("coord_EO_FB", FULLSIZE, buf);
29 if (readtableinfo(FULLSIZE, buf, &info) != NISSY_OK) { 30 if (readtableinfo(FULLSIZE, buf, &info) != NISSY_OK) {
30 printf("Error reading info from table\n"); 31 printf("Error reading info from table\n");
31 return; 32 return;
diff --git a/tools/000_gendata/gendata.c b/tools/000_gendata/gendata.c
index cd7fb0f..66c4864 100644
--- a/tools/000_gendata/gendata.c
+++ b/tools/000_gendata/gendata.c
@@ -49,7 +49,7 @@ int main(int argc, char **argv) {
49 } 49 }
50 50
51 solver = argv[1]; 51 solver = argv[1];
52 parse_h48_solver(solver, &h, &k); 52 parse_h48_hk(solver, &h, &k);
53 expected = expected_h48[h][k]; 53 expected = expected_h48[h][k];
54 54
55 nissy_setlogger(log_stderr, NULL); 55 nissy_setlogger(log_stderr, NULL);
diff --git a/tools/expected_distributions.h b/tools/expected_distributions.h
index 12faf1d..1193fb3 100644
--- a/tools/expected_distributions.h
+++ b/tools/expected_distributions.h
@@ -160,7 +160,7 @@ uint64_t expected_dreo[21] = {
160 [4] = 160, 160 [4] = 160,
161 [5] = 1286, 161 [5] = 1286,
162 [6] = 8550, 162 [6] = 8550,
163 [7] = 42512, 163 [7] = 42152,
164 [8] = 90748, 164 [8] = 90748,
165 [9] = 33466, 165 [9] = 33466,
166 [10] = 757, 166 [10] = 757,
diff --git a/tools/nissy_extra.h b/tools/nissy_extra.h
index 8b27c3e..9a7df50 100644
--- a/tools/nissy_extra.h
+++ b/tools/nissy_extra.h
@@ -10,5 +10,5 @@ for testing purposes only.
10#include "../src/solvers/tables.h" 10#include "../src/solvers/tables.h"
11 11
12size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *); 12size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *);
13long long parse_h48_solver(const char *, uint8_t [static 1], uint8_t [static 1]); 13long long parse_h48_hk(const char *, uint8_t [static 1], uint8_t [static 1]);
14long long int nissy_datainfo(uint64_t, const unsigned char *); 14long long int nissy_datainfo(uint64_t, const unsigned char *);
diff --git a/tools/tool.h b/tools/tool.h
index 77cdf34..225f789 100644
--- a/tools/tool.h
+++ b/tools/tool.h
@@ -126,7 +126,7 @@ derivetable(
126 goto derivetable_error; 126 goto derivetable_error;
127 } 127 }
128 128
129 if (parse_h48_solver(solver_small, &h, &k) != 0) { 129 if (parse_h48_hk(solver_small, &h, &k) != NISSY_OK) {
130 gensize = -3; 130 gensize = -3;
131 goto derivetable_error; 131 goto derivetable_error;
132 } 132 }

Generated with cgit - Back to sebastiano.tronto.net