aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2022-09-10 17:52:57 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2022-09-10 17:52:57 +0200
commit86dd040a2d2f06e8355f5441fb1da5ed59ecc399 (patch)
tree03bb894f39e334fd5cb98dff4f2fd6a174ee78cb
parent569983380edfb3744192b5a652e2ac038840e53d (diff)
downloadnissy-86dd040a2d2f06e8355f5441fb1da5ed59ecc399.tar.gz
nissy-86dd040a2d2f06e8355f5441fb1da5ed59ecc399.zip
Modified pruning table generation (new compressed) + website update
-rw-r--r--TODO.md4
-rw-r--r--src/cubetypes.h12
-rw-r--r--src/pruning.c137
-rw-r--r--src/pruning.h4
-rw-r--r--src/steps.c14
-rw-r--r--www/download/index.html9
-rw-r--r--www/style-3.css (renamed from www/style-2.css)0
7 files changed, 110 insertions, 70 deletions
diff --git a/TODO.md b/TODO.md
index fb57dd1..30803fb 100644
--- a/TODO.md
+++ b/TODO.md
@@ -8,13 +8,9 @@ It's more of a personal reminder than anything else.
8* add Void * extradata to DfsArg and a custom move function 8* add Void * extradata to DfsArg and a custom move function
9* add optional custom pre-process for generating special table (nx) 9* add optional custom pre-process for generating special table (nx)
10* copy_dfsdata should copy extra too! 10* copy_dfsdata should copy extra too!
11* Pruning: remove base value?
12### nx.c 11### nx.c
13* implement nxopt with all tables and all tricks 12* implement nxopt with all tables and all tricks
14 (maybe compile time variable for maximum memory to use?) 13 (maybe compile time variable for maximum memory to use?)
15* custom pruning table, copy some code from pruning.h
16* generate compressed: hard-code the base value, doable!
17* special type of pruning table with fallback and whatnot
18* is_valid should also unniss / cleanup the alg 14* is_valid should also unniss / cleanup the alg
19### fst_cube 15### fst_cube
20* slightly different from cube in v2.0.2: each "side" coordinate 16* slightly different from cube in v2.0.2: each "side" coordinate
diff --git a/src/cubetypes.h b/src/cubetypes.h
index fa19f6c..f9b4011 100644
--- a/src/cubetypes.h
+++ b/src/cubetypes.h
@@ -93,7 +93,6 @@ typedef struct dfsarg DfsArg;
93typedef struct indexer Indexer; 93typedef struct indexer Indexer;
94typedef struct movable Movable; 94typedef struct movable Movable;
95typedef struct moveset Moveset; 95typedef struct moveset Moveset;
96typedef struct pdgendata PDGenData;
97typedef struct prunedata PruneData; 96typedef struct prunedata PruneData;
98typedef struct solveoptions SolveOptions; 97typedef struct solveoptions SolveOptions;
99typedef struct step Step; 98typedef struct step Step;
@@ -245,14 +244,6 @@ moveset
245}; 244};
246 245
247struct 246struct
248pdgendata
249{
250 Coordinate * coord;
251 Moveset * moveset;
252 PruneData * pd;
253};
254
255struct
256prunedata 247prunedata
257{ 248{
258 entry_group_t * ptable; 249 entry_group_t * ptable;
@@ -260,6 +251,8 @@ prunedata
260 Coordinate * coord; 251 Coordinate * coord;
261 Moveset * moveset; 252 Moveset * moveset;
262 uint64_t count[16]; 253 uint64_t count[16];
254 bool compact;
255 int base;
263}; 256};
264 257
265struct 258struct
@@ -287,6 +280,7 @@ step
287 Coordinate * coord[MAX_N_COORD]; 280 Coordinate * coord[MAX_N_COORD];
288 Trans coord_trans[MAX_N_COORD]; 281 Trans coord_trans[MAX_N_COORD];
289 PruneData * pd[MAX_N_COORD]; 282 PruneData * pd[MAX_N_COORD];
283 bool pd_compact[MAX_N_COORD];
290 Validator is_valid; 284 Validator is_valid;
291 DfsMover custom_move_checkstop; 285 DfsMover custom_move_checkstop;
292 DfsExtraCopier copy_extra; 286 DfsExtraCopier copy_extra;
diff --git a/src/pruning.c b/src/pruning.c
index 2e30351..3cc9152 100644
--- a/src/pruning.c
+++ b/src/pruning.c
@@ -3,6 +3,7 @@
3#include "pruning.h" 3#include "pruning.h"
4 4
5#define ENTRIES_PER_GROUP (2*sizeof(entry_group_t)) 5#define ENTRIES_PER_GROUP (2*sizeof(entry_group_t))
6#define ENTRIES_PER_GROUP_COMPACT (4*sizeof(entry_group_t))
6 7
7static int findchunk(PruneData *pd, int nchunks, uint64_t i); 8static int findchunk(PruneData *pd, int nchunks, uint64_t i);
8static void genptable_bfs(PruneData *pd, int d, int nt, int nc); 9static void genptable_bfs(PruneData *pd, int d, int nt, int nc);
@@ -13,7 +14,7 @@ static void ptable_update(PruneData *pd, uint64_t ind, int m);
13static bool read_ptable_file(PruneData *pd); 14static bool read_ptable_file(PruneData *pd);
14static bool write_ptable_file(PruneData *pd); 15static bool write_ptable_file(PruneData *pd);
15 16
16PDGenData *active_pdg[256]; 17PruneData *active_pd[256];
17 18
18int 19int
19findchunk(PruneData *pd, int nchunks, uint64_t i) 20findchunk(PruneData *pd, int nchunks, uint64_t i)
@@ -27,26 +28,23 @@ findchunk(PruneData *pd, int nchunks, uint64_t i)
27} 28}
28 29
29PruneData * 30PruneData *
30genptable(PDGenData *pdg, int nthreads) 31genptable(PruneData *pd, int nthreads)
31{ 32{
32 int d, nchunks, i; 33 int d, nchunks, i, maxv;
33 uint64_t oldn; 34 uint64_t oldn;
34 PruneData *pd;
35 35
36 for (i = 0; active_pdg[i] != NULL; i++) { 36 for (i = 0; active_pd[i] != NULL; i++) {
37 pd = active_pdg[i]->pd; 37 if (active_pd[i]->coord == pd->coord &&
38 if (pd->coord == pdg->coord && pd->moveset == pdg->moveset) 38 active_pd[i]->moveset == pd->moveset &&
39 return pd; 39 active_pd[i]->compact == pd->compact)
40 return active_pd[i];
40 } 41 }
41 42
42 pd = malloc(sizeof(PruneData)); 43 init_moveset(pd->moveset);
43 pdg->pd = pd;
44 pd->coord = pdg->coord;
45 pd->moveset = pdg->moveset;
46 pd->ptable = malloc(ptablesize(pd) * sizeof(entry_group_t));
47
48 gen_coord(pd->coord); 44 gen_coord(pd->coord);
49 45
46 pd->ptable = malloc(ptablesize(pd) * sizeof(entry_group_t));
47
50 if (read_ptable_file(pd)) 48 if (read_ptable_file(pd))
51 goto genptable_done; 49 goto genptable_done;
52 50
@@ -78,7 +76,9 @@ genptable(PDGenData *pdg, int nthreads)
78 0, pd->n - oldn, pd->n, pd->coord->max); 76 0, pd->n - oldn, pd->n, pd->coord->max);
79 oldn = pd->n; 77 oldn = pd->n;
80 pd->count[0] = pd->n; 78 pd->count[0] = pd->n;
81 for (d = 0; d < 15 && pd->n < pd->coord->max; d++) { 79
80 maxv = pd->compact ? MIN(15, pd->base + 4) : 15;
81 for (d = 0; d < maxv && pd->n < pd->coord->max; d++) {
82 genptable_bfs(pd, d, nthreads, nchunks); 82 genptable_bfs(pd, d, nthreads, nchunks);
83 genptable_fixnasty(pd, d+1, nthreads); 83 genptable_fixnasty(pd, d+1, nthreads);
84 fprintf(stderr, "Depth %d done, generated %" 84 fprintf(stderr, "Depth %d done, generated %"
@@ -87,19 +87,17 @@ genptable(PDGenData *pdg, int nthreads)
87 pd->count[d+1] = pd->n - oldn; 87 pd->count[d+1] = pd->n - oldn;
88 oldn = pd->n; 88 oldn = pd->n;
89 } 89 }
90 if (pd->compact)
91 fprintf(stderr, "Compact table, values above "
92 "%d are inaccurate.\n", maxv-1);
90 fprintf(stderr, "Pruning table generated!\n"); 93 fprintf(stderr, "Pruning table generated!\n");
91 94
92 if (!write_ptable_file(pd)) 95 if (!write_ptable_file(pd))
93 fprintf(stderr, "Error writing ptable file\n"); 96 fprintf(stderr, "Error writing ptable file\n");
94 97
95genptable_done: 98genptable_done:
96 for (i = 0; active_pdg[i] != NULL; i++); 99 for (i = 0; active_pd[i] != NULL; i++);
97 active_pdg[i] = malloc(sizeof(PDGenData)); 100 return active_pd[i] = pd;
98 active_pdg[i]->coord = pdg->coord;
99 active_pdg[i]->moveset = pdg->moveset;
100 active_pdg[i]->pd = pd;
101
102 return pd;
103} 101}
104 102
105static void 103static void
@@ -169,7 +167,7 @@ instance_bfs(void *arg)
169{ 167{
170 ThreadDataGenpt *td; 168 ThreadDataGenpt *td;
171 uint64_t i, ii, blocksize, rmin, rmax, updated; 169 uint64_t i, ii, blocksize, rmin, rmax, updated;
172 int j, pval, ichunk; 170 int j, pval, ichunk, oldc, newc;
173 Move *ms; 171 Move *ms;
174 172
175 td = (ThreadDataGenpt *)arg; 173 td = (ThreadDataGenpt *)arg;
@@ -180,25 +178,43 @@ instance_bfs(void *arg)
180 td->pd->coord->max : 178 td->pd->coord->max :
181 ((uint64_t)td->thid + 1) * blocksize; 179 ((uint64_t)td->thid + 1) * blocksize;
182 180
181 if (td->pd->compact) {
182 if (td->d <= td->pd->base) {
183 oldc = 1;
184 newc = 1;
185 } else {
186 oldc = td->d - td->pd->base;
187 newc = td->d - td->pd->base;
188 }
189 } else {
190 oldc = td->d;
191 newc = td->d + 1;
192 }
193
183 updated = 0; 194 updated = 0;
184 for (i = rmin; i < rmax; i++) { 195 for (i = rmin; i < rmax; i++) {
185 ichunk = findchunk(td->pd, td->nchunks, i); 196 ichunk = findchunk(td->pd, td->nchunks, i);
186 pthread_mutex_lock(td->mutex[ichunk]); 197 pthread_mutex_lock(td->mutex[ichunk]);
187 pval = ptableval(td->pd, i); 198 pval = ptableval(td->pd, i);
188 pthread_mutex_unlock(td->mutex[ichunk]); 199 pthread_mutex_unlock(td->mutex[ichunk]);
189 if (pval == td->d) { 200 if (pval == oldc) {
190 for (j = 0; ms[j] != NULLMOVE; j++) { 201 for (j = 0; ms[j] != NULLMOVE; j++) {
191 /* ii = td->pd->coord->move(ms[j], i); */
192 ii = move_coord(td->pd->coord, ms[j], i, NULL); 202 ii = move_coord(td->pd->coord, ms[j], i, NULL);
193 ichunk = findchunk(td->pd, td->nchunks, ii); 203 ichunk = findchunk(td->pd, td->nchunks, ii);
194 pthread_mutex_lock(td->mutex[ichunk]); 204 pthread_mutex_lock(td->mutex[ichunk]);
195 pval = ptableval(td->pd, ii); 205 pval = ptableval(td->pd, ii);
196 if (pval > td->d+1) { 206 if (pval > newc) {
197 ptable_update(td->pd, ii, td->d+1); 207 ptable_update(td->pd, ii, newc);
198 updated++; 208 updated++;
199 } 209 }
200 pthread_mutex_unlock(td->mutex[ichunk]); 210 pthread_mutex_unlock(td->mutex[ichunk]);
201 } 211 }
212 if (td->pd->compact && td->d <= td->pd->base) {
213 ichunk = findchunk(td->pd, td->nchunks, i);
214 pthread_mutex_lock(td->mutex[ichunk]);
215 ptable_update(td->pd, i, 0);
216 pthread_mutex_unlock(td->mutex[ichunk]);
217 }
202 } 218 }
203 } 219 }
204 220
@@ -214,7 +230,7 @@ instance_fixnasty(void *arg)
214{ 230{
215 ThreadDataGenpt *td; 231 ThreadDataGenpt *td;
216 uint64_t i, ii, blocksize, rmin, rmax, updated, ss, M; 232 uint64_t i, ii, blocksize, rmin, rmax, updated, ss, M;
217 int j; 233 int j, oldc;
218 Trans t; 234 Trans t;
219 235
220 td = (ThreadDataGenpt *)arg; 236 td = (ThreadDataGenpt *)arg;
@@ -227,17 +243,26 @@ instance_fixnasty(void *arg)
227 td->pd->coord->max : 243 td->pd->coord->max :
228 ((uint64_t)td->thid + 1) * blocksize; 244 ((uint64_t)td->thid + 1) * blocksize;
229 245
246 if (td->pd->compact) {
247 if (td->d <= td->pd->base)
248 oldc = 1;
249 else
250 oldc = td->d - td->pd->base;
251 } else {
252 oldc = td->d;
253 }
254
230 updated = 0; 255 updated = 0;
231 for (i = rmin; i < rmax; i++) { 256 for (i = rmin; i < rmax; i++) {
232 if (ptableval(td->pd, i) == td->d) { 257 if (ptableval(td->pd, i) == oldc) {
233 ss = td->pd->coord->base[0]->selfsim[i/M]; 258 ss = td->pd->coord->base[0]->selfsim[i/M];
234 for (j = 0; j < td->pd->coord->base[0]->tgrp->n; j++) { 259 for (j = 0; j < td->pd->coord->base[0]->tgrp->n; j++) {
235 t = td->pd->coord->base[0]->tgrp->t[j]; 260 t = td->pd->coord->base[0]->tgrp->t[j];
236 if (t == uf || !(ss & ((uint64_t)1<<t))) 261 if (t == uf || !(ss & ((uint64_t)1<<t)))
237 continue; 262 continue;
238 ii = trans_coord(td->pd->coord, t, i); 263 ii = trans_coord(td->pd->coord, t, i);
239 if (ptableval(td->pd, ii) > td->d) { 264 if (ptableval(td->pd, ii) > oldc) {
240 ptable_update(td->pd, ii, td->d); 265 ptable_update(td->pd, ii, oldc);
241 updated++; 266 updated++;
242 } 267 }
243 } 268 }
@@ -257,6 +282,12 @@ print_ptable(PruneData *pd)
257 uint64_t i; 282 uint64_t i;
258 283
259 printf("Table %s_%s\n", pd->coord->name, pd->moveset->name); 284 printf("Table %s_%s\n", pd->coord->name, pd->moveset->name);
285
286 if (pd->compact) {
287 printf("Compract table with base value: %d\n", pd->base);
288 printf("Values above %d are inaccurate.\n", pd->base + 3);
289 }
290
260 for (i = 0; i < 16; i++) 291 for (i = 0; i < 16; i++)
261 printf("%2" PRIu64 "\t%10" PRIu64 "\n", i, pd->count[i]); 292 printf("%2" PRIu64 "\t%10" PRIu64 "\n", i, pd->count[i]);
262} 293}
@@ -264,32 +295,50 @@ print_ptable(PruneData *pd)
264uint64_t 295uint64_t
265ptablesize(PruneData *pd) 296ptablesize(PruneData *pd)
266{ 297{
267 return (pd->coord->max + ENTRIES_PER_GROUP - 1) / ENTRIES_PER_GROUP; 298 uint64_t e;
299
300 e = pd->compact ? ENTRIES_PER_GROUP_COMPACT : ENTRIES_PER_GROUP;
301
302 return (pd->coord->max + e - 1) / e;
268} 303}
269 304
270static void 305static void
271ptable_update(PruneData *pd, uint64_t ind, int n) 306ptable_update(PruneData *pd, uint64_t ind, int n)
272{ 307{
273 int sh; 308 int sh;
274 entry_group_t mask; 309 entry_group_t f, mask;
275 uint64_t i; 310 uint64_t i, e, b;
311
312 e = pd->compact ? ENTRIES_PER_GROUP_COMPACT : ENTRIES_PER_GROUP;
313 b = pd->compact ? 2 : 4;
314 f = pd->compact ? 3 : 15;
276 315
277 sh = 4 * (ind % ENTRIES_PER_GROUP); 316 sh = b * (ind % e);
278 mask = ((entry_group_t)15) << sh; 317 mask = f << sh;
279 i = ind/ENTRIES_PER_GROUP; 318 i = ind / e;
280 319
281 pd->ptable[i] &= ~mask; 320 pd->ptable[i] &= ~mask;
282 pd->ptable[i] |= (((entry_group_t)n)&15) << sh; 321 pd->ptable[i] |= (((entry_group_t)n) & f) << sh;
283} 322}
284 323
285int 324int
286ptableval(PruneData *pd, uint64_t ind) 325ptableval(PruneData *pd, uint64_t ind)
287{ 326{
288 int sh; 327 int sh;
328 uint64_t e;
329 entry_group_t m;
289 330
290 sh = (ind % ENTRIES_PER_GROUP) * 4; 331 if (pd->compact) {
332 e = ENTRIES_PER_GROUP_COMPACT;
333 m = 3;
334 sh = (ind % e) * 2;
335 } else {
336 e = ENTRIES_PER_GROUP;
337 m = 15;
338 sh = (ind % e) * 4;
339 }
291 340
292 return (pd->ptable[ind/ENTRIES_PER_GROUP] & (15 << sh)) >> sh; 341 return (pd->ptable[ind/e] & (m << sh)) >> sh;
293} 342}
294 343
295static bool 344static bool
@@ -299,7 +348,7 @@ read_ptable_file(PruneData *pd)
299 348
300 FILE *f; 349 FILE *f;
301 char fname[strlen(tabledir)+256]; 350 char fname[strlen(tabledir)+256];
302 int i, phony; 351 int i;
303 uint64_t r; 352 uint64_t r;
304 353
305 strcpy(fname, tabledir); 354 strcpy(fname, tabledir);
@@ -311,7 +360,7 @@ read_ptable_file(PruneData *pd)
311 if ((f = fopen(fname, "rb")) == NULL) 360 if ((f = fopen(fname, "rb")) == NULL)
312 return false; 361 return false;
313 362
314 r = fread(&phony, sizeof(int), 1, f); 363 r = fread(&(pd->base), sizeof(int), 1, f);
315 for (i = 0; i < 16; i++) 364 for (i = 0; i < 16; i++)
316 r += fread(&(pd->count[i]), sizeof(uint64_t), 1, f); 365 r += fread(&(pd->count[i]), sizeof(uint64_t), 1, f);
317 r += fread(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f); 366 r += fread(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f);
@@ -328,7 +377,7 @@ write_ptable_file(PruneData *pd)
328 377
329 FILE *f; 378 FILE *f;
330 char fname[strlen(tabledir)+256]; 379 char fname[strlen(tabledir)+256];
331 int i, phony = 0; 380 int i;
332 uint64_t w; 381 uint64_t w;
333 382
334 strcpy(fname, tabledir); 383 strcpy(fname, tabledir);
@@ -340,7 +389,7 @@ write_ptable_file(PruneData *pd)
340 if ((f = fopen(fname, "wb")) == NULL) 389 if ((f = fopen(fname, "wb")) == NULL)
341 return false; 390 return false;
342 391
343 w = fwrite(&phony, sizeof(int), 1, f); /* phony replace base */ 392 w = fwrite(&(pd->base), sizeof(int), 1, f);
344 for (i = 0; i < 16; i++) 393 for (i = 0; i < 16; i++)
345 w += fwrite(&(pd->count[i]), sizeof(uint64_t), 1, f); 394 w += fwrite(&(pd->count[i]), sizeof(uint64_t), 1, f);
346 w += fwrite(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f); 395 w += fwrite(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f);
diff --git a/src/pruning.h b/src/pruning.h
index 6965910..86691c1 100644
--- a/src/pruning.h
+++ b/src/pruning.h
@@ -4,12 +4,12 @@
4#include "coord.h" 4#include "coord.h"
5 5
6void free_pd(PruneData *pd); 6void free_pd(PruneData *pd);
7PruneData * genptable(PDGenData *data, int nthreads); 7PruneData * genptable(PruneData *data, int nthreads);
8void print_ptable(PruneData *pd); 8void print_ptable(PruneData *pd);
9uint64_t ptablesize(PruneData *pd); 9uint64_t ptablesize(PruneData *pd);
10int ptableval(PruneData *pd, uint64_t ind); 10int ptableval(PruneData *pd, uint64_t ind);
11 11
12extern PDGenData *active_pdg[256]; 12extern PruneData *active_pd[256];
13 13
14#endif 14#endif
15 15
diff --git a/src/steps.c b/src/steps.c
index a04d5e2..2f5fd2c 100644
--- a/src/steps.c
+++ b/src/steps.c
@@ -152,20 +152,16 @@ void
152prepare_cs(ChoiceStep *cs, SolveOptions *opts) 152prepare_cs(ChoiceStep *cs, SolveOptions *opts)
153{ 153{
154 int i, j; 154 int i, j;
155 PDGenData pdg;
156 Step *s; 155 Step *s;
157 156
158 for (i = 0; cs->step[i] != NULL; i++) { 157 for (i = 0; cs->step[i] != NULL; i++) {
159 s = cs->step[i]; 158 s = cs->step[i];
160 init_moveset(s->moveset);
161 pdg.moveset = s->moveset;
162 for (j = 0; j < s->n_coord; j++) { 159 for (j = 0; j < s->n_coord; j++) {
163 gen_coord(s->coord[j]); 160 s->pd[j] = malloc(sizeof(PruneData));
164 161 s->pd[j]->moveset = s->moveset;
165 pdg.coord = s->coord[j]; 162 s->pd[j]->coord = s->coord[j];
166 pdg.pd = NULL; 163 s->pd[j]->compact = s->pd_compact[j];
167 164 s->pd[j] = genptable(s->pd[j], opts->nthreads);
168 s->pd[j] = genptable(&pdg, opts->nthreads);
169 } 165 }
170 } 166 }
171} 167}
diff --git a/www/download/index.html b/www/download/index.html
index 01c4895..8e4cccd 100644
--- a/www/download/index.html
+++ b/www/download/index.html
@@ -34,8 +34,8 @@
34</tr> 34</tr>
35<tr> 35<tr>
36 <td><strong>Latest version</strong></td> 36 <td><strong>Latest version</strong></td>
37 <td><a href="/nissy-2.0.2.tar.gz">nissy-2.0.2.tar.gz (67Kb)</a></td> 37 <td><a href="/nissy-2.0.3.tar.gz">nissy-2.0.3.tar.gz (67Kb)</a></td>
38 <td><a href="/nissy-2.0.2.exe">nissy-2.0.2.exe (780Kb)</a></td> 38 <td><a href="/nissy-2.0.3.exe">nissy-2.0.3.exe (780Kb)</a></td>
39</tr> 39</tr>
40</table> 40</table>
41 41
@@ -167,6 +167,11 @@ may be not used anymore. Nissy will deal with this automatically.
167 <td><strong>Comment</strong></td> 167 <td><strong>Comment</strong></td>
168</tr> 168</tr>
169<tr> 169<tr>
170 <td><a href="/nissy-2.0.3.tar.gz">2.0.3</a></td>
171 <td>2022-09-10</td>
172 <td>Fixed bug in scramble dr</td>
173</tr>
174<tr>
170 <td><a href="/nissy-2.0.2.tar.gz">2.0.2</a></td> 175 <td><a href="/nissy-2.0.2.tar.gz">2.0.2</a></td>
171 <td>2022-06-01</td> 176 <td>2022-06-01</td>
172 <td>Improved table generation speed</td> 177 <td>Improved table generation speed</td>
diff --git a/www/style-2.css b/www/style-3.css
index ec70635..ec70635 100644
--- a/www/style-2.css
+++ b/www/style-3.css

Generated with cgit - Back to sebastiano.tronto.net