Build the full text encoder computation graph. token_ids: [L] int32 tensor (BPE token IDs, padded to ctx_len with 0s). Must be marked as input by caller; data uploaded after alloc. Returns: text_features tensor [text_out_dim, L] = [256, L]. Also creates the causal mask internally (marked as input).
| 4038 | // Returns: text_features tensor [text_out_dim, L] = [256, L]. |
| 4039 | // Also creates the causal mask internally (marked as input). |
| 4040 | static struct ggml_tensor* sam3_build_text_encoder_graph(struct ggml_context* ctx, |
| 4041 | struct ggml_tensor* token_ids, |
| 4042 | const sam3_model& model) { |
| 4043 | const auto& hp = model.hparams; |
| 4044 | const auto& enc = model.text_enc; |
| 4045 | const int L = hp.text_ctx_len; // 32 |
| 4046 | |
| 4047 | auto* x = ggml_get_rows(ctx, enc.token_embed_w, token_ids); |
| 4048 | ggml_set_name(x, "text_token_embed"); |
| 4049 | |
| 4050 | x = ggml_add(ctx, x, enc.pos_embed); |
| 4051 | ggml_set_name(x, "text_after_pos_embed"); |
| 4052 | |
| 4053 | auto* causal_mask = sam3_build_causal_mask(ctx, L); |
| 4054 | |
| 4055 | for (int i = 0; i < hp.text_layers; ++i) { |
| 4056 | x = sam3_text_block_forward(ctx, x, enc.blocks[i], hp, causal_mask, i); |
| 4057 | } |
| 4058 | |
| 4059 | x = sam3_layer_norm(ctx, x, enc.ln_final_w, enc.ln_final_b); |
| 4060 | ggml_set_name(x, "text_final_ln"); |
| 4061 | |
| 4062 | // Resizer: project 1024 → 256 |
| 4063 | x = ggml_mul_mat(ctx, enc.resizer_w, x); |
| 4064 | x = ggml_add(ctx, x, enc.resizer_b); |
| 4065 | ggml_set_name(x, "text_features_2d"); |
| 4066 | |
| 4067 | return x; |
| 4068 | } |
| 4069 | |
| 4070 | /***************************************************************************** |
| 4071 | ** SAM2 — Hiera Backbone Graph Building |
no test coverage detected