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

Function sam3_vit_block_forward

sam3.cpp:3714–3805  ·  view source on GitHub ↗

Single ViT block forward: pre-norm → attn (window or global, with RoPE) → residual → pre-norm → MLP → residual x: [E, W, H, B] in ggml layout (following sam.cpp convention)

Source from the content-addressed store, hash-verified

3712// Single ViT block forward: pre-norm → attn (window or global, with RoPE) → residual → pre-norm → MLP → residual
3713// x: [E, W, H, B] in ggml layout (following sam.cpp convention)
3714static struct ggml_tensor* sam3_vit_block_forward(struct ggml_context* ctx,
3715 struct ggml_tensor* x,
3716 const sam3_vit_block& blk,
3717 const sam3_hparams& hp,
3718 int block_idx) {
3719 const int E = hp.vit_embed_dim; // 1024
3720 const int NH = hp.vit_num_heads; // 16
3721 const int HD = hp.vit_head_dim(); // 64
3722 const int WS = hp.vit_window_size; // 24
3723 const bool is_global = hp.is_global_attn(block_idx);
3724
3725 auto* shortcut = x;
3726
3727 x = sam3_layer_norm(ctx, x, blk.norm1_w, blk.norm1_b);
3728
3729 const int64_t w0 = x->ne[1];
3730 const int64_t h0 = x->ne[2];
3731
3732 if (!is_global) {
3733 // Window partition: [E, W, H, B] → [E, WS, WS, B*num_windows]
3734 x = ggml_win_part(ctx, x, WS);
3735 }
3736
3737 const int64_t W_cur = x->ne[1];
3738 const int64_t H_cur = x->ne[2];
3739 const int64_t B_cur = x->ne[3];
3740
3741 {
3742 auto* cur = ggml_mul_mat(ctx, blk.qkv_w, x);
3743 cur = ggml_add(ctx, cur, blk.qkv_b);
3744 // cur: [3*E, W_cur, H_cur, B_cur]
3745
3746 // [3*E, W*H, B_cur] → [E, 3, W*H, B_cur] → permute → [E, W*H, B_cur, 3]
3747 cur = ggml_reshape_4d(ctx, cur, E, 3, W_cur * H_cur, B_cur);
3748 cur = ggml_cont(ctx, ggml_permute(ctx, cur, 0, 3, 1, 2));
3749 // cur: [E, W*H, B_cur, 3] (ne[3]=3 separates Q/K/V)
3750
3751 auto* Q = ggml_view_3d(ctx, cur, E, W_cur * H_cur, B_cur,
3752 cur->nb[1], cur->nb[2], 0);
3753 auto* K = ggml_view_3d(ctx, cur, E, W_cur * H_cur, B_cur,
3754 cur->nb[1], cur->nb[2], 1 * cur->nb[3]);
3755 auto* V = ggml_view_3d(ctx, cur, E, W_cur * H_cur, B_cur,
3756 cur->nb[1], cur->nb[2], 2 * cur->nb[3]);
3757
3758 Q = ggml_reshape_4d(ctx, Q, HD, NH, W_cur * H_cur, B_cur);
3759 Q = ggml_cont(ctx, ggml_permute(ctx, Q, 0, 2, 1, 3));
3760 Q = ggml_reshape_3d(ctx, Q, HD, W_cur * H_cur, NH * B_cur);
3761
3762 K = ggml_reshape_4d(ctx, K, HD, NH, W_cur * H_cur, B_cur);
3763 K = ggml_cont(ctx, ggml_permute(ctx, K, 0, 2, 1, 3));
3764 K = ggml_reshape_3d(ctx, K, HD, W_cur * H_cur, NH * B_cur);
3765
3766 V = ggml_reshape_4d(ctx, V, HD, NH, W_cur * H_cur, B_cur);
3767 V = ggml_permute(ctx, V, 0, 2, 1, 3); // [HD, N, NH, B_cur] non-contiguous view; flash_attn uses strides
3768
3769 if (blk.freqs_cis) {
3770 Q = sam3_apply_rope(ctx, Q, blk.freqs_cis);
3771 K = sam3_apply_rope(ctx, K, blk.freqs_cis);

Callers 1

sam3_build_vit_graphFunction · 0.85

Calls 4

sam3_layer_normFunction · 0.85
sam3_apply_ropeFunction · 0.85
vit_head_dimMethod · 0.80
is_global_attnMethod · 0.80

Tested by

no test coverage detected