/* * nnrun.c - run the quantised MLP over a test set and measure it (C89). * * Reads a test file written by train.py: * uint32 count (little-endian), then count*784 pixel bytes, then count labels. * * Usage: nnrun [testfile] [max-samples] * * DeepSeek (deepseek-v4.1-flash), October 2026. */ #include #include #include #include "nn.h" int main(int argc, char **argv) { const char *path = "nn_test.bin"; FILE *f; unsigned char hdr[4]; unsigned char *pix, *lab; unsigned int n, i, limit; long correct = 0; clock_t t0, t1; double secs; if (argc > 1) path = argv[1]; f = fopen(path, "rb"); if (f == NULL) { perror(path); return 1; } if (fread(hdr, 1, 4, f) != 4) { fprintf(stderr, "short header\n"); return 1; } n = (unsigned) hdr[0] | ((unsigned) hdr[1] << 8) | ((unsigned) hdr[2] << 16) | ((unsigned) hdr[3] << 24); pix = (unsigned char *) malloc((size_t) n * 784); lab = (unsigned char *) malloc((size_t) n); if (pix == NULL || lab == NULL) { fprintf(stderr, "out of memory\n"); return 1; } if (fread(pix, 1, (size_t) n * 784, f) != (size_t) n * 784 || fread(lab, 1, (size_t) n, f) != (size_t) n) { fprintf(stderr, "short data\n"); return 1; } fclose(f); limit = n; if (argc > 2) { unsigned int l = (unsigned int) atoi(argv[2]); if (l < n) limit = l; } t0 = clock(); for (i = 0; i < limit; i++) if (nn_classify(pix + (size_t) i * 784) == lab[i]) correct++; t1 = clock(); secs = (double) (t1 - t0) / (double) CLOCKS_PER_SEC; if (secs <= 0.0) secs = 1e-9; printf("samples %u\n", limit); printf("correct %ld\n", correct); printf("accuracy %.2f%%\n", 100.0 * (double) correct / (double) limit); printf("time %.3f s\n", secs); printf("per infer %.1f us\n", secs * 1e6 / (double) limit); printf("rate %.0f inferences/s\n", (double) limit / secs); return 0; }