Read SAM prompt encoder weights from GPU and cache them in state. Also pre-computes the dense PE grid and no-mask tiled embedding. These never change between PVS calls for the same model.
| 10289 | // Also pre-computes the dense PE grid and no-mask tiled embedding. |
| 10290 | // These never change between PVS calls for the same model. |
| 10291 | static void sam3_populate_pe_cache(sam3_state& state, const sam3_model& model) { |
| 10292 | if (state.pe_cache_valid) return; |
| 10293 | |
| 10294 | const int D = model.hparams.sam_embed_dim; // 256 |
| 10295 | const int H = sam3_eff_feat_size(state, model.hparams); |
| 10296 | const int num_pos_feats = D / 2; // 128 |
| 10297 | const int pe_nel = 2 * num_pos_feats; // 256 |
| 10298 | const auto& pe = model.sam_pe; |
| 10299 | |
| 10300 | state.pe_gauss_cache.resize(pe_nel); |
| 10301 | if (pe.pe_gaussian->type == GGML_TYPE_F16) { |
| 10302 | std::vector<ggml_fp16_t> tmp(pe_nel); |
| 10303 | ggml_backend_tensor_get(pe.pe_gaussian, tmp.data(), 0, pe_nel * sizeof(ggml_fp16_t)); |
| 10304 | ggml_fp16_to_fp32_row(tmp.data(), state.pe_gauss_cache.data(), pe_nel); |
| 10305 | } else { |
| 10306 | ggml_backend_tensor_get(pe.pe_gaussian, state.pe_gauss_cache.data(), 0, pe_nel * sizeof(float)); |
| 10307 | } |
| 10308 | |
| 10309 | for (int i = 0; i < 4; ++i) { |
| 10310 | if (pe.point_embed[i]->type == GGML_TYPE_F16) { |
| 10311 | std::vector<ggml_fp16_t> tmp(D); |
| 10312 | ggml_backend_tensor_get(pe.point_embed[i], tmp.data(), 0, D * sizeof(ggml_fp16_t)); |
| 10313 | ggml_fp16_to_fp32_row(tmp.data(), state.point_emb_cache[i], D); |
| 10314 | } else { |
| 10315 | ggml_backend_tensor_get(pe.point_embed[i], state.point_emb_cache[i], 0, D * sizeof(float)); |
| 10316 | } |
| 10317 | } |
| 10318 | |
| 10319 | if (pe.not_a_point_embed->type == GGML_TYPE_F16) { |
| 10320 | std::vector<ggml_fp16_t> tmp(D); |
| 10321 | ggml_backend_tensor_get(pe.not_a_point_embed, tmp.data(), 0, D * sizeof(ggml_fp16_t)); |
| 10322 | ggml_fp16_to_fp32_row(tmp.data(), state.not_a_point_cache, D); |
| 10323 | } else { |
| 10324 | ggml_backend_tensor_get(pe.not_a_point_embed, state.not_a_point_cache, 0, D * sizeof(float)); |
| 10325 | } |
| 10326 | |
| 10327 | if (pe.no_mask_embed->type == GGML_TYPE_F16) { |
| 10328 | std::vector<ggml_fp16_t> tmp(D); |
| 10329 | ggml_backend_tensor_get(pe.no_mask_embed, tmp.data(), 0, D * sizeof(ggml_fp16_t)); |
| 10330 | ggml_fp16_to_fp32_row(tmp.data(), state.no_mask_emb_cache, D); |
| 10331 | } else { |
| 10332 | ggml_backend_tensor_get(pe.no_mask_embed, state.no_mask_emb_cache, 0, D * sizeof(float)); |
| 10333 | } |
| 10334 | |
| 10335 | state.dense_pe_cache.resize(D * H * H); |
| 10336 | for (int row = 0; row < H; ++row) { |
| 10337 | for (int col = 0; col < H; ++col) { |
| 10338 | float x_norm = ((float)col + 0.5f) / (float)H; |
| 10339 | float y_norm = ((float)row + 0.5f) / (float)H; |
| 10340 | float pe_vec[256]; |
| 10341 | sam3_pe_encode_coord(pe_vec, x_norm, y_norm, |
| 10342 | state.pe_gauss_cache.data(), num_pos_feats); |
| 10343 | for (int d = 0; d < D; ++d) |
| 10344 | state.dense_pe_cache[d + col * D + row * D * H] = pe_vec[d]; |
| 10345 | } |
| 10346 | } |
| 10347 | |
| 10348 | state.dense_nomask_cache.resize(D * H * H); |
no test coverage detected