Skip to content

Commit d07c72b

Browse files
authored
Arm backend: Support constant negative pad values (#24108)
Lower negative constant padding to slices before applying non-negative TOSA padding. This supports cropping on either side, mixed cropping and padding, and cropping across multiple dimensions. Preserve internal zero pairs and mixed-sign padding in the test module. Add regression cases across floating-point and quantized TOSA and VGF pipelines. Validation: 148 padding tests pass, with three expected hardware-runner xfails. Lintrunner passes for both changed files. This commit was authored with Codex. cc @digantdesai @freddan80 @per @zingo @oscarandersson8218 @mansnils @Sebastian-Larsson @robell @rascani Signed-off-by: Erik Lundell <erik.lundell@arm.com>
1 parent 185668b commit d07c72b

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

‎backends/arm/_passes/rewrite_pad.py‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,26 @@ class RewritePadPass(ArmOpTargetedPass):
2525
}
2626

2727
def _rewrite_constant_pad(self, input_tensor, pad, value, meta):
28+
input_rank = len(input_tensor.data.shape)
29+
pad = list(pad)
30+
for i in range(0, len(pad), 2):
31+
left, right = pad[i : i + 2]
32+
if left < 0 or right < 0:
33+
# Negative padding crops the input; TOSA PAD only adds elements.
34+
input_tensor = super().call_operator(
35+
exir_ops.edge.aten.slice_copy.Tensor,
36+
(
37+
input_tensor,
38+
input_rank - 1 - i // 2,
39+
max(-left, 0),
40+
right if right < 0 else None,
41+
),
42+
{},
43+
meta,
44+
True,
45+
)
46+
pad[i : i + 2] = [max(left, 0), max(right, 0)]
47+
2848
output_dtype = meta["val"].dtype
2949
if output_dtype in (torch.int8, torch.int16):
3050
input_qparams = meta.data.get("input_qparams", {})
@@ -43,7 +63,6 @@ def _rewrite_constant_pad(self, input_tensor, pad, value, meta):
4363
input_pad = []
4464
for pair in reversed(pad_pairs):
4565
input_pad.extend(pair)
46-
input_rank = len(input_tensor.data.shape)
4766
# Place spatial dimensions last and pad non-spatial dimensions with 0 padding
4867
shape = [0] * ((input_rank * 2 - len(pad))) + input_pad
4968

‎backends/arm/test/ops/test_constant_pad_nd.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,23 @@
3535
input_t1 = Tuple[torch.Tensor] # Input x
3636

3737
test_data_suite = {
38+
"crop_end": lambda: (torch.rand(1, 4, 16), (0, -1), 0, "constant"),
39+
"crop_start": lambda: (torch.rand(1, 4, 16), (-2, 0), 0, "constant"),
40+
"crop_both": lambda: (torch.rand(1, 4, 16), (-1, -2), 0, "constant"),
41+
"crop_penultimate_dim": lambda: (
42+
torch.rand(1, 16, 4),
43+
(0, 0, 0, -1),
44+
0,
45+
"constant",
46+
),
47+
"crop_and_pad": lambda: (torch.rand(1, 4, 16), (-2, 3), 2, "constant"),
48+
"crop_shift": lambda: (torch.rand(1, 4, 16), (-1, 1), -0.5, "constant"),
49+
"crop_multidim": lambda: (
50+
torch.rand(1, 3, 8, 10),
51+
(-1, 2, 3, -2),
52+
1,
53+
"constant",
54+
),
3855
"4dim_last1dim": lambda: (
3956
torch.rand(1, 1, 16, 16),
4057
(1, 1, 0, 0, 0, 0, 0, 0),

0 commit comments

Comments
 (0)