aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpp/nissy.cpp5
-rw-r--r--python/nissy_module.c8
-rw-r--r--src/nissy.c120
-rw-r--r--src/nissy.h2
-rw-r--r--src/solvers/coord/checkdata.h65
-rw-r--r--src/solvers/coord/coord.h1
-rw-r--r--src/solvers/coord/dr.h16
-rw-r--r--src/solvers/coord/dreo.h14
-rw-r--r--src/solvers/coord/eo.h11
-rw-r--r--src/solvers/coord/gendata.h2
-rw-r--r--src/solvers/coord/solve.h3
-rw-r--r--src/solvers/coord/types_macros.h2
-rw-r--r--src/solvers/coord/utils.h28
-rw-r--r--src/solvers/dispatch.h6
-rw-r--r--src/solvers/distribution.h27
-rw-r--r--src/solvers/h48/checkdata.h234
-rw-r--r--src/solvers/h48/gendata_eoesep.h4
-rw-r--r--src/solvers/h48/gendata_h48.h90
-rw-r--r--src/solvers/h48/h48.h1
-rw-r--r--tools/000_gendata/gendata.c21
-rw-r--r--tools/001_derive_h48/derive_h48.c40
-rw-r--r--tools/100_checkdata/checkdata.c10
-rw-r--r--tools/expected_distributions.h267
-rw-r--r--tools/nissy_extra.h14
-rw-r--r--tools/tool.h86
25 files changed, 418 insertions, 659 deletions
diff --git a/cpp/nissy.cpp b/cpp/nissy.cpp
index 25039bb..ed0dc0f 100644
--- a/cpp/nissy.cpp
+++ b/cpp/nissy.cpp
@@ -17,7 +17,8 @@ extern "C" {
17 long long nissy_solverinfo(const char *, char *); 17 long long nissy_solverinfo(const char *, char *);
18 long long nissy_gendata(const char *, unsigned long long, 18 long long nissy_gendata(const char *, unsigned long long,
19 unsigned char *); 19 unsigned char *);
20 long long nissy_checkdata(unsigned long long, const unsigned char *); 20 long long nissy_checkdata(const char *, unsigned long long,
21 const unsigned char *);
21 long long nissy_solve(const char *, const char *, unsigned, unsigned, 22 long long nissy_solve(const char *, const char *, unsigned, unsigned,
22 unsigned, unsigned, unsigned, unsigned, unsigned long long, 23 unsigned, unsigned, unsigned, unsigned, unsigned long long,
23 const unsigned char *, unsigned, char *, long long *, 24 const unsigned char *, unsigned, char *, long long *,
@@ -144,7 +145,7 @@ namespace nissy {
144 145
145 error solver::check_data() 146 error solver::check_data()
146 { 147 {
147 auto err_value = nissy_checkdata(data.size(), 148 auto err_value = nissy_checkdata(name.c_str(), data.size(),
148 reinterpret_cast<const unsigned char *>(data.data())); 149 reinterpret_cast<const unsigned char *>(data.data()));
149 error err{err_value}; 150 error err{err_value};
150 data_checked = err.ok(); 151 data_checked = err.ok();
diff --git a/python/nissy_module.c b/python/nissy_module.c
index 5f5c0c4..3e5ea08 100644
--- a/python/nissy_module.c
+++ b/python/nissy_module.c
@@ -239,21 +239,23 @@ PyDoc_STRVAR(checkdata_doc,
239"Checks if the data (pruning table) given is valid or not\n" 239"Checks if the data (pruning table) given is valid or not\n"
240"\n" 240"\n"
241"Parameters:\n" 241"Parameters:\n"
242" - data: a bytearray containing the data for a solver" 242" - solver: the name of the solver\n"
243" - data: a bytearray containing the data for a solver\n"
243"\n" 244"\n"
244"Returns: true if the data is valid, false otherwise\n" 245"Returns: true if the data is valid, false otherwise\n"
245); 246);
246PyObject * 247PyObject *
247checkdata(PyObject *self, PyObject *args) 248checkdata(PyObject *self, PyObject *args)
248{ 249{
250 const char *solver;
249 long long result; 251 long long result;
250 PyByteArrayObject *data; 252 PyByteArrayObject *data;
251 253
252 if (!PyArg_ParseTuple(args, "Y", &data)) 254 if (!PyArg_ParseTuple(args, "sY", &solver, &data))
253 return NULL; 255 return NULL;
254 256
255 result = nissy_checkdata( 257 result = nissy_checkdata(
256 data->ob_alloc, (unsigned char *)data->ob_bytes); 258 solver, data->ob_alloc, (unsigned char *)data->ob_bytes);
257 259
258 if (check_error(result)) 260 if (check_error(result))
259 return Py_True; 261 return Py_True;
diff --git a/src/nissy.c b/src/nissy.c
index 1f929c0..aaa5c2a 100644
--- a/src/nissy.c
+++ b/src/nissy.c
@@ -12,9 +12,6 @@
12#include "core/core.h" 12#include "core/core.h"
13#include "solvers/solvers.h" 13#include "solvers/solvers.h"
14 14
15STATIC bool checkdata(const unsigned char *, const tableinfo_t [static 1]);
16STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN],
17 const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t);
18STATIC long long write_result(oriented_cube_t, char [static NISSY_SIZE_CUBE]); 15STATIC long long write_result(oriented_cube_t, char [static NISSY_SIZE_CUBE]);
19STATIC long long nissy_dataid(const char *, char [static NISSY_SIZE_DATAID]); 16STATIC long long nissy_dataid(const char *, char [static NISSY_SIZE_DATAID]);
20STATIC long long nissy_gendata_unsafe( 17STATIC long long nissy_gendata_unsafe(
@@ -30,47 +27,6 @@ struct {
30 GETCUBE_OPTIONS(NULL, NULL) 27 GETCUBE_OPTIONS(NULL, NULL)
31}; 28};
32 29
33STATIC bool
34checkdata(const unsigned char *buf, const tableinfo_t info[static 1])
35{
36 uint64_t distr[INFO_DISTRIBUTION_LEN];
37
38 if (info->type == TABLETYPE_PRUNING) {
39 getdistribution(buf + INFOSIZE, distr, info);
40 LOG("\n[checkdata] Checking distribution for %s\n", info->solver);
41 return distribution_equal(info->distribution, distr, info->maxvalue);
42 } else {
43 LOG("\n[checkdata] Skipping distribution check for "
44 "special table %s\n", info->solver);
45 return true;
46 }
47}
48
49STATIC bool
50distribution_equal(
51 const uint64_t expected[static INFO_DISTRIBUTION_LEN],
52 const uint64_t actual[static INFO_DISTRIBUTION_LEN],
53 uint8_t maxvalue
54)
55{
56 int wrong;
57 uint8_t i;
58
59 for (i = 0, wrong = 0; i <= MIN(maxvalue, 20); i++) {
60 if (expected[i] != actual[i]) {
61 wrong++;
62 LOG("[checkdata] Value for depth %" PRIu8
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]);
68 }
69 }
70
71 return wrong == 0;
72}
73
74STATIC long long 30STATIC long long
75write_result(oriented_cube_t cube, char result[static NISSY_SIZE_CUBE]) 31write_result(oriented_cube_t cube, char result[static NISSY_SIZE_CUBE])
76{ 32{
@@ -227,55 +183,6 @@ nissy_getcube(
227 return write_result(oc, result); 183 return write_result(oc, result);
228} 184}
229 185
230long long
231nissy_datainfo(
232 uint64_t data_size,
233 const unsigned char data[data_size]
234)
235{
236 uint8_t i;
237 tableinfo_t info;
238 long long ret;
239
240 if ((size_t)data % 8 != 0) {
241 LOG("[datainfo] Error: buffer is not 8-byte aligned\n");
242 return NISSY_ERROR_DATA;
243 }
244
245 ret = readtableinfo(data_size, data, &info);
246 if (ret != 0)
247 return ret;
248
249 LOG("\n---------\n\n"
250 "Table information for '%s'\n\n"
251 "Size: %" PRIu64 " bytes\n"
252 "Entries: %" PRIu64 " (%" PRIu8 " bits per entry)\n",
253 info.solver, info.fullsize, info.entries, info.bits);
254
255 switch (info.type) {
256 case TABLETYPE_PRUNING:
257 LOG("\nTable distribution:\nValue\tPositions\n");
258 for (i = 0; i <= info.maxvalue; i++) {
259 LOG("%" PRIu8 "\t%" PRIu64 "\n",
260 i + info.base, info.distribution[i]);
261 }
262 break;
263 case TABLETYPE_SPECIAL:
264 LOG("This is an ad-hoc table\n");
265 break;
266 default:
267 LOG("datainfo: unknown table type\n");
268 return NISSY_ERROR_DATA;
269 }
270
271 if (info.next != 0)
272 return nissy_datainfo(data_size - info.next, data + info.next);
273
274 LOG("\n---------\n");
275
276 return NISSY_OK;
277}
278
279STATIC long long 186STATIC long long
280nissy_dataid(const char *solver, char dataid[static NISSY_SIZE_DATAID]) 187nissy_dataid(const char *solver, char dataid[static NISSY_SIZE_DATAID])
281{ 188{
@@ -344,33 +251,20 @@ nissy_gendata_unsafe(
344 251
345long long 252long long
346nissy_checkdata( 253nissy_checkdata(
254 const char *solver,
347 unsigned long long data_size, 255 unsigned long long data_size,
348 const unsigned char data[data_size] 256 const unsigned char data[data_size]
349) 257)
350{ 258{
351 tableinfo_t info; 259 solver_dispatch_t *dispatch;
352 int64_t err;
353
354 if ((size_t)data % 8 != 0) {
355 LOG("[checkdata] Error: buffer is not 8-byte aligned\n");
356 return NISSY_ERROR_DATA;
357 }
358
359 for (const unsigned char *buf = data;
360 (err = readtableinfo(data_size, buf, &info)) == NISSY_OK;
361 buf += info.next, data_size -= info.next)
362 {
363 if (!checkdata(buf, &info)) {
364 LOG("[checkdata] Error: data for solver '%s' is "
365 "corrupted!\n", info.solver);
366 return NISSY_ERROR_DATA;
367 }
368 260
369 if (info.next == 0) 261 dispatch = match_solver(solver);
370 break; 262 if (dispatch == NULL) {
263 LOG("[checkdata] Unknown solver %s\n", solver);
264 return NISSY_ERROR_INVALID_SOLVER;
371 } 265 }
372 266
373 return err; 267 return dispatch->checkdata(solver, data_size, data);
374} 268}
375 269
376long long 270long long
diff --git a/src/nissy.h b/src/nissy.h
index 2fa4a75..0447d66 100644
--- a/src/nissy.h
+++ b/src/nissy.h
@@ -283,6 +283,7 @@ nissy_gendata(
283Check that the data is a valid data table for a solver. 283Check that the data is a valid data table for a solver.
284 284
285Parameters: 285Parameters:
286 solver - The name of the solver.
286 data_size - The size of the data buffer. 287 data_size - The size of the data buffer.
287 data - The data for the solver. Can be computed with gendata. 288 data - The data for the solver. Can be computed with gendata.
288 This buffer must have 8-byte alignment. 289 This buffer must have 8-byte alignment.
@@ -293,6 +294,7 @@ Return values:
293*/ 294*/
294long long 295long long
295nissy_checkdata( 296nissy_checkdata(
297 const char *solver,
296 unsigned long long data_size, 298 unsigned long long data_size,
297 const unsigned char data[data_size] 299 const unsigned char data[data_size]
298); 300);
diff --git a/src/solvers/coord/checkdata.h b/src/solvers/coord/checkdata.h
new file mode 100644
index 0000000..81394c7
--- /dev/null
+++ b/src/solvers/coord/checkdata.h
@@ -0,0 +1,65 @@
1STATIC long long checkdata_coord(
2 const char *, unsigned long long n, const unsigned char [n]);
3
4STATIC long long
5checkdata_coord(
6 const char *solver,
7 unsigned long long data_size,
8 const unsigned char data[data_size]
9)
10{
11 coord_t *coord;
12 const unsigned char *table;
13 tableinfo_t info;
14 int64_t err;
15 uint64_t actual_distribution[INFO_DISTRIBUTION_LEN];
16
17 if ((size_t)data % 8 != 0) {
18 LOG("[checkdata] Error: buffer is not 8-byte aligned\n");
19 return NISSY_ERROR_DATA;
20 }
21
22 parse_coord_and_axis(solver, &coord, NULL);
23 if (coord == NULL) {
24 LOG("[cehckdata] Unknown coordinate solver '%s'\n", solver);
25 return NISSY_ERROR_DATA;
26 }
27
28 table = data + INFOSIZE;
29 err = readtableinfo(data_size, data, &info);
30 if (err != NISSY_OK) {
31 LOG("[checkdata] Data is corrupt\n");
32 return err;
33 }
34
35 if (info.type != TABLETYPE_PRUNING) {
36 LOG("[checkdata] Skipping '%s'\n", info.solver);
37 table += info.next;
38 err = readtableinfo_n(data_size, data, 2, &info);
39 if (err != NISSY_OK) {
40 LOG("[checkdata] Data is corrupt\n");
41 return err;
42 }
43 }
44
45 LOG("[checkdata] Checking distribution for '%s' from "
46 "table preamble\n", info.solver);
47 if (!distribution_equal(coord->pruning_distribution,
48 info.distribution, coord->pruning_max)) {
49 LOG("[checkdata] Distribution from the table preamble does "
50 "not match the expected one\n");
51 return NISSY_ERROR_DATA;
52 }
53
54 LOG("\n[checkdata] Checking distribution for '%s' from "
55 "actual table\n", info.solver);
56 getdistribution(table, actual_distribution, &info);
57 if (!distribution_equal(coord->pruning_distribution,
58 actual_distribution, coord->pruning_max)) {
59 LOG("[checkdata] Distribution from the actual table does "
60 "not match the expected one\n");
61 return NISSY_ERROR_DATA;
62 }
63
64 return NISSY_OK;
65}
diff --git a/src/solvers/coord/coord.h b/src/solvers/coord/coord.h
index 2f24035..da93439 100644
--- a/src/solvers/coord/coord.h
+++ b/src/solvers/coord/coord.h
@@ -6,4 +6,5 @@
6#include "list.h" 6#include "list.h"
7#include "utils.h" 7#include "utils.h"
8#include "gendata.h" 8#include "gendata.h"
9#include "checkdata.h"
9#include "solve.h" 10#include "solve.h"
diff --git a/src/solvers/coord/dr.h b/src/solvers/coord/dr.h
index 607cc39..d986742 100644
--- a/src/solvers/coord/dr.h
+++ b/src/solvers/coord/dr.h
@@ -32,6 +32,22 @@ STATIC coord_t coordinate_dr = {
32 }, 32 },
33 .is_admissible = &solution_lastqt_cw, 33 .is_admissible = &solution_lastqt_cw,
34 .is_solvable = &is_eoco_solvable, 34 .is_solvable = &is_eoco_solvable,
35 .pruning_distribution = {
36 [0] = 1,
37 [1] = 1,
38 [2] = 5,
39 [3] = 44,
40 [4] = 487,
41 [5] = 5841,
42 [6] = 68364,
43 [7] = 776568,
44 [8] = 7950748,
45 [9] = 52098876,
46 [10] = 76236234,
47 [11] = 3771112,
48 [12] = 129,
49 },
50 .pruning_max = 12,
35 .sym = { 51 .sym = {
36 .classes = DREOESEP_CLASSES, 52 .classes = DREOESEP_CLASSES,
37 .max = DREOESEP_MAX, 53 .max = DREOESEP_MAX,
diff --git a/src/solvers/coord/dreo.h b/src/solvers/coord/dreo.h
index 1cce4e2..f6fa3e9 100644
--- a/src/solvers/coord/dreo.h
+++ b/src/solvers/coord/dreo.h
@@ -27,6 +27,20 @@ STATIC coord_t coordinate_dreo = {
27 }, 27 },
28 .is_admissible = &solution_lastqt_cw, 28 .is_admissible = &solution_lastqt_cw,
29 .is_solvable = &is_dreo_solvable, 29 .is_solvable = &is_dreo_solvable,
30 .pruning_distribution = {
31 [0] = 1,
32 [1] = 1,
33 [2] = 4,
34 [3] = 22,
35 [4] = 160,
36 [5] = 1286,
37 [6] = 8550,
38 [7] = 42152,
39 [8] = 90748,
40 [9] = 33466,
41 [10] = 757,
42 },
43 .pruning_max = 10,
30 .sym = { 44 .sym = {
31 .classes = DRESEP_CLASSES, 45 .classes = DRESEP_CLASSES,
32 .max = COMB_12_4, 46 .max = COMB_12_4,
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
index 51dfb29..7735319 100644
--- a/src/solvers/coord/eo.h
+++ b/src/solvers/coord/eo.h
@@ -20,6 +20,17 @@ STATIC coord_t coordinate_eo = {
20 }, 20 },
21 .is_admissible = &solution_lastqt_cw, 21 .is_admissible = &solution_lastqt_cw,
22 .is_solvable = &is_eo_even, 22 .is_solvable = &is_eo_even,
23 .pruning_distribution = {
24 [0] = 1,
25 [1] = 2,
26 [2] = 25,
27 [3] = 202,
28 [4] = 620,
29 [5] = 900,
30 [6] = 285,
31 [7] = 13,
32 },
33 .pruning_max = 7,
23 .sym = {0}, 34 .sym = {0},
24}; 35};
25 36
diff --git a/src/solvers/coord/gendata.h b/src/solvers/coord/gendata.h
index 1b65f49..0cc012e 100644
--- a/src/solvers/coord/gendata.h
+++ b/src/solvers/coord/gendata.h
@@ -22,7 +22,7 @@ gendata_coord_dispatch(
22{ 22{
23 coord_t *coord; 23 coord_t *coord;
24 24
25 parse_coord_and_axis(strlen(coordstr), coordstr, &coord, NULL); 25 parse_coord_and_axis(coordstr, &coord, NULL);
26 26
27 if (coord == NULL) { 27 if (coord == NULL) {
28 LOG("Error: could not parse coordinate '%s'\n", coordstr); 28 LOG("Error: could not parse coordinate '%s'\n", coordstr);
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h
index df0f6ff..659040c 100644
--- a/src/solvers/coord/solve.h
+++ b/src/solvers/coord/solve.h
@@ -222,8 +222,7 @@ solve_coord_dispatch(
222 coord_t *coord; 222 coord_t *coord;
223 uint8_t axis; 223 uint8_t axis;
224 224
225 parse_coord_and_axis( 225 parse_coord_and_axis(coord_and_axis, &coord, &axis);
226 strlen(coord_and_axis), coord_and_axis, &coord, &axis);
227 226
228 if (coord == NULL) { 227 if (coord == NULL) {
229 LOG("Error: could not parse coordinate from '%s'\n", 228 LOG("Error: could not parse coordinate from '%s'\n",
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
index a5ac7f3..0c7a3a2 100644
--- a/src/solvers/coord/types_macros.h
+++ b/src/solvers/coord/types_macros.h
@@ -26,6 +26,8 @@ typedef struct {
26 uint8_t axistrans[3]; 26 uint8_t axistrans[3];
27 bool (*is_admissible)(const solution_moves_t[static 1]); 27 bool (*is_admissible)(const solution_moves_t[static 1]);
28 bool (*is_solvable)(cube_t); 28 bool (*is_solvable)(cube_t);
29 uint64_t pruning_distribution[INFO_DISTRIBUTION_LEN];
30 uint8_t pruning_max;
29 struct { 31 struct {
30 size_t classes; 32 size_t classes;
31 uint64_t max; 33 uint64_t max;
diff --git a/src/solvers/coord/utils.h b/src/solvers/coord/utils.h
index aa4d74c..6066049 100644
--- a/src/solvers/coord/utils.h
+++ b/src/solvers/coord/utils.h
@@ -1,7 +1,6 @@
1STATIC coord_t *parse_coord(size_t n, const char [n]); 1STATIC 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(const char [static 2]);
3STATIC void parse_coord_and_axis( 3STATIC void parse_coord_and_axis(const char *, coord_t **, uint8_t *);
4 size_t n, const char [n], coord_t **, uint8_t *);
5STATIC long long dataid_coord(const char *, char [static NISSY_SIZE_DATAID]); 4STATIC long long dataid_coord(const char *, char [static NISSY_SIZE_DATAID]);
6 5
7STATIC coord_t * 6STATIC coord_t *
@@ -17,13 +16,13 @@ parse_coord(size_t n, const char coord[n])
17} 16}
18 17
19STATIC uint8_t 18STATIC uint8_t
20parse_axis(size_t n, const char axis[n]) 19parse_axis(const char axis[static 2])
21{ 20{
22 if (!strncmp(axis, "UD", n) || !strncmp(axis, "DU", n)) { 21 if (!strcmp(axis, "UD") || !strcmp(axis, "DU")) {
23 return AXIS_UD; 22 return AXIS_UD;
24 } else if (!strncmp(axis, "RL", n) || !strncmp(axis, "LR", n)) { 23 } else if (!strcmp(axis, "RL") || !strcmp(axis, "LR")) {
25 return AXIS_RL; 24 return AXIS_RL;
26 } else if (!strncmp(axis, "FB", n) || !strncmp(axis, "BF", n)) { 25 } else if (!strcmp(axis, "FB") || !strcmp(axis, "BF")) {
27 return AXIS_FB; 26 return AXIS_FB;
28 } 27 }
29 28
@@ -32,25 +31,22 @@ parse_axis(size_t n, const char axis[n])
32 31
33STATIC void 32STATIC void
34parse_coord_and_axis( 33parse_coord_and_axis(
35 size_t n, 34 const char *str,
36 const char str[n],
37 coord_t **coord, 35 coord_t **coord,
38 uint8_t *axis 36 uint8_t *axis
39) 37)
40{ 38{
41 const char *s;
42 size_t i; 39 size_t i;
43 40
44 s = str + 6; 41 for (i = 6; i < strlen(str); i++)
45 for (i = 0; i < n; i++) 42 if (str[i] == '_')
46 if (s[i] == '_')
47 break; 43 break;
48 44
49 if (coord != NULL) 45 if (coord != NULL)
50 *coord = parse_coord(i, s); 46 *coord = parse_coord(i-6, str+6);
51 47
52 if (axis != NULL) 48 if (axis != NULL)
53 *axis = i == n ? UINT8_ERROR : parse_axis(n-i-1, s+i+1); 49 *axis = i == strlen(str) ? UINT8_ERROR : parse_axis(str+i+1);
54} 50}
55 51
56STATIC long long 52STATIC long long
@@ -58,7 +54,7 @@ dataid_coord(const char *ca, char dataid[static NISSY_SIZE_DATAID])
58{ 54{
59 coord_t *c; 55 coord_t *c;
60 56
61 parse_coord_and_axis(strlen(ca), ca, &c, NULL); 57 parse_coord_and_axis(ca, &c, NULL);
62 58
63 if (c == NULL) { 59 if (c == NULL) {
64 LOG("Error: cannot parse coordinate from '%s'\n", ca); 60 LOG("Error: cannot parse coordinate from '%s'\n", ca);
diff --git a/src/solvers/dispatch.h b/src/solvers/dispatch.h
index 0cfbc3b..7cf4441 100644
--- a/src/solvers/dispatch.h
+++ b/src/solvers/dispatch.h
@@ -2,7 +2,9 @@ typedef struct {
2 const char *prefix; 2 const char *prefix;
3 long long (*dataid)(const char *, char [static NISSY_SIZE_DATAID]); 3 long long (*dataid)(const char *, char [static NISSY_SIZE_DATAID]);
4 long long (*gendata)( 4 long long (*gendata)(
5 const char *, unsigned long long, unsigned char *); 5 const char *, unsigned long long n, unsigned char [n]);
6 long long (*checkdata)(
7 const char *, unsigned long long, const unsigned char *);
6 long long (*solve)(oriented_cube_t, const char *, unsigned, unsigned, 8 long long (*solve)(oriented_cube_t, const char *, unsigned, unsigned,
7 unsigned, unsigned, unsigned, unsigned, unsigned long long, 9 unsigned, unsigned, unsigned, unsigned, unsigned long long,
8 const unsigned char *, unsigned, char *, 10 const unsigned char *, unsigned, char *,
@@ -17,12 +19,14 @@ solver_dispatch_t solver_dispatchers[] = {
17 .prefix = "h48", 19 .prefix = "h48",
18 .dataid = dataid_h48, 20 .dataid = dataid_h48,
19 .gendata = gendata_h48_dispatch, 21 .gendata = gendata_h48_dispatch,
22 .checkdata = checkdata_h48,
20 .solve = solve_h48_dispatch, 23 .solve = solve_h48_dispatch,
21}, 24},
22{ 25{
23 .prefix = "coord_", 26 .prefix = "coord_",
24 .dataid = dataid_coord, 27 .dataid = dataid_coord,
25 .gendata = gendata_coord_dispatch, 28 .gendata = gendata_coord_dispatch,
29 .checkdata = checkdata_coord,
26 .solve = solve_coord_dispatch, 30 .solve = solve_coord_dispatch,
27}, 31},
28{ 32{
diff --git a/src/solvers/distribution.h b/src/solvers/distribution.h
index 1a3719c..3c006a7 100644
--- a/src/solvers/distribution.h
+++ b/src/solvers/distribution.h
@@ -13,6 +13,8 @@ typedef struct {
13STATIC void *getdistribution_runthread(void *); 13STATIC void *getdistribution_runthread(void *);
14STATIC void getdistribution(const unsigned char *, 14STATIC void getdistribution(const unsigned char *,
15 uint64_t [static INFO_DISTRIBUTION_LEN], const tableinfo_t [static 1]); 15 uint64_t [static INFO_DISTRIBUTION_LEN], const tableinfo_t [static 1]);
16STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN],
17 const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t);
16 18
17STATIC void * 19STATIC void *
18getdistribution_runthread(void *arg) 20getdistribution_runthread(void *arg)
@@ -75,3 +77,28 @@ getdistribution(
75 distr[pval]++; 77 distr[pval]++;
76 } 78 }
77} 79}
80
81STATIC bool
82distribution_equal(
83 const uint64_t expected[static INFO_DISTRIBUTION_LEN],
84 const uint64_t actual[static INFO_DISTRIBUTION_LEN],
85 uint8_t maxvalue
86)
87{
88 int wrong;
89 uint8_t i;
90
91 for (i = 0, wrong = 0; i <= MIN(maxvalue, 20); i++) {
92 if (expected[i] != actual[i]) {
93 wrong++;
94 LOG("[checkdata] Value for depth %" PRIu8
95 ": expected %" PRIu64 ", found %" PRIu64 "\n",
96 i, expected[i], actual[i]);
97 } else {
98 LOG("[checkdata] Value for depth %" PRIu8
99 " is correct (%" PRIu64 ")\n", i, actual[i]);
100 }
101 }
102
103 return wrong == 0;
104}
diff --git a/src/solvers/h48/checkdata.h b/src/solvers/h48/checkdata.h
new file mode 100644
index 0000000..53e616b
--- /dev/null
+++ b/src/solvers/h48/checkdata.h
@@ -0,0 +1,234 @@
1STATIC long long checkdata_h48(
2 const char *, unsigned long long n, const unsigned char [n]);
3
4/*
5Currently unused.
6TODO: re-introduce check on cocsep table
7*/
8uint64_t expected_cocsep[21] = {
9 [0] = 1,
10 [1] = 6,
11 [2] = 63,
12 [3] = 468,
13 [4] = 3068,
14 [5] = 15438,
15 [6] = 53814,
16 [7] = 71352,
17 [8] = 8784,
18 [9] = 96
19};
20
21struct {
22 uint8_t max;
23 uint64_t table[21];
24} expected_h48[12][9] = {
25 [0] = {
26 [2] = {
27 .max = 3,
28 .table = {
29 [0] = 5473562,
30 [1] = 34776317,
31 [2] = 68566704,
32 [3] = 8750867,
33 },
34 },
35 [4] = {
36 .max = 12,
37 .table = {
38 [0] = 1,
39 [1] = 1,
40 [2] = 4,
41 [3] = 34,
42 [4] = 331,
43 [5] = 3612,
44 [6] = 41605,
45 [7] = 474128,
46 [8] = 4953846,
47 [9] = 34776317,
48 [10] = 68566704,
49 [11] = 8749194,
50 [12] = 1673,
51 },
52 },
53 },
54 [1] = {
55 [2] = {
56 .max = 3,
57 .table = {
58 [0] = 6012079,
59 [1] = 45822302,
60 [2] = 142018732,
61 [3] = 41281787,
62 },
63 },
64 },
65 [2] = {
66 [2] = {
67 .max = 3,
68 .table = {
69 [0] = 6391286,
70 [1] = 55494785,
71 [2] = 252389935,
72 [3] = 155993794,
73 },
74 },
75 },
76 [3] = {
77 [2] = {
78 .max = 3,
79 .table = {
80 [0] = 6686828,
81 [1] = 63867852,
82 [2] = 392789689,
83 [3] = 477195231,
84 },
85 },
86 },
87 [4] = {
88 [2] = {
89 .max = 3,
90 .table = {
91 [0] = 77147213,
92 [1] = 543379415,
93 [2] = 1139570251,
94 [3] = 120982321,
95 },
96 },
97 },
98 [5] = {
99 [2] = {
100 .max = 3,
101 .table = {
102 [0] = 82471284,
103 [1] = 687850732,
104 [2] = 2345840746,
105 [3] = 645995638,
106 },
107 },
108 },
109 [6] = {
110 [2] = {
111 .max = 3,
112 .table = {
113 [0] = 85941099,
114 [1] = 804752968,
115 [2] = 4077248182,
116 [3] = 2556374551,
117 },
118 },
119 },
120 [7] = {
121 [2] = {
122 .max = 3,
123 .table = {
124 [0] = 88529761,
125 [1] = 897323475,
126 [2] = 6126260791,
127 [3] = 7936519573,
128 },
129 },
130 },
131 [8] = {
132 [2] = {
133 .max = 3,
134 .table = {
135 [0] = 1051579940,
136 [1] = 8136021316,
137 [2] = 19024479822,
138 [3] = 18851861220,
139 },
140 },
141 },
142 [9] = {
143 [2] = {
144 .max = 3,
145 .table = {
146 [0] = 1102038189,
147 [1] = 9888265242,
148 [2] = 38299375805,
149 [3] = 10904855164,
150 },
151 },
152 },
153 [10] = {
154 [2] = {
155 .max = 3,
156 .table = {
157 [0] = 1133240039,
158 [1] = 11196285614,
159 [2] = 64164702961,
160 [3] = 43894840186,
161 },
162 },
163 },
164 [11] = {
165 [2] = {
166 .max = 3,
167 .table = {
168 [0] = 1150763161,
169 [1] = 12045845660,
170 [2] = 91163433330,
171 [3] = 136418095449,
172 },
173 },
174 },
175};
176
177STATIC long long
178checkdata_h48(
179 const char *solver,
180 unsigned long long data_size,
181 const unsigned char data[data_size]
182)
183{
184 const unsigned char *table;
185 tableinfo_t info;
186 int64_t err;
187 uint64_t actual_distribution[INFO_DISTRIBUTION_LEN];
188 uint8_t em;
189 uint64_t *ed;
190
191 if ((size_t)data % 8 != 0) {
192 LOG("[checkdata] Error: buffer is not 8-byte aligned\n");
193 return NISSY_ERROR_DATA;
194 }
195
196 do {
197 err = readtableinfo(data_size, data, &info);
198 if (err != NISSY_OK) {
199 LOG("[checkdata] Data is corrupt\n");
200 return NISSY_ERROR_DATA;
201 }
202
203 table = data + INFOSIZE;
204 data += info.next;
205 data_size -= info.next;
206
207 if (info.type != TABLETYPE_PRUNING) {
208 LOG("[checkdata] Skipping '%s'\n", info.solver);
209 continue;
210 }
211
212 ed = expected_h48[info.h48h][info.bits].table;
213 em = expected_h48[info.h48h][info.bits].max;
214
215 LOG("[checkdata] Checking distribution for '%s' from "
216 "table preamble\n", info.solver);
217 if (!distribution_equal(ed, info.distribution, em)) {
218 LOG("[checkdata] Distribution from the table preamble "
219 "does not matche the expected one\n");
220 return NISSY_ERROR_DATA;
221 }
222
223 LOG("[checkdata] Checking distribution for '%s' from "
224 "actual table\n", info.solver);
225 getdistribution(table, actual_distribution, &info);
226 if (!distribution_equal(ed, actual_distribution, em)) {
227 LOG("[checkdata] Distribution from the actual table "
228 "does not match the expected one\n");
229 return NISSY_ERROR_DATA;
230 }
231 } while (info.next != 0);
232
233 return NISSY_OK;
234}
diff --git a/src/solvers/h48/gendata_eoesep.h b/src/solvers/h48/gendata_eoesep.h
index f1e3d4c..52e2b8b 100644
--- a/src/solvers/h48/gendata_eoesep.h
+++ b/src/solvers/h48/gendata_eoesep.h
@@ -79,7 +79,7 @@ gendata_eoesep(unsigned char *buf, uint8_t maxdepth)
79 if (buf == NULL) 79 if (buf == NULL)
80 goto gendata_eoesep_return_size; 80 goto gendata_eoesep_return_size;
81 81
82 LOG("Computing eoesep data\n"); 82 LOG("[H48 gendata] Computing eoesep data\n");
83 memset(buf, 0xFF, EOESEP_FULLSIZE); 83 memset(buf, 0xFF, EOESEP_FULLSIZE);
84 esep_classes = (uint32_t *)(buf + INFOSIZE); 84 esep_classes = (uint32_t *)(buf + INFOSIZE);
85 buf8 = buf + INFOSIZE + 4*ESEP_MAX; 85 buf8 = buf + INFOSIZE + 4*ESEP_MAX;
@@ -111,7 +111,7 @@ gendata_eoesep(unsigned char *buf, uint8_t maxdepth)
111 111
112 writetableinfo(&info, EOESEP_FULLSIZE, buf); 112 writetableinfo(&info, EOESEP_FULLSIZE, buf);
113 113
114 LOG("eoesep data computed\n"); 114 LOG("[H48 gendata] eoesep data computed\n");
115 115
116gendata_eoesep_return_size: 116gendata_eoesep_return_size:
117 return EOESEP_FULLSIZE; 117 return EOESEP_FULLSIZE;
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
index 644ddc2..d1ab3bd 100644
--- a/src/solvers/h48/gendata_h48.h
+++ b/src/solvers/h48/gendata_h48.h
@@ -25,8 +25,6 @@ STATIC_INLINE uint8_t get_h48_pval_atomic(
25STATIC_INLINE void set_h48_pval_atomic( 25STATIC_INLINE void set_h48_pval_atomic(
26 _Atomic unsigned char *, int64_t, uint8_t, uint8_t); 26 _Atomic unsigned char *, int64_t, uint8_t, uint8_t);
27 27
28size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *);
29
30STATIC long long 28STATIC long long
31gendata_h48_dispatch( 29gendata_h48_dispatch(
32 const char *solver, 30 const char *solver,
@@ -711,91 +709,3 @@ set_h48_pval_atomic(
711 table[H48_INDEX(i, k)] = (table[H48_INDEX(i, k)] & (~H48_MASK(i, k))) 709 table[H48_INDEX(i, k)] = (table[H48_INDEX(i, k)] & (~H48_MASK(i, k)))
712 | (val << H48_SHIFT(i, k)); 710 | (val << H48_SHIFT(i, k));
713} 711}
714
715size_t
716gendata_h48_derive(uint8_t h, const unsigned char *fulltable, unsigned char *buf)
717{
718 size_t cocsepsize, h48size;
719 uint8_t val_full, val_derive;
720 const unsigned char *h48full;
721 unsigned char *h48derive;
722 int64_t i, j, h48max;
723 uint64_t bufsize;
724 gendata_h48_arg_t arg;
725 tableinfo_t cocsepinfo, fulltableinfo;
726
727 /* Initializing values in case of error */
728 /* TODO cleanup this */
729 fulltableinfo.h48h = 11;
730 fulltableinfo.bits = 2;
731 fulltableinfo.base = 8;
732
733 int64_t TODOlarge = 999999999999; /* TODO: cleanup here */
734
735 readtableinfo_n(TODOlarge, fulltable, 2, &fulltableinfo);
736 arg.h = h;
737 arg.k = fulltableinfo.bits;
738 arg.maxdepth = 20;
739 arg.buf = buf;
740 arg.cocsepdata = (uint32_t *)(buf + INFOSIZE);
741 arg.base = fulltableinfo.base;
742 arg.info = makeinfo_h48k2(&arg);
743
744 /* Technically this step is redundant, except that we
745 need selfsim and crep */
746 cocsepsize = gendata_cocsep(buf, arg.selfsim, arg.crep);
747 arg.h48buf = (_Atomic unsigned char *)buf + cocsepsize;
748 h48size = H48_TABLESIZE(h, arg.k) + INFOSIZE;
749
750 if (buf == NULL)
751 goto gendata_h48_derive_return_size;
752
753 bufsize = COCSEP_FULLSIZE + INFOSIZE;
754 if (readtableinfo(bufsize, buf, &cocsepinfo) != NISSY_OK) {
755 LOG("[H48 derive gendata] Error: could not read info for "
756 "cocsep table\n");
757 goto gendata_h48_derive_error;
758 }
759
760 cocsepinfo.next = cocsepsize;
761 bufsize = COCSEP_FULLSIZE + INFOSIZE;
762 if (writetableinfo(&cocsepinfo, bufsize, buf) != NISSY_OK) {
763 LOG("[H48 derive gendata] Error: could not write info for "
764 "cocsep table with updated 'next' value\n");
765 goto gendata_h48_derive_error;
766 }
767
768 h48full = fulltable + cocsepsize + INFOSIZE;
769 h48derive = (unsigned char *)arg.h48buf + INFOSIZE;
770 memset(h48derive, 0xFF, H48_TABLESIZE(h, arg.k));
771 memset(arg.info.distribution, 0,
772 INFO_DISTRIBUTION_LEN * sizeof(uint64_t));
773
774 h48max = H48_COORDMAX(fulltableinfo.h48h);
775 for (i = 0; i < h48max; i++) {
776 if (i % INT64_C(1000000000) == 0 && i > 0)
777 LOG("[H48 derive gendata] Processing %" PRId64
778 "th coordinate\n", i);
779 j = i >> (int64_t)(fulltableinfo.h48h - h);
780 val_full = get_h48_pval(h48full, i, arg.k);
781 val_derive = get_h48_pval(h48derive, j, arg.k);
782 set_h48_pval(
783 h48derive, j, arg.k, MIN(val_full, val_derive));
784 }
785
786 getdistribution(h48derive, arg.info.distribution, &arg.info);
787
788 bufsize = arg.buf_size - COCSEP_FULLSIZE - INFOSIZE;
789 if (writetableinfo(&arg.info, bufsize, (unsigned char *)arg.h48buf)
790 != NISSY_OK) {
791 LOG("H48 derive gendata] Error: could not write info "
792 "for table\n");
793 goto gendata_h48_derive_error;
794 }
795
796gendata_h48_derive_return_size:
797 return cocsepsize + h48size;
798
799gendata_h48_derive_error:
800 return 0;
801}
diff --git a/src/solvers/h48/h48.h b/src/solvers/h48/h48.h
index 79d2583..44fdb59 100644
--- a/src/solvers/h48/h48.h
+++ b/src/solvers/h48/h48.h
@@ -7,4 +7,5 @@
7#include "gendata_cocsep.h" 7#include "gendata_cocsep.h"
8#include "gendata_eoesep.h" 8#include "gendata_eoesep.h"
9#include "gendata_h48.h" 9#include "gendata_h48.h"
10#include "checkdata.h"
10#include "solve.h" 11#include "solve.h"
diff --git a/tools/000_gendata/gendata.c b/tools/000_gendata/gendata.c
index 66c4864..f2da890 100644
--- a/tools/000_gendata/gendata.c
+++ b/tools/000_gendata/gendata.c
@@ -1,13 +1,10 @@
1#include "../tool.h" 1#include "../tool.h"
2#include "../expected_distributions.h"
3 2
4char *solver; 3char *solver;
5uint64_t *expected;
6 4
7static void 5static void
8run(void) { 6run(void) {
9 int64_t size; 7 int64_t size;
10 bool consistent, expected;
11 char filename[1024], dataid[NISSY_SIZE_DATAID]; 8 char filename[1024], dataid[NISSY_SIZE_DATAID];
12 unsigned char *buf; 9 unsigned char *buf;
13 10
@@ -18,20 +15,14 @@ run(void) {
18 case -2: 15 case -2:
19 goto gendata_run_finish; 16 goto gendata_run_finish;
20 default: 17 default:
21 nissy_datainfo(size, buf); 18 if (nissy_checkdata(solver, size, buf) == NISSY_OK) {
22 consistent = nissy_checkdata(size, buf) == 0;
23 expected = check_distribution(solver, size, buf);
24 if (consistent && expected) {
25 printf("\n"); 19 printf("\n");
26 printf("Generated %" PRId64 " bytes.\n", size); 20 printf("Generated %" PRId64 " bytes.\n", size);
27 sprintf(filename, "tables/%s", dataid); 21 sprintf(filename, "tables/%s", dataid);
28 writetable(buf, size, filename); 22 writetable(buf, size, filename);
23 } else {
24 printf("Error: table generated incorrectly!\n");
29 } 25 }
30 if (!consistent)
31 printf("Error: table is not consistent with info"
32 " (nissy_checkdata() failed)\n");
33 if (!expected)
34 printf("Error: distribution is not as expected\n");
35 break; 26 break;
36 } 27 }
37 28
@@ -40,8 +31,6 @@ gendata_run_finish:
40} 31}
41 32
42int main(int argc, char **argv) { 33int main(int argc, char **argv) {
43 uint8_t h, k;
44
45 if (argc < 2) { 34 if (argc < 2) {
46 printf("Error: not enough arguments. " 35 printf("Error: not enough arguments. "
47 "A solver must be given.\n"); 36 "A solver must be given.\n");
@@ -49,11 +38,7 @@ int main(int argc, char **argv) {
49 } 38 }
50 39
51 solver = argv[1]; 40 solver = argv[1];
52 parse_h48_hk(solver, &h, &k);
53 expected = expected_h48[h][k];
54
55 nissy_setlogger(log_stderr, NULL); 41 nissy_setlogger(log_stderr, NULL);
56
57 timerun(run); 42 timerun(run);
58 43
59 return 0; 44 return 0;
diff --git a/tools/001_derive_h48/derive_h48.c b/tools/001_derive_h48/derive_h48.c
deleted file mode 100644
index e8db207..0000000
--- a/tools/001_derive_h48/derive_h48.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2This tool is specific to the H48 solver. It can be used to derive small
3intermediate tables from larger tables, including the full h11 table.
4
5When using k=2, the base values for the tables may differ. If you want
6to change this value, for example for generating a table with base = 9
7from the h11 table with base = 10, you must re-generate the large table
8with the correct base value. The easiest way to do so is to manually
9edit the base value in the source code and recompile.
10*/
11
12#include "../tool.h"
13
14char *solver_large, *solver_small, *filename_large, *filename_small;
15
16void run(void) {
17 derivedata_run(solver_large, solver_small, filename_large, filename_small);
18}
19
20int main(int argc, char **argv) {
21 if (argc < 5) {
22 printf("Error: not enough arguments. Required:\n"
23 "1. Solver name for large table\n"
24 "2. Solver name for derived table\n"
25 "3. Filename containing large table\n"
26 "4. Filename for saving derived table\n");
27 return 1;
28 }
29
30 solver_large = argv[1];
31 solver_small = argv[2];
32 filename_large = argv[3];
33 filename_small = argv[4];
34
35 nissy_setlogger(log_stderr, NULL);
36
37 timerun(run);
38
39 return 0;
40}
diff --git a/tools/100_checkdata/checkdata.c b/tools/100_checkdata/checkdata.c
index c284aa4..3a3c098 100644
--- a/tools/100_checkdata/checkdata.c
+++ b/tools/100_checkdata/checkdata.c
@@ -1,11 +1,11 @@
1#include "../tool.h" 1#include "../tool.h"
2#include "../expected_distributions.h"
3 2
4char *solver, *filename; 3char *solver, *filename;
5 4
6static void 5static void
7run(void) { 6run(void) {
8 long long int size, sizeread, result; 7 bool result;
8 long long int size, sizeread;
9 char dataid[NISSY_SIZE_DATAID]; 9 char dataid[NISSY_SIZE_DATAID];
10 unsigned char *buf; 10 unsigned char *buf;
11 FILE *f; 11 FILE *f;
@@ -25,10 +25,12 @@ run(void) {
25 buf = malloc(size); 25 buf = malloc(size);
26 sizeread = fread(buf, size, 1, f); 26 sizeread = fread(buf, size, 1, f);
27 fclose(f); 27 fclose(f);
28 result = sizeread == 1 && nissy_checkdata(size, buf); 28 if (sizeread != 1)
29 printf("File has unexpected size\n");
30 result = sizeread == 1 && nissy_checkdata(solver, size, buf) == NISSY_OK;
29 free(buf); 31 free(buf);
30 32
31 printf("checkdata %s\n", result == 0 ? "succeeded" : "failed"); 33 printf("checkdata %s\n", result ? "succeeded" : "failed");
32 34
33 /* TODO: cross-check with expected distributions? */ 35 /* TODO: cross-check with expected distributions? */
34} 36}
diff --git a/tools/expected_distributions.h b/tools/expected_distributions.h
deleted file mode 100644
index 1193fb3..0000000
--- a/tools/expected_distributions.h
+++ /dev/null
@@ -1,267 +0,0 @@
1uint64_t expected_cocsep[21] = {
2 [0] = 1,
3 [1] = 6,
4 [2] = 63,
5 [3] = 468,
6 [4] = 3068,
7 [5] = 15438,
8 [6] = 53814,
9 [7] = 71352,
10 [8] = 8784,
11 [9] = 96
12};
13
14uint64_t expected_h48[12][9][21] = {
15 [0] = {
16 [2] = {
17 [0] = 5473562,
18 [1] = 34776317,
19 [2] = 68566704,
20 [3] = 8750867,
21 },
22 [4] = {
23 [0] = 1,
24 [1] = 1,
25 [2] = 4,
26 [3] = 34,
27 [4] = 331,
28 [5] = 3612,
29 [6] = 41605,
30 [7] = 474128,
31 [8] = 4953846,
32 [9] = 34776317,
33 [10] = 68566704,
34 [11] = 8749194,
35 [12] = 1673,
36 },
37 },
38 [1] = {
39 [2] = {
40 [0] = 6012079,
41 [1] = 45822302,
42 [2] = 142018732,
43 [3] = 41281787,
44 },
45 },
46 [2] = {
47 [2] = {
48 [0] = 6391286,
49 [1] = 55494785,
50 [2] = 252389935,
51 [3] = 155993794,
52 },
53 },
54 [3] = {
55 [2] = {
56 [0] = 6686828,
57 [1] = 63867852,
58 [2] = 392789689,
59 [3] = 477195231,
60 },
61 },
62 [4] = {
63 [2] = {
64 [0] = 77147213,
65 [1] = 543379415,
66 [2] = 1139570251,
67 [3] = 120982321,
68 },
69 },
70 [5] = {
71 [2] = {
72 [0] = 82471284,
73 [1] = 687850732,
74 [2] = 2345840746,
75 [3] = 645995638,
76 },
77 },
78 [6] = {
79 [2] = {
80 [0] = 85941099,
81 [1] = 804752968,
82 [2] = 4077248182,
83 [3] = 2556374551,
84 },
85 },
86 [7] = {
87 [2] = {
88 [0] = 88529761,
89 [1] = 897323475,
90 [2] = 6126260791,
91 [3] = 7936519573,
92 },
93 },
94 [8] = {
95 [2] = {
96 [0] = 1051579940,
97 [1] = 8136021316,
98 [2] = 19024479822,
99 [3] = 18851861220,
100 },
101 },
102 [9] = {
103 [2] = {
104 [0] = 1102038189,
105 [1] = 9888265242,
106 [2] = 38299375805,
107 [3] = 10904855164,
108 },
109 },
110 [10] = {
111 [2] = {
112 [0] = 1133240039,
113 [1] = 11196285614,
114 [2] = 64164702961,
115 [3] = 43894840186,
116 },
117 },
118 [11] = {
119 [2] = {
120 [0] = 1150763161,
121 [1] = 12045845660,
122 [2] = 91163433330,
123 [3] = 136418095449,
124 },
125 },
126};
127
128uint64_t expected_eo[21] = {
129 [0] = 1,
130 [1] = 2,
131 [2] = 25,
132 [3] = 202,
133 [4] = 620,
134 [5] = 900,
135 [6] = 285,
136 [7] = 13,
137};
138
139uint64_t expected_dr[21] = {
140 [0] = 1,
141 [1] = 1,
142 [2] = 5,
143 [3] = 44,
144 [4] = 487,
145 [5] = 5841,
146 [6] = 68364,
147 [7] = 776568,
148 [8] = 7950748,
149 [9] = 52098876,
150 [10] = 76236234,
151 [11] = 3771112,
152 [12] = 129,
153};
154
155uint64_t expected_dreo[21] = {
156 [0] = 1,
157 [1] = 1,
158 [2] = 4,
159 [3] = 22,
160 [4] = 160,
161 [5] = 1286,
162 [6] = 8550,
163 [7] = 42152,
164 [8] = 90748,
165 [9] = 33466,
166 [10] = 757,
167};
168
169static bool
170distribution_equal(const uint64_t *expected, const uint64_t *actual, int n)
171{
172 bool equal;
173 int i;
174
175 for (i = 0, equal = true; i <= n; i++) {
176 if (expected[i] != actual[i]) {
177 equal = false;
178 printf("Wrong value for %d: expected %" PRIu64
179 ", actual %" PRIu64 "\n",
180 i, expected[i], actual[i]);
181 }
182 }
183
184 return equal;
185}
186
187STATIC bool
188check_table(uint64_t *exp, tableinfo_t *info)
189{
190 if (!distribution_equal(exp, info->distribution, info->maxvalue)) {
191 printf("ERROR! Distribution is incorrect\n");
192 return false;
193 }
194
195 printf("Distribution is correct\n");
196 return true;
197}
198
199static bool
200check_cocsep(size_t data_size, const unsigned char *data)
201{
202 tableinfo_t info;
203
204 readtableinfo(data_size, data, &info);
205 return distribution_equal(
206 expected_cocsep, info.distribution, info.maxvalue);
207}
208
209static bool
210unknown_h48(uint8_t h, uint8_t k)
211{
212 if (k != 2 && k != 4)
213 return true;
214
215 if (k == 4 && h != 0)
216 return true;
217
218 return k == 2 && h > 7;
219}
220
221STATIC bool
222check_distribution(
223 const char *solver,
224 size_t data_size,
225 const unsigned char *data
226)
227{
228 const char *str;
229 tableinfo_t info = {0};
230
231 if (!strncmp(solver, "h48", 3)) {
232 readtableinfo(data_size, data, &info);
233 if (!distribution_equal(
234 expected_cocsep, info.distribution, info.maxvalue)) {
235 printf("ERROR! cocsep distribution is incorrect\n");
236 return false;
237 }
238 printf("cocsep distribution is correct\n");
239
240 readtableinfo_n(data_size, data, 2, &info);
241 if (unknown_h48(info.h48h, info.bits))
242 goto check_distribution_unknown;
243
244 return check_table(expected_h48[info.h48h][info.bits], &info);
245 }
246
247 if (!strncmp(solver, "coord_", 6)) {
248 readtableinfo(data_size, data, &info);
249 if (!strncmp(info.solver, "coord helper table for ", 23))
250 readtableinfo_n(data_size, data, 2, &info);
251
252 str = info.solver + 22; /* "coordinate solver for COORD" */
253 if (!strcmp(str, "EO")) {
254 return check_table(expected_eo, &info);
255 } else if (!strcmp(str, "DR")) {
256 return check_table(expected_dr, &info);
257 } else if (!strcmp(str, "DREO")) {
258 return check_table(expected_dreo, &info);
259 } else {
260 goto check_distribution_unknown;
261 }
262 }
263
264check_distribution_unknown:
265 printf("Distribution unknown, not checked\n");
266 return true;
267}
diff --git a/tools/nissy_extra.h b/tools/nissy_extra.h
deleted file mode 100644
index 9a7df50..0000000
--- a/tools/nissy_extra.h
+++ /dev/null
@@ -1,14 +0,0 @@
1/*
2This header file exposes certain functions that are meant to be used
3for testing purposes only.
4*/
5
6#define STATIC static
7#define LOG printf
8
9#include "../src/solvers/tables_types_macros.h"
10#include "../src/solvers/tables.h"
11
12size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *);
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 *);
diff --git a/tools/tool.h b/tools/tool.h
index 225f789..9c55d2b 100644
--- a/tools/tool.h
+++ b/tools/tool.h
@@ -7,19 +7,14 @@
7#include <string.h> 7#include <string.h>
8 8
9#include "../src/nissy.h" 9#include "../src/nissy.h"
10#include "nissy_extra.h"
11 10
12static void log_stderr(const char *, void *); 11static void log_stderr(const char *, void *);
13static double timerun(void (*)(void)); 12static double timerun(void (*)(void));
14static void writetable(const unsigned char *, int64_t, const char *); 13static void writetable(const unsigned char *, int64_t, const char *);
15static long long int generatetable(const char *, unsigned char **, 14static long long int generatetable(const char *, unsigned char **,
16 char [static NISSY_SIZE_DATAID]); 15 char [static NISSY_SIZE_DATAID]);
17static long long int derivetable(
18 const char *, const char *, const char *, unsigned char **);
19static int getdata(const char *, unsigned char **, const char *); 16static int getdata(const char *, unsigned char **, const char *);
20static void gendata_run(const char *, uint64_t[static 21]); 17static void gendata_run(const char *, uint64_t[static 21]);
21static void derivedata_run(
22 const char *, const char *, const char *, const char *);
23 18
24static void 19static void
25log_stderr(const char *str, void *unused) 20log_stderr(const char *str, void *unused)
@@ -100,53 +95,6 @@ generatetable(
100 return gensize; 95 return gensize;
101} 96}
102 97
103static long long int
104derivetable(
105 const char *solver_large,
106 const char *solver_small,
107 const char *filename_large,
108 unsigned char **buf
109)
110{
111 uint8_t h, k;
112 long long int size, gensize;
113 char dataid[NISSY_SIZE_DATAID];
114 unsigned char *fulltable;
115
116 if (getdata(solver_large, &fulltable, filename_large) != 0) {
117 printf("Error reading full table.\n");
118 gensize = -1;
119 goto derivetable_error_nofree;
120 }
121
122 size = nissy_solverinfo(solver_small, dataid);
123 if (size == -1) {
124 printf("Error getting table size.\n");
125 gensize = -2;
126 goto derivetable_error;
127 }
128
129 if (parse_h48_hk(solver_small, &h, &k) != NISSY_OK) {
130 gensize = -3;
131 goto derivetable_error;
132 }
133
134 *buf = malloc(size);
135 gensize = gendata_h48_derive(h, fulltable, *buf);
136
137 if (gensize != size) {
138 printf("Error deriving table\n");
139 gensize = -4;
140 goto derivetable_error;
141 }
142
143derivetable_error:
144 free(fulltable);
145
146derivetable_error_nofree:
147 return gensize;
148}
149
150static int 98static int
151getdata( 99getdata(
152 const char *solver, 100 const char *solver,
@@ -206,8 +154,6 @@ gendata_run(
206 case -2: 154 case -2:
207 goto gendata_run_finish; 155 goto gendata_run_finish;
208 default: 156 default:
209 nissy_datainfo(size, buf);
210 printf("\n");
211 printf("Succesfully generated %lld bytes. " 157 printf("Succesfully generated %lld bytes. "
212 "See above for details on the tables.\n", size); 158 "See above for details on the tables.\n", size);
213 159
@@ -219,35 +165,3 @@ gendata_run(
219gendata_run_finish: 165gendata_run_finish:
220 free(buf); 166 free(buf);
221} 167}
222
223static void
224derivedata_run(
225 const char *solver_large,
226 const char *solver_small,
227 const char *filename_large,
228 const char *filename_small
229)
230{
231 long long int size;
232 unsigned char *buf;
233
234 buf = NULL;
235 size = derivetable(solver_large, solver_small, filename_large, &buf);
236 switch (size) {
237 case -1:
238 return;
239 case -2:
240 goto derivedata_run_finish;
241 default:
242 nissy_datainfo(size, buf);
243 printf("\n");
244 printf("Succesfully generated %lld bytes. "
245 "See above for details on the tables.\n", size);
246
247 writetable(buf, size, filename_small);
248 break;
249 }
250
251derivedata_run_finish:
252 free(buf);
253}

Generated with cgit - Back to sebastiano.tronto.net