commit 1e1fd628207034b0412c50e289f146d34c5baf71
parent bfb7b1ab9d2c85a256c42c006060ffe7c2652638
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Fri, 14 Mar 2025 16:18:29 +0100
Replaced datasize with solverinfo
Diffstat:
14 files changed, 140 insertions(+), 68 deletions(-)
diff --git a/TODO_COORDINATES b/TODO_COORDINATES
@@ -1,4 +1,5 @@
- coord solver
+ - add checkdata for coord
- return to fully qualified solver name
x undo chnages to API
- add a parameter to gendata to get a shortname (filename) for the table
@@ -30,3 +31,4 @@
- refactor common parts of coord and h48 solvers
- move parse_h48 to h48 module?
+ then maybe do like for coordinate and exclude the "h48" part
diff --git a/python/nissy_module.c b/python/nissy_module.c
@@ -219,27 +219,33 @@ getcube(PyObject *self, PyObject *args)
return string_result(err, result);
}
-PyDoc_STRVAR(datasize_doc,
-"datasize(solver)\n"
+PyDoc_STRVAR(solverinfo_doc,
+"solverinfo(solver)\n"
"--\n\n"
-"Returns the size of the data (pruning table) for the given solver\n"
+"Returns the size and the short name of the data for the given solver\n"
"\n"
"Parameters:\n"
" - solver: the name of the solver\n"
"\n"
-"Returns: the size of the data for the solver, in bytes\n"
+"Returns: a pair containing the size and the short name "
+"of the data for the solver, in bytes\n"
);
static PyObject *
-datasize(PyObject *self, PyObject *args)
+solverinfo(PyObject *self, PyObject *args)
{
long long result;
const char *solver;
+ char buf[NISSY_DATAID_SIZE];
+ PyObject *py_result, *py_buf;
if (!PyArg_ParseTuple(args, "s", &solver))
return NULL;
- result = nissy_datasize(solver);
- return long_result(result);
+ result = nissy_solverinfo(solver, buf);
+
+ py_result = PyLong_FromLong(result);
+ py_buf = PyUnicode_FromString(buf);
+ return PyTuple_Pack(2, py_result, py_buf);
}
PyDoc_STRVAR(gendata_doc,
@@ -257,12 +263,12 @@ gendata(PyObject *self, PyObject *args)
{
long long size, err;
const char *solver;
- char *buf;
+ char *buf, dataid[NISSY_DATAID_SIZE];
if (!PyArg_ParseTuple(args, "s", &solver))
return NULL;
- size = nissy_datasize(solver);
+ size = nissy_solverinfo(solver, dataid);
if (!check_error(size))
return NULL;
@@ -394,7 +400,7 @@ static PyMethodDef nissy_methods[] = {
{ "applytrans", applytrans, METH_VARARGS, applytrans_doc },
{ "convert", convert, METH_VARARGS, convert_doc },
{ "getcube", getcube, METH_VARARGS, getcube_doc },
- { "datasize", datasize, METH_VARARGS, datasize_doc },
+ { "solverinfo", solverinfo, METH_VARARGS, solverinfo_doc },
{ "gendata", gendata, METH_VARARGS, gendata_doc },
{ "checkdata", checkdata, METH_VARARGS, checkdata_doc },
{ "solve", solve, METH_VARARGS, solve_doc },
diff --git a/shell/shell.c b/shell/shell.c
@@ -65,7 +65,7 @@ static int64_t applytrans_exec(args_t *);
static int64_t frommoves_exec(args_t *);
static int64_t convert_exec(args_t *);
static int64_t randomcube_exec(args_t *);
-static int64_t datasize_exec(args_t *);
+static int64_t solverinfo_exec(args_t *);
static int64_t gendata_exec(args_t *);
static int64_t solve_exec(args_t *);
static int64_t solve_scramble_exec(args_t *);
@@ -180,11 +180,11 @@ struct {
randomcube_exec
),
COMMAND(
- "datasize",
- "datasize " FLAG_SOLVER " SOLVER",
- "Return the size in bytes of the data table used by "
- "SOLVER when called with the given OPTIONS.",
- datasize_exec
+ "solverinfo",
+ "solverinfo " FLAG_SOLVER " SOLVER",
+ "Return the size in bytes and the id of the data table "
+ "used by SOLVER when called with the given OPTIONS.",
+ solverinfo_exec
),
COMMAND(
"gendata",
@@ -340,14 +340,15 @@ randomcube_exec(args_t *args)
}
static int64_t
-datasize_exec(args_t *args)
+solverinfo_exec(args_t *args)
{
int64_t ret;
+ char buf[NISSY_DATAID_SIZE];
- ret = nissy_datasize(args->str_solver);
+ ret = nissy_solverinfo(args->str_solver, buf);
if (ret < 0)
fprintf(stderr, "Unknown error (make sure solver is valid)\n");
- printf("%" PRId64 "\n", ret);
+ printf("%" PRId64 "\n%s\n", ret, buf);
return ret;
}
@@ -357,14 +358,22 @@ gendata_exec(args_t *args)
{
int i;
FILE *file;
- char *buf, path[MAX_PATH_LENGTH];
+ char *buf, path[MAX_PATH_LENGTH], dataid[NISSY_DATAID_SIZE];
int64_t ret, size;
size_t written;
+ size = nissy_solverinfo(args->str_solver, dataid);
+
+ if (size < 0) {
+ fprintf(stderr, "gendata: unknown solver %s\n",
+ args->str_solver);
+ return -3;
+ }
+
/* TODO: should give warning if overwriting existing file */
for (i = 0; tablepaths[i] != NULL; i++) {
strcpy(path, tablepaths[i]);
- strcat(path, args->str_solver);
+ strcat(path, dataid);
file = fopen(path, "wb");
if (file != NULL)
break;
@@ -376,16 +385,6 @@ gendata_exec(args_t *args)
return -2;
}
- size = nissy_datasize(args->str_solver);
-
- if (size < 0) {
- fprintf(stderr,
- "Unknown error in retrieving data size"
- "(make sure solver is valid)\n");
- fclose(file);
- return -3;
- }
-
buf = malloc(size);
ret = nissy_gendata(args->str_solver, size, buf);
@@ -427,15 +426,24 @@ solve_exec(args_t *args)
uint8_t nissflag;
FILE *file;
char *buf, solutions[SOLUTIONS_BUFFER_SIZE], path[MAX_PATH_LENGTH];
+ char dataid[NISSY_DATAID_SIZE];
long long stats[NISSY_SIZE_SOLVE_STATS];
int64_t ret, gendata_ret, size;
size_t read;
nissflag = NISSY_NISSFLAG_NORMAL; /* TODO: parse str_nisstype */
+ size = nissy_solverinfo(args->str_solver, dataid);
+
+ if (size < 0) {
+ fprintf(stderr, "solve: unknown solver %s\n",
+ args->str_solver);
+ return size;
+ }
+
for (i = 0; tablepaths[i] != NULL; i++) {
strcpy(path, tablepaths[i]);
- strcat(path, args->str_solver);
+ strcat(path, dataid);
file = fopen(path, "rb");
if (file != NULL)
break;
@@ -454,7 +462,7 @@ solve_exec(args_t *args)
if (file == NULL) {
for (i = 0; tablepaths[i] != NULL; i++) {
strcpy(path, tablepaths[i]);
- strcat(path, args->str_solver);
+ strcat(path, dataid);
file = fopen(path, "rb");
if (file != NULL)
break;
@@ -467,7 +475,6 @@ solve_exec(args_t *args)
return -1;
}
- size = nissy_datasize(args->str_solver);
buf = malloc(size);
read = fread(buf, size, 1, file);
fclose(file);
diff --git a/src/nissy.c b/src/nissy.c
@@ -19,6 +19,7 @@ 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(cube_t, char [static NISSY_SIZE_B32]);
STATIC size_t my_strnlen(const char *, size_t);
+STATIC long long nissy_dataid(const char *, char [static NISSY_DATAID_SIZE]);
STATIC long long nissy_gendata_unsafe(
const char *, unsigned long long, char *);
@@ -412,11 +413,37 @@ nissy_datainfo(
return NISSY_OK;
}
+STATIC long long
+nissy_dataid(const char *solver, char dataid[static NISSY_DATAID_SIZE])
+{
+ if (!strncmp(solver, "h48", 3)) {
+ uint8_t h, k;
+ long long err;
+ if ((err = parse_h48_solver(solver, &h, &k)) != NISSY_OK)
+ return err;
+ /* TODO: also check that h and k are admissible */
+ else strcpy(dataid, solver);
+ return err;
+ /* TODO: do this when moved parser */
+ /* return dataid_h48(solver, dataid); */
+ } else if (!strncmp(solver, "coord_", 6)) {
+ return dataid_coord(solver+6, dataid);
+ } else {
+ LOG("gendata: unknown solver %s\n", solver);
+ return NISSY_ERROR_INVALID_SOLVER;
+ }
+}
+
long long
-nissy_datasize(
- const char *solver
+nissy_solverinfo(
+ const char *solver,
+ char dataid[static NISSY_DATAID_SIZE]
)
{
+ long long err;
+ if ((err = nissy_dataid(solver, dataid)) != NISSY_OK)
+ return err;
+
/* gendata() handles a NULL *data as a "dryrun" request */
return nissy_gendata_unsafe(solver, 0, NULL);
}
@@ -447,7 +474,7 @@ nissy_gendata_unsafe(
}
if ((size_t)data % 8 != 0) {
- LOG("nissy_datainfo: buffere is not 8-byte aligned\n");
+ LOG("nissy_gendata: buffere is not 8-byte aligned\n");
return NISSY_ERROR_DATA;
}
@@ -478,7 +505,7 @@ nissy_checkdata(
int64_t err;
if ((size_t)data % 8 != 0) {
- LOG("nissy_datainfo: buffere is not 8-byte aligned\n");
+ LOG("nissy_checkdata: buffere is not 8-byte aligned\n");
return NISSY_ERROR_DATA;
}
@@ -560,7 +587,7 @@ nissy_solve(
}
if ((size_t)data % 8 != 0) {
- LOG("nissy_datainfo: buffere is not 8-byte aligned\n");
+ LOG("nissy_solve: buffere is not 8-byte aligned\n");
return NISSY_ERROR_DATA;
}
diff --git a/src/nissy.h b/src/nissy.h
@@ -25,6 +25,7 @@ for example 'rotation UF' or 'mirrored BL'.
#define NISSY_SIZE_H48 88U
#define NISSY_SIZE_TRANSFORMATION 12U
#define NISSY_SIZE_SOLVE_STATS 10U
+#define NISSY_DATAID_SIZE 255U
/* Flags for NISS options */
#define NISSY_NISSFLAG_NORMAL 1U
@@ -191,11 +192,15 @@ nissy_getcube(
);
/*
-Compute the size of the data generated by nissy_gendata, when called with
-the same parameters, or -1 in case of error.
+Compute the size of the data generated by nissy_gendata when called for
+the given solver, and other useful information.
Parameters:
solver - The name of the solver.
+ dataid - An identifier for the data computed for the solver. Different
+ solver may use equivalent data. This identifier can be used
+ e.g. as a filename or database key to save and retrieve the
+ correct data for each solver, without duplication.
Return values:
NISSY_ERROR_INVALID_SOLVER - The given solver is not known.
@@ -204,8 +209,9 @@ Return values:
Any value >= 0 - The size of the data, in bytes.
*/
long long
-nissy_datasize(
- const char *solver
+nissy_solverinfo(
+ const char *solver,
+ char dataid[static NISSY_DATAID_SIZE]
);
/*
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h
@@ -7,6 +7,7 @@ STATIC void append_coord_name(const coord_t *, char *);
STATIC coord_t *parse_coord(const char *, int);
STATIC uint8_t parse_axis(const char *, int);
STATIC void parse_coord_and_axis(const char *, int, coord_t **, uint8_t *);
+STATIC int64_t dataid_coord(const char *, char [static NISSY_DATAID_SIZE]);
STATIC void
append_coord_name(const coord_t *coord, char *str)
@@ -61,3 +62,20 @@ parse_coord_and_axis(const char *str, int n, coord_t **coord, uint8_t *axis)
if (axis != NULL)
*axis = i == n ? UINT8_ERROR : parse_axis(str+i+1, n-i-1);
}
+
+STATIC int64_t
+dataid_coord(const char *ca, char dataid[static NISSY_DATAID_SIZE])
+{
+ coord_t *c;
+
+ parse_coord_and_axis(ca, strlen(ca), &c, NULL);
+
+ if (c == NULL) {
+ LOG("dataid_coord: cannot parse coordinate from '%s'\n", ca);
+ return NISSY_ERROR_INVALID_SOLVER;
+ }
+
+ strcpy(dataid, c->name);
+
+ return NISSY_OK;
+}
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
@@ -3,7 +3,7 @@
#define COORD_MASK(i) (UINT8_C(0xF) << COORD_SHIFT(i))
typedef struct {
- char name[255];
+ const char name[255];
uint64_t (*coord)(cube_t, const void *);
cube_t (*cube)(uint64_t, const void *);
size_t (*gendata)(void *);
diff --git a/tools/000_gendata/gendata.c b/tools/000_gendata/gendata.c
@@ -8,9 +8,9 @@ static void
run(void) {
int64_t size;
bool consistent, expected;
- char *buf, filename[1024];
+ char *buf, filename[1024], dataid[NISSY_DATAID_SIZE];
- size = generatetable(solver, &buf);
+ size = generatetable(solver, &buf, dataid);
switch (size) {
case -1:
return;
@@ -23,7 +23,7 @@ run(void) {
if (consistent && expected) {
printf("\n");
printf("Generated %" PRId64 " bytes.\n", size);
- sprintf(filename, "tables/%s", solver);
+ sprintf(filename, "tables/%s", dataid);
writetable(buf, size, filename);
}
if (!consistent)
diff --git a/tools/100_checkdata/checkdata.c b/tools/100_checkdata/checkdata.c
@@ -6,13 +6,13 @@ char *solver, *filename;
static void
run(void) {
long long int size, result;
- char *buf;
+ char *buf, dataid[NISSY_DATAID_SIZE];
FILE *f;
- size = nissy_datasize(solver);
+ size = nissy_solverinfo(solver, dataid);
if (size <= 0) {
- printf("Error in datasize\n");
+ printf("Error in solverinfo\n");
return;
}
diff --git a/tools/300_solve_small/solve_small.c b/tools/300_solve_small/solve_small.c
@@ -46,7 +46,7 @@ void run(void) {
}
int main(int argc, char **argv) {
- char filename[255];
+ char filename[255], dataid[NISSY_DATAID_SIZE];
if (argc < 2) {
printf("Error: not enough arguments. "
@@ -63,7 +63,7 @@ int main(int argc, char **argv) {
if (getdata(solver, &buf, filename) != 0)
return 1;
- size = nissy_datasize(solver);
+ size = nissy_solverinfo(solver, dataid);
timerun(run);
diff --git a/tools/301_solve_file/solve_file.c b/tools/301_solve_file/solve_file.c
@@ -33,7 +33,7 @@ void run(void) {
}
int main(int argc, char **argv) {
- char filename[255], *scrfilename;
+ char filename[255], dataid[NISSY_DATAID_SIZE], *scrfilename;
FILE *scrfile;
if (argc < 3) {
@@ -52,7 +52,7 @@ int main(int argc, char **argv) {
if (getdata(solver, &buf, filename) != 0)
return 1;
- size = nissy_datasize(solver);
+ size = nissy_solverinfo(solver, dataid);
if ((scrfile = fopen(scrfilename, "r")) == NULL) {
printf("Error: could not read given file '%s'.\n",
diff --git a/tools/302_solve_multisol/solve_multisol.c b/tools/302_solve_multisol/solve_multisol.c
@@ -39,7 +39,7 @@ void run(void) {
}
int main(int argc, char **argv) {
- char filename[255];
+ char filename[255], dataid[NISSY_DATAID_SIZE];
if (argc < 3) {
printf("Error: not enough arguments. "
@@ -57,7 +57,7 @@ int main(int argc, char **argv) {
if (getdata(solver, &buf, filename) != 0)
return 1;
- size = nissy_datasize(solver);
+ size = nissy_solverinfo(solver, dataid);
timerun(run);
diff --git a/tools/400_solvetest/solve_test.c b/tools/400_solvetest/solve_test.c
@@ -94,7 +94,7 @@ void run(void) {
}
int main(int argc, char **argv) {
- char filename[255];
+ char filename[255], dataid[NISSY_DATAID_SIZE];
if (argc < 2) {
printf("Error: not enough arguments. "
@@ -110,7 +110,7 @@ int main(int argc, char **argv) {
if (getdata(solver, &buf, filename) != 0)
return 1;
- size = nissy_datasize(solver);
+ size = nissy_solverinfo(solver, dataid);
timerun(run);
diff --git a/tools/tool.h b/tools/tool.h
@@ -13,7 +13,8 @@ static void log_stderr(const char *, ...);
static void log_stdout(const char *, ...);
static double timerun(void (*)(void));
static void writetable(const char *, int64_t, const char *);
-static long long int generatetable(const char *, char **);
+static long long int generatetable(const char *, char **,
+ char [static NISSY_DATAID_SIZE]);
static long long int derivetable(
const char *, const char *, const char *, char **);
static int getdata(const char *, char **, const char *);
@@ -86,11 +87,15 @@ writetable(const char *buf, int64_t size, const char *filename)
}
static long long int
-generatetable(const char *solver, char **buf)
+generatetable(
+ const char *solver,
+ char **buf,
+ char dataid[static NISSY_DATAID_SIZE]
+)
{
long long int size, gensize;
- size = nissy_datasize(solver);
+ size = nissy_solverinfo(solver, dataid);
if (size < 0) {
printf("Error getting table size.\n");
return -1;
@@ -120,7 +125,7 @@ derivetable(
{
uint8_t h, k;
long long int size, gensize;
- char *fulltable;
+ char *fulltable, dataid[NISSY_DATAID_SIZE];
if (getdata(solver_large, &fulltable, filename_large) != 0) {
printf("Error reading full table.\n");
@@ -128,7 +133,7 @@ derivetable(
goto derivetable_error_nofree;
}
- size = nissy_datasize(solver_small);
+ size = nissy_solverinfo(solver_small, dataid);
if (size == -1) {
printf("Error getting table size.\n");
gensize = -2;
@@ -164,10 +169,11 @@ getdata(
) {
long long int size, sizeread;
FILE *f;
+ char dataid[NISSY_DATAID_SIZE];
if ((f = fopen(filename, "rb")) == NULL) {
printf("Table file not found, generating it.\n");
- size = generatetable(solver, buf);
+ size = generatetable(solver, buf, dataid);
switch (size) {
case -1:
goto getdata_error_nofree;
@@ -179,7 +185,7 @@ getdata(
}
} else {
printf("Reading tables from file %s\n", filename);
- size = nissy_datasize(solver);
+ size = nissy_solverinfo(solver, dataid);
*buf = malloc(size);
sizeread = fread(*buf, size, 1, f);
fclose(f);
@@ -203,10 +209,10 @@ gendata_run(
uint64_t expected[static 21]
) {
long long int size;
- char *buf, filename[1024];
+ char *buf, filename[1024], dataid[NISSY_DATAID_SIZE];
- sprintf(filename, "tables/%s", solver);
- size = generatetable(solver, &buf);
+ size = generatetable(solver, &buf, dataid);
+ sprintf(filename, "tables/%s", dataid);
switch (size) {
case -1:
return;