commit 41be2d294e5b6f55d485d635065096f274bc89c1
parent 15fe089b3e625cb6d3a19dee661f4fc9c6224699
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Fri, 27 Sep 2024 16:37:55 +0200
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).
Diffstat:
5 files changed, 73 insertions(+), 41 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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;
}