aboutsummaryrefslogtreecommitdiff
path: root/src/pruning.c
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-05-01 12:48:55 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2023-05-01 12:48:55 +0200
commit6f4313bc1ed5be794146e6ca2fd73f48c7906061 (patch)
treea79c8be8613e8b4256d609477f98f440bfd7168c /src/pruning.c
parent1a5bfe9b08707b0aef748d7921a419ba4a046fba (diff)
downloadnissy-classic-6f4313bc1ed5be794146e6ca2fd73f48c7906061.tar.gz
nissy-classic-6f4313bc1ed5be794146e6ca2fd73f48c7906061.zip
Reverted to 2.0.3
Diffstat (limited to 'src/pruning.c')
-rw-r--r--src/pruning.c371
1 files changed, 252 insertions, 119 deletions
diff --git a/src/pruning.c b/src/pruning.c
index 3cc9152..1dba949 100644
--- a/src/pruning.c
+++ b/src/pruning.c
@@ -1,5 +1,3 @@
1#define PRUNING_C
2
3#include "pruning.h" 1#include "pruning.h"
4 2
5#define ENTRIES_PER_GROUP (2*sizeof(entry_group_t)) 3#define ENTRIES_PER_GROUP (2*sizeof(entry_group_t))
@@ -7,14 +5,106 @@
7 5
8static int findchunk(PruneData *pd, int nchunks, uint64_t i); 6static int findchunk(PruneData *pd, int nchunks, uint64_t i);
9static void genptable_bfs(PruneData *pd, int d, int nt, int nc); 7static void genptable_bfs(PruneData *pd, int d, int nt, int nc);
8static void genptable_compress(PruneData *pd);
10static void genptable_fixnasty(PruneData *pd, int d, int nthreads); 9static void genptable_fixnasty(PruneData *pd, int d, int nthreads);
10static void genptable_setbase(PruneData *pd);
11static void * instance_bfs(void *arg); 11static void * instance_bfs(void *arg);
12static void * instance_fixnasty(void *arg); 12static void * instance_fixnasty(void *arg);
13static void ptable_update(PruneData *pd, uint64_t ind, int m); 13static void ptable_update(PruneData *pd, Cube cube, int m);
14static void ptable_update_index(PruneData *pd, uint64_t ind, int m);
15static int ptableval_index(PruneData *pd, uint64_t ind);
14static bool read_ptable_file(PruneData *pd); 16static bool read_ptable_file(PruneData *pd);
15static bool write_ptable_file(PruneData *pd); 17static bool write_ptable_file(PruneData *pd);
16 18
17PruneData *active_pd[256]; 19PruneData
20pd_eofb_HTM = {
21 .filename = "pt_eofb_HTM",
22 .coord = &coord_eofb,
23 .moveset = &moveset_HTM,
24};
25
26PruneData
27pd_coud_HTM = {
28 .filename = "pt_coud_HTM",
29 .coord = &coord_coud,
30 .moveset = &moveset_HTM,
31};
32
33PruneData
34pd_cornershtr_HTM = {
35 .filename = "pt_cornershtr_HTM",
36 .coord = &coord_cornershtr,
37 .moveset = &moveset_HTM,
38};
39
40PruneData
41pd_corners_HTM = {
42 .filename = "pt_corners_HTM",
43 .coord = &coord_corners,
44 .moveset = &moveset_HTM,
45};
46
47PruneData
48pd_drud_sym16_HTM = {
49 .filename = "pt_drud_sym16_HTM",
50 .coord = &coord_drud_sym16,
51 .moveset = &moveset_HTM,
52};
53
54PruneData
55pd_drud_eofb = {
56 .filename = "pt_drud_eofb",
57 .coord = &coord_drud_eofb,
58 .moveset = &moveset_eofb,
59};
60
61PruneData
62pd_drudfin_noE_sym16_drud = {
63 .filename = "pt_drudfin_noE_sym16_drud",
64 .coord = &coord_drudfin_noE_sym16,
65 .moveset = &moveset_drud,
66};
67
68PruneData
69pd_htr_drud = {
70 .filename = "pt_htr_drud",
71 .coord = &coord_htr_drud,
72 .moveset = &moveset_drud,
73};
74
75PruneData
76pd_htrfin_htr = {
77 .filename = "pt_htrfin_htr",
78 .coord = &coord_htrfin,
79 .moveset = &moveset_htr,
80};
81
82PruneData
83pd_nxopt31_HTM = {
84 .filename = "pt_nxopt31_HTM",
85 .coord = &coord_nxopt31,
86 .moveset = &moveset_HTM,
87
88 .compact = true,
89 .fallback = &pd_drud_sym16_HTM,
90 .fbmod = BINOM8ON4,
91};
92
93PruneData * all_pd[] = {
94 &pd_eofb_HTM,
95 &pd_coud_HTM,
96 &pd_cornershtr_HTM,
97 &pd_corners_HTM,
98 &pd_drud_sym16_HTM,
99 &pd_drud_eofb,
100 &pd_drudfin_noE_sym16_drud,
101 &pd_htr_drud,
102 &pd_htrfin_htr,
103 &pd_nxopt31_HTM,
104 NULL
105};
106
107/* Functions *****************************************************************/
18 108
19int 109int
20findchunk(PruneData *pd, int nchunks, uint64_t i) 110findchunk(PruneData *pd, int nchunks, uint64_t i)
@@ -27,47 +117,59 @@ findchunk(PruneData *pd, int nchunks, uint64_t i)
27 return MIN(nchunks-1, (int)(i / chunksize)); 117 return MIN(nchunks-1, (int)(i / chunksize));
28} 118}
29 119
30PruneData * 120void
31genptable(PruneData *pd, int nthreads) 121free_pd(PruneData *pd)
32{ 122{
33 int d, nchunks, i, maxv; 123 if (pd->generated)
34 uint64_t oldn; 124 free(pd->ptable);
35 125
36 for (i = 0; active_pd[i] != NULL; i++) { 126 pd->generated = false;
37 if (active_pd[i]->coord == pd->coord && 127}
38 active_pd[i]->moveset == pd->moveset && 128
39 active_pd[i]->compact == pd->compact) 129void
40 return active_pd[i]; 130genptable(PruneData *pd, int nthreads)
41 } 131{
132 bool compact;
133 int d, nchunks;
134 uint64_t oldn, sz;
42 135
43 init_moveset(pd->moveset); 136 if (pd->generated)
44 gen_coord(pd->coord); 137 return;
45 138
46 pd->ptable = malloc(ptablesize(pd) * sizeof(entry_group_t)); 139 /* TODO: check if memory is enough, otherwise maybe exit gracefully? */
140 sz = ptablesize(pd) * (pd->compact ? 2 : 1);
141 pd->ptable = malloc(sz * sizeof(entry_group_t));
47 142
48 if (read_ptable_file(pd)) 143 if (read_ptable_file(pd)) {
49 goto genptable_done; 144 pd->generated = true;
145 return;
146 }
50 147
51 if (nthreads < 4) { 148 if (nthreads < 4) {
52 fprintf(stderr, 149 fprintf(stderr,
53 "--- Warning ---\n" 150 "--- Warning ---\n"
54 "You are using only %d threads to generate the pruning" 151 "You are using only %d threads to generate the pruning"
55 "tables. This can take a while.\n" 152 "tables. This can take a while."
56 "Unless you did this intentionally, you should re-run" 153 "Unless you did this intentionally, you should re-run"
57 "this command with `-t 4' or more.\n" 154 "this command with `-t 4' or more.\n"
58 "---------------\n\n", nthreads 155 "---------------\n\n", nthreads
59 ); 156 );
60 } 157 }
61 158
159
160 /* For the first steps we proceed the same way for compact and not */
161 compact = pd->compact;
162 pd->compact = false;
163 pd->generated = true;
164
62 nchunks = MIN(ptablesize(pd), 100000); 165 nchunks = MIN(ptablesize(pd), 100000);
63 fprintf(stderr, "Generating pt_%s_%s with %d threads\n", 166 fprintf(stderr, "Cannot load %s, generating it with %d threads\n",
64 pd->coord->name, pd->moveset->name, nthreads); 167 pd->filename, nthreads);
168
65 169
66 memset(pd->ptable, ~(uint8_t)0, ptablesize(pd)*sizeof(entry_group_t)); 170 memset(pd->ptable, ~(uint8_t)0, ptablesize(pd)*sizeof(entry_group_t));
67 for (i = 0; i < 16; i++)
68 pd->count[i] = 0;
69 171
70 ptable_update(pd, 0, 0); 172 ptable_update(pd, (Cube){0}, 0);
71 pd->n = 1; 173 pd->n = 1;
72 oldn = 0; 174 oldn = 0;
73 genptable_fixnasty(pd, 0, nthreads); 175 genptable_fixnasty(pd, 0, nthreads);
@@ -76,9 +178,7 @@ genptable(PruneData *pd, int nthreads)
76 0, pd->n - oldn, pd->n, pd->coord->max); 178 0, pd->n - oldn, pd->n, pd->coord->max);
77 oldn = pd->n; 179 oldn = pd->n;
78 pd->count[0] = pd->n; 180 pd->count[0] = pd->n;
79 181 for (d = 0; d < 15 && pd->n < pd->coord->max; d++) {
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); 182 genptable_bfs(pd, d, nthreads, nchunks);
83 genptable_fixnasty(pd, d+1, nthreads); 183 genptable_fixnasty(pd, d+1, nthreads);
84 fprintf(stderr, "Depth %d done, generated %" 184 fprintf(stderr, "Depth %d done, generated %"
@@ -87,17 +187,14 @@ genptable(PruneData *pd, int nthreads)
87 pd->count[d+1] = pd->n - oldn; 187 pd->count[d+1] = pd->n - oldn;
88 oldn = pd->n; 188 oldn = pd->n;
89 } 189 }
90 if (pd->compact)
91 fprintf(stderr, "Compact table, values above "
92 "%d are inaccurate.\n", maxv-1);
93 fprintf(stderr, "Pruning table generated!\n"); 190 fprintf(stderr, "Pruning table generated!\n");
94 191
192 genptable_setbase(pd);
193 if (compact)
194 genptable_compress(pd);
195
95 if (!write_ptable_file(pd)) 196 if (!write_ptable_file(pd))
96 fprintf(stderr, "Error writing ptable file\n"); 197 fprintf(stderr, "Error writing ptable file\n");
97
98genptable_done:
99 for (i = 0; active_pd[i] != NULL; i++);
100 return active_pd[i] = pd;
101} 198}
102 199
103static void 200static void
@@ -135,6 +232,31 @@ genptable_bfs(PruneData *pd, int d, int nthreads, int nchunks)
135} 232}
136 233
137static void 234static void
235genptable_compress(PruneData *pd)
236{
237 int val;
238 uint64_t i, j;
239 entry_group_t mask, v;
240
241 fprintf(stderr, "Compressing table to 2 bits per entry\n");
242
243 for (i = 0; i < pd->coord->max; i += ENTRIES_PER_GROUP_COMPACT) {
244 mask = (entry_group_t)0;
245 for (j = 0; j < ENTRIES_PER_GROUP_COMPACT; j++) {
246 if (i+j >= pd->coord->max)
247 break;
248 val = ptableval_index(pd, i+j) - pd->base;
249 v = (entry_group_t)MIN(3, MAX(0, val));
250 mask |= v << (2*j);
251 }
252 pd->ptable[i/ENTRIES_PER_GROUP_COMPACT] = mask;
253 }
254
255 pd->compact = true;
256 pd->ptable = realloc(pd->ptable, sizeof(entry_group_t)*ptablesize(pd));
257}
258
259static void
138genptable_fixnasty(PruneData *pd, int d, int nthreads) 260genptable_fixnasty(PruneData *pd, int d, int nthreads)
139{ 261{
140 int i; 262 int i;
@@ -142,7 +264,7 @@ genptable_fixnasty(PruneData *pd, int d, int nthreads)
142 ThreadDataGenpt td[nthreads]; 264 ThreadDataGenpt td[nthreads];
143 pthread_mutex_t *upmtx; 265 pthread_mutex_t *upmtx;
144 266
145 if (pd->coord->type != SYMCOMP_COORD) 267 if (pd->coord->tfind == NULL)
146 return; 268 return;
147 269
148 upmtx = malloc(sizeof(pthread_mutex_t)); 270 upmtx = malloc(sizeof(pthread_mutex_t));
@@ -162,12 +284,28 @@ genptable_fixnasty(PruneData *pd, int d, int nthreads)
162 free(upmtx); 284 free(upmtx);
163} 285}
164 286
287static void
288genptable_setbase(PruneData *pd)
289{
290 int i;
291 uint64_t sum, newsum;
292
293 pd->base = 0;
294 sum = pd->count[0] + pd->count[1] + pd->count[2];
295 for (i = 3; i < 16; i++) {
296 newsum = sum + pd->count[i] - pd->count[i-3];
297 if (newsum > sum)
298 pd->base = i-3;
299 sum = newsum;
300 }
301}
302
165static void * 303static void *
166instance_bfs(void *arg) 304instance_bfs(void *arg)
167{ 305{
168 ThreadDataGenpt *td; 306 ThreadDataGenpt *td;
169 uint64_t i, ii, blocksize, rmin, rmax, updated; 307 uint64_t i, ii, blocksize, rmin, rmax, updated;
170 int j, pval, ichunk, oldc, newc; 308 int j, pval, ichunk;
171 Move *ms; 309 Move *ms;
172 310
173 td = (ThreadDataGenpt *)arg; 311 td = (ThreadDataGenpt *)arg;
@@ -178,43 +316,25 @@ instance_bfs(void *arg)
178 td->pd->coord->max : 316 td->pd->coord->max :
179 ((uint64_t)td->thid + 1) * blocksize; 317 ((uint64_t)td->thid + 1) * blocksize;
180 318
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
194 updated = 0; 319 updated = 0;
195 for (i = rmin; i < rmax; i++) { 320 for (i = rmin; i < rmax; i++) {
196 ichunk = findchunk(td->pd, td->nchunks, i); 321 ichunk = findchunk(td->pd, td->nchunks, i);
197 pthread_mutex_lock(td->mutex[ichunk]); 322 pthread_mutex_lock(td->mutex[ichunk]);
198 pval = ptableval(td->pd, i); 323 pval = ptableval_index(td->pd, i);
199 pthread_mutex_unlock(td->mutex[ichunk]); 324 pthread_mutex_unlock(td->mutex[ichunk]);
200 if (pval == oldc) { 325 if (pval == td->d) {
201 for (j = 0; ms[j] != NULLMOVE; j++) { 326 for (j = 0; ms[j] != NULLMOVE; j++) {
202 ii = move_coord(td->pd->coord, ms[j], i, NULL); 327 ii = td->pd->coord->move(ms[j], i);
203 ichunk = findchunk(td->pd, td->nchunks, ii); 328 ichunk = findchunk(td->pd, td->nchunks, ii);
204 pthread_mutex_lock(td->mutex[ichunk]); 329 pthread_mutex_lock(td->mutex[ichunk]);
205 pval = ptableval(td->pd, ii); 330 pval = ptableval_index(td->pd, ii);
206 if (pval > newc) { 331 if (pval > td->d+1) {
207 ptable_update(td->pd, ii, newc); 332 ptable_update_index(td->pd,
333 ii, td->d+1);
208 updated++; 334 updated++;
209 } 335 }
210 pthread_mutex_unlock(td->mutex[ichunk]); 336 pthread_mutex_unlock(td->mutex[ichunk]);
211 } 337 }
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 }
218 } 338 }
219 } 339 }
220 340
@@ -229,40 +349,30 @@ static void *
229instance_fixnasty(void *arg) 349instance_fixnasty(void *arg)
230{ 350{
231 ThreadDataGenpt *td; 351 ThreadDataGenpt *td;
232 uint64_t i, ii, blocksize, rmin, rmax, updated, ss, M; 352 uint64_t i, ii, nb, blocksize, rmin, rmax, updated;
233 int j, oldc; 353 int j, n;
234 Trans t; 354 Trans t, aux[NTRANS];
235 355
236 td = (ThreadDataGenpt *)arg; 356 td = (ThreadDataGenpt *)arg;
237 357 nb = td->pd->coord->max / td->pd->coord->base->max;
238 /* We know type = SYMCOMP_COORD */ 358 blocksize = (td->pd->coord->base->max / td->nthreads) * nb;
239 M = td->pd->coord->base[1]->max;
240 blocksize = (td->pd->coord->base[0]->max / td->nthreads) * M;
241 rmin = ((uint64_t)td->thid) * blocksize; 359 rmin = ((uint64_t)td->thid) * blocksize;
242 rmax = td->thid == td->nthreads - 1 ? 360 rmax = td->thid == td->nthreads - 1 ?
243 td->pd->coord->max : 361 td->pd->coord->max :
244 ((uint64_t)td->thid + 1) * blocksize; 362 ((uint64_t)td->thid + 1) * blocksize;
245 363
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
255 updated = 0; 364 updated = 0;
256 for (i = rmin; i < rmax; i++) { 365 for (i = rmin; i < rmax; i++) {
257 if (ptableval(td->pd, i) == oldc) { 366 if (ptableval_index(td->pd, i) == td->d) {
258 ss = td->pd->coord->base[0]->selfsim[i/M]; 367 if ((n = td->pd->coord->tfind(i, aux)) == 1)
259 for (j = 0; j < td->pd->coord->base[0]->tgrp->n; j++) { 368 continue;
260 t = td->pd->coord->base[0]->tgrp->t[j]; 369
261 if (t == uf || !(ss & ((uint64_t)1<<t))) 370 for (j = 0; j < n; j++) {
371 if ((t = aux[j]) == uf)
262 continue; 372 continue;
263 ii = trans_coord(td->pd->coord, t, i); 373 ii = td->pd->coord->transform(t, i);
264 if (ptableval(td->pd, ii) > oldc) { 374 if (ptableval_index(td->pd, ii) > td->d) {
265 ptable_update(td->pd, ii, oldc); 375 ptable_update_index(td->pd, ii, td->d);
266 updated++; 376 updated++;
267 } 377 }
268 } 378 }
@@ -281,13 +391,11 @@ print_ptable(PruneData *pd)
281{ 391{
282 uint64_t i; 392 uint64_t i;
283 393
284 printf("Table %s_%s\n", pd->coord->name, pd->moveset->name); 394 if (!pd->generated)
285 395 genptable(pd, 1); /* TODO: set default nthreads somewhere */
286 if (pd->compact) { 396
287 printf("Compract table with base value: %d\n", pd->base); 397 printf("Table %s\n", pd->filename);
288 printf("Values above %d are inaccurate.\n", pd->base + 3); 398 printf("Base value: %d\n", pd->base);
289 }
290
291 for (i = 0; i < 16; i++) 399 for (i = 0; i < 16; i++)
292 printf("%2" PRIu64 "\t%10" PRIu64 "\n", i, pd->count[i]); 400 printf("%2" PRIu64 "\t%10" PRIu64 "\n", i, pd->count[i]);
293} 401}
@@ -303,31 +411,48 @@ ptablesize(PruneData *pd)
303} 411}
304 412
305static void 413static void
306ptable_update(PruneData *pd, uint64_t ind, int n) 414ptable_update(PruneData *pd, Cube cube, int n)
307{ 415{
308 int sh; 416 ptable_update_index(pd, pd->coord->index(cube), n);
309 entry_group_t f, mask; 417}
310 uint64_t i, e, b;
311 418
312 e = pd->compact ? ENTRIES_PER_GROUP_COMPACT : ENTRIES_PER_GROUP; 419static void
313 b = pd->compact ? 2 : 4; 420ptable_update_index(PruneData *pd, uint64_t ind, int n)
314 f = pd->compact ? 3 : 15; 421{
422 int sh;
423 entry_group_t mask;
424 uint64_t i;
315 425
316 sh = b * (ind % e); 426 sh = 4 * (ind % ENTRIES_PER_GROUP);
317 mask = f << sh; 427 mask = ((entry_group_t)15) << sh;
318 i = ind / e; 428 i = ind/ENTRIES_PER_GROUP;
319 429
320 pd->ptable[i] &= ~mask; 430 pd->ptable[i] &= ~mask;
321 pd->ptable[i] |= (((entry_group_t)n) & f) << sh; 431 pd->ptable[i] |= (((entry_group_t)n)&15) << sh;
322} 432}
323 433
324int 434int
325ptableval(PruneData *pd, uint64_t ind) 435ptableval(PruneData *pd, Cube cube)
326{ 436{
327 int sh; 437 return ptableval_index(pd, pd->coord->index(cube));
328 uint64_t e; 438}
439
440static int
441ptableval_index(PruneData *pd, uint64_t ind)
442{
443 int sh, ret;
444 entry_group_t mask;
445 uint64_t i, e;
329 entry_group_t m; 446 entry_group_t m;
330 447
448 if (!pd->generated) {
449 fprintf(stderr, "Warning: request pruning table value"
450 " for uninitialized table %s.\n It's fine, but it"
451 " should not happen. Please report bug.\n",
452 pd->filename);
453 genptable(pd, 1); /* TODO: set default or remove this case */
454 }
455
331 if (pd->compact) { 456 if (pd->compact) {
332 e = ENTRIES_PER_GROUP_COMPACT; 457 e = ENTRIES_PER_GROUP_COMPACT;
333 m = 3; 458 m = 3;
@@ -338,7 +463,19 @@ ptableval(PruneData *pd, uint64_t ind)
338 sh = (ind % e) * 4; 463 sh = (ind % e) * 4;
339 } 464 }
340 465
341 return (pd->ptable[ind/e] & (m << sh)) >> sh; 466 mask = m << sh;
467 i = ind/e;
468
469 ret = (pd->ptable[i] & mask) >> sh;
470
471 if (pd->compact) {
472 if (ret)
473 ret += pd->base;
474 else
475 ret = ptableval_index(pd->fallback, ind / pd->fbmod);
476 }
477
478 return ret;
342} 479}
343 480
344static bool 481static bool
@@ -347,15 +484,13 @@ read_ptable_file(PruneData *pd)
347 init_env(); 484 init_env();
348 485
349 FILE *f; 486 FILE *f;
350 char fname[strlen(tabledir)+256]; 487 char fname[strlen(tabledir)+100];
351 int i; 488 int i;
352 uint64_t r; 489 uint64_t r;
353 490
354 strcpy(fname, tabledir); 491 strcpy(fname, tabledir);
355 strcat(fname, "/pt_"); 492 strcat(fname, "/");
356 strcat(fname, pd->coord->name); 493 strcat(fname, pd->filename);
357 strcat(fname, "_");
358 strcat(fname, pd->moveset->name);
359 494
360 if ((f = fopen(fname, "rb")) == NULL) 495 if ((f = fopen(fname, "rb")) == NULL)
361 return false; 496 return false;
@@ -376,15 +511,13 @@ write_ptable_file(PruneData *pd)
376 init_env(); 511 init_env();
377 512
378 FILE *f; 513 FILE *f;
379 char fname[strlen(tabledir)+256]; 514 char fname[strlen(tabledir)+100];
380 int i; 515 int i;
381 uint64_t w; 516 uint64_t w;
382 517
383 strcpy(fname, tabledir); 518 strcpy(fname, tabledir);
384 strcat(fname, "/pt_"); 519 strcat(fname, "/");
385 strcat(fname, pd->coord->name); 520 strcat(fname, pd->filename);
386 strcat(fname, "_");
387 strcat(fname, pd->moveset->name);
388 521
389 if ((f = fopen(fname, "wb")) == NULL) 522 if ((f = fopen(fname, "wb")) == NULL)
390 return false; 523 return false;

Generated with cgit - Back to sebastiano.tronto.net