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

stats_tables_h48.c (2454B)


      1 #include <pthread.h>
      2 
      3 #include "../tool.h"
      4 
      5 #define MAXMOVES 20
      6 #define LOG_EVERY (NCUBES_PER_THREAD / 10)
      7 
      8 int NCUBES_PER_THREAD;
      9 int64_t size = 0;
     10 const char *solver = "h48stats";
     11 const char *filename = "tables/h48h0k4";
     12 char *buf;
     13 
     14 typedef struct {
     15 	int n;
     16 	int thread_id;
     17 	int64_t v[12][100];
     18 } thread_arg_t;
     19 
     20 uint64_t randll(void) {
     21 	long long int i, ret;
     22 
     23 	for (i = 0, ret = 0; i < 64; i++)
     24 		ret |= (long long int)(rand() % 2) << i;
     25 
     26 	return ret;
     27 }
     28 
     29 static void *
     30 run_thread(void *arg)
     31 {
     32 	char s[12], cube[22];
     33 	long long int ep, eo, cp, co, stats[NISSY_SIZE_SOLVE_STATS];
     34 	int i, j;
     35 
     36 	thread_arg_t *a = (thread_arg_t *)arg;
     37 
     38 	for (i = 0; i < a->n; i++) {
     39 		ep = randll();
     40 		eo = randll();
     41 		cp = randll();
     42 		co = randll();
     43 		nissy_getcube(ep, eo, cp, co, "fix", cube);
     44 		nissy_solve(cube, "h48stats", NISSY_NISSFLAG_NORMAL,
     45 		    0, MAXMOVES, 1, -1, size, buf, 12, s, stats);
     46 		for (j = 0; j < 12; j++)
     47 			a->v[j][(int)s[j]]++;
     48 		if ((i+1) % LOG_EVERY == 0)
     49 			printf("[thread %d] %d cubes solved...\n",
     50 			    a->thread_id, i+1);
     51 	}
     52 
     53 	return NULL;
     54 }
     55 
     56 void run(void) {
     57 	int64_t i, j, k, tot;
     58 	double avg;
     59 	pthread_t thread[THREADS];
     60 	thread_arg_t arg[THREADS];
     61 
     62 	size = nissy_datasize(solver);
     63 
     64 	for (i = 0; i < THREADS; i++) {
     65 		arg[i] = (thread_arg_t) {
     66 			.thread_id = i,
     67 			.n = NCUBES_PER_THREAD,
     68 			.v = {{0}}
     69 		};
     70 		pthread_create(&thread[i], NULL, run_thread, &arg[i]);
     71 	}
     72 
     73 	for (i = 0; i < THREADS; i++)
     74 		pthread_join(thread[i], NULL);
     75 
     76 	for (j = 0; j < 12; j++) {
     77 		printf("Data for h=%" PRId64 "\n", j);
     78 		for (k = 0, avg = 0.0; k < 16; k++) {
     79 			for (i = 0, tot = 0; i < THREADS; i++)
     80 				tot += arg[i].v[j][k];
     81 			printf("%" PRId64 "\t%" PRId64 "\n", k, tot);
     82 			avg += tot * k;
     83 		}
     84 		avg /= (double)(NCUBES_PER_THREAD * THREADS);
     85 		printf("Average: %.4lf\n", avg);
     86 		printf("\n");
     87 	}
     88 }
     89 
     90 int main(int argc, char **argv) {
     91 	srand(time(NULL));
     92 	nissy_setlogger(log_stderr);
     93 
     94 	if (argc < 2) {
     95 		printf("Error: not enough arguments. "
     96 		    "Number of cubes per thread must be provided.\n");
     97 		return 1;
     98 	}
     99 
    100 	NCUBES_PER_THREAD = atoi(argv[1]);
    101 
    102 	if (NCUBES_PER_THREAD < 1 || NCUBES_PER_THREAD > 1000000) {
    103 		printf("Invalid number of cubes: must be > 0 and "
    104 		    "< 1000000, but %d was given.\n", NCUBES_PER_THREAD);
    105 		return 1;
    106 	}
    107 
    108 	printf("Using %d cubes per thread (%d total)\n",
    109 	    NCUBES_PER_THREAD, NCUBES_PER_THREAD * THREADS);
    110 	if (getdata(solver, &buf, filename) != 0)
    111 		return 1;
    112 
    113 	timerun(run);
    114 
    115 	free(buf);
    116 	return 0;
    117 }