nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

tool.h (4072B)


      1 #include <time.h>
      2 #include <stdarg.h>
      3 #include <stdbool.h>
      4 #include <inttypes.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 
      9 #include "../src/nissy.h"
     10 
     11 #if defined(_WIN32)
     12 #define wrap_aligned_alloc(align, size) malloc(size)
     13 #else
     14 #define wrap_aligned_alloc(align, size) \
     15     (((size) % (align) == 0) ? aligned_alloc((align), (size)) : malloc(size))
     16 #endif
     17 
     18 static void log_stderr(const char *, void *);
     19 static double timerun(void (*)(void));
     20 static void writetable(const unsigned char *, int64_t, const char *);
     21 static long long int generatetable(const char *, unsigned char **, char *);
     22 static int getdata(const char *, unsigned char **, const char *);
     23 static void gendata_run(const char *, uint64_t *);
     24 
     25 static void
     26 log_stderr(const char *str, void *unused)
     27 {
     28 	fprintf(stderr, "%s", str);
     29 }
     30 
     31 #ifdef _WIN32
     32 
     33 #include <windows.h>
     34 
     35 static double
     36 timerun(void (*run)(void))
     37 {
     38 	LARGE_INTEGER freq, start, end;
     39 	double tdiff;
     40 	
     41 	fflush(stdout);
     42 	
     43 	if (run == NULL) {
     44 		printf("nothing to run!\n");
     45 		fflush(stdout);
     46 		return -1.0;
     47 	}
     48 
     49 	QueryPerformanceFrequency(&freq);
     50 	QueryPerformanceCounter(&start);
     51 	run();
     52 	QueryPerformanceCounter(&end);
     53 	
     54 	tdiff = (double)(end.QuadPart - start.QuadPart) / freq.QuadPart;
     55 
     56 	printf("---------\n");
     57 	printf("\nTotal time: %.4fs\n", tdiff);
     58 	fflush(stdout);
     59 
     60 	return tdiff;
     61 }
     62 
     63 #else
     64 
     65 static double
     66 timerun(void (*run)(void))
     67 {
     68 	struct timespec start, end;
     69 	double tdiff, tdsec, tdnano;
     70 
     71 	fflush(stdout);
     72 
     73 	if (run == NULL) {
     74 		printf("nothing to run!\n");
     75 		fflush(stdout);
     76 		return -1.0;
     77 	}
     78 
     79 	clock_gettime(CLOCK_MONOTONIC, &start);
     80 	run();
     81 	clock_gettime(CLOCK_MONOTONIC, &end);
     82 
     83 	tdsec = end.tv_sec - start.tv_sec;
     84 	tdnano = end.tv_nsec - start.tv_nsec;
     85 	tdiff = tdsec + 1e-9 * tdnano;
     86 
     87 	printf("---------\n");
     88 	printf("\nTotal time: %.4fs\n", tdiff);
     89 	fflush(stdout);
     90 
     91 	return tdiff;
     92 }
     93 
     94 #endif
     95 
     96 static void
     97 writetable(const unsigned char *buf, int64_t size, const char *filename)
     98 {
     99 	FILE *f;
    100 
    101 	if ((f = fopen(filename, "wb")) == NULL) {
    102 		printf("Could not write tables to file %s"
    103 		    ", will be regenerated next time.\n", filename);
    104 	} else {
    105 		fwrite(buf, size, 1, f);
    106 		fclose(f);
    107 		printf("Table written to %s.\n", filename);
    108 	}
    109 }
    110 
    111 static long long int
    112 generatetable(
    113 	const char *solver,
    114 	unsigned char **buf,
    115 	char *dataid
    116 )
    117 {
    118 	long long int size, gensize;
    119 
    120 	size = nissy_solverinfo(solver, dataid);
    121 	if (size < 0) {
    122 		printf("Error getting table size.\n");
    123 		return -1;
    124 	}
    125 
    126 	*buf = wrap_aligned_alloc((size_t)64, size);
    127 	gensize = nissy_gendata(solver, size, *buf);
    128 
    129 	if (gensize != size) {
    130 		printf("Error generating table");
    131 		if (gensize == NISSY_OK)
    132 			printf(" (got %lld bytes)", gensize);
    133 		printf("\n");
    134 		return -2;
    135 	}
    136 
    137 	return gensize;
    138 }
    139 
    140 static int
    141 getdata(
    142 	const char *solver,
    143 	unsigned char **buf,
    144 	const char *filename
    145 ) {
    146 	long long int size, sizeread;
    147 	FILE *f;
    148 	char dataid[NISSY_SIZE_DATAID];
    149 
    150 	if ((f = fopen(filename, "rb")) == NULL) {
    151 		printf("Table file not found, generating it.\n");
    152 		size = generatetable(solver, buf, dataid);
    153 		switch (size) {
    154 		case -1:
    155 			goto getdata_error_nofree;
    156 		case -2:
    157 			goto getdata_error;
    158 		default:
    159 			writetable(*buf, size, filename);
    160 			break;
    161 		}
    162 	} else {
    163 		printf("Reading tables from file %s\n", filename);
    164 		size = nissy_solverinfo(solver, dataid);
    165 		*buf = wrap_aligned_alloc((size_t)64, size);
    166 		sizeread = fread(*buf, size, 1, f);
    167 		fclose(f);
    168 		if (sizeread != 1) {
    169 			printf("Error reading table, stopping\n");
    170 			goto getdata_error;
    171 		}
    172 	}
    173 
    174 	return 0;
    175 
    176 getdata_error:
    177 	free(*buf);
    178 getdata_error_nofree:
    179 	return 1;
    180 }
    181 
    182 static void
    183 gendata_run(
    184 	const char *solver,
    185 	uint64_t *expected
    186 ) {
    187 	long long int size;
    188 	char filename[1024], dataid[NISSY_SIZE_DATAID];
    189 	unsigned char *buf;
    190 
    191 	size = generatetable(solver, &buf, dataid);
    192 	sprintf(filename, "tables/%s", dataid);
    193 	switch (size) {
    194 	case -1:
    195 		return;
    196 	case -2:
    197 		goto gendata_run_finish;
    198 	default:
    199 		printf("Succesfully generated %lld bytes. "
    200 		       "See above for details on the tables.\n", size);
    201 
    202 		writetable(buf, size, filename);
    203 		break;
    204 	}
    205 
    206 gendata_run_finish:
    207 	free(buf);
    208 }