| 6026 | *****************************************************************************/ |
| 6027 | |
| 6028 | bool sam3_encode_image(sam3_state& state, |
| 6029 | const sam3_model& model, |
| 6030 | const sam3_image& image) { |
| 6031 | // ── EdgeTAM dispatch ───────────────────────────────────────────────── |
| 6032 | if (model.hparams.is_edgetam()) { |
| 6033 | return edgetam_encode_image(state, model, image); |
| 6034 | } |
| 6035 | |
| 6036 | // ── SAM2 dispatch ──────────────────────────────────────────────────── |
| 6037 | if (model.hparams.is_sam2()) { |
| 6038 | return sam2_encode_image_hiera(state, model, image); |
| 6039 | } |
| 6040 | |
| 6041 | #if SAM3_LOG_LEVEL >= 1 |
| 6042 | auto t_start = std::chrono::high_resolution_clock::now(); |
| 6043 | #endif |
| 6044 | const auto& hp = model.hparams; |
| 6045 | const int img_size = sam3_eff_img_size(state, hp); |
| 6046 | |
| 6047 | SAM3_LOG(2, "%s: encoding %dx%d image → %dx%d\n", __func__, |
| 6048 | image.width, image.height, img_size, img_size); |
| 6049 | |
| 6050 | state.orig_width = image.width; |
| 6051 | state.orig_height = image.height; |
| 6052 | |
| 6053 | auto img_data = sam3_preprocess_image(image, img_size); |
| 6054 | |
| 6055 | const size_t buf_size = ggml_tensor_overhead() * 8192 + ggml_graph_overhead() * 2; |
| 6056 | struct ggml_init_params gparams = { |
| 6057 | /*.mem_size =*/buf_size, |
| 6058 | /*.mem_buffer =*/nullptr, |
| 6059 | /*.no_alloc =*/true, |
| 6060 | }; |
| 6061 | struct ggml_context* ctx0 = ggml_init(gparams); |
| 6062 | if (!ctx0) { |
| 6063 | fprintf(stderr, "%s: failed to init compute context\n", __func__); |
| 6064 | return false; |
| 6065 | } |
| 6066 | |
| 6067 | auto* inp = ggml_new_tensor_4d(ctx0, GGML_TYPE_F32, img_size, img_size, 3, 1); |
| 6068 | ggml_set_name(inp, "input_image"); |
| 6069 | ggml_set_input(inp); |
| 6070 | |
| 6071 | auto* vit_out = sam3_build_vit_graph(ctx0, inp, model); |
| 6072 | ggml_set_name(vit_out, "vit_output"); |
| 6073 | ggml_set_output(vit_out); |
| 6074 | struct ggml_tensor* neck_det_out[4] = {}; |
| 6075 | struct ggml_tensor* neck_trk_out[4]; |
| 6076 | if (!model.hparams.visual_only) { |
| 6077 | sam3_build_neck_graph(ctx0, vit_out, model.neck_det, neck_det_out); |
| 6078 | } |
| 6079 | sam3_build_neck_graph(ctx0, vit_out, model.neck_trk, neck_trk_out); |
| 6080 | |
| 6081 | for (int i = 0; i < 4; ++i) { |
| 6082 | char name[64]; |
| 6083 | if (!model.hparams.visual_only) { |
| 6084 | snprintf(name, sizeof(name), "neck_det_%d", i); |
| 6085 | ggml_set_name(neck_det_out[i], name); |