From 1809d7b212128fcdcb481002a17db5dc97a15e03 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Fri, 17 May 2024 17:42:43 +0200 Subject: Added inverse eo and copy_{edges,corners} --- TODO.txt | 4 +-- src/cube.c | 1 + src/cube_avx2.h | 48 +++++++++++++++++++++++---- src/cube_portable.h | 36 ++++++++++++++++---- src/solve_h48.h | 9 ++--- test/075_set_eo/00_solved_0.in | 2 ++ test/075_set_eo/00_solved_0.out | 1 + test/075_set_eo/01_solved_1.in | 2 ++ test/075_set_eo/01_solved_1.out | 1 + test/075_set_eo/02_solved_other.in | 2 ++ test/075_set_eo/02_solved_other.out | 1 + test/075_set_eo/03_solved_firstlast.in | 2 ++ test/075_set_eo/03_solved_firstlast.out | 1 + test/075_set_eo/10_scrambled_0.in | 4 +++ test/075_set_eo/10_scrambled_0.out | 1 + test/075_set_eo/11_scrambled_1.in | 4 +++ test/075_set_eo/11_scrambled_1.out | 1 + test/075_set_eo/set_eo_tests.c | 38 +++++++++++++++++++++ test/076_copy_corners/00_solved_scrambled.in | 2 ++ test/076_copy_corners/00_solved_scrambled.out | 1 + test/076_copy_corners/copy_corners_tests.c | 33 ++++++++++++++++++ test/077_copy_edges/00_solved_scrambled.in | 2 ++ test/077_copy_edges/00_solved_scrambled.out | 1 + test/077_copy_edges/copy_edges_tests.c | 33 ++++++++++++++++++ test/test | 41 +++++++++++++++++++++++ test/test.h | 1 + 26 files changed, 252 insertions(+), 20 deletions(-) create mode 100644 test/075_set_eo/00_solved_0.in create mode 100644 test/075_set_eo/00_solved_0.out create mode 100644 test/075_set_eo/01_solved_1.in create mode 100644 test/075_set_eo/01_solved_1.out create mode 100644 test/075_set_eo/02_solved_other.in create mode 100644 test/075_set_eo/02_solved_other.out create mode 100644 test/075_set_eo/03_solved_firstlast.in create mode 100644 test/075_set_eo/03_solved_firstlast.out create mode 100644 test/075_set_eo/10_scrambled_0.in create mode 100644 test/075_set_eo/10_scrambled_0.out create mode 100644 test/075_set_eo/11_scrambled_1.in create mode 100644 test/075_set_eo/11_scrambled_1.out create mode 100644 test/075_set_eo/set_eo_tests.c create mode 100644 test/076_copy_corners/00_solved_scrambled.in create mode 100644 test/076_copy_corners/00_solved_scrambled.out create mode 100644 test/076_copy_corners/copy_corners_tests.c create mode 100644 test/077_copy_edges/00_solved_scrambled.in create mode 100644 test/077_copy_edges/00_solved_scrambled.out create mode 100644 test/077_copy_edges/copy_edges_tests.c create mode 100755 test/test diff --git a/TODO.txt b/TODO.txt index e8a6496..5441a9f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,7 +1,7 @@ In progress: go back to nissy-style BFS for eosep data computation - (done) compute selfsim and cocsep representatives - - implement set_eo_fast for invcoord_h48 (with tests for set_eo_fast) - also: implement other set_stuff methods for fast cube representation + - (done) implement set_eo_fast for invcoord_h48 + - add unit tests for invcoord_h48 (compute tables, if needed) - in gendata_esep, compute representatives for esep inverse coordinate - change to BFS diff --git a/src/cube.c b/src/cube.c index 27d54b4..a6b733e 100644 --- a/src/cube.c +++ b/src/cube.c @@ -1,5 +1,6 @@ #include #include +#include /* TODO: Used only for malloc, remove if possible */ #include #ifdef DEBUG diff --git a/src/cube_avx2.h b/src/cube_avx2.h index 42fb9d1..8d1c940 100644 --- a/src/cube_avx2.h +++ b/src/cube_avx2.h @@ -23,9 +23,12 @@ _static_inline int64_t coord_fast_co(cube_fast_t); _static_inline int64_t coord_fast_csep(cube_fast_t); _static_inline int64_t coord_fast_cocsep(cube_fast_t); _static_inline int64_t coord_fast_eo(cube_fast_t); -_static_inline void set_eo_fast(cube_fast_t *, int64_t); _static_inline int64_t coord_fast_esep(cube_fast_t); +_static_inline void copy_corners_fast(cube_fast_t *, cube_fast_t); +_static_inline void copy_edges_fast(cube_fast_t *, cube_fast_t); +_static_inline void set_eo_fast(cube_fast_t *, int64_t); + _static_inline cube_fast_t fastcube( uint8_t c_ufr, @@ -199,12 +202,6 @@ coord_fast_eo(cube_fast_t c) return mask >> 17; } -_static_inline void -set_eo_fast(cube_fast_t *c, int64_t eo) -{ - /* TODO */ -} - _static_inline int64_t coord_fast_esep(cube_fast_t c) { @@ -234,3 +231,40 @@ coord_fast_esep(cube_fast_t c) return ret1 * 70 + ret2; } + +_static_inline void +copy_corners_fast(cube_fast_t *dest, cube_fast_t src) +{ + *dest = _mm256_blend_epi32(*dest, src, 0x0F); +} + +_static_inline void +copy_edges_fast(cube_fast_t *dest, cube_fast_t src) +{ + *dest = _mm256_blend_epi32(*dest, src, 0xF0); +} + +_static_inline void +set_eo_fast(cube_fast_t *cube, int64_t eo) +{ + int64_t eo12, eotop, eobot; + __m256i veo; + + eo12 = (eo << 1) + (_mm_popcnt_u64(eo) % 2); + eotop = (eo12 & (1 << 11)) << 17 | + (eo12 & (1 << 10)) << 10 | + (eo12 & (1 << 9)) << 3 | + (eo12 & (1 << 8)) >> 4; + eobot = (eo12 & (1 << 7)) << 53 | + (eo12 & (1 << 6)) << 46 | + (eo12 & (1 << 5)) << 39 | + (eo12 & (1 << 4)) << 32 | + (eo12 & (1 << 3)) << 25 | + (eo12 & (1 << 2)) << 18 | + (eo12 & (1 << 1)) << 11 | + (eo12 & 1) << 4; + veo = _mm256_set_epi64x(eotop, eobot, 0, 0); + + *cube = _mm256_andnot_si256(_eo_avx2, *cube); + *cube = _mm256_or_si256(*cube, veo); +} diff --git a/src/cube_portable.h b/src/cube_portable.h index fcd1d55..125c300 100644 --- a/src/cube_portable.h +++ b/src/cube_portable.h @@ -17,9 +17,12 @@ _static_inline int64_t coord_fast_co(cube_fast_t); _static_inline int64_t coord_fast_csep(cube_fast_t); _static_inline int64_t coord_fast_cocsep(cube_fast_t); _static_inline int64_t coord_fast_eo(cube_fast_t); -_static_inline void set_eo_fast(cube_fast_t *, int64_t eo); _static_inline int64_t coord_fast_esep(cube_fast_t); +_static_inline void copy_corners_fast(cube_fast_t *, cube_fast_t); +_static_inline void copy_edges_fast(cube_fast_t *, cube_fast_t); +_static_inline void set_eo_fast(cube_fast_t *, int64_t); + _static_inline cube_fast_t fastcube( uint8_t c_ufr, @@ -189,12 +192,6 @@ coord_fast_eo(cube_fast_t c) return ret; } -_static_inline void -_set_eo_fast(cube_fast_t *cube, int64_t eo) -{ - /* TODO */ -} - /* We encode the edge separation as a number from 0 to C(12,4)*C(8,4). It can be seen as the composition of two "subset index" coordinates. @@ -229,3 +226,28 @@ coord_fast_esep(cube_fast_t c) return ret1 * 70 + ret2; } + +_static_inline void +copy_corners_fast(cube_fast_t *dest, cube_fast_t src) +{ + memcpy(&dest->corner, src.corner, sizeof(src.corner)); +} + +_static_inline void +copy_edges_fast(cube_fast_t *dest, cube_fast_t src) +{ + memcpy(&dest->edge, src.edge, sizeof(src.edge)); +} + +_static_inline void +set_eo_fast(cube_fast_t *cube, int64_t eo) +{ + int i, sum, flip; + + for (sum = 0, i = 1; i < 12; i++, eo >>= 1) { + flip = eo % 2; + sum += flip; + cube->edge[i] = (cube->edge[i] & ~_eobit) | (_eobit * flip); + } + cube->edge[0] = (cube->edge[0] & ~_eobit) | (_eobit * (sum%2)); +} diff --git a/src/solve_h48.h b/src/solve_h48.h index e3e6de1..2fe1d69 100644 --- a/src/solve_h48.h +++ b/src/solve_h48.h @@ -88,16 +88,17 @@ invcoord_h48( cube_fast_t ret; int64_t coclass, ee, esep, eo; + DBG_ASSERT(h <= 11, cubetofast(zero), + "invcoord_h48: h must be between 0 and 11\n"); + coclass = i / H48_ESIZE; ee = i % H48_ESIZE; esep = ee >> h; eo = (ee & ((1< $TESTOUT 2> $TESTERR + if diff $cout $TESTOUT; then + printf "OK\n" + else + printf "Test failed! stderr:\n" + cat $TESTERR + exit 1 + fi + done +done + +echo "All tests passed!" +rm -rf $TESTBIN $TESTOUT $TESTERR $CUBEOBJ diff --git a/test/test.h b/test/test.h index 3cbfd10..2086283 100644 --- a/test/test.h +++ b/test/test.h @@ -21,6 +21,7 @@ typedef cube_t cube_fast_t; /* Basic functions used in most tests */ cube_t solvedcube(void); bool iserror(cube_t); +bool isconsistent(cube_t); bool issolvable(cube_t); bool issolved(cube_t); cube_t readcube(char *, char *); -- cgit v1.3