diff options
Diffstat (limited to 'src/pruning.c')
| -rw-r--r-- | src/pruning.c | 137 |
1 files changed, 93 insertions, 44 deletions
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 | ||
| 7 | static int findchunk(PruneData *pd, int nchunks, uint64_t i); | 8 | static int findchunk(PruneData *pd, int nchunks, uint64_t i); |
| 8 | static void genptable_bfs(PruneData *pd, int d, int nt, int nc); | 9 | static 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); | |||
| 13 | static bool read_ptable_file(PruneData *pd); | 14 | static bool read_ptable_file(PruneData *pd); |
| 14 | static bool write_ptable_file(PruneData *pd); | 15 | static bool write_ptable_file(PruneData *pd); |
| 15 | 16 | ||
| 16 | PDGenData *active_pdg[256]; | 17 | PruneData *active_pd[256]; |
| 17 | 18 | ||
| 18 | int | 19 | int |
| 19 | findchunk(PruneData *pd, int nchunks, uint64_t i) | 20 | findchunk(PruneData *pd, int nchunks, uint64_t i) |
| @@ -27,26 +28,23 @@ findchunk(PruneData *pd, int nchunks, uint64_t i) | |||
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | PruneData * | 30 | PruneData * |
| 30 | genptable(PDGenData *pdg, int nthreads) | 31 | genptable(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 | ||
| 95 | genptable_done: | 98 | genptable_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 | ||
| 105 | static void | 103 | static 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) | |||
| 264 | uint64_t | 295 | uint64_t |
| 265 | ptablesize(PruneData *pd) | 296 | ptablesize(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 | ||
| 270 | static void | 305 | static void |
| 271 | ptable_update(PruneData *pd, uint64_t ind, int n) | 306 | ptable_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 | ||
| 285 | int | 324 | int |
| 286 | ptableval(PruneData *pd, uint64_t ind) | 325 | ptableval(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 | ||
| 295 | static bool | 344 | static 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); |
