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


      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 #include "nissy_extra.h"
     11 
     12 static void log_stderr(const char *, void *);
     13 static double timerun(void (*)(void));
     14 static void writetable(const unsigned char *, int64_t, const char *);
     15 static long long int generatetable(const char *, unsigned char **,
     16     char [static NISSY_SIZE_DATAID]);
     17 static long long int derivetable(
     18     const char *, const char *, const char *, unsigned char **);
     19 static int getdata(const char *, unsigned char **, const char *);
     20 static void gendata_run(const char *, uint64_t[static 21]);
     21 static void derivedata_run(
     22     const char *, const char *, const char *, const char *);
     23 
     24 static void
     25 log_stderr(const char *str, void *unused)
     26 {
     27 	fprintf(stderr, "%s", str);
     28 }
     29 
     30 static double
     31 timerun(void (*run)(void))
     32 {
     33 	struct timespec start, end;
     34 	double tdiff, tdsec, tdnano;
     35 
     36 	fflush(stdout);
     37 
     38 	if (run == NULL) {
     39 		printf("nothing to run!\n");
     40 		fflush(stdout);
     41 		return -1.0;
     42 	}
     43 
     44 	clock_gettime(CLOCK_MONOTONIC, &start);
     45 	run();
     46 	clock_gettime(CLOCK_MONOTONIC, &end);
     47 
     48 	tdsec = end.tv_sec - start.tv_sec;
     49 	tdnano = end.tv_nsec - start.tv_nsec;
     50 	tdiff = tdsec + 1e-9 * tdnano;
     51 
     52 	printf("---------\n");
     53 	printf("\nTotal time: %.4fs\n", tdiff);
     54 	fflush(stdout);
     55 
     56 	return tdiff;
     57 }
     58 
     59 static void
     60 writetable(const unsigned char *buf, int64_t size, const char *filename)
     61 {
     62 	FILE *f;
     63 
     64 	if ((f = fopen(filename, "wb")) == NULL) {
     65 		printf("Could not write tables to file %s"
     66 		    ", will be regenerated next time.\n", filename);
     67 	} else {
     68 		fwrite(buf, size, 1, f);
     69 		fclose(f);
     70 		printf("Table written to %s.\n", filename);
     71 	}
     72 }
     73 
     74 static long long int
     75 generatetable(
     76 	const char *solver,
     77 	unsigned char **buf,
     78 	char dataid[static NISSY_SIZE_DATAID]
     79 )
     80 {
     81 	long long int size, gensize;
     82 
     83 	size = nissy_solverinfo(solver, dataid);
     84 	if (size < 0) {
     85 		printf("Error getting table size.\n");
     86 		return -1;
     87 	}
     88 
     89 	*buf = malloc(size);
     90 	gensize = nissy_gendata(solver, size, *buf);
     91 
     92 	if (gensize != size) {
     93 		printf("Error generating table");
     94 		if (gensize == NISSY_OK)
     95 			printf(" (got %lld bytes)", gensize);
     96 		printf("\n");
     97 		return -2;
     98 	}
     99 
    100 	return gensize;
    101 }
    102 
    103 static long long int
    104 derivetable(
    105 	const char *solver_large,
    106 	const char *solver_small,
    107 	const char *filename_large,
    108 	unsigned char **buf
    109 )
    110 {
    111 	uint8_t h, k;
    112 	long long int size, gensize;
    113 	char dataid[NISSY_SIZE_DATAID];
    114 	unsigned char *fulltable;
    115 
    116 	if (getdata(solver_large, &fulltable, filename_large) != 0) {
    117 		printf("Error reading full table.\n");
    118 		gensize = -1;
    119 		goto derivetable_error_nofree;
    120 	}
    121 
    122 	size = nissy_solverinfo(solver_small, dataid);
    123 	if (size == -1) {
    124 		printf("Error getting table size.\n");
    125 		gensize = -2;
    126 		goto derivetable_error;
    127 	}
    128 
    129 	if (parse_h48_solver(solver_small, &h, &k) != 0) {
    130 		gensize = -3;
    131 		goto derivetable_error;
    132 	}
    133 
    134 	*buf = malloc(size);
    135 	gensize = gendata_h48_derive(h, fulltable, *buf);
    136 
    137 	if (gensize != size) {
    138 		printf("Error deriving table\n");
    139 		gensize = -4;
    140 		goto derivetable_error;
    141 	}
    142 
    143 derivetable_error:
    144 	free(fulltable);
    145 
    146 derivetable_error_nofree:
    147 	return gensize;
    148 }
    149 
    150 static int
    151 getdata(
    152 	const char *solver,
    153 	unsigned char **buf,
    154 	const char *filename
    155 ) {
    156 	long long int size, sizeread;
    157 	FILE *f;
    158 	char dataid[NISSY_SIZE_DATAID];
    159 
    160 	if ((f = fopen(filename, "rb")) == NULL) {
    161 		printf("Table file not found, generating it.\n");
    162 		size = generatetable(solver, buf, dataid);
    163 		switch (size) {
    164 		case -1:
    165 			goto getdata_error_nofree;
    166 		case -2:
    167 			goto getdata_error;
    168 		default:
    169 			writetable(*buf, size, filename);
    170 			break;
    171 		}
    172 	} else {
    173 		printf("Reading tables from file %s\n", filename);
    174 		size = nissy_solverinfo(solver, dataid);
    175 		*buf = malloc(size);
    176 		sizeread = fread(*buf, size, 1, f);
    177 		fclose(f);
    178 		if (sizeread != 1) {
    179 			printf("Error reading table, stopping\n");
    180 			goto getdata_error;
    181 		}
    182 	}
    183 
    184 	return 0;
    185 
    186 getdata_error:
    187 	free(*buf);
    188 getdata_error_nofree:
    189 	return 1;
    190 }
    191 
    192 static void
    193 gendata_run(
    194 	const char *solver,
    195 	uint64_t expected[static 21]
    196 ) {
    197 	long long int size;
    198 	char filename[1024], dataid[NISSY_SIZE_DATAID];
    199 	unsigned char *buf;
    200 
    201 	size = generatetable(solver, &buf, dataid);
    202 	sprintf(filename, "tables/%s", dataid);
    203 	switch (size) {
    204 	case -1:
    205 		return;
    206 	case -2:
    207 		goto gendata_run_finish;
    208 	default:
    209 		nissy_datainfo(size, buf);
    210 		printf("\n");
    211 		printf("Succesfully generated %lld bytes. "
    212 		       "See above for details on the tables.\n", size);
    213 
    214 		/* TODO: check that the table is correct */
    215 		writetable(buf, size, filename);
    216 		break;
    217 	}
    218 
    219 gendata_run_finish:
    220 	free(buf);
    221 }
    222 
    223 static void
    224 derivedata_run(
    225 	const char *solver_large,
    226 	const char *solver_small,
    227 	const char *filename_large,
    228 	const char *filename_small
    229 )
    230 {
    231 	long long int size;
    232 	unsigned char *buf;
    233 
    234 	buf = NULL;
    235 	size = derivetable(solver_large, solver_small, filename_large, &buf);
    236 	switch (size) {
    237 	case -1:
    238 		return;
    239 	case -2:
    240 		goto derivedata_run_finish;
    241 	default:
    242 		nissy_datainfo(size, buf);
    243 		printf("\n");
    244 		printf("Succesfully generated %lld bytes. "
    245 		       "See above for details on the tables.\n", size);
    246 
    247 		writetable(buf, size, filename_small);
    248 		break;
    249 	}
    250 
    251 derivedata_run_finish:
    252 	free(buf);
    253 }