Make TFLite Pad/PadV2 op legalizations check the maximum rank in paddings.
TFLite Pad and PadV2 op kernel supports up to four dimension and it is possible to check the validity via first dimension size of the paddings argument. PiperOrigin-RevId: 315212253 Change-Id: I9c47d88a8c2e5e534be0c48f3f9e6315cf21816c
This commit is contained in:
parent
0078fff2cc
commit
5875e852b2
@ -212,11 +212,20 @@ class TFL_OperandIsRankedAndHasDimPred<int n, int dim> : And<[
|
||||
CPred<"$_op.getOperand(" # n # ").getType().cast<ShapedType>().getRank() > "
|
||||
# dim>]>;
|
||||
|
||||
// Returns true if the n-th operand is ranked and has a dimension length = size
|
||||
// at the rank dim.
|
||||
class TFL_OperandDimEquals<int n, int dim, int size> : And<[
|
||||
TFL_OperandIsRankedAndHasDimPred<n, dim>,
|
||||
CPred<"$_op.getOperand(" # n # ").getType().cast<ShapedType>()"
|
||||
".getShape()[" # dim # " ] == " # size>]>;
|
||||
|
||||
// Returns true if the n-th operand is ranked and has a dimension length <=
|
||||
// size at the rank dim.
|
||||
class TFL_OperandDimIsAtMost<int n, int dim, int size> : And<[
|
||||
TFL_OperandIsRankedAndHasDimPred<n, dim>,
|
||||
CPred<"$_op.getOperand(" # n # ").getType().cast<ShapedType>()"
|
||||
".getShape()[" # dim # " ] <= " # size>]>;
|
||||
|
||||
// Returns true if the n-th operand has unknown rank or at least rank m.
|
||||
class TFL_OperandHasAtleastRank<int n, int m> :
|
||||
PredOpTrait<"operand " # n # " is " # m # "-D",
|
||||
@ -2267,6 +2276,9 @@ def TFL_PadOp : TFL_Op<"pad", [
|
||||
TFL_OperandHasRankAtMost<0, 4>,
|
||||
TFL_OperandHasRank<1, 2>,
|
||||
TFL_OperandRankEquals1DimOfOperand<0, 1>,
|
||||
PredOpTrait<"the first dim size of the padding argument must be at most 4",
|
||||
Or<[TFL_OperandIsUnrankedPred<1>,
|
||||
TFL_OperandDimIsAtMost<1, 0, 4>]>>,
|
||||
TFL_GpuTargetOp]> {
|
||||
let summary = "Padding operator";
|
||||
|
||||
@ -2312,6 +2324,9 @@ def TFL_PadV2Op : TFL_Op<"padv2", [
|
||||
TFL_OperandHasRank<1, 2>,
|
||||
TFL_OperandHasRank<2, 0>,
|
||||
TFL_OperandRankEquals1DimOfOperand<0, 1>,
|
||||
PredOpTrait<"the first dim size of the padding argument must be at most 4",
|
||||
Or<[TFL_OperandIsUnrankedPred<1>,
|
||||
TFL_OperandDimIsAtMost<1, 0, 4>]>>,
|
||||
PredOpTrait<"input and constant value operands must have same element type",
|
||||
TFL_TCopVTEtAreSameAt<0, 2>>]> {
|
||||
let summary = "Padding operator v2";
|
||||
|
@ -923,6 +923,27 @@ func @testPadWithInvalidPaddingsRank(tensor<2x1x3xf32>, tensor<1x3x2xi32>) -> te
|
||||
|
||||
// -----
|
||||
|
||||
func @testPadUnknownPaddings(tensor<2x1x3xf32>, tensor<*xi32>) -> tensor<? x f32> {
|
||||
^bb0(%arg0: tensor<2x1x3xf32>, %arg1: tensor<*xi32>):
|
||||
%0 = "tfl.pad"(%arg0, %arg1) : (tensor<2x1x3xf32>, tensor<*xi32>) -> tensor<? x f32>
|
||||
return %0#0 : tensor<? x f32>
|
||||
|
||||
// CHECK-LABEL: testPadUnknownPaddings
|
||||
// CHECK: "tfl.pad"(%arg0, %arg1) : (tensor<2x1x3xf32>, tensor<*xi32>) -> tensor<?xf32>
|
||||
// CHECK: return
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
func @testPadUnsupportedPaddings(tensor<*xf32>, tensor<5x3xi32>) -> tensor<? x f32> {
|
||||
^bb0(%arg0: tensor<*xf32>, %arg1: tensor<5x3xi32>):
|
||||
// expected-error @+1 {{'tfl.pad' op failed to verify that the first dim size of the padding argument must be at most 4}}
|
||||
%0 = "tfl.pad"(%arg0, %arg1) : (tensor<*xf32>, tensor<5x3xi32>) -> tensor<? x f32>
|
||||
return %0#0 : tensor<? x f32>
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// CHECK-LABEL: testPadQuantizedU8
|
||||
func @testPadQuantizedU8(%arg0: tensor<2x1x3x!quant.uniform<u8:f32, 0.1>>, %arg1: tensor<3x2xi32>) -> tensor<? x !quant.uniform<u8:f32, 0.1>> {
|
||||
// CHECK: "tfl.pad"(%arg0, %arg1)
|
||||
@ -993,6 +1014,29 @@ func @testPadV2WithInvalidConstantScalar(tensor<2x1x3xf32>, tensor<3x2xi32>) ->
|
||||
|
||||
// -----
|
||||
|
||||
func @testPadV2UnknownPaddings(tensor<2x1x3xf32>, tensor<*xi32>) -> tensor<? x f32> {
|
||||
^bb0(%arg0: tensor<2x1x3xf32>, %arg1: tensor<*xi32>):
|
||||
%cst = constant dense<2.0> : tensor<f32>
|
||||
%0 = "tfl.padv2"(%arg0, %arg1, %cst) : (tensor<2x1x3xf32>, tensor<*xi32>, tensor<f32>) -> tensor<? x f32>
|
||||
return %0#0 : tensor<? x f32>
|
||||
|
||||
// CHECK-LABEL: testPadV2UnknownPaddings
|
||||
// CHECK: "tfl.padv2"(%arg0, %arg1, %cst) : (tensor<2x1x3xf32>, tensor<*xi32>, tensor<f32>) -> tensor<?xf32>
|
||||
// CHECK: return
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
func @testPadV2UnsupportedPaddings(tensor<*xf32>, tensor<5x3xi32>) -> tensor<? x f32> {
|
||||
^bb0(%arg0: tensor<*xf32>, %arg1: tensor<5x3xi32>):
|
||||
%cst = constant dense<2.0> : tensor<f32>
|
||||
// expected-error @+1 {{'tfl.padv2' op failed to verify that the first dim size of the padding argument must be at most 4}}
|
||||
%0 = "tfl.padv2"(%arg0, %arg1, %cst) : (tensor<*xf32>, tensor<5x3xi32>, tensor<f32>) -> tensor<? x f32>
|
||||
return %0#0 : tensor<? x f32>
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
func @packQuantizedU8(%arg0: tensor<2x!quant.uniform<u8:f32, 0.1>>, %arg1: tensor<2x!quant.uniform<u8:f32, 0.1>>) -> tensor<2x2x!quant.uniform<u8:f32, 0.1>> {
|
||||
// CHECK: "tfl.pack"(%arg0, %arg1) {axis = 0 : i32, values_count = 2 : i32}
|
||||
%0 = "tfl.pack"(%arg0, %arg1) {axis = 0 : i32, values_count = 2 : i32} : (tensor<2x!quant.uniform<u8:f32, 0.1>>, tensor<2x!quant.uniform<u8:f32, 0.1>>) -> tensor<2x2x!quant.uniform<u8:f32, 0.1>>
|
||||
|
Loading…
Reference in New Issue
Block a user