SIGN IN SIGN UP

Allow transposed convolution weights with a non-default dim order (#21035)

### Summary

Fixes #20804.

A transposed convolution whose weight has `out_channels == 1` fails in
the portable kernel with `Check failed
(tensor_is_default_or_channels_last_dim_order(weight))` (status 18).
`check_convolution_args` runs
`tensor_is_default_or_channels_last_dim_order(weight)` unconditionally,
but a transposed conv weight is laid out as `(in_channels, out_channels
/ groups, kH, kW)`, so when `out_channels == 1` the weight comes through
with a dim order such as `[1, 0, 2, 3]`, which is neither contiguous
(`[0,1,2,3]`) nor channels-last. For `out_channels > 1` the dim order is
`[0,1,2,3]` and the check passes, which matches the report.

The transposed path in `op_convolution.cpp` indexes the weight through
strides derived from its dim order (`dim_order_to_stride_nocheck` then
`calculate_linear_index`), so it reads the correct values regardless of
whether the weight is in `[0,1,2,3]` or `[1,0,2,3]`. I checked this with
the exact stride/index logic: every weight lookup matches between the
two layouts, so the kernel already handles this weight and only the
up-front check needs to change.

This skips the weight dim-order check when `transposed` is true, since
the kernel does not rely on that layout, rather than reordering the
weight upstream. Happy to switch to normalizing the weight instead if
that's preferred.

### Test plan

Added `TransposedWeightNonDefaultDimOrder` in
`kernels/test/op_convolution_test.cpp`: a transposed conv with a `(1, 1,
2, 2)` weight built in dim order `[1, 0, 2, 3]`, checked against a
reference output computed with `torch.nn.ConvTranspose2d`. The test
fails before this change (the weight is rejected) and passes after it.


cc @larryliu0820 @manuelcandales
S
Suryansh Sijwali committed
c46dc2726ac6488c47732c502cd18e770c8e6f34
Parent: 9eb7b65
Committed by GitHub <noreply@github.com> on 7/22/2026, 10:15:01 PM