diff options
| -rw-r--r-- | TODO.txt | 17 | ||||
| -rw-r--r-- | src/cube_avx2.h | 7 | ||||
| -rw-r--r-- | src/cube_portable.h | 7 | ||||
| -rw-r--r-- | src/solve_h48.h | 101 |
4 files changed, 95 insertions, 37 deletions
| @@ -1,9 +1,15 @@ | |||
| 1 | In progress: go back to nissy-style BFS for eosep data computation | ||
| 2 | - (done) compute selfsim and cocsep representatives | ||
| 3 | - implement set_eo_fast for invcoord_h48 (with tests for set_eo_fast) | ||
| 4 | also: implement other set_stuff methods for fast cube representation | ||
| 5 | - in gendata_esep, compute representatives for esep inverse coordinate | ||
| 6 | - change to BFS | ||
| 7 | |||
| 1 | TODO pruning tables: | 8 | TODO pruning tables: |
| 2 | - go back to nissy-style BFS for both cocsep and eoesep | ||
| 3 | - compute selfsim and keep list of representatives | ||
| 4 | - four different ruotines for k=4,2,1 for eoesep | 9 | - four different ruotines for k=4,2,1 for eoesep |
| 5 | - try: do not compute CO, but use its binary representation | 10 | - try: do not compute CO, but use its binary representation |
| 6 | (x8 memory for cocsep) | 11 | (x8 memory for cocsep) |
| 12 | (isn't this already done?) | ||
| 7 | 13 | ||
| 8 | numbers so far (eoesep h=0, k=0): | 14 | numbers so far (eoesep h=0, k=0): |
| 9 | 0 1 | 15 | 0 1 |
| @@ -64,12 +70,13 @@ switch. Here NISS may be useful. | |||
| 64 | 70 | ||
| 65 | ## Optimizations | 71 | ## Optimizations |
| 66 | 72 | ||
| 73 | * Moves: don't do full compose for U*, D*, *2 (I removed this because I | ||
| 74 | was using shuffle intructions wrong, should re-do it) | ||
| 75 | * transform edges only for h48 coord calculation | ||
| 76 | * ptable: since it is fully symmetric, do only U or U2 at depth 1 | ||
| 67 | * use threads: how to detect at runtime? what is sane number to default to? | 77 | * use threads: how to detect at runtime? what is sane number to default to? |
| 68 | pthreads or threads.h? | 78 | pthreads or threads.h? |
| 69 | * multisolve with adaptive threading | 79 | * multisolve with adaptive threading |
| 70 | * transform edges only for h48 coord calculation | ||
| 71 | * Moves: don't do full compose for U*, D*, *2 (I removed this because I | ||
| 72 | was using shuffle intructions wrong, should re-do it) | ||
| 73 | * Trans: don't do full compose, for some trans composing perm is enough. | 80 | * Trans: don't do full compose, for some trans composing perm is enough. |
| 74 | Split out sumco() as a separate function and refactor, optimize. | 81 | Split out sumco() as a separate function and refactor, optimize. |
| 75 | * Use multi-move (up to 4/5 moves at once) | 82 | * Use multi-move (up to 4/5 moves at once) |
diff --git a/src/cube_avx2.h b/src/cube_avx2.h index c61813f..42fb9d1 100644 --- a/src/cube_avx2.h +++ b/src/cube_avx2.h | |||
| @@ -23,6 +23,7 @@ _static_inline int64_t coord_fast_co(cube_fast_t); | |||
| 23 | _static_inline int64_t coord_fast_csep(cube_fast_t); | 23 | _static_inline int64_t coord_fast_csep(cube_fast_t); |
| 24 | _static_inline int64_t coord_fast_cocsep(cube_fast_t); | 24 | _static_inline int64_t coord_fast_cocsep(cube_fast_t); |
| 25 | _static_inline int64_t coord_fast_eo(cube_fast_t); | 25 | _static_inline int64_t coord_fast_eo(cube_fast_t); |
| 26 | _static_inline void set_eo_fast(cube_fast_t *, int64_t); | ||
| 26 | _static_inline int64_t coord_fast_esep(cube_fast_t); | 27 | _static_inline int64_t coord_fast_esep(cube_fast_t); |
| 27 | 28 | ||
| 28 | _static_inline cube_fast_t | 29 | _static_inline cube_fast_t |
| @@ -198,6 +199,12 @@ coord_fast_eo(cube_fast_t c) | |||
| 198 | return mask >> 17; | 199 | return mask >> 17; |
| 199 | } | 200 | } |
| 200 | 201 | ||
| 202 | _static_inline void | ||
| 203 | set_eo_fast(cube_fast_t *c, int64_t eo) | ||
| 204 | { | ||
| 205 | /* TODO */ | ||
| 206 | } | ||
| 207 | |||
| 201 | _static_inline int64_t | 208 | _static_inline int64_t |
| 202 | coord_fast_esep(cube_fast_t c) | 209 | coord_fast_esep(cube_fast_t c) |
| 203 | { | 210 | { |
diff --git a/src/cube_portable.h b/src/cube_portable.h index 281faa0..fcd1d55 100644 --- a/src/cube_portable.h +++ b/src/cube_portable.h | |||
| @@ -17,6 +17,7 @@ _static_inline int64_t coord_fast_co(cube_fast_t); | |||
| 17 | _static_inline int64_t coord_fast_csep(cube_fast_t); | 17 | _static_inline int64_t coord_fast_csep(cube_fast_t); |
| 18 | _static_inline int64_t coord_fast_cocsep(cube_fast_t); | 18 | _static_inline int64_t coord_fast_cocsep(cube_fast_t); |
| 19 | _static_inline int64_t coord_fast_eo(cube_fast_t); | 19 | _static_inline int64_t coord_fast_eo(cube_fast_t); |
| 20 | _static_inline void set_eo_fast(cube_fast_t *, int64_t eo); | ||
| 20 | _static_inline int64_t coord_fast_esep(cube_fast_t); | 21 | _static_inline int64_t coord_fast_esep(cube_fast_t); |
| 21 | 22 | ||
| 22 | _static_inline cube_fast_t | 23 | _static_inline cube_fast_t |
| @@ -188,6 +189,12 @@ coord_fast_eo(cube_fast_t c) | |||
| 188 | return ret; | 189 | return ret; |
| 189 | } | 190 | } |
| 190 | 191 | ||
| 192 | _static_inline void | ||
| 193 | _set_eo_fast(cube_fast_t *cube, int64_t eo) | ||
| 194 | { | ||
| 195 | /* TODO */ | ||
| 196 | } | ||
| 197 | |||
| 191 | /* | 198 | /* |
| 192 | We encode the edge separation as a number from 0 to C(12,4)*C(8,4). | 199 | We encode the edge separation as a number from 0 to C(12,4)*C(8,4). |
| 193 | It can be seen as the composition of two "subset index" coordinates. | 200 | It can be seen as the composition of two "subset index" coordinates. |
diff --git a/src/solve_h48.h b/src/solve_h48.h index d7473bd..e3e6de1 100644 --- a/src/solve_h48.h +++ b/src/solve_h48.h | |||
| @@ -1,11 +1,21 @@ | |||
| 1 | #define COCSEP_CLASSES 3393U | ||
| 2 | #define COCSEP_TABLESIZE (_3p7 << 7U) | ||
| 3 | #define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + 7U) / 8U) | ||
| 4 | #define COCSEP_INFOSIZE 12U | ||
| 5 | #define COCSEP_FULLSIZE (4 * (COCSEP_TABLESIZE + COCSEP_INFOSIZE)) | ||
| 6 | |||
| 7 | #define ESEP_TABLESIZE ((COCSEP_CLASSES * _12c4 * _8c4) / 2U) | ||
| 8 | #define ESEP_VISITEDSIZE ((ESEP_TABLESIZE * 2U + 7U) / 8U) | ||
| 9 | #define ESEP_INFOSIZE 25 /* TODO unknown yet */ | ||
| 10 | |||
| 11 | #define H48_ESIZE ((_12c4 * _8c4) << h) | ||
| 12 | |||
| 1 | #define _esep_ind(i) (i / 8U) | 13 | #define _esep_ind(i) (i / 8U) |
| 2 | #define _esep_shift(i) (4U * (i % 8U)) | 14 | #define _esep_shift(i) (4U * (i % 8U)) |
| 3 | #define _esep_mask(i) (((1U << 4U) - 1U) << _esep_shift(i)) | 15 | #define _esep_mask(i) (((1U << 4U) - 1U) << _esep_shift(i)) |
| 4 | #define _visited_ind(i) (i / 8U) | 16 | #define _visited_ind(i) (i / 8U) |
| 5 | #define _visited_mask(i) (1U << (i % 8U)) | 17 | #define _visited_mask(i) (1U << (i % 8U)) |
| 6 | 18 | ||
| 7 | #define COCSEP_CLASSES 3393U | ||
| 8 | |||
| 9 | typedef struct { | 19 | typedef struct { |
| 10 | cube_fast_t cube; | 20 | cube_fast_t cube; |
| 11 | uint8_t depth; | 21 | uint8_t depth; |
| @@ -28,11 +38,13 @@ typedef struct { | |||
| 28 | uint32_t *buf32; | 38 | uint32_t *buf32; |
| 29 | } dfsarg_esep_t; | 39 | } dfsarg_esep_t; |
| 30 | 40 | ||
| 31 | _static_inline int64_t coord_h48(cube_fast_t, uint32_t *, uint8_t); | 41 | _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 uint32_t *, | ||
| 43 | const cube_fast_t *, const cube_fast_t *, uint8_t); | ||
| 32 | 44 | ||
| 33 | _static size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *); | 45 | _static size_t gendata_cocsep(void *, uint64_t *, cube_fast_t *); |
| 34 | _static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); | 46 | _static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); |
| 35 | _static size_t gendata_esep(const void *, void *); | 47 | _static size_t gendata_esep(void *); |
| 36 | _static uint32_t gendata_esep_dfs(dfsarg_esep_t *); | 48 | _static uint32_t gendata_esep_dfs(dfsarg_esep_t *); |
| 37 | 49 | ||
| 38 | _static_inline bool get_visited(const uint8_t *, int64_t); | 50 | _static_inline bool get_visited(const uint8_t *, int64_t); |
| @@ -41,10 +53,10 @@ _static_inline uint8_t get_esep_pval(const uint32_t *, int64_t); | |||
| 41 | _static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t); | 53 | _static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t); |
| 42 | 54 | ||
| 43 | _static_inline int64_t | 55 | _static_inline int64_t |
| 44 | coord_h48(cube_fast_t c, uint32_t *cocsepdata, uint8_t h) | 56 | coord_h48(cube_fast_t c, const uint32_t *cocsepdata, uint8_t h) |
| 45 | { | 57 | { |
| 46 | cube_fast_t d; | 58 | cube_fast_t d; |
| 47 | int64_t cocsep, coclass, esep, eo, esize, ret; | 59 | int64_t cocsep, coclass, esep, eo, ret; |
| 48 | uint32_t data; | 60 | uint32_t data; |
| 49 | uint8_t ttrep; | 61 | uint8_t ttrep; |
| 50 | 62 | ||
| @@ -59,8 +71,33 @@ coord_h48(cube_fast_t c, uint32_t *cocsepdata, uint8_t h) | |||
| 59 | esep = coord_fast_esep(d); | 71 | esep = coord_fast_esep(d); |
| 60 | eo = coord_fast_eo(d); | 72 | eo = coord_fast_eo(d); |
| 61 | 73 | ||
| 62 | esize = (_12c4 * _8c4) << h; | 74 | ret = (coclass * H48_ESIZE) + (esep << h) + (eo >> (11-h)); |
| 63 | ret = (coclass * esize) + (esep << h) + (eo >> (11-h)); | 75 | |
| 76 | return ret; | ||
| 77 | } | ||
| 78 | |||
| 79 | _static_inline cube_fast_t | ||
| 80 | invcoord_h48( | ||
| 81 | int64_t i, | ||
| 82 | const uint32_t *cocsepdata, | ||
| 83 | const cube_fast_t *crep, | ||
| 84 | const cube_fast_t *erep, | ||
| 85 | uint8_t h | ||
| 86 | ) | ||
| 87 | { | ||
| 88 | cube_fast_t ret; | ||
| 89 | int64_t coclass, ee, esep, eo; | ||
| 90 | |||
| 91 | coclass = i / H48_ESIZE; | ||
| 92 | ee = i % H48_ESIZE; | ||
| 93 | esep = ee >> h; | ||
| 94 | eo = (ee & ((1<<h)-1)) << (11-h); | ||
| 95 | |||
| 96 | /* TODO: implement set_stuff methods | ||
| 97 | ret.c = crep[coclass]; | ||
| 98 | ret.e = erep[esep]; | ||
| 99 | set_eo_fast(&ret, eo); | ||
| 100 | */ | ||
| 64 | 101 | ||
| 65 | return ret; | 102 | return ret; |
| 66 | } | 103 | } |
| @@ -79,19 +116,15 @@ After the data as described above, more auxiliary information is appended: | |||
| 79 | _static size_t | 116 | _static size_t |
| 80 | gendata_cocsep(void *buf, uint64_t *selfsim, cube_fast_t *rep) | 117 | gendata_cocsep(void *buf, uint64_t *selfsim, cube_fast_t *rep) |
| 81 | { | 118 | { |
| 82 | size_t tablesize = _3p7 << 7U; | ||
| 83 | size_t visitedsize = (tablesize + 7U) / 8U; | ||
| 84 | size_t infosize = 12; | ||
| 85 | |||
| 86 | uint32_t *buf32, *info, cc; | 119 | uint32_t *buf32, *info, cc; |
| 87 | uint16_t n; | 120 | uint16_t n; |
| 88 | uint8_t i, j, visited[visitedsize]; | 121 | uint8_t i, j, visited[COCSEP_VISITEDSIZE]; |
| 89 | dfsarg_cocsep_t arg; | 122 | dfsarg_cocsep_t arg; |
| 90 | 123 | ||
| 91 | buf32 = (uint32_t *)buf; | 124 | buf32 = (uint32_t *)buf; |
| 92 | info = buf32 + tablesize; | 125 | info = buf32 + COCSEP_TABLESIZE; |
| 93 | memset(buf32, 0xFFU, sizeof(uint32_t) * tablesize); | 126 | memset(buf32, 0xFFU, sizeof(uint32_t) * COCSEP_TABLESIZE); |
| 94 | memset(info, 0, sizeof(uint32_t) * infosize); | 127 | memset(info, 0, sizeof(uint32_t) * COCSEP_INFOSIZE); |
| 95 | memset(selfsim, 0, sizeof(uint64_t) * COCSEP_CLASSES); | 128 | memset(selfsim, 0, sizeof(uint64_t) * COCSEP_CLASSES); |
| 96 | 129 | ||
| 97 | arg = (dfsarg_cocsep_t) { | 130 | arg = (dfsarg_cocsep_t) { |
| @@ -104,7 +137,7 @@ gendata_cocsep(void *buf, uint64_t *selfsim, cube_fast_t *rep) | |||
| 104 | }; | 137 | }; |
| 105 | for (i = 0, n = 0, cc = 0; i < 10; i++) { | 138 | for (i = 0, n = 0, cc = 0; i < 10; i++) { |
| 106 | DBG_LOG("cocsep: generating depth %" PRIu8 "\n", i); | 139 | DBG_LOG("cocsep: generating depth %" PRIu8 "\n", i); |
| 107 | memset(visited, 0, visitedsize); | 140 | memset(visited, 0, COCSEP_VISITEDSIZE); |
| 108 | arg.depth = 0; | 141 | arg.depth = 0; |
| 109 | arg.maxdepth = i; | 142 | arg.maxdepth = i; |
| 110 | cc = gendata_cocsep_dfs(&arg); | 143 | cc = gendata_cocsep_dfs(&arg); |
| @@ -125,7 +158,7 @@ gendata_cocsep(void *buf, uint64_t *selfsim, cube_fast_t *rep) | |||
| 125 | for (j = 0; j < 10; j++) | 158 | for (j = 0; j < 10; j++) |
| 126 | DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+2]); | 159 | DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+2]); |
| 127 | 160 | ||
| 128 | return 4*(tablesize + infosize); | 161 | return COCSEP_FULLSIZE; |
| 129 | } | 162 | } |
| 130 | 163 | ||
| 131 | _static uint32_t | 164 | _static uint32_t |
| @@ -134,6 +167,7 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg) | |||
| 134 | uint8_t m, t, tinv, olddepth; | 167 | uint8_t m, t, tinv, olddepth; |
| 135 | uint32_t cc; | 168 | uint32_t cc; |
| 136 | int64_t i; | 169 | int64_t i; |
| 170 | uint64_t sim; | ||
| 137 | cube_fast_t d; | 171 | cube_fast_t d; |
| 138 | dfsarg_cocsep_t nextarg; | 172 | dfsarg_cocsep_t nextarg; |
| 139 | 173 | ||
| @@ -149,6 +183,8 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg) | |||
| 149 | 183 | ||
| 150 | for (t = 0, cc = 0; t < 48; t++) { | 184 | for (t = 0, cc = 0; t < 48; t++) { |
| 151 | d = transform(arg->cube, t); | 185 | d = transform(arg->cube, t); |
| 186 | sim = equal_fast(arg->cube, d); | ||
| 187 | arg->selfsim[*arg->n] |= sim << t; | ||
| 152 | i = coord_fast_cocsep(d); | 188 | i = coord_fast_cocsep(d); |
| 153 | set_visited(arg->visited, i); | 189 | set_visited(arg->visited, i); |
| 154 | tinv = inverse_trans(t); | 190 | tinv = inverse_trans(t); |
| @@ -156,6 +192,7 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg) | |||
| 156 | arg->buf32[i] = | 192 | arg->buf32[i] = |
| 157 | (*arg->n << 16U) | (tinv << 8U) | arg->depth; | 193 | (*arg->n << 16U) | (tinv << 8U) | arg->depth; |
| 158 | } | 194 | } |
| 195 | arg->rep[*arg->n] = arg->cube; | ||
| 159 | (*arg->n)++; | 196 | (*arg->n)++; |
| 160 | 197 | ||
| 161 | return cc; | 198 | return cc; |
| @@ -176,38 +213,38 @@ TODO description | |||
| 176 | generating fixed table with h=0, k=4 | 213 | generating fixed table with h=0, k=4 |
| 177 | */ | 214 | */ |
| 178 | _static size_t | 215 | _static size_t |
| 179 | gendata_esep(const void *cocsepdata, void *buf) | 216 | gendata_esep(void *buf) |
| 180 | { | 217 | { |
| 181 | size_t tablesize = (COCSEP_CLASSES * _12c4 * _8c4) / 2U; | 218 | uint32_t *buf32, *info, *cocsepdata, cc; |
| 182 | size_t visitedsize = (tablesize * 2U + 7U) / 8U; | ||
| 183 | size_t infosize = 25; /* TODO unknown yet */ | ||
| 184 | |||
| 185 | uint32_t *buf32, *info, cc; | ||
| 186 | uint8_t moves[20]; | 219 | uint8_t moves[20]; |
| 187 | dfsarg_esep_t arg; | 220 | dfsarg_esep_t arg; |
| 188 | 221 | ||
| 189 | arg.visited = malloc(visitedsize); | 222 | arg.visited = malloc(ESEP_TABLESIZE); |
| 190 | buf32 = (uint32_t *)buf; | 223 | |
| 191 | info = buf32 + tablesize; | 224 | cocsepdata = (uint32_t *)buf; |
| 192 | memset(buf32, 0xFFU, 4*tablesize); | 225 | buf32 = cocsepdata + COCSEP_FULLSIZE; |
| 193 | memset(info, 0, 4*infosize); | 226 | info = buf32 + ESEP_TABLESIZE; |
| 227 | memset(buf32, 0xFFU, sizeof(uint32_t) * ESEP_TABLESIZE); | ||
| 228 | memset(info, 0, sizeof(uint32_t) * ESEP_INFOSIZE); | ||
| 194 | 229 | ||
| 195 | arg.cube = cubetofast(solvedcube()); | 230 | arg.cube = cubetofast(solvedcube()); |
| 196 | arg.moves = moves; | 231 | arg.moves = moves; |
| 197 | arg.nmoves = 0; | 232 | arg.nmoves = 0; |
| 198 | arg.cocsepdata = (uint32_t *)cocsepdata; | 233 | arg.cocsepdata = cocsepdata; |
| 199 | arg.buf32 = buf32; | 234 | arg.buf32 = buf32; |
| 200 | /* TODO loop until no more is done, not until 12! (or hardcode limits)*/ | 235 | /* TODO loop until no more is done, not until 12! (or hardcode limits)*/ |
| 236 | /* TODO use bfs instead | ||
| 237 | how to work with different k? k=1 is the easiest */ | ||
| 201 | for (arg.depth = 0, cc = 0; arg.depth < 12; arg.depth++) { | 238 | for (arg.depth = 0, cc = 0; arg.depth < 12; arg.depth++) { |
| 202 | DBG_LOG("esep: generating depth %" PRIu8 "\n", arg.depth); | 239 | DBG_LOG("esep: generating depth %" PRIu8 "\n", arg.depth); |
| 203 | memset(arg.visited, 0, visitedsize); | 240 | memset(arg.visited, 0, ESEP_VISITEDSIZE); |
| 204 | cc = gendata_esep_dfs(&arg); | 241 | cc = gendata_esep_dfs(&arg); |
| 205 | info[arg.depth+1] = cc; | 242 | info[arg.depth+1] = cc; |
| 206 | DBG_LOG("found %" PRIu32 "\n", cc); | 243 | DBG_LOG("found %" PRIu32 "\n", cc); |
| 207 | } | 244 | } |
| 208 | free(arg.visited); | 245 | free(arg.visited); |
| 209 | 246 | ||
| 210 | return cc; | 247 | return COCSEP_FULLSIZE + cc; |
| 211 | } | 248 | } |
| 212 | 249 | ||
| 213 | _static uint32_t | 250 | _static uint32_t |
