commit 0b32395de2500ad87e15fbb0ff4a852e313037e9
parent bb09e52a7481718ae1fe324d16b99970450908f8
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Fri, 27 Sep 2024 08:19:53 +0200
First try for derive tables
Diffstat:
5 files changed, 186 insertions(+), 7 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -6,14 +6,17 @@
#include <stdlib.h>
#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);
+}