diff options
Diffstat (limited to '')
| -rw-r--r-- | src/pruning.c | 371 |
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 | ||
| 8 | static int findchunk(PruneData *pd, int nchunks, uint64_t i); | 6 | static int findchunk(PruneData *pd, int nchunks, uint64_t i); |
| 9 | static void genptable_bfs(PruneData *pd, int d, int nt, int nc); | 7 | static void genptable_bfs(PruneData *pd, int d, int nt, int nc); |
| 8 | static void genptable_compress(PruneData *pd); | ||
| 10 | static void genptable_fixnasty(PruneData *pd, int d, int nthreads); | 9 | static void genptable_fixnasty(PruneData *pd, int d, int nthreads); |
| 10 | static void genptable_setbase(PruneData *pd); | ||
| 11 | static void * instance_bfs(void *arg); | 11 | static void * instance_bfs(void *arg); |
| 12 | static void * instance_fixnasty(void *arg); | 12 | static void * instance_fixnasty(void *arg); |
| 13 | static void ptable_update(PruneData *pd, uint64_t ind, int m); | 13 | static void ptable_update(PruneData *pd, Cube cube, int m); |
| 14 | static void ptable_update_index(PruneData *pd, uint64_t ind, int m); | ||
| 15 | static int ptableval_index(PruneData *pd, uint64_t ind); | ||
| 14 | static bool read_ptable_file(PruneData *pd); | 16 | static bool read_ptable_file(PruneData *pd); |
| 15 | static bool write_ptable_file(PruneData *pd); | 17 | static bool write_ptable_file(PruneData *pd); |
| 16 | 18 | ||
| 17 | PruneData *active_pd[256]; | 19 | PruneData |
| 20 | pd_eofb_HTM = { | ||
| 21 | .filename = "pt_eofb_HTM", | ||
| 22 | .coord = &coord_eofb, | ||
| 23 | .moveset = &moveset_HTM, | ||
| 24 | }; | ||
| 25 | |||
| 26 | PruneData | ||
| 27 | pd_coud_HTM = { | ||
| 28 | .filename = "pt_coud_HTM", | ||
| 29 | .coord = &coord_coud, | ||
| 30 | .moveset = &moveset_HTM, | ||
| 31 | }; | ||
| 32 | |||
| 33 | PruneData | ||
| 34 | pd_cornershtr_HTM = { | ||
| 35 | .filename = "pt_cornershtr_HTM", | ||
| 36 | .coord = &coord_cornershtr, | ||
| 37 | .moveset = &moveset_HTM, | ||
| 38 | }; | ||
| 39 | |||
| 40 | PruneData | ||
| 41 | pd_corners_HTM = { | ||
| 42 | .filename = "pt_corners_HTM", | ||
| 43 | .coord = &coord_corners, | ||
| 44 | .moveset = &moveset_HTM, | ||
| 45 | }; | ||
| 46 | |||
| 47 | PruneData | ||
| 48 | pd_drud_sym16_HTM = { | ||
| 49 | .filename = "pt_drud_sym16_HTM", | ||
| 50 | .coord = &coord_drud_sym16, | ||
| 51 | .moveset = &moveset_HTM, | ||
| 52 | }; | ||
| 53 | |||
| 54 | PruneData | ||
| 55 | pd_drud_eofb = { | ||
| 56 | .filename = "pt_drud_eofb", | ||
| 57 | .coord = &coord_drud_eofb, | ||
| 58 | .moveset = &moveset_eofb, | ||
| 59 | }; | ||
| 60 | |||
| 61 | PruneData | ||
| 62 | pd_drudfin_noE_sym16_drud = { | ||
| 63 | .filename = "pt_drudfin_noE_sym16_drud", | ||
| 64 | .coord = &coord_drudfin_noE_sym16, | ||
| 65 | .moveset = &moveset_drud, | ||
| 66 | }; | ||
| 67 | |||
| 68 | PruneData | ||
| 69 | pd_htr_drud = { | ||
| 70 | .filename = "pt_htr_drud", | ||
| 71 | .coord = &coord_htr_drud, | ||
| 72 | .moveset = &moveset_drud, | ||
| 73 | }; | ||
| 74 | |||
| 75 | PruneData | ||
| 76 | pd_htrfin_htr = { | ||
| 77 | .filename = "pt_htrfin_htr", | ||
| 78 | .coord = &coord_htrfin, | ||
| 79 | .moveset = &moveset_htr, | ||
| 80 | }; | ||
| 81 | |||
| 82 | PruneData | ||
| 83 | pd_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 | |||
| 93 | PruneData * 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 | ||
| 19 | int | 109 | int |
| 20 | findchunk(PruneData *pd, int nchunks, uint64_t i) | 110 | findchunk(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 | ||
| 30 | PruneData * | 120 | void |
| 31 | genptable(PruneData *pd, int nthreads) | 121 | free_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) | 129 | void |
| 40 | return active_pd[i]; | 130 | genptable(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 | |||
| 98 | genptable_done: | ||
| 99 | for (i = 0; active_pd[i] != NULL; i++); | ||
| 100 | return active_pd[i] = pd; | ||
| 101 | } | 198 | } |
| 102 | 199 | ||
| 103 | static void | 200 | static void |
| @@ -135,6 +232,31 @@ genptable_bfs(PruneData *pd, int d, int nthreads, int nchunks) | |||
| 135 | } | 232 | } |
| 136 | 233 | ||
| 137 | static void | 234 | static void |
| 235 | genptable_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 | |||
| 259 | static void | ||
| 138 | genptable_fixnasty(PruneData *pd, int d, int nthreads) | 260 | genptable_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 | ||
| 287 | static void | ||
| 288 | genptable_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 | |||
| 165 | static void * | 303 | static void * |
| 166 | instance_bfs(void *arg) | 304 | instance_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 * | |||
| 229 | instance_fixnasty(void *arg) | 349 | instance_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 | ||
| 305 | static void | 413 | static void |
| 306 | ptable_update(PruneData *pd, uint64_t ind, int n) | 414 | ptable_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; | 419 | static void |
| 313 | b = pd->compact ? 2 : 4; | 420 | ptable_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 | ||
| 324 | int | 434 | int |
| 325 | ptableval(PruneData *pd, uint64_t ind) | 435 | ptableval(PruneData *pd, Cube cube) |
| 326 | { | 436 | { |
| 327 | int sh; | 437 | return ptableval_index(pd, pd->coord->index(cube)); |
| 328 | uint64_t e; | 438 | } |
| 439 | |||
| 440 | static int | ||
| 441 | ptableval_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 | ||
| 344 | static bool | 481 | static 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; |
