diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td index ddfec2c9bfcd3..a16baf7b5147d 100644 --- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td +++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td @@ -2289,8 +2289,8 @@ def Tosa_RescaleOp: Tosa_Op<"rescale", [Pure, BoolAttr:$scale32, BoolAttr:$double_round, BoolAttr:$per_channel, - DefaultValuedOptionalAttr:$input_unsigned, - DefaultValuedOptionalAttr:$output_unsigned + BoolAttr: $input_unsigned, + BoolAttr: $output_unsigned ); let results = (outs diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir index 5db3f56cf459e..4a2dbff65852c 100644 --- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir +++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir @@ -43,7 +43,7 @@ func.func @rfft2d_with_non_float_type(%arg0 : tensor<1x1x1xi32>) -> (tensor<1x1x // CHECK-LABEL: @rescale_unsupported_type func.func @rescale_unsupported_type(%arg0: tensor<13x21x3x!quant.uniform>) -> tensor<13x21x3x!quant.uniform> { // expected-error@+1 {{failed to legalize operation 'tosa.rescale'}} - %0 = tosa.rescale %arg0 {double_round = false, input_zp = 127 : i32, multiplier = array, output_zp = -1 : i32, per_channel = false, scale32 = true, shift = array} : (tensor<13x21x3x!quant.uniform>) -> tensor<13x21x3x!quant.uniform> + %0 = tosa.rescale %arg0 {double_round = false, input_zp = 127 : i32, multiplier = array, output_zp = -1 : i32, per_channel = false, scale32 = true, shift = array, input_unsigned = true, output_unsigned = false} : (tensor<13x21x3x!quant.uniform>) -> tensor<13x21x3x!quant.uniform> return %0 : tensor<13x21x3x!quant.uniform> } diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir index 78f2e173d7cb1..4958998f88328 100644 --- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir +++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir @@ -1149,7 +1149,7 @@ func.func @rescale_i8(%arg0 : tensor<2xi8>) -> () { // CHECK-DAG: [[BOUNDED:%.+]] = arith.minsi [[CMAX]], [[LOWER]] // CHECK-DAG: [[TRUNC:%.+]] = arith.trunci [[BOUNDED]] // CHECK-DAG: linalg.yield [[TRUNC]] - %0 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false} : (tensor<2xi8>) -> tensor<2xi8> + %0 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, input_unsigned = false, output_unsigned = false} : (tensor<2xi8>) -> tensor<2xi8> // CHECK: return return @@ -1178,7 +1178,7 @@ func.func @rescale_i8_unsigned_output(%arg0 : tensor<2xi8>) -> () { // CHECK-DAG: [[BOUNDED:%.+]] = arith.minsi [[CMAX]], [[LOWER]] // CHECK-DAG: [[TRUNC:%.+]] = arith.trunci [[BOUNDED]] // CHECK: linalg.yield [[TRUNC]] - %1 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, output_unsigned = true} : (tensor<2xi8>) -> tensor<2xi8> + %1 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, input_unsigned = false, output_unsigned = true} : (tensor<2xi8>) -> tensor<2xi8> // CHECK: return return @@ -1195,13 +1195,13 @@ func.func @rescale_i8_dyn_batch(%arg0 : tensor) -> () { // CHECK: %[[BATCH:.+]] = tensor.dim %[[ARG0]], %[[C0]] // CHECK: %[[INIT:.+]] = tensor.empty(%[[BATCH]]) : tensor // CHECK: [[GENERIC:%.+]] = linalg.generic {indexing_maps = [#[[$MAP0]], #[[$MAP0]]], iterator_types = ["parallel", "parallel"]} ins(%[[ARG0]] : tensor) outs(%[[INIT]] : tensor) - %0 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false} : (tensor) -> tensor + %0 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, input_unsigned = false, output_unsigned = false} : (tensor) -> tensor // CHECK: %[[C0:.+]] = arith.constant 0 // CHECK: %[[BATCH:.+]] = tensor.dim %[[ARG0]], %[[C0]] // CHECK: %[[INIT:.+]] = tensor.empty(%[[BATCH]]) : tensor // CHECK: [[GENERIC:%.+]] = linalg.generic {indexing_maps = [#[[$MAP0]], #[[$MAP0]]], iterator_types = ["parallel", "parallel"]} ins(%[[ARG0]] : tensor) outs(%[[INIT]] : tensor) - %1 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, output_unsigned = true} : (tensor) -> tensor + %1 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, input_unsigned = false, output_unsigned = true} : (tensor) -> tensor return } @@ -1219,7 +1219,7 @@ func.func @rescale_dyn(%arg0 : tensor<1x?x?x32xi32>) -> () { // CHECK: %[[DIM2:.+]] = tensor.dim %[[ARG0]], %[[C2]] // CHECK: %[[INIT:.+]] = tensor.empty(%[[DIM1]], %[[DIM2]]) // CHECK: [[GENERIC:%.+]] = linalg.generic {indexing_maps = [#[[$MAP1]], #[[$MAP1]]], iterator_types = ["parallel", "parallel", "parallel", "parallel"]} ins(%[[ARG0]] : tensor<1x?x?x32xi32>) outs(%[[INIT]] : tensor<1x?x?x32xi8>) - %0 = tosa.rescale %arg0 {double_round = true, input_zp = 0 : i32, multiplier = array, output_zp = 0 : i32, per_channel = false, scale32 = true, shift = array} : (tensor<1x?x?x32xi32>) -> tensor<1x?x?x32xi8> + %0 = tosa.rescale %arg0 {double_round = true, input_zp = 0 : i32, multiplier = array, output_zp = 0 : i32, per_channel = false, scale32 = true, shift = array, input_unsigned = false, output_unsigned = false} : (tensor<1x?x?x32xi32>) -> tensor<1x?x?x32xi8> return } @@ -1247,7 +1247,7 @@ func.func @rescale_i8_unsigned_input(%arg0 : tensor<2xi8>) -> () { // CHECK-DAG: [[BOUNDED:%.+]] = arith.minsi [[CMAX]], [[LOWER]] // CHECK-DAG: [[TRUNC:%.+]] = arith.trunci [[BOUNDED]] // CHECK: linalg.yield [[TRUNC]] - %0 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, input_unsigned = true} : (tensor<2xi8>) -> tensor<2xi8> + %0 = tosa.rescale %arg0 {input_zp = 17 : i32, output_zp = 22 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, input_unsigned = true, output_unsigned = false} : (tensor<2xi8>) -> tensor<2xi8> return } @@ -1277,7 +1277,7 @@ func.func @rescale_per_channel(%arg0 : tensor<3xi8>) -> (tensor<3xi8>) { // CHECK-DAG: [[BOUNDED:%.+]] = arith.minsi [[CMAX]], [[LOWER]] // CHECK-DAG: [[TRUNC:%.+]] = arith.trunci [[BOUNDED]] // CHECK-DAG: linalg.yield [[TRUNC]] - %0 = tosa.rescale %arg0 {input_zp = 243 : i32, output_zp = 252 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false} : (tensor<3xi8>) -> tensor<3xi8> + %0 = tosa.rescale %arg0 {input_zp = 243 : i32, output_zp = 252 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, input_unsigned = false, output_unsigned = false} : (tensor<3xi8>) -> tensor<3xi8> // CHECK: return [[GENERIC]] return %0 : tensor<3xi8> @@ -1290,7 +1290,7 @@ func.func @rescaleDoubleRound(%arg0 : tensor<2xi8>) -> (tensor<2xi8>) { // CHECK: linalg.generic // CHECK: tosa.apply_scale // CHECK-SAME: {double_round = true} - %0 = tosa.rescale %arg0 {input_zp = 243 : i32, output_zp = 252 : i32, multiplier = array, shift = array, scale32 = true, double_round = true, per_channel = false} : (tensor<2xi8>) -> tensor<2xi8> + %0 = tosa.rescale %arg0 {input_zp = 243 : i32, output_zp = 252 : i32, multiplier = array, shift = array, scale32 = true, double_round = true, per_channel = false, input_unsigned = false, output_unsigned = false} : (tensor<2xi8>) -> tensor<2xi8> return %0 : tensor<2xi8> } @@ -1299,7 +1299,7 @@ func.func @rescaleUnnecessaryDoubleRound(%arg0 : tensor<2xi8>) -> (tensor<2xi8>) // CHECK: linalg.generic // CHECK: tosa.apply_scale // CHECK-SAME: {double_round = false} - %0 = tosa.rescale %arg0 {input_zp = 243 : i32, output_zp = 252 : i32, multiplier = array, shift = array, scale32 = true, double_round = true, per_channel = false} : (tensor<2xi8>) -> tensor<2xi8> + %0 = tosa.rescale %arg0 {input_zp = 243 : i32, output_zp = 252 : i32, multiplier = array, shift = array, scale32 = true, double_round = true, per_channel = false, input_unsigned = false, output_unsigned = false} : (tensor<2xi8>) -> tensor<2xi8> return %0 : tensor<2xi8> } diff --git a/mlir/test/Dialect/Tosa/availability.mlir b/mlir/test/Dialect/Tosa/availability.mlir index 7324b0ea52e89..98290c7b9eedd 100644 --- a/mlir/test/Dialect/Tosa/availability.mlir +++ b/mlir/test/Dialect/Tosa/availability.mlir @@ -611,7 +611,7 @@ func.func @test_cast1(%arg0: tensor<13x21x3xi32>) -> tensor<13x21x3xf32> { func.func @test_rescale(%arg0: tensor<13x21x3x!quant.uniform>, %multiplier : tensor<1xi32>, %shift : tensor<1xi8>) -> tensor<13x21x3x!quant.uniform> { // CHECK: profiles: [ [pro_int] ] // CHECK: extensions: [ [int16] ] - %0 = tosa.rescale %arg0 {double_round = false, input_zp = 127 : i32, multiplier = array, output_zp = -1 : i32, per_channel = false, scale32 = true, shift = array} : (tensor<13x21x3x!quant.uniform>) -> tensor<13x21x3x!quant.uniform> + %0 = tosa.rescale %arg0 {double_round = false, input_zp = 127 : i32, multiplier = array, output_zp = -1 : i32, per_channel = false, scale32 = true, shift = array, input_unsigned = true, output_unsigned = false} : (tensor<13x21x3x!quant.uniform>) -> tensor<13x21x3x!quant.uniform> return %0 : tensor<13x21x3x!quant.uniform> } diff --git a/mlir/test/Dialect/Tosa/canonicalize.mlir b/mlir/test/Dialect/Tosa/canonicalize.mlir index 66de6b23eae01..30f557a338fb5 100644 --- a/mlir/test/Dialect/Tosa/canonicalize.mlir +++ b/mlir/test/Dialect/Tosa/canonicalize.mlir @@ -897,8 +897,6 @@ func.func @reshape_quant_nofold() -> tensor<1x1x1x1xi32> { %0 = "tosa.const"() {value = dense<127> : tensor} : () -> tensor> %cst0 = "tosa.const_shape"() {value = dense<[1, 1, 1, 1]> : tensor<4xindex>} : () -> !tosa.shape<4> %1 = tosa.reshape %0, %cst0 : (tensor>, !tosa.shape<4>) -> tensor<1x1x1x1x!quant.uniform> - %multiplier = "tosa.const"() {value = dense<1073741824> : tensor<1xi32> } : () -> tensor<1xi32> - %shift = "tosa.const"() {value = dense<30> : tensor<1xi8> } : () -> tensor<1xi8> %2 = tosa.rescale %1 {double_round = true, input_zp = -128 : i32, multiplier = array, output_zp = 0 : i32, per_channel = false, scale32 = true, shift = array, input_unsigned = false, output_unsigned = false} : (tensor<1x1x1x1x!quant.uniform>) -> tensor<1x1x1x1xi32> return %2 : tensor<1x1x1x1xi32> } diff --git a/mlir/test/Dialect/Tosa/ops.mlir b/mlir/test/Dialect/Tosa/ops.mlir index bea73ab92f2e3..c96accdcfd596 100644 --- a/mlir/test/Dialect/Tosa/ops.mlir +++ b/mlir/test/Dialect/Tosa/ops.mlir @@ -82,7 +82,7 @@ func.func @test_conv2d_q8xi4(%arg0: tensor<1x11x11x3xi8>) -> tensor<1x1x1x3xi8> %izp = "tosa.const"() {value = dense<0> : tensor<1xi8>} : () -> tensor<1xi8> %wzp = "tosa.const"() {value = dense<0> : tensor<1xi4>} : () -> tensor<1xi4> %2 = "tosa.conv2d"(%arg0, %0, %1, %izp, %wzp) {acc_type = i32, dilation = array, pad = array, stride = array} : (tensor<1x11x11x3xi8>, tensor<3x11x11x3xi4>, tensor<3xi32>, tensor<1xi8>, tensor<1xi4>) -> tensor<1x1x1x3xi32> - %3 = "tosa.rescale"(%2) {double_round = true, input_zp = 0 : i32, multiplier = array, output_zp = 27 : i32, per_channel = true, scale32 = true, shift = array} : (tensor<1x1x1x3xi32>) -> tensor<1x1x1x3xi8> + %3 = "tosa.rescale"(%2) {double_round = true, input_zp = 0 : i32, multiplier = array, output_zp = 27 : i32, per_channel = true, scale32 = true, shift = array, input_unsigned = false, output_unsigned = false} : (tensor<1x1x1x3xi32>) -> tensor<1x1x1x3xi8> return %3 : tensor<1x1x1x3xi8> } @@ -707,7 +707,7 @@ func.func @test_cast3(%arg0: tensor<13x21x3xi32>) -> tensor<13x21x3x!quant.unifo // ----- // CHECK-LABEL: rescale func.func @test_rescale(%arg0: tensor<13x21x3x!quant.uniform>) -> tensor<13x21x3x!quant.uniform> { - %0 = tosa.rescale %arg0 {double_round = false, input_zp = 127 : i32, multiplier = array, output_zp = -1 : i32, per_channel = false, scale32 = true, shift = array} : (tensor<13x21x3x!quant.uniform>) -> tensor<13x21x3x!quant.uniform> + %0 = tosa.rescale %arg0 {double_round = false, input_zp = 127 : i32, multiplier = array, output_zp = -1 : i32, per_channel = false, scale32 = true, shift = array, input_unsigned = false, output_unsigned = false} : (tensor<13x21x3x!quant.uniform>) -> tensor<13x21x3x!quant.uniform> return %0 : tensor<13x21x3x!quant.uniform> } diff --git a/mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir b/mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir index b87e9a78bf144..d18a6833daaf0 100644 --- a/mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir +++ b/mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir @@ -94,7 +94,7 @@ func.func @test_unary_i32(%arg0 : tensor<4xi32>) -> () { %5 = tosa.reverse %arg0 { axis = 0 : i32 } : (tensor<4xi32>) -> tensor // CHECK: tosa.rescale %arg0 {{.+}} : (tensor<4xi32>) -> tensor<4xi16> - %6 = tosa.rescale %arg0 {input_zp = 243 : i32, output_zp = 252 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false} : (tensor<4xi32>) -> tensor<*xi16> + %6 = tosa.rescale %arg0 {input_zp = 243 : i32, output_zp = 252 : i32, multiplier = array, shift = array, scale32 = false, double_round = false, per_channel = false, input_unsigned = false, output_unsigned = false} : (tensor<4xi32>) -> tensor<*xi16> // CHECK: tosa.identity %arg0 : (tensor<4xi32>) -> tensor<4xi32> %7 = tosa.identity %arg0 : (tensor<4xi32>) -> tensor diff --git a/mlir/test/lib/Dialect/Tosa/TosaTestPasses.cpp b/mlir/test/lib/Dialect/Tosa/TosaTestPasses.cpp index 83db1188861ab..a97711b51ff7e 100644 --- a/mlir/test/lib/Dialect/Tosa/TosaTestPasses.cpp +++ b/mlir/test/lib/Dialect/Tosa/TosaTestPasses.cpp @@ -165,13 +165,18 @@ ConvertTosaConv2DOp::matchAndRewrite(Operation *op, // Obtain the quantized scale = multiplier and shift. computeMultiplierAndShift(opTensorScale, multiplier, shift, 32); + bool input_unsigned = + newTosaConv2DOp.getResult().getType().isUnsignedInteger(); + bool output_unsigned = outputType.isUnsignedInteger(); + auto newTosaRescaleOp = rewriter.create( op->getLoc(), outputType, newTosaConv2DOp.getResult(), rewriter.getI32IntegerAttr(0), rewriter.getI32IntegerAttr(outputZp), rewriter.getDenseI32ArrayAttr({multiplier}), rewriter.getDenseI8ArrayAttr({static_cast(shift)}), rewriter.getBoolAttr(true), rewriter.getBoolAttr(true), - rewriter.getBoolAttr(false)); + rewriter.getBoolAttr(false), rewriter.getBoolAttr(input_unsigned), + rewriter.getBoolAttr(output_unsigned)); rewriter.replaceOp(op, {newTosaRescaleOp.getResult()}); return success();