From 818186b480d7c05e0c58ff89da2180f5b2476434 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Thu, 26 Sep 2024 14:59:11 +0200 Subject: Added TOOLARGS and simplified gendata tool(s) --- .gitignore | 1 + README.md | 22 ++++-- src/nissy.c | 4 +- tools/0002_gendata_h48h0k2/gendata_h48h0k2.c | 21 ------ tools/0004_gendata_h48h0k4/gendata_h48h0k4.c | 29 -------- tools/0012_gendata_h48h1k2/gendata_h48h1k2.c | 21 ------ tools/0022_gendata_h48h2k2/gendata_h48h2k2.c | 21 ------ tools/0032_gendata_h48h3k2/gendata_h48h3k2.c | 21 ------ tools/0042_gendata_h48h4k2/gendata_h48h4k2.c | 21 ------ tools/0052_gendata_h48h5k2/gendata_h48h5k2.c | 21 ------ tools/0062_gendata_h48h6k2/gendata_h48h6k2.c | 21 ------ tools/0072_gendata_h48h7k2/gendata_h48h7k2.c | 21 ------ tools/0082_gendata_h48h8k2/gendata_h48h8k2.c | 21 ------ tools/0092_gendata_h48h9k2/gendata_h48h9k2.c | 21 ------ tools/0102_gendata_h48h10k2/gendata_h48h10k2.c | 21 ------ tools/0112_gendata_h48h11k2/gendata_h48h11k2.c | 21 ------ tools/100_gendata/gendata.c | 80 +++++++++++++++++++++ tools/100_stats_tables_h48/stats_tables_h48.c | 99 -------------------------- tools/200_solve_small/solve_small.c | 53 -------------- tools/200_stats_tables_h48/stats_tables_h48.c | 99 ++++++++++++++++++++++++++ tools/300_solve_small/solve_small.c | 53 ++++++++++++++ tools/nissy_extra.h | 3 + tools/run_tool.sh | 5 +- tools/tool.h | 20 ++++-- 24 files changed, 274 insertions(+), 446 deletions(-) delete mode 100644 tools/0002_gendata_h48h0k2/gendata_h48h0k2.c delete mode 100644 tools/0004_gendata_h48h0k4/gendata_h48h0k4.c delete mode 100644 tools/0012_gendata_h48h1k2/gendata_h48h1k2.c delete mode 100644 tools/0022_gendata_h48h2k2/gendata_h48h2k2.c delete mode 100644 tools/0032_gendata_h48h3k2/gendata_h48h3k2.c delete mode 100644 tools/0042_gendata_h48h4k2/gendata_h48h4k2.c delete mode 100644 tools/0052_gendata_h48h5k2/gendata_h48h5k2.c delete mode 100644 tools/0062_gendata_h48h6k2/gendata_h48h6k2.c delete mode 100644 tools/0072_gendata_h48h7k2/gendata_h48h7k2.c delete mode 100644 tools/0082_gendata_h48h8k2/gendata_h48h8k2.c delete mode 100644 tools/0092_gendata_h48h9k2/gendata_h48h9k2.c delete mode 100644 tools/0102_gendata_h48h10k2/gendata_h48h10k2.c delete mode 100644 tools/0112_gendata_h48h11k2/gendata_h48h11k2.c create mode 100644 tools/100_gendata/gendata.c delete mode 100644 tools/100_stats_tables_h48/stats_tables_h48.c delete mode 100644 tools/200_solve_small/solve_small.c create mode 100644 tools/200_stats_tables_h48/stats_tables_h48.c create mode 100644 tools/300_solve_small/solve_small.c create mode 100644 tools/nissy_extra.h diff --git a/.gitignore b/.gitignore index fd603d5..e9a1741 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ test/*/runtest test/run test/run.DSYM run.DSYM +run.core test/last.* tools/results .vscode diff --git a/README.md b/README.md index 09b5881..9ecd744 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ The results of the last test case run is saved in test/last.out (standard output, the results compared with the .out files) and test/last.err (standard error). -Tests are always run in "debug mode": this means that optimizations are +Tests are always run in debug mode: this means that optimizations are disabled and some extra logging is enabled. See the test folder and test/test.sh for details. @@ -70,7 +70,7 @@ See the test folder and test/test.sh for details. In the tools folder there are some small programs that test various functionality of the H48 library. They work similarly to test, but they -are not run in debug mode. +are not run in debug mode by default. To run a tool you must select it with the environment variable `TOOL`. For example the command: @@ -79,14 +79,26 @@ For example the command: TOOL=stats make tool ``` -Will run the stats_tables_h48 tool. Like for tests, the value of the -`TOOL` variable can be any regular expression matching the name of the -tool. Unlike tests, one and only one tool will be selected for each run. +Will run the stats_tables_h48 tool. + +To pass some arguments to a tool, use the `TOOLARGS` variable: + +``` +TOOL=gendata TOOLARGS="h48 0;2;20" make tool +``` + +Like for tests, the value of the `TOOL` variable can be any regular +expression matching the name of the tool. Unlike tests, one and +only one tool will be selected for each run. The content of the +`TOOLARGS` variable is used directly as command line arguments for +the chosen tool. Each tool run is automatically timed, so these tools can be used as benchmark. The output as well as the time of the run are saved to a file in the tools/results folder. +To build and run a tool in debug mode, use `make debugtool`. + ## Running commands manually This project also includes a rudimentary shell that can be used to run diff --git a/src/nissy.c b/src/nissy.c index 6bc4aea..318cff1 100644 --- a/src/nissy.c +++ b/src/nissy.c @@ -11,7 +11,7 @@ #include "nissy.h" -STATIC int parse_h48_options(const char *, uint8_t *, uint8_t *, uint8_t *); +int parse_h48_options(const char *, uint8_t *, uint8_t *, uint8_t *); STATIC int64_t write_result(cube_t, char [static 22]); /* TODO: add option to get DR, maybe C-only, E-only, eo... */ @@ -24,7 +24,7 @@ struct { GETCUBE_OPTIONS(NULL, NULL) }; -STATIC int +int parse_h48_options(const char *buf, uint8_t *h, uint8_t *k, uint8_t *maxdepth) { bool h_valid, k_valid, maxdepth_valid; diff --git a/tools/0002_gendata_h48h0k2/gendata_h48h0k2.c b/tools/0002_gendata_h48h0k2/gendata_h48h0k2.c deleted file mode 100644 index 14f99ee..0000000 --- a/tools/0002_gendata_h48h0k2/gendata_h48h0k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 5473562, - [1] = 34776317, - [2] = 68566704, - [3] = 8750867, -}; - -void run(void) { - gendata_run("h48", "0;2;20", "tables/h48h0k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 0, k = 2"); - - return 0; -} diff --git a/tools/0004_gendata_h48h0k4/gendata_h48h0k4.c b/tools/0004_gendata_h48h0k4/gendata_h48h0k4.c deleted file mode 100644 index ff34bb9..0000000 --- a/tools/0004_gendata_h48h0k4/gendata_h48h0k4.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - [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, -}; - -void run(void) { - gendata_run("h48", "0;4;20", "tables/h48h0k4", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 0, k = 4"); - - return 0; -} diff --git a/tools/0012_gendata_h48h1k2/gendata_h48h1k2.c b/tools/0012_gendata_h48h1k2/gendata_h48h1k2.c deleted file mode 100644 index 0ebdcaa..0000000 --- a/tools/0012_gendata_h48h1k2/gendata_h48h1k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "1;2;20", "tables/h48h1k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 1, k = 2"); - - return 0; -} diff --git a/tools/0022_gendata_h48h2k2/gendata_h48h2k2.c b/tools/0022_gendata_h48h2k2/gendata_h48h2k2.c deleted file mode 100644 index f437e98..0000000 --- a/tools/0022_gendata_h48h2k2/gendata_h48h2k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "2;2;20", "tables/h48h2k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 2, k = 2"); - - return 0; -} diff --git a/tools/0032_gendata_h48h3k2/gendata_h48h3k2.c b/tools/0032_gendata_h48h3k2/gendata_h48h3k2.c deleted file mode 100644 index 2e0eab5..0000000 --- a/tools/0032_gendata_h48h3k2/gendata_h48h3k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "3;2;20", "tables/h48h3k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 3, k = 2"); - - return 0; -} diff --git a/tools/0042_gendata_h48h4k2/gendata_h48h4k2.c b/tools/0042_gendata_h48h4k2/gendata_h48h4k2.c deleted file mode 100644 index 868c360..0000000 --- a/tools/0042_gendata_h48h4k2/gendata_h48h4k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "4;2;20", "tables/h48h4k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 4, k = 2"); - - return 0; -} diff --git a/tools/0052_gendata_h48h5k2/gendata_h48h5k2.c b/tools/0052_gendata_h48h5k2/gendata_h48h5k2.c deleted file mode 100644 index d292d49..0000000 --- a/tools/0052_gendata_h48h5k2/gendata_h48h5k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "5;2;20", "tables/h48h5k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 5, k = 2"); - - return 0; -} diff --git a/tools/0062_gendata_h48h6k2/gendata_h48h6k2.c b/tools/0062_gendata_h48h6k2/gendata_h48h6k2.c deleted file mode 100644 index 910d514..0000000 --- a/tools/0062_gendata_h48h6k2/gendata_h48h6k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "6;2;20", "tables/h48h6k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 6, k = 2"); - - return 0; -} diff --git a/tools/0072_gendata_h48h7k2/gendata_h48h7k2.c b/tools/0072_gendata_h48h7k2/gendata_h48h7k2.c deleted file mode 100644 index b803328..0000000 --- a/tools/0072_gendata_h48h7k2/gendata_h48h7k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "7;2;20", "tables/h48h7k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 7, k = 2"); - - return 0; -} diff --git a/tools/0082_gendata_h48h8k2/gendata_h48h8k2.c b/tools/0082_gendata_h48h8k2/gendata_h48h8k2.c deleted file mode 100644 index 52c377a..0000000 --- a/tools/0082_gendata_h48h8k2/gendata_h48h8k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "8;2;20", "tables/h48h8k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 8, k = 2"); - - return 0; -} diff --git a/tools/0092_gendata_h48h9k2/gendata_h48h9k2.c b/tools/0092_gendata_h48h9k2/gendata_h48h9k2.c deleted file mode 100644 index 5d3e34a..0000000 --- a/tools/0092_gendata_h48h9k2/gendata_h48h9k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "9;2;20", "tables/h48h9k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 9, k = 2"); - - return 0; -} diff --git a/tools/0102_gendata_h48h10k2/gendata_h48h10k2.c b/tools/0102_gendata_h48h10k2/gendata_h48h10k2.c deleted file mode 100644 index 5e8fbb0..0000000 --- a/tools/0102_gendata_h48h10k2/gendata_h48h10k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "10;2;20", "tables/h48h10k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 10, k = 2"); - - return 0; -} diff --git a/tools/0112_gendata_h48h11k2/gendata_h48h11k2.c b/tools/0112_gendata_h48h11k2/gendata_h48h11k2.c deleted file mode 100644 index 00c0747..0000000 --- a/tools/0112_gendata_h48h11k2/gendata_h48h11k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 0, /* Unknown */ - [1] = 0, /* Unknown */ - [2] = 0, /* Unknown */ - [3] = 0, /* Unknown */ -}; - -void run(void) { - gendata_run("h48", "11;2;20", "tables/h48h11k2", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark gendata_h48 h = 11, k = 2"); - - return 0; -} diff --git a/tools/100_gendata/gendata.c b/tools/100_gendata/gendata.c new file mode 100644 index 0000000..78f81ab --- /dev/null +++ b/tools/100_gendata/gendata.c @@ -0,0 +1,80 @@ +#include "../tool.h" + +char *solver, *options; +uint64_t *expected; + +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, + }, + }, +}; + +static void +run(void) { + int64_t size; + char *buf, filename[1024]; + + getfilename(solver, options, filename); + size = generatetable(solver, options, &buf); + switch (size) { + case -1: + return; + case -2: + goto gendata_run_finish; + default: + nissy_datainfo(buf, write_stdout); + printf("\n"); + printf("Succesfully generated %" PRId64 " bytes. " + "See above for details on the tables.\n", size); + + writetable(buf, size, filename); + break; + } + +gendata_run_finish: + free(buf); +} + +int main(int argc, char **argv) { + uint8_t h, k; + char description[256]; + + if (argc < 3) { + fprintf(stderr, "Error: not enough arguments." + "A solver and its options must be given.\n"); + return 1; + } + + solver = argv[1]; + options = argv[2]; + parse_h48_options(options, &h, &k, NULL); + expected = expected_h48[h][k]; + sprintf(description, "benchmark gendata_h48 h = %" PRIu8 + ", k = %" PRIu8 "", h, k); + + nissy_setlogger(log_stderr); + + timerun(run, description); + + return 0; +} diff --git a/tools/100_stats_tables_h48/stats_tables_h48.c b/tools/100_stats_tables_h48/stats_tables_h48.c deleted file mode 100644 index adac8fa..0000000 --- a/tools/100_stats_tables_h48/stats_tables_h48.c +++ /dev/null @@ -1,99 +0,0 @@ -#include - -#include "../tool.h" - -#define MAXMOVES 20 -#define NCUBES_PER_THREAD 10000 -#define LOG_EVERY (NCUBES_PER_THREAD / 10) - -const char *solver = "h48stats"; -const char *options = ""; -const char *filename = "tables/h48h0k4"; -char *buf; - -typedef struct { - int n; - int thread_id; - int64_t v[12][100]; -} thread_arg_t; - -uint64_t rand64(void) { - uint64_t i, ret; - - for (i = 0, ret = 0; i < 64; i++) - ret |= (uint64_t)(rand() % 2) << i; - - return ret; -} - -static void * -run_thread(void *arg) -{ - char sols[12], cube[22]; - int64_t ep, eo, cp, co; - int i, j; - - thread_arg_t *a = (thread_arg_t *)arg; - - for (i = 0; i < a->n; i++) { - ep = rand64(); - eo = rand64(); - cp = rand64(); - co = rand64(); - nissy_getcube(ep, eo, cp, co, "fix", cube); - nissy_solve(cube, "h48stats", "", "", - 0, MAXMOVES, 1, -1, buf, sols); - for (j = 0; j < 12; j++) - a->v[j][(int)sols[j]]++; - if ((i+1) % LOG_EVERY == 0) - fprintf(stderr, "[thread %d] %d cubes solved...\n", - a->thread_id, i+1); - } - - return NULL; -} - -void run(void) { - int64_t i, j, k, tot; - double avg; - pthread_t thread[THREADS]; - thread_arg_t arg[THREADS]; - - for (i = 0; i < THREADS; i++) { - arg[i] = (thread_arg_t) { - .thread_id = i, - .n = NCUBES_PER_THREAD, - .v = {{0}} - }; - pthread_create(&thread[i], NULL, run_thread, &arg[i]); - } - - for (i = 0; i < THREADS; i++) - pthread_join(thread[i], NULL); - - for (j = 0; j < 12; j++) { - printf("Data for h=%" PRId64 "\n", j); - for (k = 0, avg = 0.0; k < 16; k++) { - for (i = 0, tot = 0; i < THREADS; i++) - tot += arg[i].v[j][k]; - printf("%" PRId64 "\t%" PRId64 "\n", k, tot); - avg += tot * k; - } - avg /= (double)(NCUBES_PER_THREAD * THREADS); - printf("Average: %.4lf\n", avg); - printf("\n"); - } -} - -int main(void) { - srand(time(NULL)); - nissy_setlogger(log_stderr); - - if (getdata(solver, options, &buf, filename) != 0) - return 1; - - timerun(run, "h48 table stats"); - - free(buf); - return 0; -} diff --git a/tools/200_solve_small/solve_small.c b/tools/200_solve_small/solve_small.c deleted file mode 100644 index 4d07728..0000000 --- a/tools/200_solve_small/solve_small.c +++ /dev/null @@ -1,53 +0,0 @@ -#include - -#include "../tool.h" - -const char *solver = "h48"; -const char *options = "0;4;20"; -const char *filename = "tables/h48h0k4"; -char *buf; - -char *scrambles[] = { - "R D' R2 D R U2 R' D' R U2 R D R'", /* 12 optimal */ - "RLUD RLUD RLUD", /* 12 optimal */ - NULL -}; - -void run(void) { - int i; - int64_t n; - char sol[100], cube[22]; - - printf("Solved the following scrambles:\n\n"); - for (i = 0; scrambles[i] != NULL; i++) { - printf("%d. %s\n", i+1, scrambles[i]); - fprintf(stderr, "Solving scramble %s\n", scrambles[i]); - if (nissy_frommoves(scrambles[i], cube) == -1) { - fprintf(stderr, "Invalid scramble\n"); - printf("Invalid\n"); - continue; - } - n = nissy_solve( - cube, "h48", options, "", 0, 20, 1, -1, buf, sol); - if (n == 0) { - printf("No solution\n"); - fprintf(stderr, "No solution found\n"); - } else { - printf("Solutions:\n%s\n", sol); - } - } -} - -int main(void) { - - srand(time(NULL)); - nissy_setlogger(log_stderr); - - if (getdata(solver, options, &buf, filename) != 0) - return 1; - - timerun(run, "small solver benchmark"); - - free(buf); - return 0; -} diff --git a/tools/200_stats_tables_h48/stats_tables_h48.c b/tools/200_stats_tables_h48/stats_tables_h48.c new file mode 100644 index 0000000..adac8fa --- /dev/null +++ b/tools/200_stats_tables_h48/stats_tables_h48.c @@ -0,0 +1,99 @@ +#include + +#include "../tool.h" + +#define MAXMOVES 20 +#define NCUBES_PER_THREAD 10000 +#define LOG_EVERY (NCUBES_PER_THREAD / 10) + +const char *solver = "h48stats"; +const char *options = ""; +const char *filename = "tables/h48h0k4"; +char *buf; + +typedef struct { + int n; + int thread_id; + int64_t v[12][100]; +} thread_arg_t; + +uint64_t rand64(void) { + uint64_t i, ret; + + for (i = 0, ret = 0; i < 64; i++) + ret |= (uint64_t)(rand() % 2) << i; + + return ret; +} + +static void * +run_thread(void *arg) +{ + char sols[12], cube[22]; + int64_t ep, eo, cp, co; + int i, j; + + thread_arg_t *a = (thread_arg_t *)arg; + + for (i = 0; i < a->n; i++) { + ep = rand64(); + eo = rand64(); + cp = rand64(); + co = rand64(); + nissy_getcube(ep, eo, cp, co, "fix", cube); + nissy_solve(cube, "h48stats", "", "", + 0, MAXMOVES, 1, -1, buf, sols); + for (j = 0; j < 12; j++) + a->v[j][(int)sols[j]]++; + if ((i+1) % LOG_EVERY == 0) + fprintf(stderr, "[thread %d] %d cubes solved...\n", + a->thread_id, i+1); + } + + return NULL; +} + +void run(void) { + int64_t i, j, k, tot; + double avg; + pthread_t thread[THREADS]; + thread_arg_t arg[THREADS]; + + for (i = 0; i < THREADS; i++) { + arg[i] = (thread_arg_t) { + .thread_id = i, + .n = NCUBES_PER_THREAD, + .v = {{0}} + }; + pthread_create(&thread[i], NULL, run_thread, &arg[i]); + } + + for (i = 0; i < THREADS; i++) + pthread_join(thread[i], NULL); + + for (j = 0; j < 12; j++) { + printf("Data for h=%" PRId64 "\n", j); + for (k = 0, avg = 0.0; k < 16; k++) { + for (i = 0, tot = 0; i < THREADS; i++) + tot += arg[i].v[j][k]; + printf("%" PRId64 "\t%" PRId64 "\n", k, tot); + avg += tot * k; + } + avg /= (double)(NCUBES_PER_THREAD * THREADS); + printf("Average: %.4lf\n", avg); + printf("\n"); + } +} + +int main(void) { + srand(time(NULL)); + nissy_setlogger(log_stderr); + + if (getdata(solver, options, &buf, filename) != 0) + return 1; + + timerun(run, "h48 table stats"); + + free(buf); + return 0; +} diff --git a/tools/300_solve_small/solve_small.c b/tools/300_solve_small/solve_small.c new file mode 100644 index 0000000..4d07728 --- /dev/null +++ b/tools/300_solve_small/solve_small.c @@ -0,0 +1,53 @@ +#include + +#include "../tool.h" + +const char *solver = "h48"; +const char *options = "0;4;20"; +const char *filename = "tables/h48h0k4"; +char *buf; + +char *scrambles[] = { + "R D' R2 D R U2 R' D' R U2 R D R'", /* 12 optimal */ + "RLUD RLUD RLUD", /* 12 optimal */ + NULL +}; + +void run(void) { + int i; + int64_t n; + char sol[100], cube[22]; + + printf("Solved the following scrambles:\n\n"); + for (i = 0; scrambles[i] != NULL; i++) { + printf("%d. %s\n", i+1, scrambles[i]); + fprintf(stderr, "Solving scramble %s\n", scrambles[i]); + if (nissy_frommoves(scrambles[i], cube) == -1) { + fprintf(stderr, "Invalid scramble\n"); + printf("Invalid\n"); + continue; + } + n = nissy_solve( + cube, "h48", options, "", 0, 20, 1, -1, buf, sol); + if (n == 0) { + printf("No solution\n"); + fprintf(stderr, "No solution found\n"); + } else { + printf("Solutions:\n%s\n", sol); + } + } +} + +int main(void) { + + srand(time(NULL)); + nissy_setlogger(log_stderr); + + if (getdata(solver, options, &buf, filename) != 0) + return 1; + + timerun(run, "small solver benchmark"); + + free(buf); + return 0; +} diff --git a/tools/nissy_extra.h b/tools/nissy_extra.h new file mode 100644 index 0000000..17906d4 --- /dev/null +++ b/tools/nissy_extra.h @@ -0,0 +1,3 @@ +/* Intended only for tools */ + +int parse_h48_options(const char *, uint8_t *, uint8_t *, uint8_t *); diff --git a/tools/run_tool.sh b/tools/run_tool.sh index 7e09684..2216a66 100755 --- a/tools/run_tool.sh +++ b/tools/run_tool.sh @@ -5,7 +5,7 @@ if [ -z "$TOOL" ]; then exit 1 fi -CC="$CC -D_POSIX_C_SOURCE=199309L" +CC="$CC -D_POSIX_C_SOURCE=199309L" # For timer BIN="tools/run" d="$(date +'%Y-%m-%d-%H-%M-%S')" @@ -16,7 +16,8 @@ for t in tools/*; do fi toolname="$(basename "$t" .c)" $CC -o $BIN "$t"/*.c "$CUBEOBJ" || exit 1; - $BIN | tee "tools/results/$toolname-$d.txt" "tools/results/last.out" + $BIN $TOOLARGS \ + | tee "tools/results/$toolname-$d.txt" "tools/results/last.out" break done diff --git a/tools/tool.h b/tools/tool.h index 757657b..1540f22 100644 --- a/tools/tool.h +++ b/tools/tool.h @@ -6,14 +6,16 @@ #include #include "../src/nissy.h" +#include "nissy_extra.h" static void log_stderr(const char *, ...); static void log_stdout(const char *, ...); static double timerun(void (*)(void), const char *); +static void getfilename(const char *, const char *, char *); static void writetable(const char *, int64_t, const char *); static int64_t generatetable(const char *, const char *, char **); static int getdata(const char *, const char *, char **, const char *); -static void gendata_run(const char *, const char *, const char *, uint64_t[static 21]); +static void gendata_run(const char *, const char *, uint64_t *); static void log_stderr(const char *str, ...) @@ -69,6 +71,17 @@ timerun(void (*run)(void), const char *name) return tdiff; } +static void +getfilename(const char *solver, const char *options, char *filename) +{ + uint8_t h, k; + + /* Only h48 supported for now */ + parse_h48_options(options, &h, &k, NULL); + + sprintf(filename, "tables/%sh%dk%d", solver, h, k); +} + static void writetable(const char *buf, int64_t size, const char *filename) { @@ -155,13 +168,12 @@ static void gendata_run( const char *solver, const char *options, - const char *filename, /* TODO: remove filename, use solver name */ uint64_t expected[static 21] ) { int64_t size; - char *buf; + char *buf, filename[1024]; - + getfilename(solver, options, filename); size = generatetable(solver, options, &buf); switch (size) { case -1: -- cgit v1.3 From bc2cba8529a163d129dec91b5ec448a29a14591a Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Thu, 26 Sep 2024 15:57:25 +0200 Subject: Added checkdata function --- src/nissy.c | 63 +++++++++++++++++++++++++++++++ src/nissy.h | 6 +++ src/solvers/h48/gendata_cocsep.h | 12 ++++++ src/solvers/h48/gendata_h48.h | 24 +++++++++++- tools/000_gendata/gendata.c | 80 ++++++++++++++++++++++++++++++++++++++++ tools/100_gendata/gendata.c | 80 ---------------------------------------- 6 files changed, 184 insertions(+), 81 deletions(-) create mode 100644 tools/000_gendata/gendata.c delete mode 100644 tools/100_gendata/gendata.c diff --git a/src/nissy.c b/src/nissy.c index 318cff1..27e2835 100644 --- a/src/nissy.c +++ b/src/nissy.c @@ -13,6 +13,9 @@ int parse_h48_options(const char *, uint8_t *, uint8_t *, uint8_t *); STATIC int64_t write_result(cube_t, char [static 22]); +STATIC bool distribution_equal( + const uint64_t [static 21], const uint64_t [static 21], uint8_t); +STATIC bool checkdata(const void *, const tableinfo_t *); /* TODO: add option to get DR, maybe C-only, E-only, eo... */ #define GETCUBE_OPTIONS(S, F) { .option = S, .fix = F } @@ -62,6 +65,49 @@ parse_h48_options_error: return -1; } +STATIC bool +checkdata(const void *buf, const tableinfo_t *info) +{ + uint64_t distr[21]; + + if (!strncmp(info->solver, "cocsep", 6)) { + getdistribution_cocsep( + (uint32_t *)((char *)buf + INFOSIZE), distr); + } else if (!strncmp(info->solver, "h48", 3)) { + getdistribution_h48((uint8_t *)buf + INFOSIZE, distr, + info->h48h, info->bits); + } else { + LOG("checkdata: unknown solver %s\n", info->solver); + return false; + } + + return distribution_equal(info->distribution, distr, info->maxvalue); +} + +STATIC bool +distribution_equal( + const uint64_t expected[static 21], + const uint64_t actual[static 21], + uint8_t maxvalue +) +{ + int wrong; + uint8_t i; + + for (i = 0, wrong = 0; i <= MAX(maxvalue, 20); i++) { + if (expected[i] != actual[i]) { + wrong++; + LOG("Value %" PRIu8 ": expected %" PRIu64 ", found %" + PRIu64 "\n", i, expected[i], actual[i]); + } + } + + if (wrong > 0) + LOG("chekdata: %d wrong values\n", wrong); + + return wrong > 0; +} + STATIC int64_t write_result(cube_t cube, char result[static 22]) { @@ -274,6 +320,23 @@ nissy_gendata( return ret; } +int64_t +nissy_checkdata( + const char *solver, + const char *options, + const void *data +) +{ + char *buf; + tableinfo_t info; + + for (buf = (char *)data; readtableinfo(buf, &info); buf += info.next) + if (!checkdata(buf, &info)) + return 1; + + return 0; +} + int64_t nissy_solve( const char cube[static 22], diff --git a/src/nissy.h b/src/nissy.h index 336130c..e8c35c3 100644 --- a/src/nissy.h +++ b/src/nissy.h @@ -86,6 +86,12 @@ int64_t nissy_gendata( void *generated_data ); +int64_t nissy_checkdata( + const char *solver, + const char *options, + const void *data +); + /* Print information on a data table via the provided callback writer */ int64_t nissy_datainfo( const void *table, diff --git a/src/solvers/h48/gendata_cocsep.h b/src/solvers/h48/gendata_cocsep.h index 2189145..262793b 100644 --- a/src/solvers/h48/gendata_cocsep.h +++ b/src/solvers/h48/gendata_cocsep.h @@ -25,6 +25,7 @@ STATIC_INLINE void set_visited(uint8_t *, int64_t); STATIC size_t gendata_cocsep(void *, uint64_t *, cube_t *); STATIC uint32_t gendata_cocsep_dfs(cocsep_dfs_arg_t *); +STATIC void getdistribution_cocsep(const uint32_t *, uint64_t [static 21]); STATIC_INLINE int8_t get_h48_cdata(cube_t, uint32_t *, uint32_t *); @@ -157,6 +158,17 @@ gendata_cocsep_dfs(cocsep_dfs_arg_t *arg) return cc; } +STATIC void +getdistribution_cocsep(const uint32_t *table, uint64_t distr[static 21]) +{ + size_t i; + + memset(distr, 0, 21 * sizeof(uint64_t)); + + for (i = 0; i < COCSEP_TABLESIZE; i++) + distr[CBOUND(table[i])]++; +} + STATIC_INLINE bool get_visited(const uint8_t *a, int64_t i) { diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index 3445570..6e7b0ca 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h @@ -104,13 +104,16 @@ STATIC size_t gendata_h48k2_realcoord(gendata_h48_arg_t *); STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); STATIC void * gendata_h48k2_runthread(void *); STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *, uint8_t); +STATIC void getdistribution_h48( + const uint8_t *, uint64_t [static 21], uint8_t, uint8_t); STATIC uint32_t *get_cocsepdata_ptr(const void *); STATIC uint8_t *get_h48data_ptr(const void *); STATIC_INLINE uint8_t get_h48_pval(const uint8_t *, int64_t, uint8_t); STATIC_INLINE void set_h48_pval(uint8_t *, int64_t, uint8_t, uint8_t); -STATIC_INLINE uint8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint8_t, uint8_t *); +STATIC_INLINE uint8_t get_h48_bound( + cube_t, uint32_t, uint8_t, uint8_t, uint8_t *); STATIC uint64_t gendata_h48short(gendata_h48short_arg_t *arg) @@ -662,6 +665,25 @@ makeinfo_h48k2(gendata_h48_arg_t *arg, uint8_t base) return info; } +STATIC void +getdistribution_h48( + const uint8_t *table, + uint64_t distr[static 21], + uint8_t h, + uint8_t k +) { + uint8_t val; + int64_t i, h48max; + + memset(distr, 0, 21 * sizeof(uint64_t)); + + h48max = H48_COORDMAX(h); + for (i = 0; i < h48max; i++) { + val = get_h48_pval(table, i, k); + distr[val]++; + } +} + STATIC uint32_t * get_cocsepdata_ptr(const void *data) { diff --git a/tools/000_gendata/gendata.c b/tools/000_gendata/gendata.c new file mode 100644 index 0000000..78f81ab --- /dev/null +++ b/tools/000_gendata/gendata.c @@ -0,0 +1,80 @@ +#include "../tool.h" + +char *solver, *options; +uint64_t *expected; + +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, + }, + }, +}; + +static void +run(void) { + int64_t size; + char *buf, filename[1024]; + + getfilename(solver, options, filename); + size = generatetable(solver, options, &buf); + switch (size) { + case -1: + return; + case -2: + goto gendata_run_finish; + default: + nissy_datainfo(buf, write_stdout); + printf("\n"); + printf("Succesfully generated %" PRId64 " bytes. " + "See above for details on the tables.\n", size); + + writetable(buf, size, filename); + break; + } + +gendata_run_finish: + free(buf); +} + +int main(int argc, char **argv) { + uint8_t h, k; + char description[256]; + + if (argc < 3) { + fprintf(stderr, "Error: not enough arguments." + "A solver and its options must be given.\n"); + return 1; + } + + solver = argv[1]; + options = argv[2]; + parse_h48_options(options, &h, &k, NULL); + expected = expected_h48[h][k]; + sprintf(description, "benchmark gendata_h48 h = %" PRIu8 + ", k = %" PRIu8 "", h, k); + + nissy_setlogger(log_stderr); + + timerun(run, description); + + return 0; +} diff --git a/tools/100_gendata/gendata.c b/tools/100_gendata/gendata.c deleted file mode 100644 index 78f81ab..0000000 --- a/tools/100_gendata/gendata.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "../tool.h" - -char *solver, *options; -uint64_t *expected; - -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, - }, - }, -}; - -static void -run(void) { - int64_t size; - char *buf, filename[1024]; - - getfilename(solver, options, filename); - size = generatetable(solver, options, &buf); - switch (size) { - case -1: - return; - case -2: - goto gendata_run_finish; - default: - nissy_datainfo(buf, write_stdout); - printf("\n"); - printf("Succesfully generated %" PRId64 " bytes. " - "See above for details on the tables.\n", size); - - writetable(buf, size, filename); - break; - } - -gendata_run_finish: - free(buf); -} - -int main(int argc, char **argv) { - uint8_t h, k; - char description[256]; - - if (argc < 3) { - fprintf(stderr, "Error: not enough arguments." - "A solver and its options must be given.\n"); - return 1; - } - - solver = argv[1]; - options = argv[2]; - parse_h48_options(options, &h, &k, NULL); - expected = expected_h48[h][k]; - sprintf(description, "benchmark gendata_h48 h = %" PRIu8 - ", k = %" PRIu8 "", h, k); - - nissy_setlogger(log_stderr); - - timerun(run, description); - - return 0; -} -- cgit v1.3 From 91f912176045fd2f95fd45a0e12354e390dff219 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Thu, 26 Sep 2024 17:07:02 +0200 Subject: Added checkdata tool --- src/nissy.c | 7 ++++-- tools/000_gendata/gendata.c | 29 ++--------------------- tools/100_checkdata/checkdata.c | 52 +++++++++++++++++++++++++++++++++++++++++ tools/expected_distributions.h | 25 ++++++++++++++++++++ 4 files changed, 84 insertions(+), 29 deletions(-) create mode 100644 tools/100_checkdata/checkdata.c create mode 100644 tools/expected_distributions.h diff --git a/src/nissy.c b/src/nissy.c index 27e2835..953471f 100644 --- a/src/nissy.c +++ b/src/nissy.c @@ -102,8 +102,11 @@ distribution_equal( } } - if (wrong > 0) - LOG("chekdata: %d wrong values\n", wrong); + if (wrong > 0) { + LOG("checkdata: %d wrong values\n", wrong); + } else { + LOG("checkdata: table is consistent with info\n"); + } return wrong > 0; } diff --git a/tools/000_gendata/gendata.c b/tools/000_gendata/gendata.c index 78f81ab..90166dd 100644 --- a/tools/000_gendata/gendata.c +++ b/tools/000_gendata/gendata.c @@ -1,34 +1,9 @@ #include "../tool.h" +#include "../expected_distributions.h" char *solver, *options; uint64_t *expected; -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, - }, - }, -}; - static void run(void) { int64_t size; @@ -60,7 +35,7 @@ int main(int argc, char **argv) { char description[256]; if (argc < 3) { - fprintf(stderr, "Error: not enough arguments." + fprintf(stderr, "Error: not enough arguments. " "A solver and its options must be given.\n"); return 1; } diff --git a/tools/100_checkdata/checkdata.c b/tools/100_checkdata/checkdata.c new file mode 100644 index 0000000..05961c1 --- /dev/null +++ b/tools/100_checkdata/checkdata.c @@ -0,0 +1,52 @@ +#include "../tool.h" +#include "../expected_distributions.h" + +char *solver, *options, *filename; + +static void +run(void) { + int64_t size; + char *buf; + FILE *f; + + size = nissy_datasize(solver, options); + + if (size <= 0) { + fprintf(stderr, "Error in datasize\n"); + return; + } + + if ((f = fopen(filename, "rb")) == NULL) { + fprintf(stderr, "Error reading file %s\n", filename); + return; + } + + buf = malloc(size); + fread(buf, size, 1, f); + fclose(f); + nissy_checkdata(solver, options, buf); + free(buf); + + /* TODO: cross-check with expected distributions? */ +} + +int main(int argc, char **argv) { + char description[256]; + + if (argc < 4) { + fprintf(stderr, "Error: not enough arguments. " + "A solver, its options and a file name must be given.\n"); + return 1; + } + + solver = argv[1]; + options = argv[2]; + filename = argv[3]; + sprintf(description, "checking data for solver %s" + "with options %s from file %s", solver, options, filename); + nissy_setlogger(log_stderr); + + timerun(run, description); + + return 0; +} diff --git a/tools/expected_distributions.h b/tools/expected_distributions.h new file mode 100644 index 0000000..27bd64a --- /dev/null +++ b/tools/expected_distributions.h @@ -0,0 +1,25 @@ +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, + }, + }, +}; -- cgit v1.3 From 191a85f8e0dc0c812a08d81b32cf319f23247e24 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Thu, 26 Sep 2024 18:38:00 +0200 Subject: I'm stupid --- test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c b/test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c index 41ab10a..c37de3e 100644 --- a/test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c +++ b/test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c @@ -24,6 +24,7 @@ typedef struct { typedef struct { uint8_t h; uint8_t k; + uint8_t base; uint8_t maxdepth; tableinfo_t info; void *buf; -- cgit v1.3 From 79500f46632ba50b1640d16983942b940dd7955f Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Thu, 26 Sep 2024 19:07:10 +0200 Subject: small fix --- tools/tool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tool.h b/tools/tool.h index 1540f22..18b8ce9 100644 --- a/tools/tool.h +++ b/tools/tool.h @@ -15,7 +15,7 @@ static void getfilename(const char *, const char *, char *); static void writetable(const char *, int64_t, const char *); static int64_t generatetable(const char *, const char *, char **); static int getdata(const char *, const char *, char **, const char *); -static void gendata_run(const char *, const char *, uint64_t *); +static void gendata_run(const char *, const char *, uint64_t [static 21]); static void log_stderr(const char *str, ...) -- cgit v1.3 From 0b32395de2500ad87e15fbb0ff4a852e313037e9 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Fri, 27 Sep 2024 08:19:53 +0200 Subject: First try for derive tables --- src/nissy.h | 7 +++ src/solvers/h48/gendata_h48.h | 95 +++++++++++++++++++++++++++--- tools/1002_derive_h48h0k2/derive_h48h0k2.c | 21 +++++++ tools/nissy_extra.h | 6 ++ tools/tool.h | 64 ++++++++++++++++++++ 5 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 tools/1002_derive_h48h0k2/derive_h48h0k2.c create mode 100644 tools/nissy_extra.h diff --git a/src/nissy.h b/src/nissy.h index 336130c..63e7a90 100644 --- a/src/nissy.h +++ b/src/nissy.h @@ -86,6 +86,13 @@ int64_t nissy_gendata( void *generated_data ); +/* Temporarily added to test h48 intermediate tables */ +int64_t nissy_derivedata( + const char *options, + const void *fulltable, + void *generated_data +); + /* Print information on a data table via the provided callback writer */ int64_t nissy_datainfo( const void *table, diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index 3445570..a88eb4f 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h @@ -103,7 +103,7 @@ STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, int8_t, h48k2_dfs_arg_t *); STATIC size_t gendata_h48k2_realcoord(gendata_h48_arg_t *); STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); STATIC void * gendata_h48k2_runthread(void *); -STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *, uint8_t); +STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *); STATIC uint32_t *get_cocsepdata_ptr(const void *); STATIC uint8_t *get_h48data_ptr(const void *); @@ -112,6 +112,8 @@ STATIC_INLINE uint8_t get_h48_pval(const uint8_t *, int64_t, uint8_t); STATIC_INLINE void set_h48_pval(uint8_t *, int64_t, uint8_t, uint8_t); STATIC_INLINE uint8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint8_t, uint8_t *); +size_t gendata_h48_derive(uint8_t, const void *, void *); + STATIC uint64_t gendata_h48short(gendata_h48short_arg_t *arg) { @@ -387,7 +389,7 @@ gendata_h48k2(gendata_h48_arg_t *arg) [11] = 10 }; - uint8_t t, selectedbase, *table; + uint8_t t, *table; int64_t j; uint64_t i, ii, inext, count; h48map_t shortcubes; @@ -414,8 +416,9 @@ gendata_h48k2(gendata_h48_arg_t *arg) }; gendata_h48short(&shortarg); - selectedbase = arg->base < 20 ? arg->base : base[arg->h]; - arg->info = makeinfo_h48k2(arg, selectedbase); + if (arg->base >= 20) + arg->base = base[arg->h]; + arg->info = makeinfo_h48k2(arg); inext = count = 0; pthread_mutex_init(&shortcubes_mutex, NULL); @@ -425,7 +428,7 @@ gendata_h48k2(gendata_h48_arg_t *arg) dfsarg[i] = (h48k2_dfs_arg_t){ .h = arg->h, .k = arg->k, - .base = selectedbase, + .base = arg->base, .shortdepth = shortdepth, .cocsepdata = arg->cocsepdata, .table = table, @@ -637,7 +640,7 @@ gendata_h48k2_realcoord_runthread(void *arg) } STATIC tableinfo_t -makeinfo_h48k2(gendata_h48_arg_t *arg, uint8_t base) +makeinfo_h48k2(gendata_h48_arg_t *arg) { tableinfo_t info; @@ -651,7 +654,7 @@ makeinfo_h48k2(gendata_h48_arg_t *arg, uint8_t base) .classes = 0, .h48h = arg->h, .bits = 2, - .base = base, + .base = arg->base, .maxvalue = 3, .next = 0, }; @@ -695,3 +698,81 @@ get_h48_bound(cube_t cube, uint32_t cdata, uint8_t h, uint8_t k, uint8_t *table) coord = coord_h48_edges(cube, COCLASS(cdata), TTREP(cdata), h); return get_h48_pval(table, coord, k); } + +size_t +gendata_h48_derive(uint8_t h, const void *fulltable, void *buf) +{ + size_t cocsepsize, h48size; + uint8_t val_full, val_derive, val_new, *h48full, *h48derive; + int64_t i, j, h48max; + gendata_h48_arg_t arg; + tableinfo_t cocsepinfo, fulltableinfo; + + /* Initializing values in case of error */ + fulltableinfo.bits = 2; + fulltableinfo.base = 8; + + readtableinfo_n(fulltable, 2, &fulltableinfo); + arg.h = h; + arg.k = fulltableinfo.bits; + arg.maxdepth = 20; + arg.buf = buf; + arg.cocsepdata = (uint32_t *)((char *)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 = (char *)buf + cocsepsize; + h48size = H48_TABLESIZE(h, arg.k) + INFOSIZE; + + if (buf == NULL) + goto gendata_h48_derive_return_size; + + if (!readtableinfo(buf, &cocsepinfo)) { + LOG("gendata_h48: could not read info for cocsep table\n"); + goto gendata_h48_derive_error; + } + + cocsepinfo.next = cocsepsize; + if (!writetableinfo(&cocsepinfo, buf)) { + LOG("gendata_h48_derive: could not write info for cocsep table" + " with updated 'next' value\n"); + goto gendata_h48_derive_error; + } + + h48full = (uint8_t *)fulltable + INFOSIZE; + h48derive = (uint8_t *)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(11); + for (i = 0; i < h48max; i++) { + if (i % INT64_C(1000000000) == 0) + LOG("Processing %" PRId64 "th coordinate\n", i); + j = i >> (int64_t)(11-h); + val_full = get_h48_pval(h48full, i, arg.k); + val_derive = get_h48_pval(h48derive, j, arg.k); + val_new = MIN(val_full, val_derive); + set_h48_pval(h48derive, j, arg.k, val_new); + } + + h48max = H48_COORDMAX(h); + for (i = 0; i < h48max; i++) { + val_derive = get_h48_pval(h48derive, i, arg.k); + arg.info.distribution[val_derive]++; + } + + if (!writetableinfo(&arg.info, buf)) { + LOG("gendata_h48_derive: 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/tools/1002_derive_h48h0k2/derive_h48h0k2.c b/tools/1002_derive_h48h0k2/derive_h48h0k2.c new file mode 100644 index 0000000..73fab2e --- /dev/null +++ b/tools/1002_derive_h48h0k2/derive_h48h0k2.c @@ -0,0 +1,21 @@ +#include "../tool.h" + +uint64_t expected[21] = { + /* Base value is 8 */ + [0] = 5473562, + [1] = 34776317, + [2] = 68566704, + [3] = 8750867, +}; + +void run(void) { + derivedata_run(0, "tables/h48h0k2_derived", expected); +} + +int main(void) { + nissy_setlogger(log_stderr); + + timerun(run, "benchmark derivedata_h48 h = 0, k = 2"); + + return 0; +} diff --git a/tools/nissy_extra.h b/tools/nissy_extra.h new file mode 100644 index 0000000..4294c24 --- /dev/null +++ b/tools/nissy_extra.h @@ -0,0 +1,6 @@ +/* +This header file exposes certain functions that are meant to be used +for testing purposes only. +*/ + +size_t gendata_h48_derive(uint8_t, const void *, void *); diff --git a/tools/tool.h b/tools/tool.h index 757657b..59407b6 100644 --- a/tools/tool.h +++ b/tools/tool.h @@ -6,14 +6,17 @@ #include #include "../src/nissy.h" +#include "nissy_extra.h" static void log_stderr(const char *, ...); static void log_stdout(const char *, ...); static double timerun(void (*)(void), const char *); static void writetable(const char *, int64_t, const char *); static int64_t generatetable(const char *, const char *, char **); +static int64_t derivetable(uint8_t, char **); static int getdata(const char *, const char *, char **, const char *); static void gendata_run(const char *, const char *, const char *, uint64_t[static 21]); +static void derivedata_run(uint8_t, const char *, uint64_t[static 21]); static void log_stderr(const char *str, ...) @@ -109,6 +112,41 @@ generatetable(const char *solver, const char *options, char **buf) return gensize; } +static int64_t +derivetable(uint8_t h, char **buf) +{ + int64_t size, gensize; + char *fulltable; + + char options[20] = " ;2;20"; /* Fixed for k = 2 for now */ + options[0] = (char)(h + '0'); /* h = 10 not supported for now */ + + /* Support only b8 for now */ + if (getdata("h48", "11;2;20", &fulltable, "tables/h48h11k2_b8") != 0) { + printf("Error reading full table.\n"); + return -1; + } + + size = nissy_datasize("h48", options); + if (size == -1) { + printf("Error getting table size.\n"); + free(fulltable); + return -1; + } + + *buf = malloc(size); + gensize = gendata_h48_derive(h, fulltable, *buf); + + if (gensize != size) { + fprintf(stderr, "Error deriving table\n"); + free(fulltable); + return -2; + } + + free(fulltable); + return gensize; +} + static int getdata( const char *solver, @@ -182,3 +220,29 @@ gendata_run( gendata_run_finish: free(buf); } + +static void +derivedata_run(uint8_t h, const char *filename, uint64_t expected[static 21]) +{ + int64_t size; + char *buf; + + size = derivetable(h, &buf); + switch (size) { + case -1: + return; + case -2: + goto derivedata_run_finish; + default: + nissy_datainfo(buf, write_stdout); + printf("\n"); + printf("Succesfully generated %" PRId64 " bytes. " + "See above for details on the tables.\n", size); + + writetable(buf, size, filename); + break; + } + +derivedata_run_finish: + free(buf); +} -- cgit v1.3 From 388b55b4ea644aa1b6074a70652b8f62e7755280 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Fri, 27 Sep 2024 09:11:00 +0200 Subject: Use constant instead of magic number --- src/nissy.c | 10 +++++----- src/solvers/h48/gendata_h48.h | 20 ++++++++------------ tools/001_derive_h48h0k2/derive_h48h0k2.c | 21 +++++++++++++++++++++ tools/1002_derive_h48h0k2/derive_h48h0k2.c | 21 --------------------- tools/tool.h | 2 +- 5 files changed, 35 insertions(+), 39 deletions(-) create mode 100644 tools/001_derive_h48h0k2/derive_h48h0k2.c delete mode 100644 tools/1002_derive_h48h0k2/derive_h48h0k2.c diff --git a/src/nissy.c b/src/nissy.c index 953471f..2eed1b5 100644 --- a/src/nissy.c +++ b/src/nissy.c @@ -13,8 +13,8 @@ int parse_h48_options(const char *, uint8_t *, uint8_t *, uint8_t *); STATIC int64_t write_result(cube_t, char [static 22]); -STATIC bool distribution_equal( - const uint64_t [static 21], const uint64_t [static 21], uint8_t); +STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN], + const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t); STATIC bool checkdata(const void *, const tableinfo_t *); /* TODO: add option to get DR, maybe C-only, E-only, eo... */ @@ -68,7 +68,7 @@ parse_h48_options_error: STATIC bool checkdata(const void *buf, const tableinfo_t *info) { - uint64_t distr[21]; + uint64_t distr[INFO_DISTRIBUTION_LEN]; if (!strncmp(info->solver, "cocsep", 6)) { getdistribution_cocsep( @@ -86,8 +86,8 @@ checkdata(const void *buf, const tableinfo_t *info) STATIC bool distribution_equal( - const uint64_t expected[static 21], - const uint64_t actual[static 21], + const uint64_t expected[static INFO_DISTRIBUTION_LEN], + const uint64_t actual[static INFO_DISTRIBUTION_LEN], uint8_t maxvalue ) { diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index 48d5582..b1ae38c 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h @@ -104,8 +104,8 @@ STATIC size_t gendata_h48k2_realcoord(gendata_h48_arg_t *); STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); STATIC void * gendata_h48k2_runthread(void *); STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *); -STATIC void getdistribution_h48( - const uint8_t *, uint64_t [static 21], uint8_t, uint8_t); +STATIC void getdistribution_h48(const uint8_t *, + uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t); STATIC uint32_t *get_cocsepdata_ptr(const void *); STATIC uint8_t *get_h48data_ptr(const void *); @@ -671,14 +671,14 @@ makeinfo_h48k2(gendata_h48_arg_t *arg) STATIC void getdistribution_h48( const uint8_t *table, - uint64_t distr[static 21], + uint64_t distr[static INFO_DISTRIBUTION_LEN], uint8_t h, uint8_t k ) { uint8_t val; int64_t i, h48max; - memset(distr, 0, 21 * sizeof(uint64_t)); + memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); h48max = H48_COORDMAX(h); for (i = 0; i < h48max; i++) { @@ -725,12 +725,13 @@ size_t gendata_h48_derive(uint8_t h, const void *fulltable, void *buf) { size_t cocsepsize, h48size; - uint8_t val_full, val_derive, val_new, *h48full, *h48derive; + uint8_t val_full, val_derive, *h48full, *h48derive; int64_t i, j, h48max; gendata_h48_arg_t arg; tableinfo_t cocsepinfo, fulltableinfo; /* Initializing values in case of error */ + /* TODO cleanup this */ fulltableinfo.bits = 2; fulltableinfo.base = 8; @@ -777,15 +778,10 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf) j = i >> (int64_t)(11-h); val_full = get_h48_pval(h48full, i, arg.k); val_derive = get_h48_pval(h48derive, j, arg.k); - val_new = MIN(val_full, val_derive); - set_h48_pval(h48derive, j, arg.k, val_new); + set_h48_pval(h48derive, j, arg.k, MIN(val_full, val_derive)); } - h48max = H48_COORDMAX(h); - for (i = 0; i < h48max; i++) { - val_derive = get_h48_pval(h48derive, i, arg.k); - arg.info.distribution[val_derive]++; - } + getdistribution_h48(h48derive, arg.info.distribution, h, arg.k); if (!writetableinfo(&arg.info, buf)) { LOG("gendata_h48_derive: could not write info for table\n"); diff --git a/tools/001_derive_h48h0k2/derive_h48h0k2.c b/tools/001_derive_h48h0k2/derive_h48h0k2.c new file mode 100644 index 0000000..73fab2e --- /dev/null +++ b/tools/001_derive_h48h0k2/derive_h48h0k2.c @@ -0,0 +1,21 @@ +#include "../tool.h" + +uint64_t expected[21] = { + /* Base value is 8 */ + [0] = 5473562, + [1] = 34776317, + [2] = 68566704, + [3] = 8750867, +}; + +void run(void) { + derivedata_run(0, "tables/h48h0k2_derived", expected); +} + +int main(void) { + nissy_setlogger(log_stderr); + + timerun(run, "benchmark derivedata_h48 h = 0, k = 2"); + + return 0; +} diff --git a/tools/1002_derive_h48h0k2/derive_h48h0k2.c b/tools/1002_derive_h48h0k2/derive_h48h0k2.c deleted file mode 100644 index 73fab2e..0000000 --- a/tools/1002_derive_h48h0k2/derive_h48h0k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 5473562, - [1] = 34776317, - [2] = 68566704, - [3] = 8750867, -}; - -void run(void) { - derivedata_run(0, "tables/h48h0k2_derived", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark derivedata_h48 h = 0, k = 2"); - - return 0; -} diff --git a/tools/tool.h b/tools/tool.h index 5eec318..d9071fb 100644 --- a/tools/tool.h +++ b/tools/tool.h @@ -130,7 +130,7 @@ derivetable(uint8_t h, char **buf) int64_t size, gensize; char *fulltable; - char options[20] = " ;2;20"; /* Fixed for k = 2 for now */ + char options[20] = " ;2;20"; /* Only for k = 2 for now */ options[0] = (char)(h + '0'); /* h = 10 not supported for now */ /* Support only b8 for now */ -- cgit v1.3 From 5c22df4e8600d49983f008f22e942a2dd120ad9a Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Fri, 27 Sep 2024 09:11:55 +0200 Subject: Fixed checkdata --- src/nissy.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/nissy.c b/src/nissy.c index 953471f..08cacf0 100644 --- a/src/nissy.c +++ b/src/nissy.c @@ -333,9 +333,12 @@ nissy_checkdata( char *buf; tableinfo_t info; - for (buf = (char *)data; readtableinfo(buf, &info); buf += info.next) + for (buf = (char *)data; readtableinfo(buf, &info); buf += info.next) { if (!checkdata(buf, &info)) return 1; + if (info.next == 0) + break; + } return 0; } -- cgit v1.3 From 41be2d294e5b6f55d485d635065096f274bc89c1 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Fri, 27 Sep 2024 16:37:55 +0200 Subject: Made table derivation tool more flexible So apparently my RAM is broken. That took me a while to figure out. While I get a replacement, I have to restrict myself to a weaker test for the intermediate tables: instead of deriving them from the huge table and checking that they are the same, I have to derive a small h0k2 table from the intermediate ones and check that it is correct. This is not a 100% proof of correctness, but it is good enough (and much faster). --- src/solvers/h48/gendata_h48.h | 19 ++++++++++-------- tools/001_derive_h48/derive_h48.c | 33 +++++++++++++++++++++++++++++++ tools/001_derive_h48h0k2/derive_h48h0k2.c | 21 -------------------- tools/expected_distributions.h | 8 ++++++++ tools/tool.h | 33 ++++++++++++++++++++----------- 5 files changed, 73 insertions(+), 41 deletions(-) create mode 100644 tools/001_derive_h48/derive_h48.c delete mode 100644 tools/001_derive_h48h0k2/derive_h48h0k2.c diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index b1ae38c..d7f4c92 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h @@ -389,7 +389,7 @@ gendata_h48k2(gendata_h48_arg_t *arg) [8] = 10, [9] = 10, [10] = 10, - [11] = 10 + [11] = 8 }; uint8_t t, *table; @@ -609,14 +609,17 @@ STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg) { uint64_t val; - int64_t coord; + int64_t coord, mutex; int8_t oldval; if (arg->h == 0 || arg->h == 11) { /* We are in the "real coordinate" case, we can stop if this coordinate has already been visited */ coord = coord_h48(cube, arg->cocsepdata, arg->h); + mutex = H48_INDEX(coord, arg->k) % CHUNKS; + pthread_mutex_lock(arg->table_mutex[mutex]); oldval = get_h48_pval(arg->table, coord, arg->k); + pthread_mutex_unlock(arg->table_mutex[mutex]); return oldval <= depth; } else { /* With 0 < k < 11 we do not have a "real coordinate". @@ -747,7 +750,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf) /* Technically this step is redundant, except that we need selfsim and crep */ cocsepsize = gendata_cocsep(buf, arg.selfsim, arg.crep); - arg.h48buf = (char *)buf + cocsepsize; + arg.h48buf = (uint8_t *)buf + cocsepsize; h48size = H48_TABLESIZE(h, arg.k) + INFOSIZE; if (buf == NULL) @@ -765,17 +768,17 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf) goto gendata_h48_derive_error; } - h48full = (uint8_t *)fulltable + INFOSIZE; + h48full = (uint8_t *)fulltable + cocsepsize + INFOSIZE; h48derive = (uint8_t *)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(11); + h48max = H48_COORDMAX(fulltableinfo.h48h); for (i = 0; i < h48max; i++) { - if (i % INT64_C(1000000000) == 0) + if (i % INT64_C(1000000000) == 0 && i > 0) LOG("Processing %" PRId64 "th coordinate\n", i); - j = i >> (int64_t)(11-h); + 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)); @@ -783,7 +786,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf) getdistribution_h48(h48derive, arg.info.distribution, h, arg.k); - if (!writetableinfo(&arg.info, buf)) { + if (!writetableinfo(&arg.info, arg.h48buf)) { LOG("gendata_h48_derive: could not write info for table\n"); goto gendata_h48_derive_error; } diff --git a/tools/001_derive_h48/derive_h48.c b/tools/001_derive_h48/derive_h48.c new file mode 100644 index 0000000..3c7f8cc --- /dev/null +++ b/tools/001_derive_h48/derive_h48.c @@ -0,0 +1,33 @@ +#include "../tool.h" + +char *opts_large, *opts_small, *filename_large, *filename_small; + +void run(void) { + derivedata_run(opts_large, opts_small, filename_large, filename_small); +} + +int main(int argc, char **argv) { + char description[256]; + + if (argc < 5) { + fprintf(stderr, + "Error: not enough arguments. Required:\n" + "1. Options for large table\n" + "2. Options for derived table\n" + "3. Filename containing large table\n" + "4. Filename for saving derived table\n"); + return 1; + } + + opts_large = argv[1]; + opts_small = argv[2]; + filename_large = argv[3]; + filename_small = argv[4]; + sprintf(description, "deriving %s from %s\n", opts_small, opts_large); + + nissy_setlogger(log_stderr); + + timerun(run, description); + + return 0; +} diff --git a/tools/001_derive_h48h0k2/derive_h48h0k2.c b/tools/001_derive_h48h0k2/derive_h48h0k2.c deleted file mode 100644 index 73fab2e..0000000 --- a/tools/001_derive_h48h0k2/derive_h48h0k2.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../tool.h" - -uint64_t expected[21] = { - /* Base value is 8 */ - [0] = 5473562, - [1] = 34776317, - [2] = 68566704, - [3] = 8750867, -}; - -void run(void) { - derivedata_run(0, "tables/h48h0k2_derived", expected); -} - -int main(void) { - nissy_setlogger(log_stderr); - - timerun(run, "benchmark derivedata_h48 h = 0, k = 2"); - - return 0; -} diff --git a/tools/expected_distributions.h b/tools/expected_distributions.h index 27bd64a..535cab2 100644 --- a/tools/expected_distributions.h +++ b/tools/expected_distributions.h @@ -22,4 +22,12 @@ uint64_t expected_h48[12][9][21] = { [12] = 1673, }, }, + [1] = { + [2] = { + [0] = 6012079, + [1] = 45822302, + [2] = 142018732, + [3] = 41281787, + }, + }, }; diff --git a/tools/tool.h b/tools/tool.h index d9071fb..c44828d 100644 --- a/tools/tool.h +++ b/tools/tool.h @@ -14,10 +14,11 @@ static double timerun(void (*)(void), const char *); static void getfilename(const char *, const char *, char *); static void writetable(const char *, int64_t, const char *); static int64_t generatetable(const char *, const char *, char **); -static int64_t derivetable(uint8_t, char **); +static int64_t derivetable(const char *, const char *, const char *, char **); static int getdata(const char *, const char *, char **, const char *); static void gendata_run(const char *, const char *, uint64_t[static 21]); -static void derivedata_run(uint8_t, 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, ...) @@ -125,27 +126,30 @@ generatetable(const char *solver, const char *options, char **buf) } static int64_t -derivetable(uint8_t h, char **buf) +derivetable( + const char *opts_large, + const char *opts_small, + const char *filename_large, + char **buf +) { + uint8_t h; int64_t size, gensize; char *fulltable; - char options[20] = " ;2;20"; /* Only for k = 2 for now */ - options[0] = (char)(h + '0'); /* h = 10 not supported for now */ - - /* Support only b8 for now */ - if (getdata("h48", "11;2;20", &fulltable, "tables/h48h11k2_b8") != 0) { + if (getdata("h48", opts_large, &fulltable, filename_large) != 0) { printf("Error reading full table.\n"); return -1; } - size = nissy_datasize("h48", options); + size = nissy_datasize("h48", opts_small); if (size == -1) { printf("Error getting table size.\n"); free(fulltable); return -1; } + h = atoi(opts_small); /* TODO: use option parser */ *buf = malloc(size); gensize = gendata_h48_derive(h, fulltable, *buf); @@ -233,12 +237,17 @@ gendata_run_finish: } static void -derivedata_run(uint8_t h, const char *filename, uint64_t expected[static 21]) +derivedata_run( + const char *opts_large, + const char *opts_small, + const char *filename_large, + const char *filename_small +) { int64_t size; char *buf; - size = derivetable(h, &buf); + size = derivetable(opts_large, opts_small, filename_large, &buf); switch (size) { case -1: return; @@ -250,7 +259,7 @@ derivedata_run(uint8_t h, const char *filename, uint64_t expected[static 21]) printf("Succesfully generated %" PRId64 " bytes. " "See above for details on the tables.\n", size); - writetable(buf, size, filename); + writetable(buf, size, filename_small); break; } -- cgit v1.3 From 954a9f9100e8f30e0303a3815c4104526aceb4a0 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Fri, 27 Sep 2024 16:42:38 +0200 Subject: oopsie --- src/solvers/h48/gendata_h48.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index d7f4c92..75b7abf 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h @@ -389,7 +389,7 @@ gendata_h48k2(gendata_h48_arg_t *arg) [8] = 10, [9] = 10, [10] = 10, - [11] = 8 + [11] = 10 }; uint8_t t, *table; -- cgit v1.3 From 3429b552bc4367136f015c182f723ee977bb55a3 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Sat, 28 Sep 2024 17:47:49 +0200 Subject: Solved alignment UB issue --- src/solvers/tables.h | 50 ++++++++++++---------- test/090_tables_readwrite/tables_readwrite_tests.c | 6 +-- test/100_gendata_cocsep/gendata_cocsep_tests.c | 6 +-- test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c | 6 +-- 4 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/solvers/tables.h b/src/solvers/tables.h index bad3b2c..a668988 100644 --- a/src/solvers/tables.h +++ b/src/solvers/tables.h @@ -7,34 +7,34 @@ #define TABLETYPE_PRUNING 0 #define TABLETYPE_SPECIAL 1 -#define INFO_OFFSET_SOLVER 0 -#define INFO_OFFSET_TYPE INFO_SOLVER_STRLEN +#define INFO_OFFSET_DISTRIBUTION 0 +#define INFO_OFFSET_TYPE (INFO_DISTRIBUTION_LEN * sizeof(uint64_t)) #define INFO_OFFSET_INFOSIZE (INFO_OFFSET_TYPE + sizeof(uint64_t)) #define INFO_OFFSET_FULLSIZE (INFO_OFFSET_INFOSIZE + sizeof(uint64_t)) #define INFO_OFFSET_HASH (INFO_OFFSET_FULLSIZE + sizeof(uint64_t)) #define INFO_OFFSET_ENTRIES (INFO_OFFSET_HASH + sizeof(uint64_t)) #define INFO_OFFSET_CLASSES (INFO_OFFSET_ENTRIES + sizeof(uint64_t)) -#define INFO_OFFSET_H48H (INFO_OFFSET_CLASSES + sizeof(uint64_t)) +#define INFO_OFFSET_NEXT (INFO_OFFSET_CLASSES + sizeof(uint64_t)) +#define INFO_OFFSET_SOLVER (INFO_OFFSET_NEXT + sizeof(uint64_t)) +#define INFO_OFFSET_H48H (INFO_OFFSET_SOLVER + INFO_SOLVER_STRLEN) #define INFO_OFFSET_BITS (INFO_OFFSET_H48H + sizeof(uint8_t)) #define INFO_OFFSET_BASE (INFO_OFFSET_BITS + sizeof(uint8_t)) #define INFO_OFFSET_MAXVALUE (INFO_OFFSET_BASE + sizeof(uint8_t)) -#define INFO_OFFSET_NEXT (INFO_OFFSET_MAXVALUE + sizeof(uint8_t)) -#define INFO_OFFSET_DISTRIBUTION (INFO_OFFSET_NEXT + sizeof(uint64_t)) typedef struct { - char solver[INFO_SOLVER_STRLEN]; + uint64_t distribution[INFO_DISTRIBUTION_LEN]; uint64_t type; uint64_t infosize; uint64_t fullsize; uint64_t hash; uint64_t entries; uint64_t classes; /* Used only by cocsepdata, for now */ + uint64_t next; + char solver[INFO_SOLVER_STRLEN]; uint8_t h48h; /* Specific to H48 tables */ uint8_t bits; uint8_t base; uint8_t maxvalue; - uint64_t next; - uint64_t distribution[INFO_DISTRIBUTION_LEN]; } tableinfo_t; STATIC bool readtableinfo(const void *, tableinfo_t *); @@ -54,21 +54,24 @@ readtableinfo(const void *buf, tableinfo_t *info) return false; } - memcpy(info->solver, OFFSET(buf, INFO_OFFSET_SOLVER), - INFO_SOLVER_STRLEN); + memcpy(info->distribution, OFFSET(buf, INFO_OFFSET_DISTRIBUTION), + INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); + info->type = *(const uint64_t *)OFFSET(buf, INFO_OFFSET_TYPE); info->infosize = *(const uint64_t *)OFFSET(buf, INFO_OFFSET_INFOSIZE); info->fullsize = *(const uint64_t *)OFFSET(buf, INFO_OFFSET_FULLSIZE); info->hash = *(const uint64_t *)OFFSET(buf, INFO_OFFSET_HASH); info->entries = *(const uint64_t *)OFFSET(buf, INFO_OFFSET_ENTRIES); info->classes = *(const uint64_t *)OFFSET(buf, INFO_OFFSET_CLASSES); + info->next = *(const uint64_t* )OFFSET(buf, INFO_OFFSET_NEXT); + + memcpy(info->solver, OFFSET(buf, INFO_OFFSET_SOLVER), + INFO_SOLVER_STRLEN); + info->h48h = *OFFSET(buf, INFO_OFFSET_H48H); info->bits = *OFFSET(buf, INFO_OFFSET_BITS); info->base = *OFFSET(buf, INFO_OFFSET_BASE); info->maxvalue = *OFFSET(buf, INFO_OFFSET_MAXVALUE); - info->next = *(const uint64_t* )OFFSET(buf, INFO_OFFSET_NEXT); - memcpy(info->distribution, OFFSET(buf, INFO_OFFSET_DISTRIBUTION), - INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); return true; } @@ -98,6 +101,17 @@ writetableinfo(const tableinfo_t *info, void *buf) return false; } + memcpy(OFFSET(buf, INFO_OFFSET_DISTRIBUTION), info->distribution, + INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); + + *(uint64_t *)OFFSET(buf, INFO_OFFSET_TYPE) = info->type; + *(uint64_t *)OFFSET(buf, INFO_OFFSET_INFOSIZE) = info->infosize; + *(uint64_t *)OFFSET(buf, INFO_OFFSET_FULLSIZE) = info->fullsize; + *(uint64_t *)OFFSET(buf, INFO_OFFSET_HASH) = info->hash; + *(uint64_t *)OFFSET(buf, INFO_OFFSET_ENTRIES) = info->entries; + *(uint64_t *)OFFSET(buf, INFO_OFFSET_CLASSES) = info->classes; + *(uint64_t *)OFFSET(buf, INFO_OFFSET_NEXT) = info->next; + memcpy(OFFSET(buf, INFO_OFFSET_SOLVER), info->solver, INFO_SOLVER_STRLEN); @@ -106,20 +120,10 @@ writetableinfo(const tableinfo_t *info, void *buf) if (*OFFSET(buf, i) == 0) *OFFSET(buf, i) = 0; - *(uint64_t *)OFFSET(buf, INFO_OFFSET_TYPE) = info->type; - *(uint64_t *)OFFSET(buf, INFO_OFFSET_INFOSIZE) = info->infosize; - *(uint64_t *)OFFSET(buf, INFO_OFFSET_FULLSIZE) = info->fullsize; - *(uint64_t *)OFFSET(buf, INFO_OFFSET_HASH) = info->hash; - *(uint64_t *)OFFSET(buf, INFO_OFFSET_ENTRIES) = info->entries; - *(uint64_t *)OFFSET(buf, INFO_OFFSET_CLASSES) = info->classes; *OFFSET(buf, INFO_OFFSET_H48H) = info->h48h; *OFFSET(buf, INFO_OFFSET_BITS) = info->bits; *OFFSET(buf, INFO_OFFSET_BASE) = info->base; *OFFSET(buf, INFO_OFFSET_MAXVALUE) = info->maxvalue; - *(uint64_t *)OFFSET(buf, INFO_OFFSET_NEXT) = info->next; - - memcpy(OFFSET(buf, INFO_OFFSET_DISTRIBUTION), info->distribution, - INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); return true; } diff --git a/test/090_tables_readwrite/tables_readwrite_tests.c b/test/090_tables_readwrite/tables_readwrite_tests.c index e1c2015..73c4e21 100644 --- a/test/090_tables_readwrite/tables_readwrite_tests.c +++ b/test/090_tables_readwrite/tables_readwrite_tests.c @@ -5,19 +5,19 @@ #define INFO_DISTRIBUTION_LEN 21 typedef struct { - char solver[INFO_SOLVER_STRLEN]; + uint64_t distribution[INFO_DISTRIBUTION_LEN]; uint64_t type; uint64_t infosize; uint64_t fullsize; uint64_t hash; uint64_t entries; uint64_t classes; + uint64_t next; + char solver[INFO_SOLVER_STRLEN]; uint8_t h48h; uint8_t bits; uint8_t base; uint8_t maxvalue; - uint64_t next; - uint64_t distribution[INFO_DISTRIBUTION_LEN]; } tableinfo_t; bool readtableinfo(const void *, tableinfo_t *); diff --git a/test/100_gendata_cocsep/gendata_cocsep_tests.c b/test/100_gendata_cocsep/gendata_cocsep_tests.c index 7630a71..62f52fb 100644 --- a/test/100_gendata_cocsep/gendata_cocsep_tests.c +++ b/test/100_gendata_cocsep/gendata_cocsep_tests.c @@ -6,19 +6,19 @@ #define COCSEP_CLASSES 3393 typedef struct { - char solver[INFO_SOLVER_STRLEN]; + uint64_t distribution[INFO_DISTRIBUTION_LEN]; uint64_t type; uint64_t infosize; uint64_t fullsize; uint64_t hash; uint64_t entries; uint64_t classes; /* Used only by cocsepdata, for now */ + uint64_t next; + char solver[INFO_SOLVER_STRLEN]; uint8_t h48h; uint8_t bits; uint8_t base; uint8_t maxvalue; - uint64_t next; - uint64_t distribution[INFO_DISTRIBUTION_LEN]; } tableinfo_t; size_t gendata_cocsep(void *, uint64_t *, cube_t *); diff --git a/test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c b/test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c index c37de3e..7c5b441 100644 --- a/test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c +++ b/test/120_gendata_h48h0k4/gendata_h48h0k4_tests.c @@ -6,19 +6,19 @@ #define INFO_DISTRIBUTION_LEN 21 typedef struct { - char solver[INFO_SOLVER_STRLEN]; + uint64_t distribution[INFO_DISTRIBUTION_LEN]; uint64_t type; uint64_t infosize; uint64_t fullsize; uint64_t hash; uint64_t entries; uint64_t classes; /* Used only by cocsepdata, for now */ + uint64_t next; + char solver[INFO_SOLVER_STRLEN]; uint8_t h48h; uint8_t bits; uint8_t base; uint8_t maxvalue; - uint64_t next; - uint64_t distribution[INFO_DISTRIBUTION_LEN]; } tableinfo_t; typedef struct { -- cgit v1.3 From 774a824a6c80b5af495f4fb99d98758e3b9f6b81 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Sat, 28 Sep 2024 17:52:01 +0200 Subject: Use address and UB sanitizers by default, always --- configure.sh | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/configure.sh b/configure.sh index e61a163..2b2f40b 100755 --- a/configure.sh +++ b/configure.sh @@ -22,10 +22,10 @@ # SANITIZE="option1,option2,..." # Add the options "-fsanitize=option1", "-fsanitize=option2", ... to the # compilation command when compiling in debug mode. -# By default, "-fsanitize=address" and "-fsanitize=undefined" will be used, -# if available. If this variable is set, the default is overridden. -# No check is performed on the given sanitizers, make sure that the ones you -# choose are available on your system and compatible with each other. +# By default, "-fsanitize=address" and "-fsanitize=undefined" will be used. +# If this variable is set, the default is overridden. No check is performed +# on the availability of any sanitizer used, make sure the ones you use are +# available on your system. # # Examples # @@ -39,10 +39,6 @@ greparch() { $CC -march=native -dM -E - /dev/null | grep "$1" } -grepsan() { - $CC -fsanitize="$1" -dM -E -x c - /dev/null | grep "SANITIZE" -} - detectthreads() { echo 16 # TODO: choose based on system } @@ -100,10 +96,7 @@ if [ -n "$SANITIZE" ]; then SAN="$SAN -fsanitize=$san" done else - # No sanitizer specified, use "address" and "undefined" if present - [ -n "$(grepsan address)" ] && ADDR="-fsanitize=address" - [ -n "$(grepsan undefined)" ] && UNDEF="-fsanitize=undefined" - SAN="$ADDR $UNDEF" + SAN="-fsanitize=address -fsanitize=undefined" fi LIBS="-lpthread" -- cgit v1.3