Full EdgeTAM image encoding: preprocess → RepViT → FPN → state
| 4831 | |
| 4832 | // Full EdgeTAM image encoding: preprocess → RepViT → FPN → state |
| 4833 | static bool edgetam_encode_image(sam3_state& state, |
| 4834 | const sam3_model& model, |
| 4835 | const sam3_image& image) { |
| 4836 | auto t_start = std::chrono::high_resolution_clock::now(); |
| 4837 | const auto& hp = model.hparams; |
| 4838 | const int img_size = sam3_eff_img_size(state, hp); |
| 4839 | |
| 4840 | fprintf(stderr, "%s: encoding %dx%d image (EdgeTAM RepViT)\n", __func__, |
| 4841 | image.width, image.height); |
| 4842 | |
| 4843 | state.orig_width = image.width; |
| 4844 | state.orig_height = image.height; |
| 4845 | |
| 4846 | // ── Preprocess (same ImageNet normalization as SAM2) ───────────────── |
| 4847 | auto img_data = sam2_preprocess_image(image, img_size); |
| 4848 | |
| 4849 | // ── Build graph ────────────────────────────────────────────────────── |
| 4850 | const size_t buf_size = ggml_tensor_overhead() * 16384 + ggml_graph_overhead() * 2; |
| 4851 | struct ggml_init_params gparams = { |
| 4852 | /*.mem_size =*/buf_size, |
| 4853 | /*.mem_buffer =*/nullptr, |
| 4854 | /*.no_alloc =*/true, |
| 4855 | }; |
| 4856 | auto* ctx0 = ggml_init(gparams); |
| 4857 | if (!ctx0) { |
| 4858 | fprintf(stderr, "%s: failed to init compute context\n", __func__); |
| 4859 | return false; |
| 4860 | } |
| 4861 | |
| 4862 | auto* inp = ggml_new_tensor_4d(ctx0, GGML_TYPE_F32, img_size, img_size, 3, 1); |
| 4863 | ggml_set_name(inp, "input_image"); |
| 4864 | ggml_set_input(inp); |
| 4865 | |
| 4866 | // Build RepViT backbone |
| 4867 | struct ggml_tensor* stage_outs[4] = {}; |
| 4868 | edgetam_build_repvit_graph(ctx0, inp, model, stage_outs); |
| 4869 | |
| 4870 | // Build EdgeTAM FPN neck (optimized: mul_mat for 1×1, unified [W,H,C] layout) |
| 4871 | struct ggml_tensor* fpn_outs[4] = {}; |
| 4872 | edgetam_build_fpn_neck_graph(ctx0, stage_outs, model, fpn_outs); |
| 4873 | |
| 4874 | // Mark FPN outputs |
| 4875 | int n_fpn = 4 - hp.scalp; |
| 4876 | for (int i = 0; i < n_fpn; ++i) { |
| 4877 | char name[64]; |
| 4878 | snprintf(name, sizeof(name), "fpn_out_%d", i); |
| 4879 | ggml_set_name(fpn_outs[i], name); |
| 4880 | ggml_set_output(fpn_outs[i]); |
| 4881 | } |
| 4882 | |
| 4883 | // Build computation graph |
| 4884 | auto* graph = ggml_new_graph_custom(ctx0, 32768, false); |
| 4885 | for (int i = 0; i < n_fpn; ++i) { |
| 4886 | ggml_build_forward_expand(graph, fpn_outs[i]); |
| 4887 | } |
| 4888 | |
| 4889 | // ── Allocate + compute ─────────────────────────────────────────────── |
| 4890 | auto* galloc = ggml_gallocr_new(ggml_backend_get_default_buffer_type(model.backend)); |
no test coverage detected