1.8 KiB
1.8 KiB
ggml CONV_TRANSPOSE_2D semantics
Source of truth: ggml_compute_forward_conv_transpose_2d().
This note documents the exact contract the Metal kernel mirrors.
Tensor layouts
src0weights:(KW, KH, Cout, Cin), contiguous,F16in the CPU implementation used by SAM.src1input:(IW, IH, Cin, N), contiguous,F32.dstoutput:(OW, OH, Cout, N),F32.
For ggml_conv_transpose_2d_p0() the output size is:
OW = (IW - 1) * stride + KWOH = (IH - 1) * stride + KH
The p0 variant used here has:
- zero padding only
- one shared spatial stride
s0 - no dilation
- no output padding
- no bias term
CPU computation
The CPU implementation permutes weights and inputs into temporary buffers, zeros dst,
then performs a scatter-add over output channel, input spatial position, and kernel tap:
for out_c in [0, Cout):
for in_y in [0, IH):
for in_x in [0, IW):
for kh in [0, KH):
for kw in [0, KW):
dst[in_x * stride + kw, in_y * stride + kh, out_c] +=
dot(input[in_x, in_y, :, 0], weight[kw, kh, out_c, :, 0])
The Metal reference kernel uses the equivalent gather form for one output element:
dst[ow, oh, out_c] =
sum over kh, kw, in_c where
ow = in_x * stride + kw
oh = in_y * stride + kh
of weight[kw, kh, out_c, in_c] * input[in_x, in_y, in_c]
Numeric behavior
- input source type:
F32, but the CPU implementation first packs it toF16 - weight type:
F16orF32on Metal,F16in the CPU path used here - multiply inputs:
F16 x F16in the reference CPU path - accumulation type:
float - output type:
F32
Scope
The current CPU implementation only uses batch N = 1 in practice for this path, and
the Metal implementation matches that contract explicitly.