MCPcopy Create free account
hub / github.com/PABannier/sam3.cpp / sam3_propagate_single

Function sam3_propagate_single

sam3.cpp:11175–11457  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

11173}
11174
11175static sam3_prop_output sam3_propagate_single(
11176 sam3_tracker& tracker, sam3_state& state, const sam3_model& model,
11177 const sam3_masklet& masklet,
11178 const std::vector<sam3_memory_slot>& mem_bank,
11179 const std::vector<std::pair<int, struct ggml_tensor*>>& ptr_bank) {
11180 sam3_prop_output output = {};
11181 const auto& hp = model.hparams;
11182 const int D = hp.neck_dim, MD = hp.mem_out_dim;
11183 const int H = sam3_eff_feat_size(state, hp);
11184 const int N = H * H;
11185
11186 auto sel = sam3_select_memory_frames(mem_bank, hp.num_maskmem);
11187 if (sel.empty()) return output;
11188
11189 // ── Build prompt and prompt_pos via sam3_build_prompt_and_pos ─────────
11190 // EdgeTAM with perceiver: each slot has 512 tokens (not H*H).
11191 // Standard SAM2/SAM3: each slot has H*H tokens.
11192 const bool use_perceiver = hp.has_perceiver != 0;
11193 const int N_per_slot = use_perceiver ? (hp.perceiver_n_latents_1d + hp.perceiver_n_latents_2d) : N;
11194
11195 int n_sel = (int)sel.size();
11196 std::vector<std::vector<float>> slot_feats(n_sel), slot_pes(n_sel);
11197 std::vector<int> spatial_tpos(n_sel, 1); // default t_pos=1 for non-cond
11198 for (int s = 0; s < n_sel; ++s) {
11199 slot_feats[s].resize(MD * N_per_slot);
11200 ggml_backend_tensor_get(mem_bank[sel[s]].spatial_feats,
11201 slot_feats[s].data(), 0, MD * N_per_slot * sizeof(float));
11202 slot_pes[s].resize(MD * N_per_slot);
11203 if (mem_bank[sel[s]].spatial_pe) {
11204 ggml_backend_tensor_get(mem_bank[sel[s]].spatial_pe,
11205 slot_pes[s].data(), 0, MD * N_per_slot * sizeof(float));
11206 } else {
11207 sam3_ensure_tracker_pe_caches(tracker, hp, H);
11208 if (use_perceiver) {
11209 // For perceiver: zeros for 1D tokens, sinusoidal for 2D tokens
11210 const int N_1d = hp.perceiver_n_latents_1d;
11211 const int N_2d = hp.perceiver_n_latents_2d;
11212 memset(slot_pes[s].data(), 0, MD * N_1d * sizeof(float));
11213 auto pe_2d = sam3_sinusoidal_pe_2d(16, 16, MD);
11214 memcpy(slot_pes[s].data() + MD * N_1d, pe_2d.data(), MD * N_2d * sizeof(float));
11215 } else {
11216 slot_pes[s] = tracker.cached_sinpe_64;
11217 }
11218 }
11219 spatial_tpos[s] = mem_bank[sel[s]].is_cond_frame ? 0 : (n_sel - s);
11220 }
11221
11222 int P = std::min((int)ptr_bank.size(), hp.max_obj_ptrs);
11223 std::vector<std::vector<float>> obj_ptrs(P);
11224 std::vector<int> ptr_tpos(P);
11225 int cur_frame = tracker.frame_index;
11226 for (int p = 0; p < P; ++p) {
11227 obj_ptrs[p].resize(D);
11228 ggml_backend_tensor_get(ptr_bank[p].second, obj_ptrs[p].data(), 0, D * sizeof(float));
11229 // Use actual frame distance (matches Python: abs(frame_idx - t))
11230 ptr_tpos[p] = std::abs(cur_frame - ptr_bank[p].first);
11231 if (ptr_tpos[p] < 1) ptr_tpos[p] = 1; // minimum distance of 1
11232 }

Callers 2

sam3_track_frameFunction · 0.85
sam3_propagate_frameFunction · 0.85

Calls 11

sam3_eff_feat_sizeFunction · 0.85
sam3_sinusoidal_pe_2dFunction · 0.85
sam3_build_sam_dec_graphFunction · 0.85
sam3_populate_pe_cacheFunction · 0.85
sam3_graph_computeFunction · 0.85
is_sam2Method · 0.80
is_edgetamMethod · 0.80

Tested by

no test coverage detected