CXBlock: depthwise conv + LayerNorm + pointwise MLP with residual scaling.
| 9064 | |
| 9065 | // CXBlock: depthwise conv + LayerNorm + pointwise MLP with residual scaling. |
| 9066 | static struct ggml_tensor* sam3_cxblock_forward( |
| 9067 | struct ggml_context* ctx, |
| 9068 | struct ggml_tensor* x, // [D, H, W, B] |
| 9069 | struct ggml_tensor* dw_w, // [7, 7, 1, D] depthwise |
| 9070 | struct ggml_tensor* dw_b, // [D] |
| 9071 | struct ggml_tensor* norm_w, // [D] |
| 9072 | struct ggml_tensor* norm_b, // [D] |
| 9073 | struct ggml_tensor* fc1_w, // [D, 1024] |
| 9074 | struct ggml_tensor* fc1_b, // [1024] |
| 9075 | struct ggml_tensor* fc2_w, // [1024, D] |
| 9076 | struct ggml_tensor* fc2_b, // [D] |
| 9077 | struct ggml_tensor* gamma) // [D] |
| 9078 | { |
| 9079 | const int D = (int)x->ne[0]; |
| 9080 | const int H = (int)x->ne[1]; |
| 9081 | const int W = (int)x->ne[2]; |
| 9082 | |
| 9083 | // ggml conv expects WHCB layout; internal feature maps are stored as CWHB. |
| 9084 | auto* x_whcb = ggml_cont(ctx, ggml_permute(ctx, x, 2, 0, 1, 3)); |
| 9085 | |
| 9086 | // Depthwise conv (groups = D): use the direct depthwise path. |
| 9087 | // ggml_conv_2d_dw_direct only supports f32 kernel — cast if needed. |
| 9088 | auto* dw_w_f32 = (dw_w->type == GGML_TYPE_F32) ? dw_w : ggml_cast(ctx, dw_w, GGML_TYPE_F32); |
| 9089 | auto* h = ggml_conv_2d_dw_direct(ctx, dw_w_f32, x_whcb, 1, 1, 3, 3, 1, 1); |
| 9090 | h = ggml_add(ctx, h, ggml_reshape_4d(ctx, dw_b, 1, 1, D, 1)); |
| 9091 | h = ggml_cont(ctx, ggml_permute(ctx, h, 1, 2, 0, 3)); |
| 9092 | |
| 9093 | // LayerNorm2d |
| 9094 | h = sam3_layer_norm_2d(ctx, h, norm_w, norm_b); |
| 9095 | |
| 9096 | // Pointwise MLP: reshape to [D, H*W, B], apply FC, reshape back |
| 9097 | auto* flat = ggml_reshape_3d(ctx, h, D, H * W, 1); |
| 9098 | flat = ggml_add(ctx, ggml_mul_mat(ctx, fc1_w, flat), fc1_b); |
| 9099 | flat = ggml_gelu(ctx, flat); |
| 9100 | flat = ggml_add(ctx, ggml_mul_mat(ctx, fc2_w, flat), fc2_b); |
| 9101 | h = ggml_reshape_4d(ctx, flat, D, H, W, 1); |
| 9102 | |
| 9103 | // Residual with learnable scaling: x + gamma * h |
| 9104 | auto* gamma_4d = ggml_reshape_4d(ctx, gamma, D, 1, 1, 1); |
| 9105 | h = ggml_mul(ctx, h, gamma_4d); |
| 9106 | return ggml_add(ctx, x, h); |
| 9107 | } |
| 9108 | |
| 9109 | /***************************************************************************** |
| 9110 | ** Prompt building for memory attention (Phase 7) |
no test coverage detected