aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-10-29 10:29:27 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2023-10-29 10:31:38 +0100
commit80ec600701aae54350679bbf5e0ce874c915506e (patch)
tree137007693afb0d12b0886990b4bfb6d7278bfa22 /src
parentf2dd7feb819fe4a8a4181dd1d04488e31f4b63a1 (diff)
downloadnissy-core-80ec600701aae54350679bbf5e0ce874c915506e.tar.gz
nissy-core-80ec600701aae54350679bbf5e0ce874c915506e.zip
AVX2 compiles, fails all tests; + some renaming
Diffstat (limited to 'src')
-rw-r--r--src/_base_arr.c30
-rw-r--r--src/_base_avx2.c28
-rw-r--r--src/_constants.c4
-rw-r--r--src/_move_logic_avx2.c7
-rw-r--r--src/cube.c128
-rw-r--r--src/cube.h28
6 files changed, 123 insertions, 102 deletions
diff --git a/src/_base_arr.c b/src/_base_arr.c
deleted file mode 100644
index 2169cd5..0000000
--- a/src/_base_arr.c
+++ /dev/null
@@ -1,30 +0,0 @@
1cube_t solvedcube = {
2 .c = {0, 1, 2, 3, 4, 5, 6, 7},
3 .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
4};
5static cube_t errorcube = { .e = {0}, .c = {0} };
6static cube_t zerocube = { .e = {0}, .c = {0} };
7
8static uint8_t
9get_edge(cube_t c, uint8_t i)
10{
11 return c.e[i];
12}
13
14static uint8_t
15get_corner(cube_t c, uint8_t i)
16{
17 return c.c[i];
18}
19
20static void
21set_edge(cube_t *c, uint8_t i, uint8_t p)
22{
23 c->e[i] = p;
24}
25
26static void
27set_corner(cube_t *c, uint8_t i, uint8_t p)
28{
29 c->c[i] = p;
30}
diff --git a/src/_base_avx2.c b/src/_base_avx2.c
deleted file mode 100644
index 7af88eb..0000000
--- a/src/_base_avx2.c
+++ /dev/null
@@ -1,28 +0,0 @@
1#define solvedcube _mm256_set_epi8( \
2 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0, /* Corners */ \
3 0, 0, 0, 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 /* Edges */ \
4)
5#define errorcube _mm256_setzero_si256()
6#define zerocube _mm256_setzero_si256()
7
8static uint8_t
9get_edge(cube_t c, uint8_t i)
10{
11 return 0;
12}
13
14static uint8_t
15get_corner(cube_t c, uint8_t i)
16{
17 return 0;
18}
19
20static void
21set_edge(cube_t *c, uint8_t i, uint8_t p)
22{
23}
24
25static void
26set_corner(cube_t *c, uint8_t i, uint8_t p)
27{
28}
diff --git a/src/_constants.c b/src/_constants.c
index 3121e3b..0070990 100644
--- a/src/_constants.c
+++ b/src/_constants.c
@@ -32,7 +32,7 @@
32#define _eflip 0x10U 32#define _eflip 0x10U
33#define _error 0xFFU 33#define _error 0xFFU
34 34
35move_t inverse_move[] = { 35static move_t inverse_move_arr[] = {
36 [U] = U3, 36 [U] = U3,
37 [U2] = U2, 37 [U2] = U2,
38 [U3] = U, 38 [U3] = U,
@@ -53,7 +53,7 @@ move_t inverse_move[] = {
53 [B3] = B, 53 [B3] = B,
54}; 54};
55 55
56trans_t inverse_trans[] = { 56static trans_t inverse_trans_arr[] = {
57 [UFr] = UFr, 57 [UFr] = UFr,
58 [ULr] = URr, 58 [ULr] = URr,
59 [UBr] = UBr, 59 [UBr] = UBr,
diff --git a/src/_move_logic_avx2.c b/src/_move_logic_avx2.c
index 7bf881c..29df776 100644
--- a/src/_move_logic_avx2.c
+++ b/src/_move_logic_avx2.c
@@ -1,3 +1,6 @@
1static cube_t move_cube[18]; /* TODO */ 1/* TODO:
2 2static cube_t move_cube[18];
3return compose(move_cube[m], c); 3return compose(move_cube[m], c);
4*/
5
6goto move_error;
diff --git a/src/cube.c b/src/cube.c
index 4651b00..fc04ee7 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -14,10 +14,38 @@
14 14
15#include "_constants.c" 15#include "_constants.c"
16 16
17cube_arr_t solvedcube_arr = {
18 .c = {0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0},
19 .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0}
20};
21cube_arr_t zerocube_arr = { .e = {0}, .c = {0} };
22
17#ifdef CUBE_AVX2 23#ifdef CUBE_AVX2
18#include "_base_avx2.c" 24
25#define setsolved(cube) cube = _mm256_loadu_si256((__m256i_u *)&solvedcube_arr)
26#define setzero(cube) cube = _mm256_setzero_si256()
27#define _c _mm256_set_epi64x(0, 0, 0, 0xFF)
28#define _e _mm256_set_epi64x(0, 0xFF, 0, 0)
29/* TODO: in the next 4 macros, all 0 should be i, but must be constant! */
30#define get_edge(cube, i) _mm256_extract_epi8(cube, 0+16)
31#define get_corner(cube, i) _mm256_extract_epi8(cube, 0)
32#define set_edge(cube, i, p) _mm256_or_si256( \
33 _mm256_andnot_si256(cube, _mm256_slli_si256(_e, 0)), \
34 _mm256_and_si256(_mm256_set1_epi8(p), _mm256_slli_si256(_e, 0)))
35#define set_corner(cube, i, p) _mm256_or_si256( \
36 _mm256_andnot_si256(cube, _mm256_slli_si256(_c, 0)), \
37 _mm256_and_si256(_mm256_set1_epi8(p), _mm256_slli_si256(_c, 0)))
38
19#else 39#else
20#include "_base_arr.c" 40
41#define setsolved(cube) cube = solvedcube_arr
42#define setzero(cube) cube = zerocube_arr
43#define _c _mm256_set_epi64x(0, 0, 0, 0xFF)
44#define get_edge(cube, i) (cube).e[(i)]
45#define get_corner(cube, i) (cube).c[(i)]
46#define set_edge(cube, i, p) (cube).e[(i)] = (p)
47#define set_corner(cube, i, p) (cube).c[(i)] = (p)
48
21#endif 49#endif
22 50
23static bool isconsistent(cube_t); 51static bool isconsistent(cube_t);
@@ -34,6 +62,22 @@ static int writepiece_SRC(uint8_t, char *);
34static void writecube_SRC(cube_t, char *); 62static void writecube_SRC(cube_t, char *);
35static int permsign(uint8_t *, int); 63static int permsign(uint8_t *, int);
36 64
65cube_t
66solvedcube(void)
67{
68 cube_t solved;
69 setsolved(solved);
70 return solved;
71}
72
73cube_t
74zerocube(void)
75{
76 cube_t solved;
77 setzero(solved);
78 return solved;
79}
80
37static uint8_t 81static uint8_t
38readco(char *str) 82readco(char *str)
39{ 83{
@@ -100,30 +144,34 @@ readcube_H48(char *buf)
100{ 144{
101 int i; 145 int i;
102 uint8_t piece, orient; 146 uint8_t piece, orient;
103 cube_t ret = zerocube; 147 cube_t ret, err;
104 char *b = buf; 148 char *b;
149
150 setzero(ret);
151 setzero(err);
152 b = buf;
105 153
106 for (i = 0; i < 12; i++) { 154 for (i = 0; i < 12; i++) {
107 while (*b == ' ' || *b == '\t' || *b == '\n') 155 while (*b == ' ' || *b == '\t' || *b == '\n')
108 b++; 156 b++;
109 if ((piece = readep(b)) == _error) 157 if ((piece = readep(b)) == _error)
110 return errorcube; 158 return err;
111 b += 2; 159 b += 2;
112 if ((orient = readeo(b)) == _error) 160 if ((orient = readeo(b)) == _error)
113 return errorcube; 161 return err;
114 b++; 162 b++;
115 set_edge(&ret, i, piece | orient); 163 set_edge(ret, i, piece | orient);
116 } 164 }
117 for (i = 0; i < 8; i++) { 165 for (i = 0; i < 8; i++) {
118 while (*b == ' ' || *b == '\t' || *b == '\n') 166 while (*b == ' ' || *b == '\t' || *b == '\n')
119 b++; 167 b++;
120 if ((piece = readcp(b)) == _error) 168 if ((piece = readcp(b)) == _error)
121 return errorcube; 169 return err;
122 b += 3; 170 b += 3;
123 if ((orient = readco(b)) == _error) 171 if ((orient = readco(b)) == _error)
124 return errorcube; 172 return err;
125 b++; 173 b++;
126 set_corner(&ret, i, piece | orient); 174 set_corner(ret, i, piece | orient);
127 } 175 }
128 176
129 return ret; 177 return ret;
@@ -142,7 +190,7 @@ readcube(format_t format, char *buf)
142 #ifdef DEBUG 190 #ifdef DEBUG
143 fprintf(stderr, "Cannot read cube in the given format\n"); 191 fprintf(stderr, "Cannot read cube in the given format\n");
144 #endif 192 #endif
145 ret = errorcube; 193 setzero(ret);
146 } 194 }
147 195
148#ifdef DEBUG 196#ifdef DEBUG
@@ -373,6 +421,18 @@ writetrans(trans_t t, char *buf)
373 buf[11] = '\0'; 421 buf[11] = '\0';
374} 422}
375 423
424move_t
425inverse_move(move_t m)
426{
427 return inverse_move_arr[m];
428}
429
430trans_t
431inverse_trans(trans_t t)
432{
433 return inverse_trans_arr[t];
434}
435
376static int 436static int
377permsign(uint8_t *a, int n) 437permsign(uint8_t *a, int n)
378{ 438{
@@ -532,18 +592,24 @@ equal(cube_t cube1, cube_t cube2)
532bool 592bool
533issolved(cube_t cube) 593issolved(cube_t cube)
534{ 594{
535 return equal(cube, solvedcube); 595 cube_t solved;
596 setsolved(solved);
597 return equal(cube, solved);
536} 598}
537 599
538bool 600bool
539iserror(cube_t cube) 601iserror(cube_t cube)
540{ 602{
541 return equal(cube, errorcube); 603 cube_t err;
604 setzero(err);
605 return equal(cube, err);
542} 606}
543 607
544cube_t 608cube_t
545move(cube_t c, move_t m) 609move(cube_t c, move_t m)
546{ 610{
611 cube_t err;
612
547#ifdef DEBUG 613#ifdef DEBUG
548 if (!isconsistent(c)) { 614 if (!isconsistent(c)) {
549 fprintf(stderr, "move error, inconsistent cube\n"); 615 fprintf(stderr, "move error, inconsistent cube\n");
@@ -558,7 +624,8 @@ move(cube_t c, move_t m)
558#endif 624#endif
559 625
560move_error: 626move_error:
561 return errorcube; 627 setzero(err);
628 return err;
562} 629}
563 630
564cube_t 631cube_t
@@ -566,25 +633,27 @@ inverse(cube_t c)
566{ 633{
567 /* TODO: optimize for avx2 */ 634 /* TODO: optimize for avx2 */
568 uint8_t i, piece, orien; 635 uint8_t i, piece, orien;
569 cube_t ret = zerocube; 636 cube_t ret;
637
638 setzero(ret);
570 639
571#ifdef DEBUG 640#ifdef DEBUG
572 if (!isconsistent(c)) { 641 if (!isconsistent(c)) {
573 fprintf(stderr, "inverse error, inconsistent cube\n"); 642 fprintf(stderr, "inverse error, inconsistent cube\n");
574 return errorcube; 643 return ret;
575 } 644 }
576#endif 645#endif
577 646
578 for (i = 0; i < 12; i++) { 647 for (i = 0; i < 12; i++) {
579 piece = get_edge(c, i); 648 piece = get_edge(c, i);
580 orien = piece & _eobit; 649 orien = piece & _eobit;
581 set_edge(&ret, piece & _pbits, i | orien); 650 set_edge(ret, piece & _pbits, i | orien);
582 } 651 }
583 652
584 for (i = 0; i < 8; i++) { 653 for (i = 0; i < 8; i++) {
585 piece = get_corner(c, i); 654 piece = get_corner(c, i);
586 orien = ((piece << 1) | (piece >> 1)) & _cobits2; 655 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
587 set_corner(&ret, piece & _pbits, i | orien); 656 set_corner(ret, piece & _pbits, i | orien);
588 } 657 }
589 658
590 return ret; 659 return ret;
@@ -595,12 +664,14 @@ compose(cube_t c1, cube_t c2)
595{ 664{
596 /* TODO: optimize for avx2 */ 665 /* TODO: optimize for avx2 */
597 uint8_t i, piece1, piece2, p, orien, aux, auy; 666 uint8_t i, piece1, piece2, p, orien, aux, auy;
598 cube_t ret = zerocube; 667 cube_t ret;
668
669 setzero(ret);
599 670
600#ifdef DEBUG 671#ifdef DEBUG
601 if (!isconsistent(c1) || !isconsistent(c2)) { 672 if (!isconsistent(c1) || !isconsistent(c2)) {
602 fprintf(stderr, "compose error, inconsistent cube\n"); 673 fprintf(stderr, "compose error, inconsistent cube\n");
603 return errorcube; 674 return ret;
604 } 675 }
605#endif 676#endif
606 677
@@ -609,7 +680,7 @@ compose(cube_t c1, cube_t c2)
609 p = piece2 & _pbits; 680 p = piece2 & _pbits;
610 piece1 = get_edge(c1, p); 681 piece1 = get_edge(c1, p);
611 orien = (piece2 ^ piece1) & _eobit; 682 orien = (piece2 ^ piece1) & _eobit;
612 set_edge(&ret, i, (piece1 & _pbits) | orien); 683 set_edge(ret, i, (piece1 & _pbits) | orien);
613 } 684 }
614 685
615 for (i = 0; i < 8; i++) { 686 for (i = 0; i < 8; i++) {
@@ -619,7 +690,7 @@ compose(cube_t c1, cube_t c2)
619 aux = (piece2 & _cobits) + (piece1 & _cobits); 690 aux = (piece2 & _cobits) + (piece1 & _cobits);
620 auy = (aux + _ctwist_cw) >> 2U; 691 auy = (aux + _ctwist_cw) >> 2U;
621 orien = (aux + auy) & _cobits2; 692 orien = (aux + auy) & _cobits2;
622 set_corner(&ret, i, (piece1 & _pbits) | orien); 693 set_corner(ret, i, (piece1 & _pbits) | orien);
623 } 694 }
624 695
625 return ret; 696 return ret;
@@ -637,7 +708,7 @@ flipallcorners(cube_t c)
637 for (i = 0; i < 8; i++) { 708 for (i = 0; i < 8; i++) {
638 piece = get_corner(c, i); 709 piece = get_corner(c, i);
639 orien = ((piece << 1) | (piece >> 1)) & _cobits2; 710 orien = ((piece << 1) | (piece >> 1)) & _cobits2;
640 set_corner(&ret, i, (piece & _pbits) | orien); 711 set_corner(ret, i, (piece & _pbits) | orien);
641 } 712 }
642 713
643 return ret; 714 return ret;
@@ -646,16 +717,17 @@ flipallcorners(cube_t c)
646cube_t 717cube_t
647transform(cube_t c, trans_t t) 718transform(cube_t c, trans_t t)
648{ 719{
649 cube_t ret; 720 cube_t ret, solved;
650 721
651#ifdef DEBUG 722#ifdef DEBUG
723 setzero(ret);
652 if (!isconsistent(c)) { 724 if (!isconsistent(c)) {
653 fprintf(stderr, "transform error, inconsistent cube\n"); 725 fprintf(stderr, "transform error, inconsistent cube\n");
654 return errorcube; 726 return ret;
655 } 727 }
656 if (t >= 48) { 728 if (t >= 48) {
657 fprintf(stderr, "transform error, unknown transformation\n"); 729 fprintf(stderr, "transform error, unknown transformation\n");
658 return errorcube; 730 return ret;
659 } 731 }
660#endif 732#endif
661 733
@@ -665,7 +737,9 @@ transform(cube_t c, trans_t t)
665#include "_trans_move_arr.c" 737#include "_trans_move_arr.c"
666#endif 738#endif
667 739
668 ret = compose(solvedcube, trans_move_cube[t]); 740 setsolved(solved);
741
742 ret = compose(solved, trans_move_cube[t]);
669 ret = compose(ret, c); 743 ret = compose(ret, c);
670 ret = compose(ret, trans_move_cube_inverse[t]); 744 ret = compose(ret, trans_move_cube_inverse[t]);
671 745
diff --git a/src/cube.h b/src/cube.h
index 4c6de2f..43d9172 100644
--- a/src/cube.h
+++ b/src/cube.h
@@ -1,43 +1,45 @@
1/* Types *********************************************************************/ 1/* Types *********************************************************************/
2 2
3/* See doc/CUBE_INTERNAL.md for a description of the cube format */ 3/* See doc/CUBE_INTERNAL.md for a description of the cube format */
4typedef struct {
5 uint8_t c[16];
6 uint8_t e[16];
7} cube_arr_t;
4#ifdef CUBE_AVX2 8#ifdef CUBE_AVX2
5typedef __m256i cube_t; 9typedef __m256i cube_t;
6#else 10#else
7typedef struct { uint8_t c[8]; uint8_t e[12]; } cube_t; 11typedef cube_arr_t cube_t;
8#endif 12#endif
9 13
10typedef uint8_t move_t; 14typedef uint8_t move_t;
11typedef uint8_t trans_t; 15typedef uint8_t trans_t;
12 16
13extern move_t inverse_move[];
14extern trans_t inverse_trans[];
15extern cube_t solvedcube;
16
17/* Functions *****************************************************************/ 17/* Functions *****************************************************************/
18 18
19int readmoves(char *, move_t *);
20void writemoves(move_t *, int, char *);
21trans_t readtrans(char *);
22void writetrans(trans_t, char *);
23
24move_t inverse_move(move_t);
25trans_t inverse_trans(trans_t);
26
19/* Not all formats are supported for both read and write. */ 27/* Not all formats are supported for both read and write. */
20/* See doc/CUBE_TEXT.md for details. */ 28/* See doc/CUBE_TEXT.md for details. */
21typedef enum {H48, SRC} format_t; 29typedef enum {H48, SRC} format_t;
22cube_t readcube(format_t, char *); 30cube_t readcube(format_t, char *);
23void writecube(format_t, cube_t, char *); 31void writecube(format_t, cube_t, char *);
24 32
33cube_t solvedcube(void);
34cube_t zerocube(void);
25bool issolvable(cube_t); 35bool issolvable(cube_t);
26bool equal(cube_t, cube_t); 36bool equal(cube_t, cube_t);
27bool issolved(cube_t); 37bool issolved(cube_t);
28bool iserror(cube_t); 38bool iserror(cube_t);
29 39
30int readmoves(char *, move_t *);
31void writemoves(move_t *, int, char *);
32
33trans_t readtrans(char *);
34void writetrans(trans_t, char *);
35
36cube_t move(cube_t, move_t); 40cube_t move(cube_t, move_t);
37cube_t inverse(cube_t); 41cube_t inverse(cube_t);
38cube_t compose(cube_t, cube_t); 42cube_t compose(cube_t, cube_t);
39
40/* See doc/TRANSFORMATIONS.md for how transformations are applied */
41cube_t transform(cube_t, trans_t); 43cube_t transform(cube_t, trans_t);
42 44
43/* Constants for moves and transformations ***********************************/ 45/* Constants for moves and transformations ***********************************/

Generated with cgit - Back to sebastiano.tronto.net