100 lines
3.9 KiB
C
100 lines
3.9 KiB
C
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
|
/* Copyright (C) 2026 David (Corey) Herrera */
|
|
/*
|
|
* ternarize-flip: Run 47 scoring on a single layer. Fully self-contained.
|
|
* Can run on any GPU die, any order, in parallel.
|
|
*
|
|
* Usage:
|
|
* ternarize-flip --workdir ./work --layer 15 [--iterations 10]
|
|
*/
|
|
|
|
#include "../ternarize/ternarize.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static void usage(const char *prog) {
|
|
fprintf(stderr, "Usage: %s --workdir <dir> --layer <N> [options]\n", prog);
|
|
fprintf(stderr, "\nOptions:\n");
|
|
fprintf(stderr, " --workdir Work directory\n");
|
|
fprintf(stderr, " --layer Layer index to process\n");
|
|
fprintf(stderr, " --config Path to config.json (re-parse architecture)\n");
|
|
fprintf(stderr, " --iterations Number of flip iterations (default: phase1+phase2)\n");
|
|
fprintf(stderr, " --k-frac Initial flip rate (default: 0.00008)\n");
|
|
fprintf(stderr, " --boltz Initial Boltzmann fraction (default: 0.17)\n");
|
|
fprintf(stderr, " --snr SNR weight (default: 0.3)\n");
|
|
fprintf(stderr, " --hess Hessian power (default: 0.15)\n");
|
|
fprintf(stderr, " --momentum Momentum bonus (default: 0.2)\n");
|
|
fprintf(stderr, " --temporal Temporal weight (default: 1.8)\n");
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
ft_config cfg = ft_config_defaults();
|
|
const char *workdir = NULL;
|
|
const char *config_path = NULL;
|
|
int layer_idx = -1;
|
|
int iterations = 0;
|
|
|
|
for (int i = 1; i < argc; i++) {
|
|
if (strcmp(argv[i], "--workdir") == 0 && i + 1 < argc) {
|
|
workdir = argv[++i];
|
|
} else if (strcmp(argv[i], "--layer") == 0 && i + 1 < argc) {
|
|
layer_idx = atoi(argv[++i]);
|
|
} else if (strcmp(argv[i], "--config") == 0 && i + 1 < argc) {
|
|
config_path = argv[++i];
|
|
} else if (strcmp(argv[i], "--iterations") == 0 && i + 1 < argc) {
|
|
iterations = atoi(argv[++i]);
|
|
} else if (strcmp(argv[i], "--k-frac") == 0 && i + 1 < argc) {
|
|
cfg.k_frac_start = strtof(argv[++i], NULL);
|
|
} else if (strcmp(argv[i], "--boltz") == 0 && i + 1 < argc) {
|
|
cfg.boltz_frac_start = strtof(argv[++i], NULL);
|
|
} else if (strcmp(argv[i], "--snr") == 0 && i + 1 < argc) {
|
|
cfg.snr_weight = strtof(argv[++i], NULL);
|
|
} else if (strcmp(argv[i], "--hess") == 0 && i + 1 < argc) {
|
|
cfg.hess_power = strtof(argv[++i], NULL);
|
|
} else if (strcmp(argv[i], "--momentum") == 0 && i + 1 < argc) {
|
|
cfg.momentum_bonus = strtof(argv[++i], NULL);
|
|
} else if (strcmp(argv[i], "--temporal") == 0 && i + 1 < argc) {
|
|
cfg.temporal_weight = strtof(argv[++i], NULL);
|
|
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
|
|
usage(argv[0]);
|
|
return 0;
|
|
} else {
|
|
fprintf(stderr, "Unknown option: %s\n", argv[i]);
|
|
usage(argv[0]);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!workdir || layer_idx < 0) {
|
|
usage(argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
if (config_path) {
|
|
if (!ft_config_from_json(&cfg, config_path)) {
|
|
fprintf(stderr, "ERROR: failed to parse %s\n", config_path);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
snprintf(cfg.workdir, sizeof(cfg.workdir), "%s", workdir);
|
|
|
|
fprintf(stderr, "ternarize-flip\n");
|
|
fprintf(stderr, " Workdir: %s\n", workdir);
|
|
fprintf(stderr, " Layer: %d\n", layer_idx);
|
|
fprintf(stderr, " Iterations: %d (0 = default %d+%d)\n",
|
|
iterations, cfg.phase1_iters, cfg.phase2_iters);
|
|
fprintf(stderr, " K-frac: %.6f -> %.6f\n", cfg.k_frac_start, cfg.k_frac_end);
|
|
fprintf(stderr, " Boltzmann: %.3f -> %.3f\n", cfg.boltz_frac_start, cfg.boltz_frac_end);
|
|
|
|
int64_t flips = ft_flip(&cfg, layer_idx, iterations);
|
|
if (flips < 0) {
|
|
fprintf(stderr, "ERROR: flip failed\n");
|
|
return 1;
|
|
}
|
|
|
|
fprintf(stderr, "Done: %lld flips\n", (long long)flips);
|
|
return 0;
|
|
}
|