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

Function sam3_fenc_layer_forward

sam3.cpp:8033–8139  ·  view source on GitHub ↗

Single fusion encoder layer. x: [D, N, B] image features (N=5184), prompt: [D, T, B] text/exemplar tokens, pos: [D, N, B] Returns: updated x [D, N, B]

Source from the content-addressed store, hash-verified

8031// x: [D, N, B] image features (N=5184), prompt: [D, T, B] text/exemplar tokens, pos: [D, N, B]
8032// Returns: updated x [D, N, B]
8033static struct ggml_tensor* sam3_fenc_layer_forward(
8034 struct ggml_context* ctx,
8035 const sam3_fenc_layer& ly,
8036 struct ggml_tensor* x,
8037 struct ggml_tensor* prompt,
8038 struct ggml_tensor* pos,
8039 struct ggml_tensor* prompt_attn_bias,
8040 int n_heads) {
8041 // Self-attention: Q/K get positional encoding, V does not
8042 {
8043 auto* shortcut = x;
8044 auto* x_norm = sam3_layer_norm(ctx, x, ly.norm1_w, ly.norm1_b);
8045 auto* q_in = ggml_add(ctx, x_norm, pos);
8046 auto* k_in = ggml_add(ctx, x_norm, pos);
8047
8048 const int64_t D = x->ne[0];
8049
8050 auto* q_w = ggml_view_2d(ctx, ly.sa_in_proj_w, D, D, ly.sa_in_proj_w->nb[1], 0);
8051 auto* k_w = ggml_view_2d(ctx, ly.sa_in_proj_w, D, D, ly.sa_in_proj_w->nb[1], D * ly.sa_in_proj_w->nb[1]);
8052 auto* v_w = ggml_view_2d(ctx, ly.sa_in_proj_w, D, D, ly.sa_in_proj_w->nb[1], 2 * D * ly.sa_in_proj_w->nb[1]);
8053
8054 auto* q_b = ggml_view_1d(ctx, ly.sa_in_proj_b, D, 0);
8055 auto* k_b = ggml_view_1d(ctx, ly.sa_in_proj_b, D, D * sizeof(float));
8056 auto* v_b = ggml_view_1d(ctx, ly.sa_in_proj_b, D, 2 * D * sizeof(float));
8057
8058 auto* Q = ggml_add(ctx, ggml_mul_mat(ctx, q_w, q_in), q_b);
8059 auto* K = ggml_add(ctx, ggml_mul_mat(ctx, k_w, k_in), k_b);
8060 auto* V = ggml_add(ctx, ggml_mul_mat(ctx, v_w, x_norm), v_b);
8061
8062 const int64_t N = x->ne[1];
8063 const int64_t B = x->ne[2];
8064 const int64_t HD = D / n_heads;
8065
8066 Q = ggml_reshape_4d(ctx, Q, HD, n_heads, N, B);
8067 Q = ggml_cont(ctx, ggml_permute(ctx, Q, 0, 2, 1, 3));
8068 K = ggml_reshape_4d(ctx, K, HD, n_heads, N, B);
8069 K = ggml_cont(ctx, ggml_permute(ctx, K, 0, 2, 1, 3));
8070 V = ggml_reshape_4d(ctx, V, HD, n_heads, N, B);
8071 V = ggml_permute(ctx, V, 0, 2, 1, 3);
8072
8073 float scale = 1.0f / sqrtf((float)HD);
8074 auto* sa_out = ggml_flash_attn_ext(ctx, Q, K, V, nullptr, scale, 0.0f, 0.0f);
8075 sa_out = ggml_reshape_3d(ctx, sa_out, D, N, B);
8076
8077 sa_out = ggml_mul_mat(ctx, ly.sa_out_proj_w, sa_out);
8078 sa_out = ggml_add(ctx, sa_out, ly.sa_out_proj_b);
8079
8080 x = ggml_add(ctx, shortcut, sa_out);
8081 }
8082
8083 // Cross-attention: Q from image features, K/V from prompt tokens.
8084 // ca_q_w stores fused [D, 3*D] weights split as Q-proj, K-proj, V-proj.
8085 {
8086 auto* shortcut = x;
8087 auto* x_norm = sam3_layer_norm(ctx, x, ly.norm2_w, ly.norm2_b);
8088 const int64_t D = x->ne[0];
8089
8090 auto* q_w = ggml_view_2d(ctx, ly.ca_q_w, D, D, ly.ca_q_w->nb[1], 0);

Callers 1

sam3_build_fenc_graphFunction · 0.85

Calls 2

sam3_layer_normFunction · 0.85

Tested by

no test coverage detected