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 f64a5a67a37015bd5066efd9b1edb6ac3e0b7a97
parent 5727f06c5694a4831881322876e3ba4d8ce3b743
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Sat, 20 Jul 2024 22:51:23 +0200

Fixed gendata tool and cleaned up some stuff

Diffstat:
Dtools/01_gendata_h48/benchmark_gendata_h48.c | 47-----------------------------------------------
Dtools/02_stats_tables_h48/stats_tables_h48.c | 152-------------------------------------------------------------------------------
Atools/gendata_h48/gendata_h48.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Atools/stats_tables_h48/stats_tables_h48.c | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtools/timerun.h | 12++++++++++++
5 files changed, 212 insertions(+), 199 deletions(-)

diff --git a/tools/01_gendata_h48/benchmark_gendata_h48.c b/tools/01_gendata_h48/benchmark_gendata_h48.c @@ -1,47 +0,0 @@ -#include "../timerun.h" -#include "../../src/cube.h" - -#define MAXDEPTH 10 -#define HVALUE 2 -#define OPTIONS "2;10" -#define LONGOPTIONS "h = 2, max depth = 10" - -#define COCSEPSIZE 1119792 -#define ETABLESIZE(h) (((3393 * 495 * 70) >> 1) << (size_t)(h)) - -char *buf; - -void run(void) { - uint32_t *h48info; - int i; - int64_t s; - - s = nissy_gendata("H48", OPTIONS, buf); - - if (s == -1) { - printf("Error generating table\n"); - } else { - printf("Succesfully generated %" PRId64 " bytes. Table:\n", s); - h48info = (uint32_t *)buf + (ETABLESIZE(HVALUE) + COCSEPSIZE) / 4; - for (i = 0; i < MAXDEPTH+1; i++) - printf("%d:\t%" PRIu32 "\n", i, h48info[i+1]); - } -} - -int main() { - int64_t size; - - size = nissy_datasize("H48", OPTIONS); - if (size == -1) { - printf("gendata_h48 benchmark: error in datasize\n"); - return 1; - } - - buf = malloc(size); - - timerun(run, "benchmark gendata_h48 " LONGOPTIONS); - - free(buf); - - return 0; -} diff --git a/tools/02_stats_tables_h48/stats_tables_h48.c b/tools/02_stats_tables_h48/stats_tables_h48.c @@ -1,152 +0,0 @@ -#include <pthread.h> -#include <stdarg.h> -#include <time.h> -#include "../timerun.h" -#include "../../src/cube.h" - -#define MAXMOVES 20 -#define NTHREADS 32 -#define NCUBES_PER_THREAD 10000 -#define LOG_EVERY (NCUBES_PER_THREAD / 10) - -typedef struct { - int n; - int thread_id; - int64_t v[12][100]; -} thread_arg_t; - -const char *filename = "tables/h48h0k4"; -char *buf; - -uint64_t rand64(void) { - uint64_t i, ret; - - for (i = 0, ret = 0; i < 64; i++) - ret |= (uint64_t)(rand() % 2) << i; - - return ret; -} - -void log_stderr(const char *str, ...) { - va_list args; - - va_start(args, str); - vfprintf(stderr, str, args); - va_end(args); -} - -static void * -run_thread(void *arg) -{ - char sols[12], cube[22]; - int64_t ep, eo, cp, co; - int i, j; - - thread_arg_t *a = (thread_arg_t *)arg; - - for (i = 0; i < a->n; i++) { - ep = rand64(); - eo = rand64(); - cp = rand64(); - co = rand64(); - nissy_getcube(ep, eo, cp, co, "fix", cube); - nissy_solve(cube, "h48stats", "", "", - 0, MAXMOVES, 1, -1, buf, sols); - for (j = 0; j < 12; j++) - a->v[j][(int)sols[j]]++; - if ((i+1) % LOG_EVERY == 0) - fprintf(stderr, "[thread %d] %d cubes solved...\n", - a->thread_id, i+1); - } - - return NULL; -} - -void run(void) { - int64_t i, j, k, tot; - double avg; - pthread_t thread[NTHREADS]; - thread_arg_t arg[NTHREADS]; - - for (i = 0; i < NTHREADS; i++) { - arg[i] = (thread_arg_t) { - .thread_id = i, - .n = NCUBES_PER_THREAD, - .v = {{0}} - }; - pthread_create(&thread[i], NULL, run_thread, &arg[i]); - } - - for (i = 0; i < NTHREADS; i++) - pthread_join(thread[i], NULL); - - for (j = 0; j < 12; j++) { - printf("Data for h=%" PRId64 "\n", j); - for (k = 0, avg = 0.0; k <= 16; k++) { - for (i = 0, tot = 0; i < NTHREADS; i++) - tot += arg[i].v[j][k]; - printf("%" PRId64 "\t%" PRId64 "\n", k, tot); - avg += tot * k; - } - avg /= (double)(NCUBES_PER_THREAD * NTHREADS); - printf("Average: %.4lf\n", avg); - printf("\n"); - } -} - -int getdata(int64_t size) { - int64_t s; - FILE *f; - - buf = malloc(size); - - if ((f = fopen(filename, "rb")) == NULL) { - fprintf(stderr, "Table file not found, generating them." - " This can take a while.\n"); - s = nissy_gendata("h48stats", "", buf); - if (s != size) { - fprintf(stderr, "Error generating table"); - if (s != -1) - fprintf(stderr, " (got %" PRId64 " bytes)", s); - fprintf(stderr, "\n"); - return 1; - } - if ((f = fopen(filename, "wb")) == NULL) { - fprintf(stderr, "Could not write tables to file %s" - ", will be regenerated next time.\n", filename); - } else { - fwrite(buf, size, 1, f); - fclose(f); - } - } else { - fprintf(stderr, "Reading tables from file %s\n", filename); - fread(buf, size, 1, f); - fclose(f); - } - - return 0; -} - -int main(void) { - int64_t size; - - srand(time(NULL)); - - nissy_setlogger(log_stderr); - size = nissy_datasize("h48stats", ""); - if (size == -1) { - printf("h48 stats: error in datasize\n"); - return 1; - } - - if (getdata(size) != 0) { - printf("Error getting table, stopping\n"); - free(buf); - return 1; - } - - timerun(run, "h48 table stats"); - - free(buf); - return 0; -} diff --git a/tools/gendata_h48/gendata_h48.c b/tools/gendata_h48/gendata_h48.c @@ -0,0 +1,49 @@ +#include "../timerun.h" +#include "../../src/cube.h" + +#define MAXDEPTH 20 +#define HVALUE 0 +#define OPTIONS "0;20" +#define LONGOPTIONS "h = 0, max depth = 20" + +#define COCSEPSIZE 1119792 +#define ETABLESIZE(h) (((3393 * 495 * 70) >> 1) << (size_t)(h)) + +char *buf; + +void run(void) { + uint32_t *h48info; + int i; + int64_t s; + + s = nissy_gendata("h48", OPTIONS, buf); + + if (s == -1) { + printf("Error generating table\n"); + } else { + printf("Succesfully generated %" PRId64 " bytes. Table:\n", s); + h48info = (uint32_t *)buf + (ETABLESIZE(HVALUE) + COCSEPSIZE) / 4; + for (i = 0; i < MAXDEPTH+1; i++) + printf("%d:\t%" PRIu32 "\n", i, h48info[i+1]); + } +} + +int main(void) { + int64_t size; + + nissy_setlogger(log_stderr); + + size = nissy_datasize("h48", OPTIONS); + if (size == -1) { + printf("gendata_h48 benchmark: error in datasize\n"); + return 1; + } + + buf = malloc(size); + + timerun(run, "benchmark gendata_h48 " LONGOPTIONS); + + free(buf); + + return 0; +} diff --git a/tools/stats_tables_h48/stats_tables_h48.c b/tools/stats_tables_h48/stats_tables_h48.c @@ -0,0 +1,151 @@ +#include <pthread.h> +#include <time.h> +#include "../timerun.h" +#include "../../src/cube.h" + +#define MAXMOVES 20 +#define NTHREADS 32 +#define NCUBES_PER_THREAD 10000 +#define LOG_EVERY (NCUBES_PER_THREAD / 10) + +typedef struct { + int n; + int thread_id; + int64_t v[12][100]; +} thread_arg_t; + +const char *filename = "tables/h48h0k4"; +char *buf; + +uint64_t rand64(void) { + uint64_t i, ret; + + for (i = 0, ret = 0; i < 64; i++) + ret |= (uint64_t)(rand() % 2) << i; + + return ret; +} + +void log_stderr(const char *str, ...) { + va_list args; + + va_start(args, str); + vfprintf(stderr, str, args); + va_end(args); +} + +static void * +run_thread(void *arg) +{ + char sols[12], cube[22]; + int64_t ep, eo, cp, co; + int i, j; + + thread_arg_t *a = (thread_arg_t *)arg; + + for (i = 0; i < a->n; i++) { + ep = rand64(); + eo = rand64(); + cp = rand64(); + co = rand64(); + nissy_getcube(ep, eo, cp, co, "fix", cube); + nissy_solve(cube, "h48stats", "", "", + 0, MAXMOVES, 1, -1, buf, sols); + for (j = 0; j < 12; j++) + a->v[j][(int)sols[j]]++; + if ((i+1) % LOG_EVERY == 0) + fprintf(stderr, "[thread %d] %d cubes solved...\n", + a->thread_id, i+1); + } + + return NULL; +} + +void run(void) { + int64_t i, j, k, tot; + double avg; + pthread_t thread[NTHREADS]; + thread_arg_t arg[NTHREADS]; + + for (i = 0; i < NTHREADS; i++) { + arg[i] = (thread_arg_t) { + .thread_id = i, + .n = NCUBES_PER_THREAD, + .v = {{0}} + }; + pthread_create(&thread[i], NULL, run_thread, &arg[i]); + } + + for (i = 0; i < NTHREADS; i++) + pthread_join(thread[i], NULL); + + for (j = 0; j < 12; j++) { + printf("Data for h=%" PRId64 "\n", j); + for (k = 0, avg = 0.0; k <= 16; k++) { + for (i = 0, tot = 0; i < NTHREADS; i++) + tot += arg[i].v[j][k]; + printf("%" PRId64 "\t%" PRId64 "\n", k, tot); + avg += tot * k; + } + avg /= (double)(NCUBES_PER_THREAD * NTHREADS); + printf("Average: %.4lf\n", avg); + printf("\n"); + } +} + +int getdata(int64_t size) { + int64_t s; + FILE *f; + + buf = malloc(size); + + if ((f = fopen(filename, "rb")) == NULL) { + fprintf(stderr, "Table file not found, generating them." + " This can take a while.\n"); + s = nissy_gendata("h48stats", "", buf); + if (s != size) { + fprintf(stderr, "Error generating table"); + if (s != -1) + fprintf(stderr, " (got %" PRId64 " bytes)", s); + fprintf(stderr, "\n"); + return 1; + } + if ((f = fopen(filename, "wb")) == NULL) { + fprintf(stderr, "Could not write tables to file %s" + ", will be regenerated next time.\n", filename); + } else { + fwrite(buf, size, 1, f); + fclose(f); + } + } else { + fprintf(stderr, "Reading tables from file %s\n", filename); + fread(buf, size, 1, f); + fclose(f); + } + + return 0; +} + +int main(void) { + int64_t size; + + srand(time(NULL)); + + nissy_setlogger(log_stderr); + size = nissy_datasize("h48stats", ""); + if (size == -1) { + printf("h48 stats: error in datasize\n"); + return 1; + } + + if (getdata(size) != 0) { + printf("Error getting table, stopping\n"); + free(buf); + return 1; + } + + timerun(run, "h48 table stats"); + + free(buf); + return 0; +} diff --git a/tools/timerun.h b/tools/timerun.h @@ -1,9 +1,21 @@ +#include <stdarg.h> #include <stdbool.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <time.h> +void +log_stderr(const char *str, ...) +{ + va_list args; + + va_start(args, str); + vfprintf(stderr, str, args); + va_end(args); +} + + double timerun(void (*run)(void), char *name) {