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 (4145B)


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