Full SAM2 image encoding: preprocess → Hiera → FPN → state
| 5859 | |
| 5860 | // Full SAM2 image encoding: preprocess → Hiera → FPN → state |
| 5861 | static bool sam2_encode_image_hiera(sam3_state& state, |
| 5862 | const sam3_model& model, |
| 5863 | const sam3_image& image) { |
| 5864 | auto t_start = std::chrono::high_resolution_clock::now(); |
| 5865 | const auto& hp = model.hparams; |
| 5866 | const int img_size = sam3_eff_img_size(state, hp); |
| 5867 | |
| 5868 | fprintf(stderr, "%s: encoding %dx%d image (SAM2 Hiera)\n", __func__, |
| 5869 | image.width, image.height); |
| 5870 | |
| 5871 | state.orig_width = image.width; |
| 5872 | state.orig_height = image.height; |
| 5873 | |
| 5874 | // ── Preprocess ─────────────────────────────────────────────────────── |
| 5875 | auto img_data = sam2_preprocess_image(image, img_size); |
| 5876 | |
| 5877 | // ── Build graph ────────────────────────────────────────────────────── |
| 5878 | const size_t buf_size = ggml_tensor_overhead() * 16384 + ggml_graph_overhead() * 2; |
| 5879 | struct ggml_init_params gparams = { |
| 5880 | /*.mem_size =*/buf_size, |
| 5881 | /*.mem_buffer =*/nullptr, |
| 5882 | /*.no_alloc =*/true, |
| 5883 | }; |
| 5884 | auto* ctx0 = ggml_init(gparams); |
| 5885 | |
| 5886 | auto* inp = ggml_new_tensor_4d(ctx0, GGML_TYPE_F32, img_size, img_size, 3, 1); |
| 5887 | ggml_set_name(inp, "input_image"); |
| 5888 | ggml_set_input(inp); |
| 5889 | |
| 5890 | // Build Hiera backbone |
| 5891 | struct ggml_tensor* stage_outs[4] = {}; |
| 5892 | sam2_build_hiera_graph(ctx0, inp, model, stage_outs); |
| 5893 | |
| 5894 | // Build FPN neck |
| 5895 | struct ggml_tensor* fpn_outs[4] = {}; |
| 5896 | sam2_build_fpn_neck_graph(ctx0, stage_outs, model, fpn_outs); |
| 5897 | |
| 5898 | // Mark FPN outputs |
| 5899 | int n_fpn = 4 - hp.scalp; |
| 5900 | for (int i = 0; i < n_fpn; ++i) { |
| 5901 | char name[64]; |
| 5902 | snprintf(name, sizeof(name), "fpn_out_%d", i); |
| 5903 | ggml_set_name(fpn_outs[i], name); |
| 5904 | ggml_set_output(fpn_outs[i]); |
| 5905 | } |
| 5906 | |
| 5907 | // Build computation graph |
| 5908 | auto* graph = ggml_new_graph_custom(ctx0, 32768, false); |
| 5909 | for (int i = 0; i < n_fpn; ++i) { |
| 5910 | ggml_build_forward_expand(graph, fpn_outs[i]); |
| 5911 | } |
| 5912 | |
| 5913 | // ── Allocate + compute ─────────────────────────────────────────────── |
| 5914 | auto* galloc = ggml_gallocr_new(ggml_backend_get_default_buffer_type(model.backend)); |
| 5915 | if (!ggml_gallocr_reserve(galloc, graph)) { |
| 5916 | fprintf(stderr, "%s: failed to reserve graph memory\n", __func__); |
| 5917 | ggml_gallocr_free(galloc); |
| 5918 | ggml_free(ctx0); |
no test coverage detected