h48

A prototype for an optimal Rubik's cube solver, work in progress.
git clone https://git.tronto.net/h48
Download | Log | Files | Refs | README | LICENSE

commit 4e7906014664ba878a8a7b5b3d30124234900dc0
parent c92122402bc82fb23c9021364f47c8f67455f81f
Author: enricotenuti <tenutz_27@outlook.it>
Date:   Thu,  8 Aug 2024 15:39:37 +0200

spaces fix

Diffstat:
Msrc/cube_neon.h | 110+++++++++++++++++++++++++++----------------------------------------------------
Mtest/test.sh | 2+-
2 files changed, 39 insertions(+), 73 deletions(-)

diff --git a/src/cube_neon.h b/src/cube_neon.h @@ -6,18 +6,18 @@ typedef struct } cube_t; // static cube -#define static_cube(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \ - e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br) \ - ((cube_t){ \ - .corner = {c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, 0, 0, 0, 0, 0, 0, 0, 0}, \ +#define static_cube(c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, \ + e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br) \ + ((cube_t){ \ + .corner = {c_ufr, c_ubl, c_dfl, c_dbr, c_ufl, c_ubr, c_dfr, c_dbl, 0, 0, 0, 0, 0, 0, 0, 0}, \ .edge = {e_uf, e_ub, e_db, e_df, e_ur, e_ul, e_dl, e_dr, e_fr, e_fl, e_bl, e_br, 0, 0, 0, 0}}) // zero cube -#define zero \ - (cube_t) \ - { \ - .corner = vdupq_n_u8(0), \ - .edge = vdupq_n_u8(0) \ +#define zero \ + (cube_t) \ + { \ + .corner = vdupq_n_u8(0), \ + .edge = vdupq_n_u8(0) \ } // solved cube @@ -28,10 +28,10 @@ typedef struct _static void pieces(cube_t *, uint8_t[static 8], uint8_t[static 12]); _static_inline bool equal(cube_t, cube_t); _static_inline cube_t invertco(cube_t); -_static_inline cube_t compose_edges(cube_t, cube_t); // implementation similar to portable compose_edges_inplace -_static_inline cube_t compose_corners(cube_t, cube_t); // implementation similar to portable compose_corners_inplace -_static_inline uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); // similar to compose_edges but without the cube_t struct -_static_inline uint8x16_t compose_corners_slim(uint8x16_t, uint8x16_t); // similar to compose_corners but without the cube_t struct +_static_inline cube_t compose_edges(cube_t, cube_t); +_static_inline cube_t compose_corners(cube_t, cube_t); +_static_inline uint8x16_t compose_edges_slim(uint8x16_t, uint8x16_t); +_static_inline uint8x16_t compose_corners_slim(uint8x16_t, uint8x16_t); _static_inline cube_t compose(cube_t, cube_t); _static_inline cube_t inverse(cube_t); @@ -82,7 +82,8 @@ equal(cube_t c1, cube_t c2) return vgetq_lane_u64(cmp_result, 0) == ~0ULL && vgetq_lane_u64(cmp_result, 1) == ~0ULL; } -_static_inline cube_t invertco(cube_t c) +_static_inline cube_t +invertco(cube_t c) { cube_t ret; @@ -117,67 +118,24 @@ _static_inline cube_t invertco(cube_t c) return ret; } -_static_inline cube_t compose_edges(cube_t c1, cube_t c2) +_static_inline cube_t +compose_edges(cube_t c1, cube_t c2) { cube_t ret = {0}; - - uint8x16_t edge1 = c1.edge; - uint8x16_t edge2 = c2.edge; - - // Masks - uint8x16_t p_bits = vdupq_n_u8(_pbits); - uint8x16_t eo_bit = vdupq_n_u8(_eobit); - - // Find the index and permutation - uint8x16_t p = vandq_u8(edge2, p_bits); - uint8x16_t piece1 = vqtbl1q_u8(edge1, p); - - // Calculate the orientation through XOR - uint8x16_t orien = vandq_u8(veorq_u8(edge2, piece1), eo_bit); - - // Combine the results - uint8x16_t result = vorrq_u8(vandq_u8(piece1, p_bits), orien); - - // Mask to clear the last 32 bits of the result - uint8x16_t mask_last_32 = vsetq_lane_u32(0, vreinterpretq_u32_u8(result), 3); - result = vreinterpretq_u8_u32(mask_last_32); - - ret.edge = result; + ret.edge = compose_edges_slim(c1.edge, c2.edge); return ret; } -_static_inline cube_t compose_corners(cube_t c1, cube_t c2) +_static_inline cube_t +compose_corners(cube_t c1, cube_t c2) { cube_t ret = {0}; - uint8x16_t corner1 = c1.corner; - uint8x16_t corner2 = c2.corner; - - // Masks - uint8x16_t p_bits = vdupq_n_u8(_pbits); - uint8x16_t cobits = vdupq_n_u8(_cobits); - uint8x16_t cobits2 = vdupq_n_u8(_cobits2); - uint8x16_t twist_cw = vdupq_n_u8(_ctwist_cw); - - // Find the index and permutation - uint8x16_t p = vandq_u8(corner2, p_bits); - uint8x16_t piece1 = vqtbl1q_u8(corner1, p); - - // Calculate the orientation - uint8x16_t aux = vaddq_u8(vandq_u8(corner2, cobits), vandq_u8(piece1, cobits)); - uint8x16_t auy = vshrq_n_u8(vaddq_u8(aux, twist_cw), 2); - uint8x16_t orien = vandq_u8(vaddq_u8(aux, auy), cobits2); - - // Combine the results - uint8x16_t result = vorrq_u8(vandq_u8(piece1, p_bits), orien); - - // Mask to clear the last 64 bits of the result - uint8x16_t mask_last_64 = vsetq_lane_u64(0, vreinterpretq_u64_u8(result), 1); - result = vreinterpretq_u8_u64(mask_last_64); - - ret.corner = result; + ret.corner = compose_corners_slim(c1.corner, c2.corner); return ret; } -_static_inline uint8x16_t compose_edges_slim(uint8x16_t edge1, uint8x16_t edge2) + +_static_inline uint8x16_t +compose_edges_slim(uint8x16_t edge1, uint8x16_t edge2) { // Masks uint8x16_t p_bits = vdupq_n_u8(_pbits); @@ -199,7 +157,9 @@ _static_inline uint8x16_t compose_edges_slim(uint8x16_t edge1, uint8x16_t edge2) return ret; } -_static_inline uint8x16_t compose_corners_slim(uint8x16_t corner1, uint8x16_t corner2) + +_static_inline uint8x16_t +compose_corners_slim(uint8x16_t corner1, uint8x16_t corner2) { // Masks uint8x16_t p_bits = vdupq_n_u8(_pbits); @@ -225,7 +185,9 @@ _static_inline uint8x16_t compose_corners_slim(uint8x16_t corner1, uint8x16_t co return ret; } -_static_inline cube_t compose(cube_t c1, cube_t c2) + +_static_inline cube_t +compose(cube_t c1, cube_t c2) { cube_t ret = {0}; @@ -235,7 +197,8 @@ _static_inline cube_t compose(cube_t c1, cube_t c2) return ret; } -_static_inline cube_t inverse(cube_t cube) +_static_inline cube_t +inverse(cube_t cube) { uint8_t i, piece, orien; cube_t ret; @@ -274,7 +237,8 @@ _static_inline cube_t inverse(cube_t cube) return ret; } -_static_inline int64_t coord_co(cube_t c) +_static_inline int64_t +coord_co(cube_t c) { // Temp array to store the NEON vector uint8_t mem[16]; @@ -311,7 +275,8 @@ coord_cocsep(cube_t c) return (coord_co(c) << 7) + coord_csep(c); } -_static_inline int64_t coord_eo(cube_t c) +_static_inline int64_t +coord_eo(cube_t c) { int64_t ret = 0; int64_t p = 1; @@ -328,7 +293,8 @@ _static_inline int64_t coord_eo(cube_t c) return ret; } -_static_inline int64_t coord_esep(cube_t c) +_static_inline int64_t +coord_esep(cube_t c) { int64_t i, j, jj, k, l, ret1, ret2, bit1, bit2, is1; diff --git a/test/test.sh b/test/test.sh @@ -12,7 +12,7 @@ for t in test/*; do continue fi - # Verifica se $t รจ una directory e se il suo nome inizia con tre cifre + # Verify if $t is a directory and if its name starts with three digits if [ -d "$t" ] && echo "$(basename "$t")" | grep -Eq '^[0-9]{3}'; then $CC -o $TESTBIN $t/*.c $CUBEOBJ || exit 1 for cin in $t/*.in; do