commit 62d87e063318cc4c842b1b2d8c184f48aeaf6659
parent 8b94d135429a9f3253cc7f25a1453b412065c4a0
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Mon, 19 May 2025 17:45:14 +0200
Refactored checkdata
Relevant changes include:
- Changed the signature of nissy_checkdata().
- Removed expected_distribution.h from tools; this data is now included
in each solver's src/ code.
- Removed distribution check for cocsep; may add back later.
Diffstat:
25 files changed, 418 insertions(+), 659 deletions(-)
diff --git a/cpp/nissy.cpp b/cpp/nissy.cpp
@@ -17,7 +17,8 @@ extern "C" {
long long nissy_solverinfo(const char *, char *);
long long nissy_gendata(const char *, unsigned long long,
unsigned char *);
- long long nissy_checkdata(unsigned long long, const unsigned char *);
+ long long nissy_checkdata(const char *, unsigned long long,
+ const unsigned char *);
long long nissy_solve(const char *, const char *, unsigned, unsigned,
unsigned, unsigned, unsigned, unsigned, unsigned long long,
const unsigned char *, unsigned, char *, long long *,
@@ -144,7 +145,7 @@ namespace nissy {
error solver::check_data()
{
- auto err_value = nissy_checkdata(data.size(),
+ auto err_value = nissy_checkdata(name.c_str(), data.size(),
reinterpret_cast<const unsigned char *>(data.data()));
error err{err_value};
data_checked = err.ok();
diff --git a/python/nissy_module.c b/python/nissy_module.c
@@ -239,21 +239,23 @@ PyDoc_STRVAR(checkdata_doc,
"Checks if the data (pruning table) given is valid or not\n"
"\n"
"Parameters:\n"
-" - data: a bytearray containing the data for a solver"
+" - solver: the name of the solver\n"
+" - data: a bytearray containing the data for a solver\n"
"\n"
"Returns: true if the data is valid, false otherwise\n"
);
PyObject *
checkdata(PyObject *self, PyObject *args)
{
+ const char *solver;
long long result;
PyByteArrayObject *data;
- if (!PyArg_ParseTuple(args, "Y", &data))
+ if (!PyArg_ParseTuple(args, "sY", &solver, &data))
return NULL;
result = nissy_checkdata(
- data->ob_alloc, (unsigned char *)data->ob_bytes);
+ solver, data->ob_alloc, (unsigned char *)data->ob_bytes);
if (check_error(result))
return Py_True;
diff --git a/src/nissy.c b/src/nissy.c
@@ -12,9 +12,6 @@
#include "core/core.h"
#include "solvers/solvers.h"
-STATIC bool checkdata(const unsigned char *, const tableinfo_t [static 1]);
-STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN],
- const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t);
STATIC long long write_result(oriented_cube_t, char [static NISSY_SIZE_CUBE]);
STATIC long long nissy_dataid(const char *, char [static NISSY_SIZE_DATAID]);
STATIC long long nissy_gendata_unsafe(
@@ -30,47 +27,6 @@ struct {
GETCUBE_OPTIONS(NULL, NULL)
};
-STATIC bool
-checkdata(const unsigned char *buf, const tableinfo_t info[static 1])
-{
- uint64_t distr[INFO_DISTRIBUTION_LEN];
-
- if (info->type == TABLETYPE_PRUNING) {
- getdistribution(buf + INFOSIZE, distr, info);
- LOG("\n[checkdata] Checking distribution for %s\n", info->solver);
- return distribution_equal(info->distribution, distr, info->maxvalue);
- } else {
- LOG("\n[checkdata] Skipping distribution check for "
- "special table %s\n", info->solver);
- return true;
- }
-}
-
-STATIC bool
-distribution_equal(
- const uint64_t expected[static INFO_DISTRIBUTION_LEN],
- const uint64_t actual[static INFO_DISTRIBUTION_LEN],
- uint8_t maxvalue
-)
-{
- int wrong;
- uint8_t i;
-
- for (i = 0, wrong = 0; i <= MIN(maxvalue, 20); i++) {
- if (expected[i] != actual[i]) {
- wrong++;
- LOG("[checkdata] Value for depth %" PRIu8
- ": expected %" PRIu64 ", found %" PRIu64 "\n",
- i, expected[i], actual[i]);
- } else {
- LOG("[checkdata] Value for depth %" PRIu8
- " is correct (%" PRIu64 ")\n", i, actual[i]);
- }
- }
-
- return wrong == 0;
-}
-
STATIC long long
write_result(oriented_cube_t cube, char result[static NISSY_SIZE_CUBE])
{
@@ -227,55 +183,6 @@ nissy_getcube(
return write_result(oc, result);
}
-long long
-nissy_datainfo(
- uint64_t data_size,
- const unsigned char data[data_size]
-)
-{
- uint8_t i;
- tableinfo_t info;
- long long ret;
-
- if ((size_t)data % 8 != 0) {
- LOG("[datainfo] Error: buffer is not 8-byte aligned\n");
- return NISSY_ERROR_DATA;
- }
-
- ret = readtableinfo(data_size, data, &info);
- if (ret != 0)
- return ret;
-
- LOG("\n---------\n\n"
- "Table information for '%s'\n\n"
- "Size: %" PRIu64 " bytes\n"
- "Entries: %" PRIu64 " (%" PRIu8 " bits per entry)\n",
- info.solver, info.fullsize, info.entries, info.bits);
-
- switch (info.type) {
- case TABLETYPE_PRUNING:
- LOG("\nTable distribution:\nValue\tPositions\n");
- for (i = 0; i <= info.maxvalue; i++) {
- LOG("%" PRIu8 "\t%" PRIu64 "\n",
- i + info.base, info.distribution[i]);
- }
- break;
- case TABLETYPE_SPECIAL:
- LOG("This is an ad-hoc table\n");
- break;
- default:
- LOG("datainfo: unknown table type\n");
- return NISSY_ERROR_DATA;
- }
-
- if (info.next != 0)
- return nissy_datainfo(data_size - info.next, data + info.next);
-
- LOG("\n---------\n");
-
- return NISSY_OK;
-}
-
STATIC long long
nissy_dataid(const char *solver, char dataid[static NISSY_SIZE_DATAID])
{
@@ -344,33 +251,20 @@ nissy_gendata_unsafe(
long long
nissy_checkdata(
+ const char *solver,
unsigned long long data_size,
const unsigned char data[data_size]
)
{
- tableinfo_t info;
- int64_t err;
-
- if ((size_t)data % 8 != 0) {
- LOG("[checkdata] Error: buffer is not 8-byte aligned\n");
- return NISSY_ERROR_DATA;
- }
+ solver_dispatch_t *dispatch;
- for (const unsigned char *buf = data;
- (err = readtableinfo(data_size, buf, &info)) == NISSY_OK;
- buf += info.next, data_size -= info.next)
- {
- if (!checkdata(buf, &info)) {
- LOG("[checkdata] Error: data for solver '%s' is "
- "corrupted!\n", info.solver);
- return NISSY_ERROR_DATA;
- }
-
- if (info.next == 0)
- break;
+ dispatch = match_solver(solver);
+ if (dispatch == NULL) {
+ LOG("[checkdata] Unknown solver %s\n", solver);
+ return NISSY_ERROR_INVALID_SOLVER;
}
- return err;
+ return dispatch->checkdata(solver, data_size, data);
}
long long
diff --git a/src/nissy.h b/src/nissy.h
@@ -283,6 +283,7 @@ nissy_gendata(
Check that the data is a valid data table for a solver.
Parameters:
+ solver - The name of the solver.
data_size - The size of the data buffer.
data - The data for the solver. Can be computed with gendata.
This buffer must have 8-byte alignment.
@@ -293,6 +294,7 @@ Return values:
*/
long long
nissy_checkdata(
+ const char *solver,
unsigned long long data_size,
const unsigned char data[data_size]
);
diff --git a/src/solvers/coord/checkdata.h b/src/solvers/coord/checkdata.h
@@ -0,0 +1,65 @@
+STATIC long long checkdata_coord(
+ const char *, unsigned long long n, const unsigned char [n]);
+
+STATIC long long
+checkdata_coord(
+ const char *solver,
+ unsigned long long data_size,
+ const unsigned char data[data_size]
+)
+{
+ coord_t *coord;
+ const unsigned char *table;
+ tableinfo_t info;
+ int64_t err;
+ uint64_t actual_distribution[INFO_DISTRIBUTION_LEN];
+
+ if ((size_t)data % 8 != 0) {
+ LOG("[checkdata] Error: buffer is not 8-byte aligned\n");
+ return NISSY_ERROR_DATA;
+ }
+
+ parse_coord_and_axis(solver, &coord, NULL);
+ if (coord == NULL) {
+ LOG("[cehckdata] Unknown coordinate solver '%s'\n", solver);
+ return NISSY_ERROR_DATA;
+ }
+
+ table = data + INFOSIZE;
+ err = readtableinfo(data_size, data, &info);
+ if (err != NISSY_OK) {
+ LOG("[checkdata] Data is corrupt\n");
+ return err;
+ }
+
+ if (info.type != TABLETYPE_PRUNING) {
+ LOG("[checkdata] Skipping '%s'\n", info.solver);
+ table += info.next;
+ err = readtableinfo_n(data_size, data, 2, &info);
+ if (err != NISSY_OK) {
+ LOG("[checkdata] Data is corrupt\n");
+ return err;
+ }
+ }
+
+ LOG("[checkdata] Checking distribution for '%s' from "
+ "table preamble\n", info.solver);
+ if (!distribution_equal(coord->pruning_distribution,
+ info.distribution, coord->pruning_max)) {
+ LOG("[checkdata] Distribution from the table preamble does "
+ "not match the expected one\n");
+ return NISSY_ERROR_DATA;
+ }
+
+ LOG("\n[checkdata] Checking distribution for '%s' from "
+ "actual table\n", info.solver);
+ getdistribution(table, actual_distribution, &info);
+ if (!distribution_equal(coord->pruning_distribution,
+ actual_distribution, coord->pruning_max)) {
+ LOG("[checkdata] Distribution from the actual table does "
+ "not match the expected one\n");
+ return NISSY_ERROR_DATA;
+ }
+
+ return NISSY_OK;
+}
diff --git a/src/solvers/coord/coord.h b/src/solvers/coord/coord.h
@@ -6,4 +6,5 @@
#include "list.h"
#include "utils.h"
#include "gendata.h"
+#include "checkdata.h"
#include "solve.h"
diff --git a/src/solvers/coord/dr.h b/src/solvers/coord/dr.h
@@ -32,6 +32,22 @@ STATIC coord_t coordinate_dr = {
},
.is_admissible = &solution_lastqt_cw,
.is_solvable = &is_eoco_solvable,
+ .pruning_distribution = {
+ [0] = 1,
+ [1] = 1,
+ [2] = 5,
+ [3] = 44,
+ [4] = 487,
+ [5] = 5841,
+ [6] = 68364,
+ [7] = 776568,
+ [8] = 7950748,
+ [9] = 52098876,
+ [10] = 76236234,
+ [11] = 3771112,
+ [12] = 129,
+ },
+ .pruning_max = 12,
.sym = {
.classes = DREOESEP_CLASSES,
.max = DREOESEP_MAX,
diff --git a/src/solvers/coord/dreo.h b/src/solvers/coord/dreo.h
@@ -27,6 +27,20 @@ STATIC coord_t coordinate_dreo = {
},
.is_admissible = &solution_lastqt_cw,
.is_solvable = &is_dreo_solvable,
+ .pruning_distribution = {
+ [0] = 1,
+ [1] = 1,
+ [2] = 4,
+ [3] = 22,
+ [4] = 160,
+ [5] = 1286,
+ [6] = 8550,
+ [7] = 42152,
+ [8] = 90748,
+ [9] = 33466,
+ [10] = 757,
+ },
+ .pruning_max = 10,
.sym = {
.classes = DRESEP_CLASSES,
.max = COMB_12_4,
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
@@ -20,6 +20,17 @@ STATIC coord_t coordinate_eo = {
},
.is_admissible = &solution_lastqt_cw,
.is_solvable = &is_eo_even,
+ .pruning_distribution = {
+ [0] = 1,
+ [1] = 2,
+ [2] = 25,
+ [3] = 202,
+ [4] = 620,
+ [5] = 900,
+ [6] = 285,
+ [7] = 13,
+ },
+ .pruning_max = 7,
.sym = {0},
};
diff --git a/src/solvers/coord/gendata.h b/src/solvers/coord/gendata.h
@@ -22,7 +22,7 @@ gendata_coord_dispatch(
{
coord_t *coord;
- parse_coord_and_axis(strlen(coordstr), coordstr, &coord, NULL);
+ parse_coord_and_axis(coordstr, &coord, NULL);
if (coord == NULL) {
LOG("Error: could not parse coordinate '%s'\n", coordstr);
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h
@@ -222,8 +222,7 @@ solve_coord_dispatch(
coord_t *coord;
uint8_t axis;
- parse_coord_and_axis(
- strlen(coord_and_axis), coord_and_axis, &coord, &axis);
+ parse_coord_and_axis(coord_and_axis, &coord, &axis);
if (coord == NULL) {
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
@@ -26,6 +26,8 @@ typedef struct {
uint8_t axistrans[3];
bool (*is_admissible)(const solution_moves_t[static 1]);
bool (*is_solvable)(cube_t);
+ uint64_t pruning_distribution[INFO_DISTRIBUTION_LEN];
+ uint8_t pruning_max;
struct {
size_t classes;
uint64_t max;
diff --git a/src/solvers/coord/utils.h b/src/solvers/coord/utils.h
@@ -1,7 +1,6 @@
STATIC coord_t *parse_coord(size_t n, const char [n]);
-STATIC uint8_t parse_axis(size_t n, const char [n]);
-STATIC void parse_coord_and_axis(
- size_t n, const char [n], coord_t **, uint8_t *);
+STATIC uint8_t parse_axis(const char [static 2]);
+STATIC void parse_coord_and_axis(const char *, coord_t **, uint8_t *);
STATIC long long dataid_coord(const char *, char [static NISSY_SIZE_DATAID]);
STATIC coord_t *
@@ -17,13 +16,13 @@ parse_coord(size_t n, const char coord[n])
}
STATIC uint8_t
-parse_axis(size_t n, const char axis[n])
+parse_axis(const char axis[static 2])
{
- if (!strncmp(axis, "UD", n) || !strncmp(axis, "DU", n)) {
+ if (!strcmp(axis, "UD") || !strcmp(axis, "DU")) {
return AXIS_UD;
- } else if (!strncmp(axis, "RL", n) || !strncmp(axis, "LR", n)) {
+ } else if (!strcmp(axis, "RL") || !strcmp(axis, "LR")) {
return AXIS_RL;
- } else if (!strncmp(axis, "FB", n) || !strncmp(axis, "BF", n)) {
+ } else if (!strcmp(axis, "FB") || !strcmp(axis, "BF")) {
return AXIS_FB;
}
@@ -32,25 +31,22 @@ parse_axis(size_t n, const char axis[n])
STATIC void
parse_coord_and_axis(
- size_t n,
- const char str[n],
+ const char *str,
coord_t **coord,
uint8_t *axis
)
{
- const char *s;
size_t i;
- s = str + 6;
- for (i = 0; i < n; i++)
- if (s[i] == '_')
+ for (i = 6; i < strlen(str); i++)
+ if (str[i] == '_')
break;
if (coord != NULL)
- *coord = parse_coord(i, s);
+ *coord = parse_coord(i-6, str+6);
if (axis != NULL)
- *axis = i == n ? UINT8_ERROR : parse_axis(n-i-1, s+i+1);
+ *axis = i == strlen(str) ? UINT8_ERROR : parse_axis(str+i+1);
}
STATIC long long
@@ -58,7 +54,7 @@ dataid_coord(const char *ca, char dataid[static NISSY_SIZE_DATAID])
{
coord_t *c;
- parse_coord_and_axis(strlen(ca), ca, &c, NULL);
+ parse_coord_and_axis(ca, &c, NULL);
if (c == NULL) {
LOG("Error: cannot parse coordinate from '%s'\n", ca);
diff --git a/src/solvers/dispatch.h b/src/solvers/dispatch.h
@@ -2,7 +2,9 @@ typedef struct {
const char *prefix;
long long (*dataid)(const char *, char [static NISSY_SIZE_DATAID]);
long long (*gendata)(
- const char *, unsigned long long, unsigned char *);
+ const char *, unsigned long long n, unsigned char [n]);
+ long long (*checkdata)(
+ const char *, unsigned long long, const unsigned char *);
long long (*solve)(oriented_cube_t, const char *, unsigned, unsigned,
unsigned, unsigned, unsigned, unsigned, unsigned long long,
const unsigned char *, unsigned, char *,
@@ -17,12 +19,14 @@ solver_dispatch_t solver_dispatchers[] = {
.prefix = "h48",
.dataid = dataid_h48,
.gendata = gendata_h48_dispatch,
+ .checkdata = checkdata_h48,
.solve = solve_h48_dispatch,
},
{
.prefix = "coord_",
.dataid = dataid_coord,
.gendata = gendata_coord_dispatch,
+ .checkdata = checkdata_coord,
.solve = solve_coord_dispatch,
},
{
diff --git a/src/solvers/distribution.h b/src/solvers/distribution.h
@@ -13,6 +13,8 @@ typedef struct {
STATIC void *getdistribution_runthread(void *);
STATIC void getdistribution(const unsigned char *,
uint64_t [static INFO_DISTRIBUTION_LEN], const tableinfo_t [static 1]);
+STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN],
+ const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t);
STATIC void *
getdistribution_runthread(void *arg)
@@ -75,3 +77,28 @@ getdistribution(
distr[pval]++;
}
}
+
+STATIC bool
+distribution_equal(
+ const uint64_t expected[static INFO_DISTRIBUTION_LEN],
+ const uint64_t actual[static INFO_DISTRIBUTION_LEN],
+ uint8_t maxvalue
+)
+{
+ int wrong;
+ uint8_t i;
+
+ for (i = 0, wrong = 0; i <= MIN(maxvalue, 20); i++) {
+ if (expected[i] != actual[i]) {
+ wrong++;
+ LOG("[checkdata] Value for depth %" PRIu8
+ ": expected %" PRIu64 ", found %" PRIu64 "\n",
+ i, expected[i], actual[i]);
+ } else {
+ LOG("[checkdata] Value for depth %" PRIu8
+ " is correct (%" PRIu64 ")\n", i, actual[i]);
+ }
+ }
+
+ return wrong == 0;
+}
diff --git a/src/solvers/h48/checkdata.h b/src/solvers/h48/checkdata.h
@@ -0,0 +1,234 @@
+STATIC long long checkdata_h48(
+ const char *, unsigned long long n, const unsigned char [n]);
+
+/*
+Currently unused.
+TODO: re-introduce check on cocsep table
+*/
+uint64_t expected_cocsep[21] = {
+ [0] = 1,
+ [1] = 6,
+ [2] = 63,
+ [3] = 468,
+ [4] = 3068,
+ [5] = 15438,
+ [6] = 53814,
+ [7] = 71352,
+ [8] = 8784,
+ [9] = 96
+};
+
+struct {
+ uint8_t max;
+ uint64_t table[21];
+} expected_h48[12][9] = {
+ [0] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 5473562,
+ [1] = 34776317,
+ [2] = 68566704,
+ [3] = 8750867,
+ },
+ },
+ [4] = {
+ .max = 12,
+ .table = {
+ [0] = 1,
+ [1] = 1,
+ [2] = 4,
+ [3] = 34,
+ [4] = 331,
+ [5] = 3612,
+ [6] = 41605,
+ [7] = 474128,
+ [8] = 4953846,
+ [9] = 34776317,
+ [10] = 68566704,
+ [11] = 8749194,
+ [12] = 1673,
+ },
+ },
+ },
+ [1] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 6012079,
+ [1] = 45822302,
+ [2] = 142018732,
+ [3] = 41281787,
+ },
+ },
+ },
+ [2] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 6391286,
+ [1] = 55494785,
+ [2] = 252389935,
+ [3] = 155993794,
+ },
+ },
+ },
+ [3] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 6686828,
+ [1] = 63867852,
+ [2] = 392789689,
+ [3] = 477195231,
+ },
+ },
+ },
+ [4] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 77147213,
+ [1] = 543379415,
+ [2] = 1139570251,
+ [3] = 120982321,
+ },
+ },
+ },
+ [5] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 82471284,
+ [1] = 687850732,
+ [2] = 2345840746,
+ [3] = 645995638,
+ },
+ },
+ },
+ [6] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 85941099,
+ [1] = 804752968,
+ [2] = 4077248182,
+ [3] = 2556374551,
+ },
+ },
+ },
+ [7] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 88529761,
+ [1] = 897323475,
+ [2] = 6126260791,
+ [3] = 7936519573,
+ },
+ },
+ },
+ [8] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 1051579940,
+ [1] = 8136021316,
+ [2] = 19024479822,
+ [3] = 18851861220,
+ },
+ },
+ },
+ [9] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 1102038189,
+ [1] = 9888265242,
+ [2] = 38299375805,
+ [3] = 10904855164,
+ },
+ },
+ },
+ [10] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 1133240039,
+ [1] = 11196285614,
+ [2] = 64164702961,
+ [3] = 43894840186,
+ },
+ },
+ },
+ [11] = {
+ [2] = {
+ .max = 3,
+ .table = {
+ [0] = 1150763161,
+ [1] = 12045845660,
+ [2] = 91163433330,
+ [3] = 136418095449,
+ },
+ },
+ },
+};
+
+STATIC long long
+checkdata_h48(
+ const char *solver,
+ unsigned long long data_size,
+ const unsigned char data[data_size]
+)
+{
+ const unsigned char *table;
+ tableinfo_t info;
+ int64_t err;
+ uint64_t actual_distribution[INFO_DISTRIBUTION_LEN];
+ uint8_t em;
+ uint64_t *ed;
+
+ if ((size_t)data % 8 != 0) {
+ LOG("[checkdata] Error: buffer is not 8-byte aligned\n");
+ return NISSY_ERROR_DATA;
+ }
+
+ do {
+ err = readtableinfo(data_size, data, &info);
+ if (err != NISSY_OK) {
+ LOG("[checkdata] Data is corrupt\n");
+ return NISSY_ERROR_DATA;
+ }
+
+ table = data + INFOSIZE;
+ data += info.next;
+ data_size -= info.next;
+
+ if (info.type != TABLETYPE_PRUNING) {
+ LOG("[checkdata] Skipping '%s'\n", info.solver);
+ continue;
+ }
+
+ ed = expected_h48[info.h48h][info.bits].table;
+ em = expected_h48[info.h48h][info.bits].max;
+
+ LOG("[checkdata] Checking distribution for '%s' from "
+ "table preamble\n", info.solver);
+ if (!distribution_equal(ed, info.distribution, em)) {
+ LOG("[checkdata] Distribution from the table preamble "
+ "does not matche the expected one\n");
+ return NISSY_ERROR_DATA;
+ }
+
+ LOG("[checkdata] Checking distribution for '%s' from "
+ "actual table\n", info.solver);
+ getdistribution(table, actual_distribution, &info);
+ if (!distribution_equal(ed, actual_distribution, em)) {
+ LOG("[checkdata] Distribution from the actual table "
+ "does not match the expected one\n");
+ return NISSY_ERROR_DATA;
+ }
+ } while (info.next != 0);
+
+ return NISSY_OK;
+}
diff --git 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)
if (buf == NULL)
goto gendata_eoesep_return_size;
- LOG("Computing eoesep data\n");
+ LOG("[H48 gendata] Computing eoesep data\n");
memset(buf, 0xFF, EOESEP_FULLSIZE);
esep_classes = (uint32_t *)(buf + INFOSIZE);
buf8 = buf + INFOSIZE + 4*ESEP_MAX;
@@ -111,7 +111,7 @@ gendata_eoesep(unsigned char *buf, uint8_t maxdepth)
writetableinfo(&info, EOESEP_FULLSIZE, buf);
- LOG("eoesep data computed\n");
+ LOG("[H48 gendata] eoesep data computed\n");
gendata_eoesep_return_size:
return EOESEP_FULLSIZE;
diff --git 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(
STATIC_INLINE void set_h48_pval_atomic(
_Atomic unsigned char *, int64_t, uint8_t, uint8_t);
-size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *);
-
STATIC long long
gendata_h48_dispatch(
const char *solver,
@@ -711,91 +709,3 @@ set_h48_pval_atomic(
table[H48_INDEX(i, k)] = (table[H48_INDEX(i, k)] & (~H48_MASK(i, k)))
| (val << H48_SHIFT(i, k));
}
-
-size_t
-gendata_h48_derive(uint8_t h, const unsigned char *fulltable, unsigned char *buf)
-{
- size_t cocsepsize, h48size;
- uint8_t val_full, val_derive;
- const unsigned char *h48full;
- unsigned char *h48derive;
- int64_t i, j, h48max;
- uint64_t bufsize;
- gendata_h48_arg_t arg;
- tableinfo_t cocsepinfo, fulltableinfo;
-
- /* Initializing values in case of error */
- /* TODO cleanup this */
- fulltableinfo.h48h = 11;
- fulltableinfo.bits = 2;
- fulltableinfo.base = 8;
-
- int64_t TODOlarge = 999999999999; /* TODO: cleanup here */
-
- readtableinfo_n(TODOlarge, fulltable, 2, &fulltableinfo);
- arg.h = h;
- arg.k = fulltableinfo.bits;
- arg.maxdepth = 20;
- arg.buf = buf;
- arg.cocsepdata = (uint32_t *)(buf + INFOSIZE);
- arg.base = fulltableinfo.base;
- arg.info = makeinfo_h48k2(&arg);
-
- /* Technically this step is redundant, except that we
- need selfsim and crep */
- cocsepsize = gendata_cocsep(buf, arg.selfsim, arg.crep);
- arg.h48buf = (_Atomic unsigned char *)buf + cocsepsize;
- h48size = H48_TABLESIZE(h, arg.k) + INFOSIZE;
-
- if (buf == NULL)
- goto gendata_h48_derive_return_size;
-
- bufsize = COCSEP_FULLSIZE + INFOSIZE;
- if (readtableinfo(bufsize, buf, &cocsepinfo) != NISSY_OK) {
- LOG("[H48 derive gendata] Error: could not read info for "
- "cocsep table\n");
- goto gendata_h48_derive_error;
- }
-
- cocsepinfo.next = cocsepsize;
- bufsize = COCSEP_FULLSIZE + INFOSIZE;
- if (writetableinfo(&cocsepinfo, bufsize, buf) != NISSY_OK) {
- LOG("[H48 derive gendata] Error: could not write info for "
- "cocsep table with updated 'next' value\n");
- goto gendata_h48_derive_error;
- }
-
- h48full = fulltable + cocsepsize + INFOSIZE;
- h48derive = (unsigned char *)arg.h48buf + INFOSIZE;
- memset(h48derive, 0xFF, H48_TABLESIZE(h, arg.k));
- memset(arg.info.distribution, 0,
- INFO_DISTRIBUTION_LEN * sizeof(uint64_t));
-
- h48max = H48_COORDMAX(fulltableinfo.h48h);
- for (i = 0; i < h48max; i++) {
- if (i % INT64_C(1000000000) == 0 && i > 0)
- LOG("[H48 derive gendata] Processing %" PRId64
- "th coordinate\n", i);
- j = i >> (int64_t)(fulltableinfo.h48h - h);
- val_full = get_h48_pval(h48full, i, arg.k);
- val_derive = get_h48_pval(h48derive, j, arg.k);
- set_h48_pval(
- h48derive, j, arg.k, MIN(val_full, val_derive));
- }
-
- getdistribution(h48derive, arg.info.distribution, &arg.info);
-
- bufsize = arg.buf_size - COCSEP_FULLSIZE - INFOSIZE;
- if (writetableinfo(&arg.info, bufsize, (unsigned char *)arg.h48buf)
- != NISSY_OK) {
- LOG("H48 derive gendata] Error: could not write info "
- "for table\n");
- goto gendata_h48_derive_error;
- }
-
-gendata_h48_derive_return_size:
- return cocsepsize + h48size;
-
-gendata_h48_derive_error:
- return 0;
-}
diff --git a/src/solvers/h48/h48.h b/src/solvers/h48/h48.h
@@ -7,4 +7,5 @@
#include "gendata_cocsep.h"
#include "gendata_eoesep.h"
#include "gendata_h48.h"
+#include "checkdata.h"
#include "solve.h"
diff --git a/tools/000_gendata/gendata.c b/tools/000_gendata/gendata.c
@@ -1,13 +1,10 @@
#include "../tool.h"
-#include "../expected_distributions.h"
char *solver;
-uint64_t *expected;
static void
run(void) {
int64_t size;
- bool consistent, expected;
char filename[1024], dataid[NISSY_SIZE_DATAID];
unsigned char *buf;
@@ -18,20 +15,14 @@ run(void) {
case -2:
goto gendata_run_finish;
default:
- nissy_datainfo(size, buf);
- consistent = nissy_checkdata(size, buf) == 0;
- expected = check_distribution(solver, size, buf);
- if (consistent && expected) {
+ if (nissy_checkdata(solver, size, buf) == NISSY_OK) {
printf("\n");
printf("Generated %" PRId64 " bytes.\n", size);
sprintf(filename, "tables/%s", dataid);
writetable(buf, size, filename);
+ } else {
+ printf("Error: table generated incorrectly!\n");
}
- if (!consistent)
- printf("Error: table is not consistent with info"
- " (nissy_checkdata() failed)\n");
- if (!expected)
- printf("Error: distribution is not as expected\n");
break;
}
@@ -40,8 +31,6 @@ gendata_run_finish:
}
int main(int argc, char **argv) {
- uint8_t h, k;
-
if (argc < 2) {
printf("Error: not enough arguments. "
"A solver must be given.\n");
@@ -49,11 +38,7 @@ int main(int argc, char **argv) {
}
solver = argv[1];
- parse_h48_hk(solver, &h, &k);
- expected = expected_h48[h][k];
-
nissy_setlogger(log_stderr, NULL);
-
timerun(run);
return 0;
diff --git a/tools/001_derive_h48/derive_h48.c b/tools/001_derive_h48/derive_h48.c
@@ -1,40 +0,0 @@
-/*
-This tool is specific to the H48 solver. It can be used to derive small
-intermediate tables from larger tables, including the full h11 table.
-
-When using k=2, the base values for the tables may differ. If you want
-to change this value, for example for generating a table with base = 9
-from the h11 table with base = 10, you must re-generate the large table
-with the correct base value. The easiest way to do so is to manually
-edit the base value in the source code and recompile.
-*/
-
-#include "../tool.h"
-
-char *solver_large, *solver_small, *filename_large, *filename_small;
-
-void run(void) {
- derivedata_run(solver_large, solver_small, filename_large, filename_small);
-}
-
-int main(int argc, char **argv) {
- if (argc < 5) {
- printf("Error: not enough arguments. Required:\n"
- "1. Solver name for large table\n"
- "2. Solver name for derived table\n"
- "3. Filename containing large table\n"
- "4. Filename for saving derived table\n");
- return 1;
- }
-
- solver_large = argv[1];
- solver_small = argv[2];
- filename_large = argv[3];
- filename_small = argv[4];
-
- nissy_setlogger(log_stderr, NULL);
-
- timerun(run);
-
- return 0;
-}
diff --git a/tools/100_checkdata/checkdata.c b/tools/100_checkdata/checkdata.c
@@ -1,11 +1,11 @@
#include "../tool.h"
-#include "../expected_distributions.h"
char *solver, *filename;
static void
run(void) {
- long long int size, sizeread, result;
+ bool result;
+ long long int size, sizeread;
char dataid[NISSY_SIZE_DATAID];
unsigned char *buf;
FILE *f;
@@ -25,10 +25,12 @@ run(void) {
buf = malloc(size);
sizeread = fread(buf, size, 1, f);
fclose(f);
- result = sizeread == 1 && nissy_checkdata(size, buf);
+ if (sizeread != 1)
+ printf("File has unexpected size\n");
+ result = sizeread == 1 && nissy_checkdata(solver, size, buf) == NISSY_OK;
free(buf);
- printf("checkdata %s\n", result == 0 ? "succeeded" : "failed");
+ printf("checkdata %s\n", result ? "succeeded" : "failed");
/* TODO: cross-check with expected distributions? */
}
diff --git a/tools/expected_distributions.h b/tools/expected_distributions.h
@@ -1,267 +0,0 @@
-uint64_t expected_cocsep[21] = {
- [0] = 1,
- [1] = 6,
- [2] = 63,
- [3] = 468,
- [4] = 3068,
- [5] = 15438,
- [6] = 53814,
- [7] = 71352,
- [8] = 8784,
- [9] = 96
-};
-
-uint64_t expected_h48[12][9][21] = {
- [0] = {
- [2] = {
- [0] = 5473562,
- [1] = 34776317,
- [2] = 68566704,
- [3] = 8750867,
- },
- [4] = {
- [0] = 1,
- [1] = 1,
- [2] = 4,
- [3] = 34,
- [4] = 331,
- [5] = 3612,
- [6] = 41605,
- [7] = 474128,
- [8] = 4953846,
- [9] = 34776317,
- [10] = 68566704,
- [11] = 8749194,
- [12] = 1673,
- },
- },
- [1] = {
- [2] = {
- [0] = 6012079,
- [1] = 45822302,
- [2] = 142018732,
- [3] = 41281787,
- },
- },
- [2] = {
- [2] = {
- [0] = 6391286,
- [1] = 55494785,
- [2] = 252389935,
- [3] = 155993794,
- },
- },
- [3] = {
- [2] = {
- [0] = 6686828,
- [1] = 63867852,
- [2] = 392789689,
- [3] = 477195231,
- },
- },
- [4] = {
- [2] = {
- [0] = 77147213,
- [1] = 543379415,
- [2] = 1139570251,
- [3] = 120982321,
- },
- },
- [5] = {
- [2] = {
- [0] = 82471284,
- [1] = 687850732,
- [2] = 2345840746,
- [3] = 645995638,
- },
- },
- [6] = {
- [2] = {
- [0] = 85941099,
- [1] = 804752968,
- [2] = 4077248182,
- [3] = 2556374551,
- },
- },
- [7] = {
- [2] = {
- [0] = 88529761,
- [1] = 897323475,
- [2] = 6126260791,
- [3] = 7936519573,
- },
- },
- [8] = {
- [2] = {
- [0] = 1051579940,
- [1] = 8136021316,
- [2] = 19024479822,
- [3] = 18851861220,
- },
- },
- [9] = {
- [2] = {
- [0] = 1102038189,
- [1] = 9888265242,
- [2] = 38299375805,
- [3] = 10904855164,
- },
- },
- [10] = {
- [2] = {
- [0] = 1133240039,
- [1] = 11196285614,
- [2] = 64164702961,
- [3] = 43894840186,
- },
- },
- [11] = {
- [2] = {
- [0] = 1150763161,
- [1] = 12045845660,
- [2] = 91163433330,
- [3] = 136418095449,
- },
- },
-};
-
-uint64_t expected_eo[21] = {
- [0] = 1,
- [1] = 2,
- [2] = 25,
- [3] = 202,
- [4] = 620,
- [5] = 900,
- [6] = 285,
- [7] = 13,
-};
-
-uint64_t expected_dr[21] = {
- [0] = 1,
- [1] = 1,
- [2] = 5,
- [3] = 44,
- [4] = 487,
- [5] = 5841,
- [6] = 68364,
- [7] = 776568,
- [8] = 7950748,
- [9] = 52098876,
- [10] = 76236234,
- [11] = 3771112,
- [12] = 129,
-};
-
-uint64_t expected_dreo[21] = {
- [0] = 1,
- [1] = 1,
- [2] = 4,
- [3] = 22,
- [4] = 160,
- [5] = 1286,
- [6] = 8550,
- [7] = 42152,
- [8] = 90748,
- [9] = 33466,
- [10] = 757,
-};
-
-static bool
-distribution_equal(const uint64_t *expected, const uint64_t *actual, int n)
-{
- bool equal;
- int i;
-
- for (i = 0, equal = true; i <= n; i++) {
- if (expected[i] != actual[i]) {
- equal = false;
- printf("Wrong value for %d: expected %" PRIu64
- ", actual %" PRIu64 "\n",
- i, expected[i], actual[i]);
- }
- }
-
- return equal;
-}
-
-STATIC bool
-check_table(uint64_t *exp, tableinfo_t *info)
-{
- if (!distribution_equal(exp, info->distribution, info->maxvalue)) {
- printf("ERROR! Distribution is incorrect\n");
- return false;
- }
-
- printf("Distribution is correct\n");
- return true;
-}
-
-static bool
-check_cocsep(size_t data_size, const unsigned char *data)
-{
- tableinfo_t info;
-
- readtableinfo(data_size, data, &info);
- return distribution_equal(
- expected_cocsep, info.distribution, info.maxvalue);
-}
-
-static bool
-unknown_h48(uint8_t h, uint8_t k)
-{
- if (k != 2 && k != 4)
- return true;
-
- if (k == 4 && h != 0)
- return true;
-
- return k == 2 && h > 7;
-}
-
-STATIC bool
-check_distribution(
- const char *solver,
- size_t data_size,
- const unsigned char *data
-)
-{
- const char *str;
- tableinfo_t info = {0};
-
- if (!strncmp(solver, "h48", 3)) {
- readtableinfo(data_size, data, &info);
- if (!distribution_equal(
- expected_cocsep, info.distribution, info.maxvalue)) {
- printf("ERROR! cocsep distribution is incorrect\n");
- return false;
- }
- printf("cocsep distribution is correct\n");
-
- readtableinfo_n(data_size, data, 2, &info);
- if (unknown_h48(info.h48h, info.bits))
- goto check_distribution_unknown;
-
- return check_table(expected_h48[info.h48h][info.bits], &info);
- }
-
- if (!strncmp(solver, "coord_", 6)) {
- readtableinfo(data_size, data, &info);
- if (!strncmp(info.solver, "coord helper table for ", 23))
- readtableinfo_n(data_size, data, 2, &info);
-
- str = info.solver + 22; /* "coordinate solver for COORD" */
- if (!strcmp(str, "EO")) {
- return check_table(expected_eo, &info);
- } else if (!strcmp(str, "DR")) {
- return check_table(expected_dr, &info);
- } else if (!strcmp(str, "DREO")) {
- return check_table(expected_dreo, &info);
- } else {
- goto check_distribution_unknown;
- }
- }
-
-check_distribution_unknown:
- printf("Distribution unknown, not checked\n");
- return true;
-}
diff --git a/tools/nissy_extra.h b/tools/nissy_extra.h
@@ -1,14 +0,0 @@
-/*
-This header file exposes certain functions that are meant to be used
-for testing purposes only.
-*/
-
-#define STATIC static
-#define LOG printf
-
-#include "../src/solvers/tables_types_macros.h"
-#include "../src/solvers/tables.h"
-
-size_t gendata_h48_derive(uint8_t, const unsigned char *, unsigned char *);
-long long parse_h48_hk(const char *, uint8_t [static 1], uint8_t [static 1]);
-long long int nissy_datainfo(uint64_t, const unsigned char *);
diff --git a/tools/tool.h b/tools/tool.h
@@ -7,19 +7,14 @@
#include <string.h>
#include "../src/nissy.h"
-#include "nissy_extra.h"
static void log_stderr(const char *, void *);
static double timerun(void (*)(void));
static void writetable(const unsigned char *, int64_t, const char *);
static long long int generatetable(const char *, unsigned char **,
char [static NISSY_SIZE_DATAID]);
-static long long int derivetable(
- const char *, const char *, const char *, unsigned char **);
static int getdata(const char *, unsigned char **, const char *);
static void gendata_run(const char *, uint64_t[static 21]);
-static void derivedata_run(
- const char *, const char *, const char *, const char *);
static void
log_stderr(const char *str, void *unused)
@@ -100,53 +95,6 @@ generatetable(
return gensize;
}
-static long long int
-derivetable(
- const char *solver_large,
- const char *solver_small,
- const char *filename_large,
- unsigned char **buf
-)
-{
- uint8_t h, k;
- long long int size, gensize;
- char dataid[NISSY_SIZE_DATAID];
- unsigned char *fulltable;
-
- if (getdata(solver_large, &fulltable, filename_large) != 0) {
- printf("Error reading full table.\n");
- gensize = -1;
- goto derivetable_error_nofree;
- }
-
- size = nissy_solverinfo(solver_small, dataid);
- if (size == -1) {
- printf("Error getting table size.\n");
- gensize = -2;
- goto derivetable_error;
- }
-
- if (parse_h48_hk(solver_small, &h, &k) != NISSY_OK) {
- gensize = -3;
- goto derivetable_error;
- }
-
- *buf = malloc(size);
- gensize = gendata_h48_derive(h, fulltable, *buf);
-
- if (gensize != size) {
- printf("Error deriving table\n");
- gensize = -4;
- goto derivetable_error;
- }
-
-derivetable_error:
- free(fulltable);
-
-derivetable_error_nofree:
- return gensize;
-}
-
static int
getdata(
const char *solver,
@@ -206,8 +154,6 @@ gendata_run(
case -2:
goto gendata_run_finish;
default:
- nissy_datainfo(size, buf);
- printf("\n");
printf("Succesfully generated %lld bytes. "
"See above for details on the tables.\n", size);
@@ -219,35 +165,3 @@ gendata_run(
gendata_run_finish:
free(buf);
}
-
-static void
-derivedata_run(
- const char *solver_large,
- const char *solver_small,
- const char *filename_large,
- const char *filename_small
-)
-{
- long long int size;
- unsigned char *buf;
-
- buf = NULL;
- size = derivetable(solver_large, solver_small, filename_large, &buf);
- switch (size) {
- case -1:
- return;
- case -2:
- goto derivedata_run_finish;
- default:
- nissy_datainfo(size, buf);
- printf("\n");
- printf("Succesfully generated %lld bytes. "
- "See above for details on the tables.\n", size);
-
- writetable(buf, size, filename_small);
- break;
- }
-
-derivedata_run_finish:
- free(buf);
-}