aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.txt30
-rw-r--r--src/solve_h48.h176
-rw-r--r--test/102_gendata_esep/gendata_esep_tests.c22
-rw-r--r--test/102_gendata_h48/00_all.in (renamed from test/102_gendata_esep/00_all.in)0
-rw-r--r--test/102_gendata_h48/00_all.out (renamed from test/102_gendata_esep/00_all.out)0
-rw-r--r--test/102_gendata_h48/gendata_h48_tests.c18
6 files changed, 109 insertions, 137 deletions
diff --git a/TODO.txt b/TODO.txt
index a93be99..07455b6 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,27 +1,9 @@
1In progress: go back to nissy-style BFS for eosep data computation 1TODO
2 - (done) compute selfsim and cocsep representatives 2 - test h48 table by adding a parameter to stop computation at certain depth
3 - (done) implement set_eo_fast for invcoord_h48 3 - add back benchmark, test performance of table computation
4 - (done) for invcoord_h48 remove erep, implement inverse esep coord 4 - table generation is still slow, how to improve? profile!
5 - (done) add unit tests for invcoord_h48 (compute tables, if needed) 5 selfsim could be a list of cubes (representatives)
6 - change to BFS 6 - add h48 table for different values of k
7
8TODO pruning tables:
9 - four different ruotines for k=4,2,1 for eoesep
10 - try: do not compute CO, but use its binary representation
11 (x8 memory for cocsep)
12 (isn't this already done?)
13
14 numbers so far (eoesep h=0, k=0):
15 0 1
16 1 1
17 2 4
18 3 34
19 4 331
20 5 3612
21 6 41605
22 7 474128
23 8 4953846
24 9 34776317
25 7
26TODO checkdata (available from cube.h) and hash check for cocsep 8TODO checkdata (available from cube.h) and hash check for cocsep
27TODO benchmarks for solve and table generation 9TODO benchmarks for solve and table generation
diff --git a/src/solve_h48.h b/src/solve_h48.h
index b04ae47..b95e6ce 100644
--- a/src/solve_h48.h
+++ b/src/solve_h48.h
@@ -1,20 +1,20 @@
1#define COCSEP_CLASSES 3393U 1#define COCSEP_CLASSES 3393U
2#define COCSEP_TABLESIZE (_3p7 << 7U) 2#define COCSEP_TABLESIZE (_3p7 << 7U)
3#define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + 7U) / 8U) 3#define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + 7U) / 8U)
4#define COCSEP_INFOSIZE 12U 4#define COCSEP_INFOSIZE 12U
5#define COCSEP_FULLSIZE (4 * (COCSEP_TABLESIZE + COCSEP_INFOSIZE)) 5#define COCSEP_FULLSIZE (4 * (COCSEP_TABLESIZE + COCSEP_INFOSIZE))
6 6
7#define ESEP_TABLESIZE ((COCSEP_CLASSES * _12c4 * _8c4) / 2U) 7#define ESEP_MAX(h) ((COCSEP_CLASSES * _12c4 * _8c4) << (h))
8#define ESEP_VISITEDSIZE ((ESEP_TABLESIZE * 2U + 7U) / 8U) 8#define ESEP_TABLESIZE(h, k) (ESEP_MAX((h)) >> (k))
9#define ESEP_INFOSIZE 25 /* TODO unknown yet */ 9#define ESEP_INFOSIZE 25 /* TODO unknown yet */
10 10
11#define H48_ESIZE(h) ((_12c4 * _8c4) << (h)) 11#define H48_ESIZE(h) ((_12c4 * _8c4) << (h))
12 12
13#define _esep_ind(i) (i / 8U) 13#define _esep_ind(i) (i / 8U)
14#define _esep_shift(i) (4U * (i % 8U)) 14#define _esep_shift(i) (4U * (i % 8U))
15#define _esep_mask(i) (((1U << 4U) - 1U) << _esep_shift(i)) 15#define _esep_mask(i) (((1U << 4U) - 1U) << _esep_shift(i))
16#define _visited_ind(i) (i / 8U) 16#define _visited_ind(i) (i / 8U)
17#define _visited_mask(i) (1U << (i % 8U)) 17#define _visited_mask(i) (1U << (i % 8U))
18 18
19typedef struct { 19typedef struct {
20 cube_fast_t cube; 20 cube_fast_t cube;
@@ -28,23 +28,21 @@ typedef struct {
28} dfsarg_cocsep_t; 28} dfsarg_cocsep_t;
29 29
30typedef struct { 30typedef struct {
31 cube_fast_t cube;
32 uint8_t *visited;
33 uint8_t *moves;
34 uint8_t nmoves;
35 uint8_t depth; 31 uint8_t depth;
36 uint16_t *nclasses; 32 uint8_t h;
37 uint32_t *cocsepdata; 33 uint32_t *cocsepdata;
38 uint32_t *buf32; 34 uint32_t *buf32;
39} dfsarg_esep_t; 35 uint64_t *selfsim;
36 cube_fast_t *crep;
37} bfsarg_esep_t;
40 38
41_static_inline int64_t coord_h48(cube_fast_t, const uint32_t *, uint8_t); 39_static_inline int64_t coord_h48(cube_fast_t, const uint32_t *, uint8_t);
42_static_inline cube_fast_t invcoord_h48(int64_t, const cube_fast_t *, uint8_t); 40_static_inline cube_fast_t invcoord_h48(int64_t, const cube_fast_t *, uint8_t);
43 41
44_static size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *); 42_static size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *);
45_static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); 43_static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *);
46_static size_t gendata_esep(void *); 44_static size_t gendata_h48(void *, uint8_t);
47_static uint32_t gendata_esep_dfs(dfsarg_esep_t *); 45_static uint64_t gendata_esep_bfs(bfsarg_esep_t *);
48 46
49_static_inline bool get_visited(const uint8_t *, int64_t); 47_static_inline bool get_visited(const uint8_t *, int64_t);
50_static_inline void set_visited(uint8_t *, int64_t); 48_static_inline void set_visited(uint8_t *, int64_t);
@@ -86,7 +84,7 @@ invcoord_h48(int64_t i, const cube_fast_t *crep, uint8_t h) {
86 cube_fast_t ret; int64_t coclass, ee, esep, eo; 84 cube_fast_t ret; int64_t coclass, ee, esep, eo;
87 85
88 DBG_ASSERT(h <= 11, cubetofast(zero), 86 DBG_ASSERT(h <= 11, cubetofast(zero),
89 "invcoord_h48: h must be between 0 and 11\n"); 87 "invcoord_h48: h must be between 0 and 11\n");
90 88
91 coclass = i / H48_ESIZE(h); 89 coclass = i / H48_ESIZE(h);
92 ee = i % H48_ESIZE(h); 90 ee = i % H48_ESIZE(h);
@@ -164,7 +162,7 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg)
164{ 162{
165 uint8_t m, t, tinv, olddepth; 163 uint8_t m, t, tinv, olddepth;
166 uint32_t cc; 164 uint32_t cc;
167 int64_t i; 165 int64_t i, ii;
168 uint64_t sim; 166 uint64_t sim;
169 cube_fast_t d; 167 cube_fast_t d;
170 dfsarg_cocsep_t nextarg; 168 dfsarg_cocsep_t nextarg;
@@ -181,13 +179,12 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg)
181 179
182 for (t = 0, cc = 0; t < 48; t++) { 180 for (t = 0, cc = 0; t < 48; t++) {
183 d = transform(arg->cube, t); 181 d = transform(arg->cube, t);
184 sim = equal_fast(arg->cube, d); 182 ii = coord_fast_cocsep(d);
185 arg->selfsim[*arg->n] |= sim << t; 183 arg->selfsim[*arg->n] |= (i == ii) << t;
186 i = coord_fast_cocsep(d); 184 set_visited(arg->visited, ii);
187 set_visited(arg->visited, i);
188 tinv = inverse_trans(t); 185 tinv = inverse_trans(t);
189 cc += (arg->buf32[i] & 0xFFU) == 0xFFU; 186 cc += (arg->buf32[ii] & 0xFFU) == 0xFFU;
190 arg->buf32[i] = 187 arg->buf32[ii] =
191 (*arg->n << 16U) | (tinv << 8U) | arg->depth; 188 (*arg->n << 16U) | (tinv << 8U) | arg->depth;
192 } 189 }
193 arg->rep[*arg->n] = arg->cube; 190 arg->rep[*arg->n] = arg->cube;
@@ -211,84 +208,81 @@ TODO description
211generating fixed table with h=0, k=4 208generating fixed table with h=0, k=4
212*/ 209*/
213_static size_t 210_static size_t
214gendata_esep(void *buf) 211gendata_h48(void *buf, uint8_t h)
215{ 212{
216 uint32_t *buf32, *info, *cocsepdata, cc; 213 const int k = 1; /* TODO: other cases? */
217 uint8_t moves[20]; 214 uint32_t *buf32, *info, *cocsepdata;
218 dfsarg_esep_t arg; 215 bfsarg_esep_t arg;
216 int64_t sc, cc, tot;
217 uint64_t selfsim[COCSEP_CLASSES];
218 cube_fast_t crep[COCSEP_CLASSES];
219 size_t cocsepsize;
219 220
220 arg.visited = malloc(ESEP_TABLESIZE); 221 cocsepsize = gendata_cocsep(buf, selfsim, crep);
222 DBG_ASSERT(cocsepsize == COCSEP_FULLSIZE, 0,
223 "gendata_h48: error computing cocsep data\n");
221 224
222 cocsepdata = (uint32_t *)buf; 225 cocsepdata = (uint32_t *)buf;
223 buf32 = cocsepdata + COCSEP_FULLSIZE; 226 buf32 = cocsepdata + cocsepsize;
224 info = buf32 + ESEP_TABLESIZE; 227 info = buf32 + ESEP_TABLESIZE(h, k);
225 memset(buf32, 0xFFU, sizeof(uint32_t) * ESEP_TABLESIZE); 228 memset(buf32, 0xFFU, sizeof(uint32_t) * ESEP_TABLESIZE(h, k));
226 memset(info, 0, sizeof(uint32_t) * ESEP_INFOSIZE); 229 memset(info, 0, sizeof(uint32_t) * ESEP_INFOSIZE);
227 230
228 arg.cube = cubetofast(solvedcube()); 231 sc = coord_h48(cubetofast(solved), cocsepdata, h);
229 arg.moves = moves; 232 set_esep_pval(buf32, sc, 0);
230 arg.nmoves = 0; 233 arg = (bfsarg_esep_t) {
231 arg.cocsepdata = cocsepdata; 234 .h = h,
232 arg.buf32 = buf32; 235 .cocsepdata = cocsepdata,
233 /* TODO loop until no more is done, not until 12! (or hardcode limits)*/ 236 .buf32 = buf32,
234 /* TODO use bfs instead 237 .crep = crep,
235 how to work with different k? k=1 is the easiest */ 238 .selfsim = selfsim
236 for (arg.depth = 0, cc = 0; arg.depth < 12; arg.depth++) { 239 };
240 for (tot = 1, arg.depth = 1, cc = 0; tot < ESEP_MAX(h); arg.depth++) {
237 DBG_LOG("esep: generating depth %" PRIu8 "\n", arg.depth); 241 DBG_LOG("esep: generating depth %" PRIu8 "\n", arg.depth);
238 memset(arg.visited, 0, ESEP_VISITEDSIZE); 242 cc = gendata_esep_bfs(&arg);
239 cc = gendata_esep_dfs(&arg); 243 tot += cc;
240 info[arg.depth+1] = cc; 244 info[arg.depth+1] = cc;
241 DBG_LOG("found %" PRIu32 "\n", cc); 245 DBG_LOG("found %" PRIu64 "\n", cc);
242 } 246 }
243 free(arg.visited);
244 247
245 return COCSEP_FULLSIZE + cc; 248 return COCSEP_FULLSIZE + cc;
246} 249}
247 250
248_static uint32_t 251_static uint64_t
249gendata_esep_dfs(dfsarg_esep_t *arg) 252gendata_esep_bfs(bfsarg_esep_t *arg)
250{ 253{
251 uint8_t m, t, olddepth; 254 uint8_t c, m, t, x;
252 uint32_t cc; 255 uint32_t cc;
253 uint64_t i; 256 uint64_t i, j, k, cocsep_coord, sim;
254 cube_fast_t d; 257 cube_fast_t cube, moved, transd;
255 dfsarg_esep_t nextarg;
256
257 if (!allowednextmove(arg->moves, arg->nmoves))
258 return 0;
259 258
260 if (arg->nmoves > 0) 259 for (i = 0, cc = 0; i < ESEP_MAX(arg->h); i++) {
261 arg->cube = move(arg->cube, arg->moves[arg->nmoves-1]); 260 c = get_esep_pval(arg->buf32, i);
262 261 if (c != arg->depth - 1)
263 i = coord_h48(arg->cube, arg->cocsepdata, 0U); 262 continue;
264 olddepth = get_esep_pval(arg->buf32, i); 263 cube = invcoord_h48(i, arg->crep, arg->h);
265 264 for (m = 0; m < 18; m++) {
266 if (olddepth < arg->nmoves || get_visited(arg->visited, i)) 265 moved = move(cube, m);
267 return 0; 266 j = coord_h48(moved, arg->cocsepdata, arg->h);
268 set_visited(arg->visited, i); 267 x = get_esep_pval(arg->buf32, j);
269 268 if (x <= arg->depth)
270 if (arg->nmoves == arg->depth) { 269 continue;
271 if (olddepth != 15U) 270 set_esep_pval(arg->buf32, j, arg->depth);
272 return 0; 271 cc += x != arg->depth;
273 272 cocsep_coord = j / H48_ESIZE(arg->h);
274 for (t = 0, cc = 0; t < 48; t++) { 273 sim = arg->selfsim[cocsep_coord];
275 d = transform(arg->cube, t); 274 for (t = 1; t < 48; t++) { /* Skip trivial trans */
276 i = coord_h48(d, arg->cocsepdata, 0U); 275 if (!(sim & (1 << t)))
277 set_visited(arg->visited, i); 276 continue;
278 cc += get_esep_pval(arg->buf32, i) == 15U; 277 transd = transform(moved, t);
279 set_esep_pval(arg->buf32, i, arg->depth); 278 k = coord_h48(transd, arg->cocsepdata, arg->h);
279 x = get_esep_pval(arg->buf32, k);
280 if (x <= arg->depth)
281 continue;
282 set_esep_pval(arg->buf32, k, arg->depth);
283 cc += x != arg->depth;
284 }
280 } 285 }
281
282 return cc;
283 }
284
285
286 nextarg = *arg;
287 nextarg.nmoves = arg->nmoves + 1;
288 for (m = 0, cc = 0; m < 18; m++) {
289 nextarg.cube = arg->cube;
290 nextarg.moves[arg->nmoves] = m;
291 cc += gendata_esep_dfs(&nextarg);
292 } 286 }
293 287
294 return cc; 288 return cc;
diff --git a/test/102_gendata_esep/gendata_esep_tests.c b/test/102_gendata_esep/gendata_esep_tests.c
deleted file mode 100644
index bc7ce25..0000000
--- a/test/102_gendata_esep/gendata_esep_tests.c
+++ /dev/null
@@ -1,22 +0,0 @@
1#include "../test.h"
2
3#define CSIZE 1200000
4#define ESIZE 250000000
5
6uint32_t buf_c[CSIZE/4];
7uint32_t buf_e[ESIZE/4];
8
9size_t gendata_cocsep(void *);
10size_t gendata_esep(const void *, void *);
11
12int main(void) {
13 uint32_t i;
14 size_t result;
15
16 gendata_cocsep(buf_c);
17 result = gendata_esep(buf_c, buf_e);
18
19 printf("nothing\n");
20
21 return 0;
22}
diff --git a/test/102_gendata_esep/00_all.in b/test/102_gendata_h48/00_all.in
index e69de29..e69de29 100644
--- a/test/102_gendata_esep/00_all.in
+++ b/test/102_gendata_h48/00_all.in
diff --git a/test/102_gendata_esep/00_all.out b/test/102_gendata_h48/00_all.out
index deba01f..deba01f 100644
--- a/test/102_gendata_esep/00_all.out
+++ b/test/102_gendata_h48/00_all.out
diff --git a/test/102_gendata_h48/gendata_h48_tests.c b/test/102_gendata_h48/gendata_h48_tests.c
new file mode 100644
index 0000000..f918e4d
--- /dev/null
+++ b/test/102_gendata_h48/gendata_h48_tests.c
@@ -0,0 +1,18 @@
1#include "../test.h"
2
3#define H 0
4#define SIZE (120000000 << (H))
5
6uint32_t buf[SIZE];
7
8size_t gendata_h48(void *, uint8_t);
9
10int main(void) {
11 size_t result;
12
13 result = gendata_h48(buf, H);
14
15 printf("nothing\n");
16
17 return 0;
18}

Generated with cgit - Back to sebastiano.tronto.net