Skip to content

Commit 44d0d92

Browse files
authored
[TorchOnnxToTorch] Support valid auto pad in onnx.ConvInteger (#4717)
Enable VALID auto_pad attribute for [onnx.ConvInteger](https://onnx.ai/onnx/operators/onnx__ConvInteger.html). If auto_pad is VALID, then 0 padding size should be used. Such nodes are seen in the int8 quantized vision encoders of [SmolVLM2](https://huggingface.co/HuggingFaceTB/SmolVLM2-500M-Video-Instruct/tree/main/onnx) and [Florence-2](https://huggingface.co/onnx-community/Florence-2-base/tree/main/onnx)
1 parent 9f615e5 commit 44d0d92

3 files changed

Lines changed: 60 additions & 8 deletions

File tree

lib/Conversion/TorchOnnxToTorch/DefaultDomainAtoF.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,10 +1627,11 @@ void mlir::torch::onnx_c::populateDefaultDomainAtoF(
16271627
std::string autoPad;
16281628
if (binder.customOpNameStringAttr(autoPad, "auto_pad", "NOTSET"))
16291629
return failure();
1630-
if (autoPad != "NOTSET")
1631-
// TODO: Add support for `auto_pad` != "NOTSET"
1630+
if (autoPad != "NOTSET" && autoPad != "VALID")
1631+
// TODO: Add support for "SAME_UPPER" and "SAME_LOWER" auto_pad
16321632
return rewriter.notifyMatchFailure(
1633-
binder.op, "unsupported conversion: auto_pad != NOTSET");
1633+
binder.op, "unsupported conversion: only NOTSET and VALID "
1634+
"auto_pad supported");
16341635

16351636
Torch::ValueTensorType resultType;
16361637
Value input, weight, inputZp, weightZp;
@@ -1683,11 +1684,16 @@ void mlir::torch::onnx_c::populateDefaultDomainAtoF(
16831684
// x2_begin…x1_end, x2_end,…], where xi_begin the number of pixels added
16841685
// at the beginning of axis i and xi_end, the number of pixels added at
16851686
// the end of axis i.
1686-
if (binder.s64IntegerArrayAttr(padding, "pads", defaultPadding))
1687-
return failure();
1688-
if (padding.size() != rank - 2 && padding.size() != 2 * (rank - 2))
1689-
return rewriter.notifyMatchFailure(
1690-
binder.op, "padding list size does not match the number of axes");
1687+
if (autoPad == "VALID")
1688+
padding = defaultPadding;
1689+
else if (autoPad == "NOTSET") {
1690+
if (binder.s64IntegerArrayAttr(padding, "pads", defaultPadding))
1691+
return failure();
1692+
if (padding.size() != rank - 2 && padding.size() != 2 * (rank - 2))
1693+
return rewriter.notifyMatchFailure(
1694+
binder.op,
1695+
"padding list size does not match the number of axes");
1696+
}
16911697
if (binder.s64IntegerArrayAttr(dilations, "dilations",
16921698
defaultDilations))
16931699
return failure();
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: torch-mlir-opt %s -split-input-file -verify-diagnostics -convert-torch-onnx-to-torch
2+
3+
func.func @test_convinteger_invalid_padding_size(
4+
%arg0: !torch.vtensor<[1,1,3,3],ui8>,
5+
%arg1: !torch.vtensor<[1,1,2,2],ui8>)
6+
-> !torch.vtensor<[1,1,2,2],si32>
7+
attributes {torch.onnx_meta.opset_version = 17 : si64} {
8+
// expected-error @below {{failed to legalize operation 'torch.operator' that was explicitly marked illegal}}
9+
%0 = torch.operator "onnx.ConvInteger"(%arg0, %arg1) {
10+
torch.onnx.pads = [0 : si64, 0 : si64, 0 : si64]
11+
} : (!torch.vtensor<[1,1,3,3],ui8>,
12+
!torch.vtensor<[1,1,2,2],ui8>)
13+
-> !torch.vtensor<[1,1,2,2],si32>
14+
return %0 : !torch.vtensor<[1,1,2,2],si32>
15+
}

test/Conversion/TorchOnnxToTorch/simple_ops_a_to_f.mlir

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,37 @@ func.func @test_convinteger_without_padding(%arg0: !torch.vtensor<[1,1,3,3],ui8>
12171217

12181218
// -----
12191219

1220+
// CHECK-LABEL: @test_convinteger_with_valid_autopad
1221+
func.func @test_convinteger_with_valid_autopad(%arg0: !torch.vtensor<[1,1,3,3],ui8>, %arg1: !torch.vtensor<[1,1,2,2],ui8>, %arg2: !torch.vtensor<[],ui8>, %arg3: !torch.vtensor<[1],ui8>) -> !torch.vtensor<[1,1,2,2],si32> attributes {torch.onnx_meta.ir_version = 5 : si64, torch.onnx_meta.opset_version = 17 : si64, torch.onnx_meta.producer_name = "backend-test", torch.onnx_meta.producer_version = ""} {
1222+
// CHECK: %[[NONE:.*]] = torch.constant.none
1223+
// CHECK: %[[SCALE:.*]] = torch.constant.float 1.000000e+00
1224+
// CHECK: %[[INPUT_ZP:.*]] = torch.aten.item %arg2 : !torch.vtensor<[],ui8> -> !torch.int
1225+
// CHECK: %[[WEIGHT_ZP:.*]] = torch.aten.item %arg3 : !torch.vtensor<[1],ui8> -> !torch.int
1226+
// CHECK: %[[C0:.*]] = torch.constant.int 0
1227+
// CHECK: %[[C0_0:.*]] = torch.constant.int 0
1228+
// CHECK: %[[PADDING:.*]] = torch.prim.ListConstruct %[[C0]], %[[C0_0]] : (!torch.int, !torch.int) -> !torch.list<int>
1229+
// CHECK: %[[C1_0:.*]] = torch.constant.int 1
1230+
// CHECK: %[[C1_1:.*]] = torch.constant.int 1
1231+
// CHECK: %[[DILATIONS:.*]] = torch.prim.ListConstruct %[[C1_0]], %[[C1_1]] : (!torch.int, !torch.int) -> !torch.list<int>
1232+
// CHECK: %[[C1_2:.*]] = torch.constant.int 1
1233+
// CHECK: %[[C1_3:.*]] = torch.constant.int 1
1234+
// CHECK: %[[STRIDE:.*]] = torch.prim.ListConstruct %[[C1_2]], %[[C1_3]] : (!torch.int, !torch.int) -> !torch.list<int>
1235+
// CHECK: %[[C0_1:.*]] = torch.constant.int 0
1236+
// CHECK: %[[C0_2:.*]] = torch.constant.int 0
1237+
// CHECK: %[[OUTPUT_PADDING:.*]] = torch.prim.ListConstruct %[[C0_1]], %[[C0_2]] : (!torch.int, !torch.int) -> !torch.list<int>
1238+
// CHECK: %[[TRANSPOSED:.*]] = torch.constant.bool false
1239+
// CHECK: %[[BIAS:.*]] = torch.constant.none
1240+
// CHECK: %[[GROUPS:.*]] = torch.constant.int 1
1241+
// CHECK: %[[INPUT:.*]] = torch.aten._make_per_tensor_quantized_tensor %arg0, %[[SCALE]], %[[INPUT_ZP]] : !torch.vtensor<[1,1,3,3],ui8>, !torch.float, !torch.int -> !torch.vtensor<[1,1,3,3],!torch.quint8>
1242+
// CHECK: %[[WEIGHT:.*]] = torch.aten._make_per_tensor_quantized_tensor %arg1, %[[SCALE]], %[[WEIGHT_ZP]] : !torch.vtensor<[1,1,2,2],ui8>, !torch.float, !torch.int -> !torch.vtensor<[1,1,2,2],!torch.quint8>
1243+
// CHECK: torch.aten.convolution %[[INPUT]], %[[WEIGHT]], %[[BIAS]], %[[STRIDE]], %[[PADDING]], %[[DILATIONS]], %[[TRANSPOSED]], %[[OUTPUT_PADDING]], %[[GROUPS]] : !torch.vtensor<[1,1,3,3],!torch.quint8>, !torch.vtensor<[1,1,2,2],!torch.quint8>, !torch.none, !torch.list<int>, !torch.list<int>, !torch.list<int>, !torch.bool, !torch.list<int>, !torch.int -> !torch.vtensor<[1,1,2,2],si32>
1244+
%none = torch.constant.none
1245+
%0 = torch.operator "onnx.ConvInteger"(%arg0, %arg1, %arg2, %arg3) {torch.onnx.auto_pad = "VALID"} : (!torch.vtensor<[1,1,3,3],ui8>, !torch.vtensor<[1,1,2,2],ui8>, !torch.vtensor<[],ui8>, !torch.vtensor<[1],ui8>) -> !torch.vtensor<[1,1,2,2],si32>
1246+
return %0 : !torch.vtensor<[1,1,2,2],si32>
1247+
}
1248+
1249+
// -----
1250+
12201251
// CHECK-LABEL: @test_convinteger_with_padding
12211252
func.func @test_convinteger_with_padding(%arg0: !torch.vtensor<[1,1,3,3],ui8>, %arg1: !torch.vtensor<[1,1,2,2],ui8>, %arg2: !torch.vtensor<[],ui8>) -> !torch.vtensor<[1,1,4,4],si32> attributes {torch.onnx_meta.ir_version = 5 : si64, torch.onnx_meta.opset_version = 17 : si64, torch.onnx_meta.producer_name = "backend-test", torch.onnx_meta.producer_version = ""} {
12221253
// CHECK: %[[NONE:.*]] = torch.constant.none

0 commit comments

Comments
 (0)