aboutsummaryrefslogtreecommitdiff
path: root/src/pruning.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/pruning.c95
1 files changed, 52 insertions, 43 deletions
diff --git a/src/pruning.c b/src/pruning.c
index b305a89..0a6e305 100644
--- a/src/pruning.c
+++ b/src/pruning.c
@@ -1,11 +1,10 @@
1#include "pruning.h" 1#include "pruning.h"
2 2
3/* Chunks for multithreading */ 3#define NCHUNKS 100000
4/* TODO: try smaller */ 4#define ENTRIES_PER_GROUP (2*sizeof(entry_group_t))
5#define NCHUNKS 100000
6 5
7static int findchunk(PruneData *pd, int nchunks, uint64_t i); 6static int findchunk(PruneData *pd, int nchunks, uint64_t i);
8static void genptable_bfs(PruneData *pd,int d,Move *ms,int nt,int nc); 7static void genptable_bfs(PruneData *pd, int d, int nt, int nc);
9static void genptable_fixnasty(PruneData *pd, int d); 8static void genptable_fixnasty(PruneData *pd, int d);
10static void * instance_bfs(void *arg); 9static void * instance_bfs(void *arg);
11static void ptable_update(PruneData *pd, Cube cube, int m); 10static void ptable_update(PruneData *pd, Cube cube, int m);
@@ -18,70 +17,77 @@ PruneData
18pd_eofb_HTM = { 17pd_eofb_HTM = {
19 .filename = "pt_eofb_HTM", 18 .filename = "pt_eofb_HTM",
20 .coord = &coord_eofb, 19 .coord = &coord_eofb,
21 .moveset = moveset_HTM, 20 .moveset = &moveset_HTM,
22}; 21};
23 22
24PruneData 23PruneData
25pd_coud_HTM = { 24pd_coud_HTM = {
26 .filename = "pt_coud_HTM", 25 .filename = "pt_coud_HTM",
27 .coord = &coord_coud, 26 .coord = &coord_coud,
28 .moveset = moveset_HTM, 27 .moveset = &moveset_HTM,
29}; 28};
30 29
31PruneData 30PruneData
32pd_cornershtr_HTM = { 31pd_cornershtr_HTM = {
33 .filename = "pt_cornershtr_HTM", 32 .filename = "pt_cornershtr_HTM",
34 .coord = &coord_cornershtr, 33 .coord = &coord_cornershtr,
35 .moveset = moveset_HTM, 34 .moveset = &moveset_HTM,
36}; 35};
37 36
38PruneData 37PruneData
39pd_corners_HTM = { 38pd_corners_HTM = {
40 .filename = "pt_corners_HTM", 39 .filename = "pt_corners_HTM",
41 .coord = &coord_corners, 40 .coord = &coord_corners,
42 .moveset = moveset_HTM, 41 .moveset = &moveset_HTM,
43}; 42};
44 43
45PruneData 44PruneData
46pd_drud_sym16_HTM = { 45pd_drud_sym16_HTM = {
47 .filename = "pt_drud_sym16_HTM", 46 .filename = "pt_drud_sym16_HTM",
48 .coord = &coord_drud_sym16, 47 .coord = &coord_drud_sym16,
49 .moveset = moveset_HTM, 48 .moveset = &moveset_HTM,
50}; 49};
51 50
52PruneData 51PruneData
53pd_drud_eofb = { 52pd_drud_eofb = {
54 .filename = "pt_drud_eofb", 53 .filename = "pt_drud_eofb",
55 .coord = &coord_drud_eofb, 54 .coord = &coord_drud_eofb,
56 .moveset = moveset_eofb, 55 .moveset = &moveset_eofb,
57}; 56};
58 57
59PruneData 58PruneData
60pd_drudfin_noE_sym16_drud = { 59pd_drudfin_noE_sym16_drud = {
61 .filename = "pt_drudfin_noE_sym16_drud", 60 .filename = "pt_drudfin_noE_sym16_drud",
62 .coord = &coord_drudfin_noE_sym16, 61 .coord = &coord_drudfin_noE_sym16,
63 .moveset = moveset_drud, 62 .moveset = &moveset_drud,
64}; 63};
65 64
66PruneData 65PruneData
67pd_htr_drud = { 66pd_htr_drud = {
68 .filename = "pt_htr_drud", 67 .filename = "pt_htr_drud",
69 .coord = &coord_htr_drud, 68 .coord = &coord_htr_drud,
70 .moveset = moveset_drud, 69 .moveset = &moveset_drud,
71}; 70};
72 71
73PruneData 72PruneData
74pd_htrfin_htr = { 73pd_htrfin_htr = {
75 .filename = "pt_htrfin_htr", 74 .filename = "pt_htrfin_htr",
76 .coord = &coord_htrfin, 75 .coord = &coord_htrfin,
77 .moveset = moveset_htr, 76 .moveset = &moveset_htr,
78}; 77};
79 78
80PruneData 79PruneData
81pd_khuge_HTM = { 80pd_khuge_HTM = {
82 .filename = "pt_khuge_HTM", 81 .filename = "pt_khuge_HTM",
83 .coord = &coord_khuge, 82 .coord = &coord_khuge,
84 .moveset = moveset_HTM, 83 .moveset = &moveset_HTM,
84};
85
86PruneData
87pd_nxopt31_HTM = {
88 .filename = "pt_nxopt31_HTM",
89 .coord = &coord_nxopt31,
90 .moveset = &moveset_HTM,
85}; 91};
86 92
87PruneData * allpd[NPTABLES] = { 93PruneData * allpd[NPTABLES] = {
@@ -95,6 +101,7 @@ PruneData * allpd[NPTABLES] = {
95 &pd_htr_drud, 101 &pd_htr_drud,
96 &pd_htrfin_htr, 102 &pd_htrfin_htr,
97 &pd_khuge_HTM, 103 &pd_khuge_HTM,
104 &pd_nxopt31_HTM,
98}; 105};
99 106
100/* Functions *****************************************************************/ 107/* Functions *****************************************************************/
@@ -105,8 +112,7 @@ findchunk(PruneData *pd, int nchunks, uint64_t i)
105 uint64_t chunksize; 112 uint64_t chunksize;
106 113
107 chunksize = pd->coord->max / (uint64_t)nchunks; 114 chunksize = pd->coord->max / (uint64_t)nchunks;
108 if (chunksize % 2 != 0) 115 chunksize += ENTRIES_PER_GROUP - (chunksize % ENTRIES_PER_GROUP);
109 chunksize++;
110 116
111 return MIN(nchunks-1, (int)(i / chunksize)); 117 return MIN(nchunks-1, (int)(i / chunksize));
112} 118}
@@ -114,15 +120,14 @@ findchunk(PruneData *pd, int nchunks, uint64_t i)
114void 120void
115genptable(PruneData *pd, int nthreads) 121genptable(PruneData *pd, int nthreads)
116{ 122{
117 Move *ms;
118 int d, nchunks; 123 int d, nchunks;
119 uint64_t j, oldn; 124 uint64_t oldn;
120 125
121 if (pd->generated) 126 if (pd->generated)
122 return; 127 return;
123 128
124 /* TODO: check if memory is enough, otherwise maybe exit gracefully? */ 129 /* TODO: check if memory is enough, otherwise maybe exit gracefully? */
125 pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t)); 130 pd->ptable = malloc(ptablesize(pd) * sizeof(entry_group_t));
126 131
127 if (read_ptable_file(pd)) { 132 if (read_ptable_file(pd)) {
128 pd->generated = true; 133 pd->generated = true;
@@ -130,17 +135,12 @@ genptable(PruneData *pd, int nthreads)
130 } 135 }
131 pd->generated = true; 136 pd->generated = true;
132 137
133 nchunks = MIN(pd->coord->max/2, NCHUNKS); 138 nchunks = MIN(pd->coord->max/ENTRIES_PER_GROUP, NCHUNKS);
134 fprintf(stderr, "Cannot load %s, generating it " 139 fprintf(stderr, "Cannot load %s, generating it "
135 "with %d threads and %d chunks\n", 140 "with %d threads and %d chunks\n",
136 pd->filename, nthreads, nchunks); 141 pd->filename, nthreads, nchunks);
137 142
138 ms = malloc(NMOVES * sizeof(Move)); 143 memset(pd->ptable, ~(uint8_t)0, ptablesize(pd)*sizeof(entry_group_t));
139 moveset_to_list(pd->moveset, ms);
140
141 /* We use 4 bits per value, so any distance >= 15 is set to 15 */
142 for (j = 0; j < pd->coord->max; j++)
143 ptable_update_index(pd, j, 15);
144 144
145 ptable_update(pd, (Cube){0}, 0); 145 ptable_update(pd, (Cube){0}, 0);
146 pd->n = 1; 146 pd->n = 1;
@@ -151,7 +151,7 @@ genptable(PruneData *pd, int nthreads)
151 0, pd->n - oldn, pd->n, pd->coord->max); 151 0, pd->n - oldn, pd->n, pd->coord->max);
152 oldn = pd->n; 152 oldn = pd->n;
153 for (d = 0; d < 15 && pd->n < pd->coord->max; d++) { 153 for (d = 0; d < 15 && pd->n < pd->coord->max; d++) {
154 genptable_bfs(pd, d, ms, nthreads, nchunks); 154 genptable_bfs(pd, d, nthreads, nchunks);
155 genptable_fixnasty(pd, d+1); 155 genptable_fixnasty(pd, d+1);
156 fprintf(stderr, "Depth %d done, generated %" 156 fprintf(stderr, "Depth %d done, generated %"
157 PRIu64 "\t(%" PRIu64 "/%" PRIu64 ")\n", 157 PRIu64 "\t(%" PRIu64 "/%" PRIu64 ")\n",
@@ -162,12 +162,10 @@ genptable(PruneData *pd, int nthreads)
162 162
163 if (!write_ptable_file(pd)) 163 if (!write_ptable_file(pd))
164 fprintf(stderr, "Error writing ptable file\n"); 164 fprintf(stderr, "Error writing ptable file\n");
165
166 free(ms);
167} 165}
168 166
169static void 167static void
170genptable_bfs(PruneData *pd, int d, Move *ms, int nthreads, int nchunks) 168genptable_bfs(PruneData *pd, int d, int nthreads, int nchunks)
171{ 169{
172 int i; 170 int i;
173 pthread_t t[nthreads]; 171 pthread_t t[nthreads];
@@ -186,7 +184,6 @@ genptable_bfs(PruneData *pd, int d, Move *ms, int nthreads, int nchunks)
186 td[i].nthreads = nthreads; 184 td[i].nthreads = nthreads;
187 td[i].pd = pd; 185 td[i].pd = pd;
188 td[i].d = d; 186 td[i].d = d;
189 td[i].ms = ms;
190 td[i].nchunks = nchunks; 187 td[i].nchunks = nchunks;
191 td[i].mutex = mtx; 188 td[i].mutex = mtx;
192 td[i].upmutex = upmtx; 189 td[i].upmutex = upmtx;
@@ -237,8 +234,10 @@ instance_bfs(void *arg)
237 uint64_t i, ii, blocksize, rmin, rmax, updated; 234 uint64_t i, ii, blocksize, rmin, rmax, updated;
238 int j, pval, ichunk; 235 int j, pval, ichunk;
239 Cube c, cc; 236 Cube c, cc;
237 Move *ms;
240 238
241 td = (ThreadDataGenpt *)arg; 239 td = (ThreadDataGenpt *)arg;
240 ms = td->pd->moveset->sorted_moves;
242 blocksize = td->pd->coord->max / (uint64_t)td->nthreads; 241 blocksize = td->pd->coord->max / (uint64_t)td->nthreads;
243 rmin = ((uint64_t)td->thid) * blocksize; 242 rmin = ((uint64_t)td->thid) * blocksize;
244 rmax = td->thid == td->nthreads - 1 ? 243 rmax = td->thid == td->nthreads - 1 ?
@@ -253,8 +252,8 @@ instance_bfs(void *arg)
253 pthread_mutex_unlock(td->mutex[ichunk]); 252 pthread_mutex_unlock(td->mutex[ichunk]);
254 if (pval == td->d) { 253 if (pval == td->d) {
255 c = td->pd->coord->cube(i); 254 c = td->pd->coord->cube(i);
256 for (j = 0; td->ms[j] != NULLMOVE; j++) { 255 for (j = 0; ms[j] != NULLMOVE; j++) {
257 cc = apply_move(td->ms[j], c); 256 cc = apply_move(ms[j], c);
258 ii = td->pd->coord->index(cc); 257 ii = td->pd->coord->index(cc);
259 ichunk = findchunk(td->pd, td->nchunks, ii); 258 ichunk = findchunk(td->pd, td->nchunks, ii);
260 pthread_mutex_lock(td->mutex[ichunk]); 259 pthread_mutex_lock(td->mutex[ichunk]);
@@ -296,7 +295,7 @@ print_ptable(PruneData *pd)
296uint64_t 295uint64_t
297ptablesize(PruneData *pd) 296ptablesize(PruneData *pd)
298{ 297{
299 return (pd->coord->max + 1) / 2; 298 return (pd->coord->max + ENTRIES_PER_GROUP - 1) / ENTRIES_PER_GROUP;
300} 299}
301 300
302static void 301static void
@@ -308,14 +307,16 @@ ptable_update(PruneData *pd, Cube cube, int n)
308static void 307static void
309ptable_update_index(PruneData *pd, uint64_t ind, int n) 308ptable_update_index(PruneData *pd, uint64_t ind, int n)
310{ 309{
311 uint8_t oldval2; 310 int sh;
312 int other; 311 entry_group_t mask;
312 uint64_t i;
313 313
314 oldval2 = pd->ptable[ind/2]; 314 sh = 4 * (ind % ENTRIES_PER_GROUP);
315 other = (ind % 2) ? oldval2 % 16 : oldval2 / 16; 315 mask = ((entry_group_t)15) << sh;
316 i = ind/ENTRIES_PER_GROUP;
316 317
317 pd->ptable[ind/2] = (ind % 2) ? 16*n + other : 16*other + n; 318 pd->ptable[i] &= ~mask;
318 /*pd->n++;*/ 319 pd->ptable[i] |= (((entry_group_t)n)&15) << sh;
319} 320}
320 321
321int 322int
@@ -327,6 +328,10 @@ ptableval(PruneData *pd, Cube cube)
327static int 328static int
328ptableval_index(PruneData *pd, uint64_t ind) 329ptableval_index(PruneData *pd, uint64_t ind)
329{ 330{
331 int sh;
332 entry_group_t mask;
333 uint64_t i;
334
330 if (!pd->generated) { 335 if (!pd->generated) {
331 fprintf(stderr, "Warning: request pruning table value" 336 fprintf(stderr, "Warning: request pruning table value"
332 " for uninitialized table %s.\n It's fine, but it" 337 " for uninitialized table %s.\n It's fine, but it"
@@ -335,7 +340,11 @@ ptableval_index(PruneData *pd, uint64_t ind)
335 genptable(pd, 1); /* TODO: set default or remove this case */ 340 genptable(pd, 1); /* TODO: set default or remove this case */
336 } 341 }
337 342
338 return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16; 343 sh = 4 * (ind % ENTRIES_PER_GROUP);
344 mask = ((entry_group_t)15) << sh;
345 i = ind/ENTRIES_PER_GROUP;
346
347 return (pd->ptable[i] & mask) >> sh;
339} 348}
340 349
341static bool 350static bool
@@ -354,7 +363,7 @@ read_ptable_file(PruneData *pd)
354 if ((f = fopen(fname, "rb")) == NULL) 363 if ((f = fopen(fname, "rb")) == NULL)
355 return false; 364 return false;
356 365
357 r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f); 366 r = fread(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f);
358 fclose(f); 367 fclose(f);
359 368
360 return r == ptablesize(pd); 369 return r == ptablesize(pd);
@@ -376,7 +385,7 @@ write_ptable_file(PruneData *pd)
376 if ((f = fopen(fname, "wb")) == NULL) 385 if ((f = fopen(fname, "wb")) == NULL)
377 return false; 386 return false;
378 387
379 written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f); 388 written = fwrite(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f);
380 fclose(f); 389 fclose(f);
381 390
382 return written == ptablesize(pd); 391 return written == ptablesize(pd);

Generated with cgit - Back to sebastiano.tronto.net