diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | README.md | 8 | ||||
| -rwxr-xr-x | configure.sh | 55 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_h48.h | 34 | ||||
| -rw-r--r-- | src/solvers/h48/h48.h | 1 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 100 | ||||
| -rw-r--r-- | src/solvers/h48/stats.h | 100 | ||||
| -rw-r--r-- | tools/0022_gendata_h48h2k2/gendata_h48h2k2.c | 21 | ||||
| -rw-r--r-- | tools/0032_gendata_h48h3k2/gendata_h48h3k2.c | 21 | ||||
| -rw-r--r-- | tools/0042_gendata_h48h4k2/gendata_h48h4k2.c | 21 | ||||
| -rw-r--r-- | tools/0052_gendata_h48h5k2/gendata_h48h5k2.c | 21 | ||||
| -rw-r--r-- | tools/0062_gendata_h48h6k2/gendata_h48h6k2.c | 21 | ||||
| -rw-r--r-- | tools/0072_gendata_h48h7k2/gendata_h48h7k2.c | 21 | ||||
| -rw-r--r-- | tools/0082_gendata_h48h8k2/gendata_h48h8k2.c | 21 | ||||
| -rw-r--r-- | tools/0092_gendata_h48h9k2/gendata_h48h9k2.c | 21 | ||||
| -rw-r--r-- | tools/0102_gendata_h48h10k2/gendata_h48h10k2.c | 21 | ||||
| -rw-r--r-- | tools/0112_gendata_h48h11k2/gendata_h48h11k2.c | 21 |
17 files changed, 387 insertions, 122 deletions
| @@ -2,6 +2,7 @@ | |||
| 2 | config.mk | 2 | config.mk |
| 3 | gen | 3 | gen |
| 4 | debuggen | 4 | debuggen |
| 5 | flamegraph.html | ||
| 5 | utils/.DS_Store | 6 | utils/.DS_Store |
| 6 | perf.data | 7 | perf.data |
| 7 | perf.data.old | 8 | perf.data.old |
| @@ -14,9 +14,8 @@ In the future this project may evolve as a new "back-end" for the classic | |||
| 14 | 14 | ||
| 15 | ## Building | 15 | ## Building |
| 16 | 16 | ||
| 17 | First run the configuration script to detect the system | 17 | First run the configuration script to detect the system configuration. |
| 18 | configuration. This is going to select a C compiler and | 18 | This is going to select a C compiler and architecture-specific optimizations. |
| 19 | architecture-specific optimizations. | ||
| 20 | 19 | ||
| 21 | ``` | 20 | ``` |
| 22 | $ ./configure.sh | 21 | $ ./configure.sh |
| @@ -25,10 +24,11 @@ $ ./configure.sh | |||
| 25 | These settings can be overridden, for example: | 24 | These settings can be overridden, for example: |
| 26 | 25 | ||
| 27 | ``` | 26 | ``` |
| 28 | $ CC=clang ./configure.sh # Force use of clang instead of default cc | ||
| 29 | $ THREADS=3 CC=gcc ./configure.sh # Use 3 threads and compile with gcc | 27 | $ THREADS=3 CC=gcc ./configure.sh # Use 3 threads and compile with gcc |
| 30 | ``` | 28 | ``` |
| 31 | 29 | ||
| 30 | All the configuration-time options are described in the `configure.sh` script. | ||
| 31 | |||
| 32 | Once the configuration is done, you can build with make | 32 | Once the configuration is done, you can build with make |
| 33 | 33 | ||
| 34 | ``` | 34 | ``` |
diff --git a/configure.sh b/configure.sh index fcf2dce..e61a163 100755 --- a/configure.sh +++ b/configure.sh | |||
| @@ -1,5 +1,40 @@ | |||
| 1 | #!/bin/sh | 1 | #!/bin/sh |
| 2 | 2 | ||
| 3 | # The following environment variables can be used to configure the build: | ||
| 4 | # | ||
| 5 | # CC="compiler" | ||
| 6 | # Specify the compiler to use. | ||
| 7 | # By default, cc will be used. | ||
| 8 | # The string "compiler" must be the name of an executable in $PATH. | ||
| 9 | # | ||
| 10 | # ARCH="architecture" | ||
| 11 | # You can use this variable to build for a different architecture, for example | ||
| 12 | # if you want to cross-compile or to use the portable version. | ||
| 13 | # By default, the build script will detect which architecture it is running on. | ||
| 14 | # The string "architecture" must be one of "AVX2", "NEON" or "PORTABLE". | ||
| 15 | # | ||
| 16 | # THREADS=n | ||
| 17 | # Choose how many threads to use for multi-threaded oerations. | ||
| 18 | # By default, 16 threads will be used (TODO: in the future this will be | ||
| 19 | # determined base on the system). | ||
| 20 | # The number n must be between 1 and 128. | ||
| 21 | # | ||
| 22 | # SANITIZE="option1,option2,..." | ||
| 23 | # Add the options "-fsanitize=option1", "-fsanitize=option2", ... to the | ||
| 24 | # compilation command when compiling in debug mode. | ||
| 25 | # By default, "-fsanitize=address" and "-fsanitize=undefined" will be used, | ||
| 26 | # if available. If this variable is set, the default is overridden. | ||
| 27 | # No check is performed on the given sanitizers, make sure that the ones you | ||
| 28 | # choose are available on your system and compatible with each other. | ||
| 29 | # | ||
| 30 | # Examples | ||
| 31 | # | ||
| 32 | # 1. Build using clang and 8 threads | ||
| 33 | # CC=clang THREADS=8 ./configure.sh && make | ||
| 34 | # | ||
| 35 | # 2. Build using thread and undefined behavior sanitizers when in debug mode | ||
| 36 | # SANITIZE="thread,undefined" ./configures && make | ||
| 37 | |||
| 3 | greparch() { | 38 | greparch() { |
| 4 | $CC -march=native -dM -E - </dev/null 2>/dev/null | grep "$1" | 39 | $CC -march=native -dM -E - </dev/null 2>/dev/null | grep "$1" |
| 5 | } | 40 | } |
| @@ -53,23 +88,33 @@ validatecc | |||
| 53 | validatethreads | 88 | validatethreads |
| 54 | validatearch | 89 | validatearch |
| 55 | 90 | ||
| 56 | STD="-std=c99" | 91 | STD="-std=c11" |
| 57 | WFLAGS="-pedantic -Wall -Wextra" | 92 | WFLAGS="-pedantic -Wall -Wextra" |
| 58 | WNOFLAGS="-Wno-unused-parameter -Wno-unused-function -Wno-unknown-pragmas" | 93 | WNOFLAGS="-Wno-unused-parameter -Wno-unused-function -Wno-unknown-pragmas" |
| 59 | 94 | ||
| 60 | [ "$ARCH" = "AVX2" ] && AVX="-mavx2" | 95 | [ "$ARCH" = "AVX2" ] && AVX="-mavx2" |
| 61 | [ -n "$(grepsan address)" ] && ADDR="-fsanitize=address" | 96 | |
| 62 | [ -n "$(grepsan undefined)" ] && UNDEF="-fsanitize=undefined" | 97 | if [ -n "$SANITIZE" ]; then |
| 63 | SAN="$ADDR $UNDEF" | 98 | # Use the user-specified comma-separated sanitizers |
| 99 | for san in $(echo "$SANITIZE" | tr ',' '\n'); do | ||
| 100 | SAN="$SAN -fsanitize=$san" | ||
| 101 | done | ||
| 102 | else | ||
| 103 | # No sanitizer specified, use "address" and "undefined" if present | ||
| 104 | [ -n "$(grepsan address)" ] && ADDR="-fsanitize=address" | ||
| 105 | [ -n "$(grepsan undefined)" ] && UNDEF="-fsanitize=undefined" | ||
| 106 | SAN="$ADDR $UNDEF" | ||
| 107 | fi | ||
| 64 | LIBS="-lpthread" | 108 | LIBS="-lpthread" |
| 65 | 109 | ||
| 66 | CFLAGS="$STD $LIBS $WFLAGS $WNOFLAGS $AVX -O3" | 110 | CFLAGS="$STD $LIBS $WFLAGS $WNOFLAGS $AVX -O3" |
| 67 | DBGFLAGS="$STD $LIBS $WFLAGS $WNOFLAGS $SAN $AVX -g3 -DDEBUG" | 111 | DBGFLAGS="$STD $LIBS $WFLAGS $WNOFLAGS $SAN $AVX -g3 -DDEBUG" |
| 68 | MACROS="-DTHREADS=$THREADS -D$ARCH" | 112 | MACROS="-DTHREADS=$THREADS -D$ARCH" |
| 69 | 113 | ||
| 114 | echo "Compiler: $CC" | ||
| 70 | echo "Selected architecture: $ARCH" | 115 | echo "Selected architecture: $ARCH" |
| 71 | echo "Number of threads: $THREADS" | 116 | echo "Number of threads: $THREADS" |
| 72 | echo "Compiler: $CC" | 117 | echo "Sanitizer options (debug build only): $SAN" |
| 73 | 118 | ||
| 74 | { | 119 | { |
| 75 | echo "ARCH = $ARCH"; | 120 | echo "ARCH = $ARCH"; |
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h index e8ffee3..2a62b1d 100644 --- a/src/solvers/h48/gendata_h48.h +++ b/src/solvers/h48/gendata_h48.h | |||
| @@ -344,7 +344,7 @@ gendata_h48k2(gendata_h48_arg_t *arg) | |||
| 344 | 344 | ||
| 345 | uint8_t t, selectedbase, *table; | 345 | uint8_t t, selectedbase, *table; |
| 346 | int64_t j; | 346 | int64_t j; |
| 347 | uint64_t nshort, i, ii, inext, count; | 347 | uint64_t i, ii, inext, count; |
| 348 | h48map_t shortcubes; | 348 | h48map_t shortcubes; |
| 349 | gendata_h48short_arg_t shortarg; | 349 | gendata_h48short_arg_t shortarg; |
| 350 | h48k2_dfs_arg_t dfsarg[THREADS]; | 350 | h48k2_dfs_arg_t dfsarg[THREADS]; |
| @@ -367,8 +367,7 @@ gendata_h48k2(gendata_h48_arg_t *arg) | |||
| 367 | .selfsim = arg->selfsim, | 367 | .selfsim = arg->selfsim, |
| 368 | .map = &shortcubes | 368 | .map = &shortcubes |
| 369 | }; | 369 | }; |
| 370 | nshort = gendata_h48short(&shortarg); | 370 | gendata_h48short(&shortarg); |
| 371 | LOG("Cubes in <= %" PRIu8 " moves: %" PRIu64 "\n", shortdepth, nshort); | ||
| 372 | 371 | ||
| 373 | selectedbase = base[arg->h]; | 372 | selectedbase = base[arg->h]; |
| 374 | arg->info = (tableinfo_t) { | 373 | arg->info = (tableinfo_t) { |
| @@ -434,6 +433,7 @@ gendata_h48k2_return_size: | |||
| 434 | STATIC void * | 433 | STATIC void * |
| 435 | gendata_h48k2_runthread(void *arg) | 434 | gendata_h48k2_runthread(void *arg) |
| 436 | { | 435 | { |
| 436 | uint64_t count, coord, mutex; | ||
| 437 | kvpair_t kv; | 437 | kvpair_t kv; |
| 438 | h48k2_dfs_arg_t *dfsarg; | 438 | h48k2_dfs_arg_t *dfsarg; |
| 439 | 439 | ||
| @@ -447,15 +447,22 @@ gendata_h48k2_runthread(void *arg) | |||
| 447 | pthread_mutex_unlock(dfsarg->shortcubes_mutex); | 447 | pthread_mutex_unlock(dfsarg->shortcubes_mutex); |
| 448 | break; | 448 | break; |
| 449 | } | 449 | } |
| 450 | (*dfsarg->count)++; | 450 | count = ++(*dfsarg->count); |
| 451 | if (*dfsarg->count % UINT64_C(1000000) == 0) | ||
| 452 | LOG("Processing %" PRIu64 "th short cube\n", | ||
| 453 | *dfsarg->count); | ||
| 454 | |||
| 455 | pthread_mutex_unlock(dfsarg->shortcubes_mutex); | 451 | pthread_mutex_unlock(dfsarg->shortcubes_mutex); |
| 456 | 452 | ||
| 457 | dfsarg->cube = invcoord_h48(kv.key, dfsarg->crep, 11); | 453 | if (count % UINT64_C(1000000) == 0) |
| 458 | gendata_h48k2_dfs(dfsarg); | 454 | LOG("Processing %" PRIu64 "th short cube\n", count); |
| 455 | |||
| 456 | if (kv.val < dfsarg->shortdepth) { | ||
| 457 | coord = kv.key >> (int64_t)(11 - dfsarg->h); | ||
| 458 | mutex = H48_INDEX(coord, dfsarg->k) % CHUNKS; | ||
| 459 | pthread_mutex_lock(dfsarg->table_mutex[mutex]); | ||
| 460 | set_h48_pval(dfsarg->table, coord, dfsarg->k, 0); | ||
| 461 | pthread_mutex_unlock(dfsarg->table_mutex[mutex]); | ||
| 462 | } else { | ||
| 463 | dfsarg->cube = invcoord_h48(kv.key, dfsarg->crep, 11); | ||
| 464 | gendata_h48k2_dfs(dfsarg); | ||
| 465 | } | ||
| 459 | } | 466 | } |
| 460 | 467 | ||
| 461 | return NULL; | 468 | return NULL; |
| @@ -524,16 +531,17 @@ STATIC_INLINE void | |||
| 524 | gendata_h48k2_mark(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg) | 531 | gendata_h48k2_mark(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg) |
| 525 | { | 532 | { |
| 526 | uint8_t oldval, newval; | 533 | uint8_t oldval, newval; |
| 527 | int64_t coord, fullcoord; | 534 | int64_t coord, fullcoord, mutex; |
| 528 | 535 | ||
| 529 | FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim, | 536 | FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim, |
| 530 | fullcoord = coord_h48(cube, arg->cocsepdata, 11); | 537 | fullcoord = coord_h48(cube, arg->cocsepdata, 11); |
| 531 | coord = fullcoord >> (int64_t)(11 - arg->h); | 538 | coord = fullcoord >> (int64_t)(11 - arg->h); |
| 532 | pthread_mutex_lock(arg->table_mutex[coord % CHUNKS]); | 539 | mutex = H48_INDEX(coord, arg->k) % CHUNKS; |
| 540 | pthread_mutex_lock(arg->table_mutex[mutex]); | ||
| 533 | oldval = get_h48_pval(arg->table, coord, arg->k); | 541 | oldval = get_h48_pval(arg->table, coord, arg->k); |
| 534 | newval = (uint8_t)MAX(depth, 0); | 542 | newval = (uint8_t)MAX(depth, 0); |
| 535 | set_h48_pval(arg->table, coord, arg->k, MIN(oldval, newval)); | 543 | set_h48_pval(arg->table, coord, arg->k, MIN(oldval, newval)); |
| 536 | pthread_mutex_unlock(arg->table_mutex[coord % CHUNKS]); | 544 | pthread_mutex_unlock(arg->table_mutex[mutex]); |
| 537 | ) | 545 | ) |
| 538 | } | 546 | } |
| 539 | 547 | ||
diff --git a/src/solvers/h48/h48.h b/src/solvers/h48/h48.h index ee865d9..2fe9575 100644 --- a/src/solvers/h48/h48.h +++ b/src/solvers/h48/h48.h | |||
| @@ -2,5 +2,6 @@ | |||
| 2 | #include "map.h" | 2 | #include "map.h" |
| 3 | #include "gendata_cocsep.h" | 3 | #include "gendata_cocsep.h" |
| 4 | #include "gendata_h48.h" | 4 | #include "gendata_h48.h" |
| 5 | #include "stats.h" | ||
| 5 | #include "solve.h" | 6 | #include "solve.h" |
| 6 | #include "thread.h" | 7 | #include "thread.h" |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index 4bf55ca..b67aedc 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -16,16 +16,6 @@ typedef struct { | |||
| 16 | uint8_t premoves[MAXLEN]; | 16 | uint8_t premoves[MAXLEN]; |
| 17 | } dfsarg_solveh48_t; | 17 | } dfsarg_solveh48_t; |
| 18 | 18 | ||
| 19 | typedef struct { | ||
| 20 | cube_t cube; | ||
| 21 | int8_t nmoves; | ||
| 22 | int8_t depth; | ||
| 23 | uint8_t moves[MAXLEN]; | ||
| 24 | uint32_t *cocsepdata; | ||
| 25 | uint8_t *h48data; | ||
| 26 | char *s; | ||
| 27 | } dfsarg_solveh48stats_t; | ||
| 28 | |||
| 29 | STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint32_t); | 19 | STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint32_t); |
| 30 | 20 | ||
| 31 | STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *); | 21 | STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *); |
| @@ -33,9 +23,6 @@ STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *); | |||
| 33 | STATIC int64_t solve_h48_dfs(dfsarg_solveh48_t *); | 23 | STATIC int64_t solve_h48_dfs(dfsarg_solveh48_t *); |
| 34 | STATIC int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, const void *, char *); | 24 | STATIC int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, const void *, char *); |
| 35 | 25 | ||
| 36 | STATIC int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); | ||
| 37 | STATIC int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]); | ||
| 38 | |||
| 39 | STATIC uint32_t | 26 | STATIC uint32_t |
| 40 | allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch) | 27 | allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch) |
| 41 | { | 28 | { |
| @@ -215,90 +202,3 @@ solve_h48( | |||
| 215 | 202 | ||
| 216 | return nsols; | 203 | return nsols; |
| 217 | } | 204 | } |
| 218 | |||
| 219 | /* | ||
| 220 | The h48stats solver computes how many moves it takes to solve to | ||
| 221 | each of the 12 h48 coordinates, one for each value of h from 0 to 11. | ||
| 222 | The solutions array is filled with the length of the solutions. The | ||
| 223 | solution array is therefore not a printable string. | ||
| 224 | */ | ||
| 225 | STATIC int64_t | ||
| 226 | solve_h48stats_dfs(dfsarg_solveh48stats_t *arg) | ||
| 227 | { | ||
| 228 | const int64_t limit = 11; | ||
| 229 | |||
| 230 | int8_t bound, u; | ||
| 231 | uint8_t m; | ||
| 232 | uint32_t d; | ||
| 233 | int64_t coord, h; | ||
| 234 | dfsarg_solveh48stats_t nextarg; | ||
| 235 | |||
| 236 | /* Check cocsep lower bound (corners only) */ | ||
| 237 | bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d); | ||
| 238 | if (bound + arg->nmoves > arg->depth) | ||
| 239 | return 0; | ||
| 240 | |||
| 241 | /* Check h48 lower bound for h=0 (esep, but no eo) */ | ||
| 242 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 0); | ||
| 243 | bound = get_h48_bound(arg->cube, d, 0, 4, arg->h48data); | ||
| 244 | if (bound + arg->nmoves > arg->depth) | ||
| 245 | return 0; | ||
| 246 | |||
| 247 | /* Update all other values, if solved */ | ||
| 248 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11); | ||
| 249 | for (h = 0; h <= limit; h++) { | ||
| 250 | u = coord >> (11-h) == 0 && arg->s[h] == 99; | ||
| 251 | arg->s[h] = u * arg->nmoves + (1-u) * arg->s[h]; | ||
| 252 | } | ||
| 253 | |||
| 254 | if (arg->s[limit] != 99) | ||
| 255 | return 0; | ||
| 256 | |||
| 257 | nextarg = *arg; | ||
| 258 | nextarg.nmoves = arg->nmoves + 1; | ||
| 259 | for (m = 0; m < 18; m++) { | ||
| 260 | nextarg.moves[arg->nmoves] = m; | ||
| 261 | if (!allowednextmove(nextarg.moves, nextarg.nmoves)) { | ||
| 262 | /* If a move is not allowed, neither are its 180 | ||
| 263 | * and 270 degree variations */ | ||
| 264 | m += 2; | ||
| 265 | continue; | ||
| 266 | } | ||
| 267 | nextarg.cube = move(arg->cube, m); | ||
| 268 | solve_h48stats_dfs(&nextarg); | ||
| 269 | } | ||
| 270 | |||
| 271 | return 0; | ||
| 272 | } | ||
| 273 | |||
| 274 | STATIC int64_t | ||
| 275 | solve_h48stats( | ||
| 276 | cube_t cube, | ||
| 277 | int8_t maxmoves, | ||
| 278 | const void *data, | ||
| 279 | char solutions[static 12] | ||
| 280 | ) | ||
| 281 | { | ||
| 282 | int i; | ||
| 283 | dfsarg_solveh48stats_t arg; | ||
| 284 | |||
| 285 | arg = (dfsarg_solveh48stats_t) { | ||
| 286 | .cube = cube, | ||
| 287 | .cocsepdata = get_cocsepdata_ptr(data), | ||
| 288 | .h48data = get_h48data_ptr(data), | ||
| 289 | .s = solutions | ||
| 290 | }; | ||
| 291 | |||
| 292 | for (i = 0; i < 12; i++) | ||
| 293 | solutions[i] = (char)99; | ||
| 294 | |||
| 295 | for (arg.depth = 0; | ||
| 296 | arg.depth <= maxmoves && solutions[11] == 99; | ||
| 297 | arg.depth++) | ||
| 298 | { | ||
| 299 | arg.nmoves = 0; | ||
| 300 | solve_h48stats_dfs(&arg); | ||
| 301 | } | ||
| 302 | |||
| 303 | return 0; | ||
| 304 | } | ||
diff --git a/src/solvers/h48/stats.h b/src/solvers/h48/stats.h new file mode 100644 index 0000000..6e78ab5 --- /dev/null +++ b/src/solvers/h48/stats.h | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | /* | ||
| 2 | The h48stats solver computes how many moves it takes to solve to | ||
| 3 | each of the 12 h48 coordinates, one for each value of h from 0 to 11. | ||
| 4 | The solutions array is filled with the length of the solutions. The | ||
| 5 | solutions array is therefore not a printable string. | ||
| 6 | */ | ||
| 7 | |||
| 8 | typedef struct { | ||
| 9 | cube_t cube; | ||
| 10 | int8_t nmoves; | ||
| 11 | int8_t depth; | ||
| 12 | uint8_t moves[MAXLEN]; | ||
| 13 | uint32_t *cocsepdata; | ||
| 14 | uint8_t *h48data; | ||
| 15 | char *s; | ||
| 16 | } dfsarg_solveh48stats_t; | ||
| 17 | |||
| 18 | STATIC int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); | ||
| 19 | STATIC int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]); | ||
| 20 | |||
| 21 | STATIC int64_t | ||
| 22 | solve_h48stats_dfs(dfsarg_solveh48stats_t *arg) | ||
| 23 | { | ||
| 24 | const int64_t limit = 11; | ||
| 25 | |||
| 26 | int8_t bound, u; | ||
| 27 | uint8_t m; | ||
| 28 | uint32_t d; | ||
| 29 | int64_t coord, h; | ||
| 30 | dfsarg_solveh48stats_t nextarg; | ||
| 31 | |||
| 32 | /* Check cocsep lower bound (corners only) */ | ||
| 33 | bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d); | ||
| 34 | if (bound + arg->nmoves > arg->depth) | ||
| 35 | return 0; | ||
| 36 | |||
| 37 | /* Check h48 lower bound for h=0 (esep, but no eo) */ | ||
| 38 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 0); | ||
| 39 | bound = get_h48_bound(arg->cube, d, 0, 4, arg->h48data); | ||
| 40 | if (bound + arg->nmoves > arg->depth) | ||
| 41 | return 0; | ||
| 42 | |||
| 43 | /* Update all other values, if solved */ | ||
| 44 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11); | ||
| 45 | for (h = 0; h <= limit; h++) { | ||
| 46 | u = coord >> (11-h) == 0 && arg->s[h] == 99; | ||
| 47 | arg->s[h] = u * arg->nmoves + (1-u) * arg->s[h]; | ||
| 48 | } | ||
| 49 | |||
| 50 | if (arg->s[limit] != 99) | ||
| 51 | return 0; | ||
| 52 | |||
| 53 | nextarg = *arg; | ||
| 54 | nextarg.nmoves = arg->nmoves + 1; | ||
| 55 | for (m = 0; m < 18; m++) { | ||
| 56 | nextarg.moves[arg->nmoves] = m; | ||
| 57 | if (!allowednextmove(nextarg.moves, nextarg.nmoves)) { | ||
| 58 | /* If a move is not allowed, neither are its 180 | ||
| 59 | * and 270 degree variations */ | ||
| 60 | m += 2; | ||
| 61 | continue; | ||
| 62 | } | ||
| 63 | nextarg.cube = move(arg->cube, m); | ||
| 64 | solve_h48stats_dfs(&nextarg); | ||
| 65 | } | ||
| 66 | |||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | STATIC int64_t | ||
| 71 | solve_h48stats( | ||
| 72 | cube_t cube, | ||
| 73 | int8_t maxmoves, | ||
| 74 | const void *data, | ||
| 75 | char solutions[static 12] | ||
| 76 | ) | ||
| 77 | { | ||
| 78 | int i; | ||
| 79 | dfsarg_solveh48stats_t arg; | ||
| 80 | |||
| 81 | arg = (dfsarg_solveh48stats_t) { | ||
| 82 | .cube = cube, | ||
| 83 | .cocsepdata = get_cocsepdata_ptr(data), | ||
| 84 | .h48data = get_h48data_ptr(data), | ||
| 85 | .s = solutions | ||
| 86 | }; | ||
| 87 | |||
| 88 | for (i = 0; i < 12; i++) | ||
| 89 | solutions[i] = (char)99; | ||
| 90 | |||
| 91 | for (arg.depth = 0; | ||
| 92 | arg.depth <= maxmoves && solutions[11] == 99; | ||
| 93 | arg.depth++) | ||
| 94 | { | ||
| 95 | arg.nmoves = 0; | ||
| 96 | solve_h48stats_dfs(&arg); | ||
| 97 | } | ||
| 98 | |||
| 99 | return 0; | ||
| 100 | } | ||
diff --git a/tools/0022_gendata_h48h2k2/gendata_h48h2k2.c b/tools/0022_gendata_h48h2k2/gendata_h48h2k2.c new file mode 100644 index 0000000..f437e98 --- /dev/null +++ b/tools/0022_gendata_h48h2k2/gendata_h48h2k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "2;2;20", "tables/h48h2k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 2, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/tools/0032_gendata_h48h3k2/gendata_h48h3k2.c b/tools/0032_gendata_h48h3k2/gendata_h48h3k2.c new file mode 100644 index 0000000..2e0eab5 --- /dev/null +++ b/tools/0032_gendata_h48h3k2/gendata_h48h3k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "3;2;20", "tables/h48h3k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 3, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/tools/0042_gendata_h48h4k2/gendata_h48h4k2.c b/tools/0042_gendata_h48h4k2/gendata_h48h4k2.c new file mode 100644 index 0000000..868c360 --- /dev/null +++ b/tools/0042_gendata_h48h4k2/gendata_h48h4k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "4;2;20", "tables/h48h4k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 4, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/tools/0052_gendata_h48h5k2/gendata_h48h5k2.c b/tools/0052_gendata_h48h5k2/gendata_h48h5k2.c new file mode 100644 index 0000000..d292d49 --- /dev/null +++ b/tools/0052_gendata_h48h5k2/gendata_h48h5k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "5;2;20", "tables/h48h5k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 5, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/tools/0062_gendata_h48h6k2/gendata_h48h6k2.c b/tools/0062_gendata_h48h6k2/gendata_h48h6k2.c new file mode 100644 index 0000000..910d514 --- /dev/null +++ b/tools/0062_gendata_h48h6k2/gendata_h48h6k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "6;2;20", "tables/h48h6k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 6, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/tools/0072_gendata_h48h7k2/gendata_h48h7k2.c b/tools/0072_gendata_h48h7k2/gendata_h48h7k2.c new file mode 100644 index 0000000..b803328 --- /dev/null +++ b/tools/0072_gendata_h48h7k2/gendata_h48h7k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "7;2;20", "tables/h48h7k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 7, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/tools/0082_gendata_h48h8k2/gendata_h48h8k2.c b/tools/0082_gendata_h48h8k2/gendata_h48h8k2.c new file mode 100644 index 0000000..52c377a --- /dev/null +++ b/tools/0082_gendata_h48h8k2/gendata_h48h8k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "8;2;20", "tables/h48h8k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 8, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/tools/0092_gendata_h48h9k2/gendata_h48h9k2.c b/tools/0092_gendata_h48h9k2/gendata_h48h9k2.c new file mode 100644 index 0000000..5d3e34a --- /dev/null +++ b/tools/0092_gendata_h48h9k2/gendata_h48h9k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "9;2;20", "tables/h48h9k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 9, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/tools/0102_gendata_h48h10k2/gendata_h48h10k2.c b/tools/0102_gendata_h48h10k2/gendata_h48h10k2.c new file mode 100644 index 0000000..5e8fbb0 --- /dev/null +++ b/tools/0102_gendata_h48h10k2/gendata_h48h10k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "10;2;20", "tables/h48h10k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 10, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
diff --git a/tools/0112_gendata_h48h11k2/gendata_h48h11k2.c b/tools/0112_gendata_h48h11k2/gendata_h48h11k2.c new file mode 100644 index 0000000..00c0747 --- /dev/null +++ b/tools/0112_gendata_h48h11k2/gendata_h48h11k2.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | #include "../tool.h" | ||
| 2 | |||
| 3 | uint64_t expected[21] = { | ||
| 4 | /* Base value is 8 */ | ||
| 5 | [0] = 0, /* Unknown */ | ||
| 6 | [1] = 0, /* Unknown */ | ||
| 7 | [2] = 0, /* Unknown */ | ||
| 8 | [3] = 0, /* Unknown */ | ||
| 9 | }; | ||
| 10 | |||
| 11 | void run(void) { | ||
| 12 | gendata_run("h48", "11;2;20", "tables/h48h11k2", expected); | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(void) { | ||
| 16 | nissy_setlogger(log_stderr); | ||
| 17 | |||
| 18 | timerun(run, "benchmark gendata_h48 h = 11, k = 2"); | ||
| 19 | |||
| 20 | return 0; | ||
| 21 | } | ||
