Test-only: encode from pre-preprocessed float data (bypasses C++ resize/normalize). chw_data is in [C, H, W] layout, already normalized, with C=3, H=W=img_size.
| 6999 | // Test-only: encode from pre-preprocessed float data (bypasses C++ resize/normalize). |
| 7000 | // chw_data is in [C, H, W] layout, already normalized, with C=3, H=W=img_size. |
| 7001 | bool sam3_encode_image_from_preprocessed(sam3_state& state, |
| 7002 | const sam3_model& model, |
| 7003 | const float* chw_data, |
| 7004 | int img_size) { |
| 7005 | auto t_start = std::chrono::high_resolution_clock::now(); |
| 7006 | const auto& hp = model.hparams; |
| 7007 | |
| 7008 | if (img_size != hp.img_size) { |
| 7009 | fprintf(stderr, "%s: img_size mismatch: got %d, expected %d\n", |
| 7010 | __func__, img_size, hp.img_size); |
| 7011 | return false; |
| 7012 | } |
| 7013 | |
| 7014 | fprintf(stderr, "%s: encoding from preprocessed %dx%d\n", __func__, img_size, img_size); |
| 7015 | |
| 7016 | // EdgeTAM dispatch: build RepViT graph directly from preprocessed data |
| 7017 | if (hp.is_edgetam()) { |
| 7018 | state.orig_width = img_size; |
| 7019 | state.orig_height = img_size; |
| 7020 | |
| 7021 | const size_t buf_size = ggml_tensor_overhead() * 16384 + ggml_graph_overhead() * 2; |
| 7022 | struct ggml_init_params gparams = {buf_size, nullptr, true}; |
| 7023 | auto* ctx0 = ggml_init(gparams); |
| 7024 | if (!ctx0) return false; |
| 7025 | |
| 7026 | auto* inp = ggml_new_tensor_4d(ctx0, GGML_TYPE_F32, img_size, img_size, 3, 1); |
| 7027 | ggml_set_name(inp, "input_image"); |
| 7028 | ggml_set_input(inp); |
| 7029 | |
| 7030 | struct ggml_tensor* stage_outs[4] = {}; |
| 7031 | edgetam_build_repvit_graph(ctx0, inp, model, stage_outs); |
| 7032 | |
| 7033 | struct ggml_tensor* fpn_outs[4] = {}; |
| 7034 | edgetam_build_fpn_neck_graph(ctx0, stage_outs, model, fpn_outs); |
| 7035 | |
| 7036 | int n_fpn = 4 - hp.scalp; |
| 7037 | for (int i = 0; i < n_fpn; ++i) { |
| 7038 | char name[64]; |
| 7039 | snprintf(name, sizeof(name), "fpn_out_%d", i); |
| 7040 | ggml_set_name(fpn_outs[i], name); |
| 7041 | ggml_set_output(fpn_outs[i]); |
| 7042 | } |
| 7043 | |
| 7044 | auto* graph = ggml_new_graph_custom(ctx0, 32768, false); |
| 7045 | for (int i = 0; i < n_fpn; ++i) |
| 7046 | ggml_build_forward_expand(graph, fpn_outs[i]); |
| 7047 | |
| 7048 | auto* galloc = ggml_gallocr_new(ggml_backend_get_default_buffer_type(model.backend)); |
| 7049 | if (!ggml_gallocr_reserve(galloc, graph) || !ggml_gallocr_alloc_graph(galloc, graph)) { |
| 7050 | ggml_gallocr_free(galloc); |
| 7051 | ggml_free(ctx0); |
| 7052 | return false; |
| 7053 | } |
| 7054 | |
| 7055 | ggml_backend_tensor_set(inp, chw_data, 0, 3 * img_size * img_size * sizeof(float)); |
| 7056 | |
| 7057 | if (!sam3_graph_compute(model.backend, graph, state.n_threads)) { |
| 7058 | ggml_gallocr_free(galloc); |