Window partition: [B, H, W, C] -> [B*nW, ws, ws, C] with padding if needed. In ggml layout: input ne = {C, W, H, B}, output ne = {C, ws, ws, B*nW}. Pad H, W to be divisible by ws. Returns (padded_H, padded_W) in pad_hw. The algorithm (4D ggml only): 1. Reshape [C, Wp, Hp, B] -> [C*ws, nW_w, Hp, B] -- group W into windows 2. Permute (0,2,1,3) -> [C*ws, Hp, nW_w, B] -- move H before nW
| 4192 | // |
| 4193 | // Window ordering: n = nw_h + nw_w*nW_h (H-major, reversed from typical). |
| 4194 | static struct ggml_tensor* sam2_window_partition(struct ggml_context* ctx, |
| 4195 | struct ggml_tensor* x, |
| 4196 | int ws, int pad_hw[2]) { |
| 4197 | // ggml layout: ne = {C, W, H, B} |
| 4198 | const int64_t C = x->ne[0]; |
| 4199 | const int64_t W = x->ne[1]; |
| 4200 | const int64_t H = x->ne[2]; |
| 4201 | const int64_t B = x->ne[3]; |
| 4202 | |
| 4203 | // Pad to ws-divisible |
| 4204 | int64_t Hp = ((H + ws - 1) / ws) * ws; |
| 4205 | int64_t Wp = ((W + ws - 1) / ws) * ws; |
| 4206 | pad_hw[0] = (int)Hp; |
| 4207 | pad_hw[1] = (int)Wp; |
| 4208 | |
| 4209 | if (Hp != H || Wp != W) { |
| 4210 | x = ggml_pad(ctx, x, 0, (int)(Wp - W), (int)(Hp - H), 0); |
| 4211 | } |
| 4212 | |
| 4213 | int64_t nW_w = Wp / ws; |
| 4214 | int64_t nW_h = Hp / ws; |
| 4215 | int64_t nW = nW_w * nW_h; |
| 4216 | |
| 4217 | // Step 1: Reshape [C, Wp, Hp, B] -> [C*ws, nW_w, Hp, B] |
| 4218 | auto* r1 = ggml_reshape_4d(ctx, x, C * ws, nW_w, Hp, B); |
| 4219 | // Step 2: Permute to [C*ws, Hp, nW_w, B] |
| 4220 | auto* p1 = ggml_permute(ctx, r1, 0, 2, 1, 3); |
| 4221 | // Step 3: Cont |
| 4222 | auto* c1 = ggml_cont(ctx, p1); |
| 4223 | // Step 4: Reshape [C*ws, Hp, nW_w, B] -> [C*ws, ws, nW_h, nW_w*B] |
| 4224 | // Splits dim 1 (Hp = ws*nW_h) into (ws=local_H, nW_h=window_H_index) |
| 4225 | auto* r2 = ggml_reshape_4d(ctx, c1, C * ws, ws, nW_h, nW_w * B); |
| 4226 | // Step 5 (direct reshape, no permute): |
| 4227 | // [C*ws, ws, nW_h, nW_w*B] -> [C, ws, ws, nW*B] |
| 4228 | // Splits dim 0 (C*ws) into (C, ws=local_W) and merges dims 2,3. |
| 4229 | auto* out = ggml_reshape_4d(ctx, r2, C, ws, ws, nW * B); |
| 4230 | |
| 4231 | return out; |
| 4232 | } |
| 4233 | |
| 4234 | // Window unpartition: reverse of sam2_window_partition. |
| 4235 | // Input ne = {C, ws, ws, nW*B}, output ne = {C, orig_W, orig_H, B}. |
no outgoing calls
no test coverage detected