Foundry/examples/ternarize_flip.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;
}