diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-13 23:55:21 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-13 23:55:21 +0100 |
| commit | 0570941761936d74b573801c45385f4baaa6399c (patch) | |
| tree | 45f72d56d713af2cb5429abd1131db8366d571dd | |
| parent | 112d7f82a4fccbe26ae2b4696d87464494253ce1 (diff) | |
cnn_test: Add --weights option for runtime weight loading
Enables testing different CNN v2 weight files without rebuilding. Automatically forces CNN v2 when --weights is specified, with warning if --cnn-version conflicts.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
| -rw-r--r-- | tools/cnn_test.cc | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/tools/cnn_test.cc b/tools/cnn_test.cc index 3fad2ff..826d9ea 100644 --- a/tools/cnn_test.cc +++ b/tools/cnn_test.cc @@ -46,6 +46,8 @@ struct Args { int num_layers = 3; // Default to 3 layers bool debug_hex = false; // Print first 8 pixels as hex int cnn_version = 1; // 1=CNNEffect, 2=CNNv2Effect + const char* weights_path = nullptr; // Optional .bin weights file + bool cnn_version_explicit = false; // Track if --cnn-version was explicitly set }; // Parse command-line arguments @@ -87,10 +89,13 @@ static bool parse_args(int argc, char** argv, Args* args) { args->debug_hex = true; } else if (strcmp(argv[i], "--cnn-version") == 0 && i + 1 < argc) { args->cnn_version = atoi(argv[++i]); + args->cnn_version_explicit = true; if (args->cnn_version < 1 || args->cnn_version > 2) { fprintf(stderr, "Error: cnn-version must be 1 or 2\n"); return false; } + } else if (strcmp(argv[i], "--weights") == 0 && i + 1 < argc) { + args->weights_path = argv[++i]; } else if (strcmp(argv[i], "--help") == 0) { return false; } else { @@ -99,6 +104,15 @@ static bool parse_args(int argc, char** argv, Args* args) { } } + // Force CNN v2 when --weights is specified + if (args->weights_path) { + if (args->cnn_version_explicit && args->cnn_version != 2) { + fprintf(stderr, "WARNING: --cnn-version %d ignored (--weights forces CNN v2)\n", + args->cnn_version); + } + args->cnn_version = 2; + } + return true; } @@ -112,6 +126,7 @@ static void print_usage(const char* prog) { fprintf(stderr, " --save-intermediates DIR Save intermediate layers to directory\n"); fprintf(stderr, " --debug-hex Print first 8 pixels as hex (debug)\n"); fprintf(stderr, " --cnn-version N CNN version: 1 (default) or 2\n"); + fprintf(stderr, " --weights PATH Load weights from .bin file (forces CNN v2)\n"); fprintf(stderr, " --help Show this help\n"); } @@ -586,10 +601,38 @@ static bool process_cnn_v2(WGPUDevice device, WGPUQueue queue, int width, int height, const Args& args) { printf("Using CNN v2 (storage buffer architecture)\n"); - // Load weights + // Load weights (from file or asset system) size_t weights_size = 0; - const uint8_t* weights_data = - (const uint8_t*)GetAsset(AssetId::ASSET_WEIGHTS_CNN_V2, &weights_size); + const uint8_t* weights_data = nullptr; + std::vector<uint8_t> file_weights; // For file-based loading + + if (args.weights_path) { + // Load from file + printf("Loading weights from '%s'...\n", args.weights_path); + FILE* f = fopen(args.weights_path, "rb"); + if (!f) { + fprintf(stderr, "Error: failed to open weights file '%s'\n", args.weights_path); + return false; + } + + fseek(f, 0, SEEK_END); + weights_size = ftell(f); + fseek(f, 0, SEEK_SET); + + file_weights.resize(weights_size); + size_t read = fread(file_weights.data(), 1, weights_size, f); + fclose(f); + + if (read != weights_size) { + fprintf(stderr, "Error: failed to read weights file\n"); + return false; + } + + weights_data = file_weights.data(); + } else { + // Load from asset system + weights_data = (const uint8_t*)GetAsset(AssetId::ASSET_WEIGHTS_CNN_V2, &weights_size); + } if (!weights_data || weights_size < 20) { fprintf(stderr, "Error: CNN v2 weights not available\n"); |
