MCPcopy Create free account
hub / github.com/pytorch/executorch / _emit_conv_transpose_weight

Function _emit_conv_transpose_weight

backends/mlx/ops.py:2241–2284  ·  view source on GitHub ↗

Get conv_transpose weight in MLX format, handling grouped convolutions. PyTorch conv_transpose weight shape: [C_in, C_out/G, *K] MLX expects: [C_out, *K, C_in/G] For groups=1, a simple permute suffices (C_in==C_in/G, C_out/G==C_out). For groups>1, we need re

(
    P: MLXProgramBuilder, w_node: Node, groups: int, ndim: int
)

Source from the content-addressed store, hash-verified

2239
2240
2241def _emit_conv_transpose_weight(
2242 P: MLXProgramBuilder, w_node: Node, groups: int, ndim: int
2243) -> Slot:
2244 """Get conv_transpose weight in MLX format, handling grouped convolutions.
2245
2246 PyTorch conv_transpose weight shape: [C_in, C_out/G, *K]
2247 MLX expects: [C_out, *K, C_in/G]
2248
2249 For groups=1, a simple permute suffices (C_in==C_in/G, C_out/G==C_out).
2250 For groups>1, we need reshape-permute-reshape to rearrange the group dim:
2251 [C_in, C_out/G, *K] -> [G, C_in/G, C_out/G, *K]
2252 -> [G, C_out/G, *K, C_in/G]
2253 -> [C_out, *K, C_in/G]
2254 """
2255 if groups == 1:
2256 # Simple permute: [C_in, C_out, *K] -> [C_out, *K, C_in]
2257 # e.g. 1D: [1, 2, 0], 2D: [1, 2, 3, 0], 3D: [1, 2, 3, 4, 0]
2258 perm = list(range(1, ndim + 2)) + [0]
2259 return _emit_channel_last_weight(P, w_node, perm)
2260
2261 # Grouped: need reshape-permute-reshape at compile time
2262 if w_node.op != "placeholder":
2263 raise ValueError(
2264 f"conv_transpose with groups > 1 requires static weights, "
2265 f"got dynamic weight from {w_node.op}"
2266 )
2267
2268 w_target, w_tensor = P.get_placeholder_target_and_tensor(w_node)
2269 c_in = w_tensor.shape[0]
2270 c_out_per_g = w_tensor.shape[1]
2271 kernel_shape = list(w_tensor.shape[2:])
2272 c_in_per_g = c_in // groups
2273
2274 # [C_in, C_out/G, *K] -> [G, C_in/G, C_out/G, *K]
2275 w = w_tensor.reshape([groups, c_in_per_g, c_out_per_g] + kernel_shape)
2276 # [G, C_in/G, C_out/G, *K] -> [G, C_out/G, *K, C_in/G]
2277 # perm: [0, 2, 3, ..., ndim+1, 1]
2278 perm = [0, 2] + list(range(3, ndim + 3)) + [1]
2279 w = w.permute(perm).contiguous()
2280 # [G, C_out/G, *K, C_in/G] -> [C_out, *K, C_in/G]
2281 c_out = groups * c_out_per_g
2282 w = w.reshape([c_out] + kernel_shape + [c_in_per_g])
2283
2284 return P.make_or_get_constant(f"{w_target}_channel_last", w)
2285
2286
2287def _emit_conv_bias(

Callers 1

_emit_conv_transposeFunction · 0.85

Calls 4

make_or_get_constantMethod · 0.80
permuteMethod · 0.45

Tested by

no test coverage detected