aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48
diff options
context:
space:
mode:
Diffstat (limited to 'src/solvers/h48')
-rw-r--r--src/solvers/h48/gendata_h48.h91
-rw-r--r--src/solvers/h48/gendata_types_macros.h24
2 files changed, 72 insertions, 43 deletions
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
index 4124d56..b5af03a 100644
--- a/src/solvers/h48/gendata_h48.h
+++ b/src/solvers/h48/gendata_h48.h
@@ -1,43 +1,27 @@
1/*
2TODO: This loop over similar h48 coordinates can be improved by only
3transforming edges, but we need to compose transformations (i.e. conjugate
4_t by _ttrep).
5*/
6#define FOREACH_H48SIM(ARG_CUBE, ARG_COCSEPDATA, ARG_SELFSIM, ARG_ACTION) \
7 int64_t VAR_COCSEP = coord_cocsep(ARG_CUBE); \
8 uint8_t VAR_TTREP = TTREP(ARG_COCSEPDATA[VAR_COCSEP]); \
9 uint8_t VAR_INVERSE_TTREP = inverse_trans(VAR_TTREP); \
10 int64_t VAR_COCLASS = COCLASS(ARG_COCSEPDATA[VAR_COCSEP]); \
11 cube_t VAR_REP = transform(ARG_CUBE, VAR_TTREP); \
12 uint64_t VAR_S = ARG_SELFSIM[VAR_COCLASS]; \
13 for (uint8_t VAR_T = 0; VAR_T < 48 && VAR_S; VAR_T++, VAR_S >>= 1) { \
14 if (!(VAR_S & 1)) continue; \
15 ARG_CUBE = transform(VAR_REP, VAR_T); \
16 ARG_CUBE = transform(ARG_CUBE, VAR_INVERSE_TTREP); \
17 ARG_ACTION \
18 }
19
20STATIC uint64_t gendata_h48short(gendata_h48short_arg_t *); 1STATIC uint64_t gendata_h48short(gendata_h48short_arg_t *);
21STATIC size_t gendata_h48(gendata_h48_arg_t *); 2STATIC size_t gendata_h48(gendata_h48_arg_t *);
22STATIC size_t gendata_h48h0k4(gendata_h48_arg_t *); 3STATIC size_t gendata_h48h0k4(gendata_h48_arg_t *);
23STATIC size_t gendata_h48k2(gendata_h48_arg_t *); 4STATIC size_t gendata_h48k2(gendata_h48_arg_t *);
24STATIC void * gendata_h48h0k4_runthread(void *); 5STATIC void * gendata_h48h0k4_runthread(void *);
6STATIC_INLINE void gendata_h48_mark_atomic(gendata_h48_mark_t *);
25STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t *); 7STATIC_INLINE void gendata_h48_mark(gendata_h48_mark_t *);
26STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, int8_t, h48k2_dfs_arg_t *); 8STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, int8_t, h48k2_dfs_arg_t *);
27STATIC size_t gendata_h48k2_realcoord(gendata_h48_arg_t *); 9STATIC size_t gendata_h48k2_realcoord(gendata_h48_arg_t *);
28STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); 10STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg);
29STATIC void * gendata_h48k2_runthread(void *); 11STATIC void * gendata_h48k2_runthread(void *);
30STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *); 12STATIC tableinfo_t makeinfo_h48k2(gendata_h48_arg_t *);
31STATIC void getdistribution_h48(_Atomic const uint8_t *, 13STATIC void getdistribution_h48(const uint8_t *,
32 uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t); 14 uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t, uint8_t);
33 15
34STATIC const uint32_t *get_cocsepdata_constptr(const void *); 16STATIC const uint32_t *get_cocsepdata_constptr(const void *);
35STATIC const uint8_t *get_h48data_constptr(const void *); 17STATIC const uint8_t *get_h48data_constptr(const void *);
36 18
19STATIC_INLINE uint8_t get_h48_pval(const uint8_t *, int64_t, uint8_t);
20STATIC_INLINE void set_h48_pval(uint8_t *, int64_t, uint8_t, uint8_t);
37STATIC_INLINE uint8_t get_h48_pval_atomic( 21STATIC_INLINE uint8_t get_h48_pval_atomic(
38 _Atomic const uint8_t *, int64_t, uint8_t); 22 _Atomic const uint8_t *, int64_t, uint8_t);
39STATIC_INLINE uint8_t get_h48_pval(const uint8_t *, int64_t, uint8_t); 23STATIC_INLINE void set_h48_pval_atomic(
40STATIC_INLINE void set_h48_pval(_Atomic uint8_t *, int64_t, uint8_t, uint8_t); 24 _Atomic uint8_t *, int64_t, uint8_t, uint8_t);
41STATIC_INLINE uint8_t get_h48_bound( 25STATIC_INLINE uint8_t get_h48_bound(
42 cube_t, uint32_t, uint8_t, uint8_t, const uint8_t *); 26 cube_t, uint32_t, uint8_t, uint8_t, const uint8_t *);
43 27
@@ -166,7 +150,7 @@ gendata_h48h0k4(gendata_h48_arg_t *arg)
166 150
167 h48max = (int64_t)H48_COORDMAX(0); 151 h48max = (int64_t)H48_COORDMAX(0);
168 sc = coord_h48(SOLVED_CUBE, arg->cocsepdata, 0); 152 sc = coord_h48(SOLVED_CUBE, arg->cocsepdata, 0);
169 set_h48_pval(table, sc, 4, 0); 153 set_h48_pval_atomic(table, sc, 4, 0);
170 arg->info.distribution[0] = 1; 154 arg->info.distribution[0] = 1;
171 155
172 isize = h48max / THREADS; 156 isize = h48max / THREADS;
@@ -235,7 +219,7 @@ gendata_h48h0k4_runthread(void *arg)
235 .k = 4, 219 .k = 4,
236 .cocsepdata = bfsarg->cocsepdata, 220 .cocsepdata = bfsarg->cocsepdata,
237 .selfsim = bfsarg->selfsim, 221 .selfsim = bfsarg->selfsim,
238 .table = bfsarg->table, 222 .table_atomic = bfsarg->table,
239 .table_mutex = bfsarg->table_mutex, 223 .table_mutex = bfsarg->table_mutex,
240 }; 224 };
241 225
@@ -259,12 +243,12 @@ gendata_h48h0k4_runthread(void *arg)
259 if (c <= bfsarg->depth) 243 if (c <= bfsarg->depth)
260 continue; 244 continue;
261 markarg.cube = moved; 245 markarg.cube = moved;
262 gendata_h48_mark(&markarg); 246 gendata_h48_mark_atomic(&markarg);
263 } else { 247 } else {
264 if (c >= bfsarg->depth) 248 if (c >= bfsarg->depth)
265 continue; 249 continue;
266 markarg.cube = cube; 250 markarg.cube = cube;
267 gendata_h48_mark(&markarg); 251 gendata_h48_mark_atomic(&markarg);
268 break; /* Enough to find one, skip the rest */ 252 break; /* Enough to find one, skip the rest */
269 } 253 }
270 } 254 }
@@ -326,7 +310,7 @@ gendata_h48k2(gendata_h48_arg_t *arg)
326 }; 310 };
327 311
328 uint8_t t; 312 uint8_t t;
329 _Atomic uint8_t *table; 313 uint8_t *table;
330 int64_t j; 314 int64_t j;
331 uint64_t i, ii, inext, count; 315 uint64_t i, ii, inext, count;
332 h48map_t shortcubes; 316 h48map_t shortcubes;
@@ -338,7 +322,7 @@ gendata_h48k2(gendata_h48_arg_t *arg)
338 if (arg->buf == NULL) 322 if (arg->buf == NULL)
339 goto gendata_h48k2_return_size; 323 goto gendata_h48k2_return_size;
340 324
341 table = (_Atomic uint8_t *)arg->h48buf + INFOSIZE; 325 table = (uint8_t *)arg->h48buf + INFOSIZE;
342 if (arg->buf != NULL) 326 if (arg->buf != NULL)
343 memset(table, 0xFF, H48_TABLESIZE(arg->h, arg->k)); 327 memset(table, 0xFF, H48_TABLESIZE(arg->h, arg->k));
344 328
@@ -389,7 +373,7 @@ gendata_h48k2(gendata_h48_arg_t *arg)
389 h48map_destroy(&shortcubes); 373 h48map_destroy(&shortcubes);
390 374
391 for (j = 0; j < H48_COORDMAX(arg->h); j++) { 375 for (j = 0; j < H48_COORDMAX(arg->h); j++) {
392 t = get_h48_pval_atomic(table, j, 2); 376 t = get_h48_pval(table, j, 2);
393 arg->info.distribution[t]++; 377 arg->info.distribution[t]++;
394 } 378 }
395 379
@@ -517,24 +501,42 @@ gendata_h48k2_dfs(h48k2_dfs_arg_t *arg)
517} 501}
518 502
519STATIC_INLINE void 503STATIC_INLINE void
520gendata_h48_mark(gendata_h48_mark_t *arg) 504gendata_h48_mark_atomic(gendata_h48_mark_t *arg)
521{ 505{
522 uint8_t oldval, newval; 506 uint8_t oldval, newval;
523 int64_t coord, mutex; 507 int64_t coord, mutex;
524 508
525 FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim, 509 FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim,
526 coord = coord_h48(arg->cube, arg->cocsepdata, arg->h); 510 coord = coord_h48(arg->cube, arg->cocsepdata, arg->h);
527 oldval = get_h48_pval_atomic(arg->table, coord, arg->k); 511 oldval = get_h48_pval_atomic(arg->table_atomic, coord, arg->k);
528 newval = (uint8_t)MAX(arg->depth, 0); 512 newval = (uint8_t)MAX(arg->depth, 0);
529 if (newval < oldval) { 513 if (newval < oldval) {
530 mutex = H48_INDEX(coord, arg->k) % CHUNKS; 514 mutex = H48_INDEX(coord, arg->k) % CHUNKS;
531 pthread_mutex_lock(arg->table_mutex[mutex]); 515 pthread_mutex_lock(arg->table_mutex[mutex]);
532 set_h48_pval(arg->table, coord, arg->k, newval); 516 set_h48_pval_atomic(
517 arg->table_atomic, coord, arg->k, newval);
533 pthread_mutex_unlock(arg->table_mutex[mutex]); 518 pthread_mutex_unlock(arg->table_mutex[mutex]);
534 } 519 }
535 ) 520 )
536} 521}
537 522
523STATIC_INLINE void
524gendata_h48_mark(gendata_h48_mark_t *arg)
525{
526 uint8_t oldval, newval;
527 int64_t coord, mutex;
528
529 FOREACH_H48SIM(arg->cube, arg->cocsepdata, arg->selfsim,
530 coord = coord_h48(arg->cube, arg->cocsepdata, arg->h);
531 mutex = H48_INDEX(coord, arg->k) % CHUNKS;
532 pthread_mutex_lock(arg->table_mutex[mutex]);
533 oldval = get_h48_pval(arg->table, coord, arg->k);
534 newval = (uint8_t)MAX(arg->depth, 0);
535 set_h48_pval(arg->table, coord, arg->k, MIN(newval, oldval));
536 pthread_mutex_unlock(arg->table_mutex[mutex]);
537 )
538}
539
538STATIC_INLINE bool 540STATIC_INLINE bool
539gendata_h48k2_dfs_stop(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg) 541gendata_h48k2_dfs_stop(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg)
540{ 542{
@@ -548,7 +550,7 @@ gendata_h48k2_dfs_stop(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg)
548 coord = coord_h48(cube, arg->cocsepdata, arg->h); 550 coord = coord_h48(cube, arg->cocsepdata, arg->h);
549 mutex = H48_INDEX(coord, arg->k) % CHUNKS; 551 mutex = H48_INDEX(coord, arg->k) % CHUNKS;
550 pthread_mutex_lock(arg->table_mutex[mutex]); 552 pthread_mutex_lock(arg->table_mutex[mutex]);
551 oldval = get_h48_pval_atomic(arg->table, coord, arg->k); 553 oldval = get_h48_pval(arg->table, coord, arg->k);
552 pthread_mutex_unlock(arg->table_mutex[mutex]); 554 pthread_mutex_unlock(arg->table_mutex[mutex]);
553 return oldval <= depth; 555 return oldval <= depth;
554 } else { 556 } else {
@@ -603,7 +605,7 @@ makeinfo_h48k2(gendata_h48_arg_t *arg)
603 605
604STATIC void 606STATIC void
605getdistribution_h48( 607getdistribution_h48(
606 _Atomic const uint8_t *table, 608 const uint8_t *table,
607 uint64_t distr[static INFO_DISTRIBUTION_LEN], 609 uint64_t distr[static INFO_DISTRIBUTION_LEN],
608 uint8_t h, 610 uint8_t h,
609 uint8_t k 611 uint8_t k
@@ -615,7 +617,7 @@ getdistribution_h48(
615 617
616 h48max = H48_COORDMAX(h); 618 h48max = H48_COORDMAX(h);
617 for (i = 0; i < h48max; i++) { 619 for (i = 0; i < h48max; i++) {
618 val = get_h48_pval_atomic(table, i, k); 620 val = get_h48_pval(table, i, k);
619 distr[val]++; 621 distr[val]++;
620 } 622 }
621} 623}
@@ -633,19 +635,26 @@ get_h48data_constptr(const void *data)
633} 635}
634 636
635STATIC_INLINE uint8_t 637STATIC_INLINE uint8_t
636get_h48_pval_atomic(_Atomic const uint8_t *table, int64_t i, uint8_t k) 638get_h48_pval(const uint8_t *table, int64_t i, uint8_t k)
637{ 639{
638 return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k); 640 return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k);
639} 641}
640 642
641STATIC_INLINE uint8_t 643STATIC_INLINE uint8_t
642get_h48_pval(const uint8_t *table, int64_t i, uint8_t k) 644get_h48_pval_atomic(_Atomic const uint8_t *table, int64_t i, uint8_t k)
643{ 645{
644 return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k); 646 return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k);
645} 647}
646 648
647STATIC_INLINE void 649STATIC_INLINE void
648set_h48_pval(_Atomic uint8_t *table, int64_t i, uint8_t k, uint8_t val) 650set_h48_pval(uint8_t *table, int64_t i, uint8_t k, uint8_t val)
651{
652 table[H48_INDEX(i, k)] = (table[H48_INDEX(i, k)] & (~H48_MASK(i, k)))
653 | (val << H48_SHIFT(i, k));
654}
655
656STATIC_INLINE void
657set_h48_pval_atomic(_Atomic uint8_t *table, int64_t i, uint8_t k, uint8_t val)
649{ 658{
650 table[H48_INDEX(i, k)] = (table[H48_INDEX(i, k)] & (~H48_MASK(i, k))) 659 table[H48_INDEX(i, k)] = (table[H48_INDEX(i, k)] & (~H48_MASK(i, k)))
651 | (val << H48_SHIFT(i, k)); 660 | (val << H48_SHIFT(i, k));
@@ -671,7 +680,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
671 size_t cocsepsize, h48size; 680 size_t cocsepsize, h48size;
672 uint8_t val_full, val_derive; 681 uint8_t val_full, val_derive;
673 const uint8_t *h48full; 682 const uint8_t *h48full;
674 _Atomic uint8_t *h48derive; 683 uint8_t *h48derive;
675 int64_t i, j, h48max; 684 int64_t i, j, h48max;
676 gendata_h48_arg_t arg; 685 gendata_h48_arg_t arg;
677 tableinfo_t cocsepinfo, fulltableinfo; 686 tableinfo_t cocsepinfo, fulltableinfo;
@@ -712,7 +721,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
712 } 721 }
713 722
714 h48full = (const uint8_t *)fulltable + cocsepsize + INFOSIZE; 723 h48full = (const uint8_t *)fulltable + cocsepsize + INFOSIZE;
715 h48derive = (_Atomic uint8_t *)arg.h48buf + INFOSIZE; 724 h48derive = (uint8_t *)arg.h48buf + INFOSIZE;
716 memset(h48derive, 0xFF, H48_TABLESIZE(h, arg.k)); 725 memset(h48derive, 0xFF, H48_TABLESIZE(h, arg.k));
717 memset(arg.info.distribution, 0, 726 memset(arg.info.distribution, 0,
718 INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); 727 INFO_DISTRIBUTION_LEN * sizeof(uint64_t));
@@ -723,7 +732,7 @@ gendata_h48_derive(uint8_t h, const void *fulltable, void *buf)
723 LOG("Processing %" PRId64 "th coordinate\n", i); 732 LOG("Processing %" PRId64 "th coordinate\n", i);
724 j = i >> (int64_t)(fulltableinfo.h48h - h); 733 j = i >> (int64_t)(fulltableinfo.h48h - h);
725 val_full = get_h48_pval(h48full, i, arg.k); 734 val_full = get_h48_pval(h48full, i, arg.k);
726 val_derive = get_h48_pval_atomic(h48derive, j, arg.k); 735 val_derive = get_h48_pval(h48derive, j, arg.k);
727 set_h48_pval( 736 set_h48_pval(
728 h48derive, j, arg.k, MIN(val_full, val_derive)); 737 h48derive, j, arg.k, MIN(val_full, val_derive));
729 } 738 }
diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h
index 4b503ab..e0e4df7 100644
--- a/src/solvers/h48/gendata_types_macros.h
+++ b/src/solvers/h48/gendata_types_macros.h
@@ -22,6 +22,25 @@
22#define MAXLEN 20 22#define MAXLEN 20
23#define CHUNKS COCSEP_CLASSES 23#define CHUNKS COCSEP_CLASSES
24 24
25/*
26TODO: This loop over similar h48 coordinates can be improved by only
27transforming edges, but we need to compose transformations (i.e. conjugate
28_t by _ttrep).
29*/
30#define FOREACH_H48SIM(ARG_CUBE, ARG_COCSEPDATA, ARG_SELFSIM, ARG_ACTION) \
31 int64_t VAR_COCSEP = coord_cocsep(ARG_CUBE); \
32 uint8_t VAR_TTREP = TTREP(ARG_COCSEPDATA[VAR_COCSEP]); \
33 uint8_t VAR_INVERSE_TTREP = inverse_trans(VAR_TTREP); \
34 int64_t VAR_COCLASS = COCLASS(ARG_COCSEPDATA[VAR_COCSEP]); \
35 cube_t VAR_REP = transform(ARG_CUBE, VAR_TTREP); \
36 uint64_t VAR_S = ARG_SELFSIM[VAR_COCLASS]; \
37 for (uint8_t VAR_T = 0; VAR_T < 48 && VAR_S; VAR_T++, VAR_S >>= 1) { \
38 if (!(VAR_S & 1)) continue; \
39 ARG_CUBE = transform(VAR_REP, VAR_T); \
40 ARG_CUBE = transform(ARG_CUBE, VAR_INVERSE_TTREP); \
41 ARG_ACTION \
42 }
43
25typedef struct { 44typedef struct {
26 cube_t cube; 45 cube_t cube;
27 uint8_t depth; 46 uint8_t depth;
@@ -72,7 +91,7 @@ typedef struct {
72 uint8_t base; 91 uint8_t base;
73 uint8_t shortdepth; 92 uint8_t shortdepth;
74 uint32_t *cocsepdata; 93 uint32_t *cocsepdata;
75 _Atomic uint8_t *table; 94 uint8_t *table;
76 uint64_t *selfsim; 95 uint64_t *selfsim;
77 cube_t *crep; 96 cube_t *crep;
78 h48map_t *shortcubes; 97 h48map_t *shortcubes;
@@ -89,6 +108,7 @@ typedef struct {
89 uint8_t k; 108 uint8_t k;
90 uint32_t *cocsepdata; 109 uint32_t *cocsepdata;
91 uint64_t *selfsim; 110 uint64_t *selfsim;
92 _Atomic uint8_t *table; 111 uint8_t *table;
112 _Atomic uint8_t *table_atomic;
93 pthread_mutex_t **table_mutex; 113 pthread_mutex_t **table_mutex;
94} gendata_h48_mark_t; 114} gendata_h48_mark_t;

Generated with cgit - Back to sebastiano.tronto.net