diff options
author | Feng Liu <fengliuai@google.com> | 2019-08-29 10:08:46 -0700 |
---|---|---|
committer | A. Unique TensorFlower <gardener@tensorflow.org> | 2019-08-29 10:09:22 -0700 |
commit | 6de6c2c13828742249377585fd1ef19d9cfd1773 (patch) | |
tree | dd0ef16c044bd319e82aa80edad5d9c4f62667fa | |
parent | 4bb6f8ecdb54f4ee096d8f92603d628d0cac4ed6 (diff) | |
download | bcm5719-llvm-6de6c2c13828742249377585fd1ef19d9cfd1773.tar.gz bcm5719-llvm-6de6c2c13828742249377585fd1ef19d9cfd1773.zip |
Add tests to verify 0.0 is quantized correctly
We should consider both signed and narrow_range cases.
PiperOrigin-RevId: 266167366
-rw-r--r-- | mlir/lib/Dialect/QuantOps/Utils/FakeQuantSupport.cpp | 2 | ||||
-rw-r--r-- | mlir/test/Dialect/QuantOps/convert-const.mlir | 33 | ||||
-rw-r--r-- | mlir/test/Dialect/QuantOps/convert-fakequant.mlir | 60 |
3 files changed, 94 insertions, 1 deletions
diff --git a/mlir/lib/Dialect/QuantOps/Utils/FakeQuantSupport.cpp b/mlir/lib/Dialect/QuantOps/Utils/FakeQuantSupport.cpp index eeb69b77102..637f6a04988 100644 --- a/mlir/lib/Dialect/QuantOps/Utils/FakeQuantSupport.cpp +++ b/mlir/lib/Dialect/QuantOps/Utils/FakeQuantSupport.cpp @@ -76,7 +76,7 @@ mlir::quant::fakeQuantAttrsToType(Location loc, unsigned numBits, double rmin, // points and dequantized to 0.0. if (std::fabs(rmax - rmin) < std::numeric_limits<double>::epsilon()) { return UniformQuantizedType::getChecked(flags, storageType, expressedType, - 1.0, 0, qmin, qmax, loc); + 1.0, qmin, qmin, qmax, loc); } // Determine the scale. diff --git a/mlir/test/Dialect/QuantOps/convert-const.mlir b/mlir/test/Dialect/QuantOps/convert-const.mlir index 0fe294173a1..87619df4310 100644 --- a/mlir/test/Dialect/QuantOps/convert-const.mlir +++ b/mlir/test/Dialect/QuantOps/convert-const.mlir @@ -138,3 +138,36 @@ func @const_custom_storage_range_i8_fixedpoint() -> tensor<7xf32> { %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i8<-100:100>:f32, 7.812500e-03>>) -> (tensor<7xf32>) return %2 : tensor<7xf32> } + +// ----- +// Verifies quantization results of all-0.0 tensors are quantized to zero points. +// CHECK-LABEL: zero_tensors_to_zero_points +func @zero_tensors_to_zero_points() -> (tensor<7xf32>, tensor<7xf32>, tensor<7xf32>, tensor<7xf32>) { + +// CHECK: %[[cst:.*]] = constant dense<-127> : tensor<7xi8> +// CHECK: %[[cst0:.*]] = constant dense<0> : tensor<7xi8> +// CHECK: %[[cst1:.*]] = constant dense<1> : tensor<7xi8> +// CHECK: "quant.scast"(%[[cst0]]) : (tensor<7xi8>) -> tensor<7x!quant.uniform<i8:f32, 1.000000e+00>> +// CHECK: "quant.scast"(%[[cst]]) : (tensor<7xi8>) -> tensor<7x!quant.uniform<i8<-127:127>:f32, 1.000000e+00:-127>> +// CHECK: "quant.scast"(%[[cst0]]) : (tensor<7xi8>) -> tensor<7x!quant.uniform<u8:f32, 1.000000e+00>> +// CHECK: "quant.scast"(%[[cst1]]) : (tensor<7xi8>) -> tensor<7x!quant.uniform<u8<1:255>:f32, 1.000000e+00:1>> + + %cst = constant dense<0.0> : tensor<7xf32> + %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i8:f32, 1.0>> + %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i8:f32, 1.0>>) -> (tensor<7xf32>) + + %cst0 = constant dense<0.0> : tensor<7xf32> + %3 = "quant.qcast"(%cst0) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i8<-127:127>:f32, 1.0:-127>> + %4 = "quant.dcast"(%3) : (tensor<7x!quant.uniform<i8<-127:127>:f32, 1.0:-127>>) -> (tensor<7xf32>) + + %cst1 = constant dense<0.0> : tensor<7xf32> + %5 = "quant.qcast"(%cst1) : (tensor<7xf32>) -> tensor<7x!quant.uniform<u8:f32, 1.0>> + %6 = "quant.dcast"(%5) : (tensor<7x!quant.uniform<u8:f32, 1.0>>) -> (tensor<7xf32>) + + %cst2 = constant dense<0.0> : tensor<7xf32> + %7 = "quant.qcast"(%cst2) : (tensor<7xf32>) -> tensor<7x!quant.uniform<u8<1:255>:f32, 1.0:1>> + %8 = "quant.dcast"(%7) : (tensor<7x!quant.uniform<u8<1:255>:f32, 1.0:1>>) -> (tensor<7xf32>) + + return %2, %4, %6, %8 : tensor<7xf32>, tensor<7xf32>, tensor<7xf32>, tensor<7xf32> +} + diff --git a/mlir/test/Dialect/QuantOps/convert-fakequant.mlir b/mlir/test/Dialect/QuantOps/convert-fakequant.mlir index 61561c5e359..15de088f39c 100644 --- a/mlir/test/Dialect/QuantOps/convert-fakequant.mlir +++ b/mlir/test/Dialect/QuantOps/convert-fakequant.mlir @@ -1,6 +1,36 @@ // RUN: mlir-opt %s -split-input-file -quant-convert-simulated-quantization | FileCheck %s --dump-input=fail // ----- +// Verifies a quint8 single point. +// CHECK-LABEL: fakeQuantArgs_Quint8_0 +func @fakeQuantArgs_Quint8_0(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> { +^bb0(%arg0: tensor<8x4x3xf32>): + // CHECK: %[[qc:.*]] = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>) + // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<u8:f32, 1.000000e+00>> + // CHECK-NEXT: "quant.dcast"(%[[qc]]) : (tensor<8x4x3x!quant.uniform<u8:f32, 1.000000e+00>>) + // CHECK-SAME: -> tensor<8x4x3xf32> + %0 = "quant.const_fake_quant"(%arg0) { + min = 0.0 : f32, max = 0.0 : f32, num_bits = 8 + } : (tensor<8x4x3xf32>) -> tensor<8x4x3xf32> + return %0 : tensor<8x4x3xf32> +} + +// ----- +// Verifies a quint8 single point (with narrow_range = true). +// CHECK-LABEL: fakeQuantArgs_Quint8_0_NarrowRange +func @fakeQuantArgs_Quint8_0_NarrowRange(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> { +^bb0(%arg0: tensor<8x4x3xf32>): + // CHECK: %[[qc:.*]] = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>) + // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<u8<1:255>:f32, 1.000000e+00:1>> + // CHECK-NEXT: "quant.dcast"(%[[qc]]) : (tensor<8x4x3x!quant.uniform<u8<1:255>:f32, 1.000000e+00:1>>) + // CHECK-SAME: -> tensor<8x4x3xf32> + %0 = "quant.const_fake_quant"(%arg0) { + min = 0.0 : f32, max = 0.0 : f32, num_bits = 8, narrow_range = true + } : (tensor<8x4x3xf32>) -> tensor<8x4x3xf32> + return %0 : tensor<8x4x3xf32> +} + +// ----- // Verifies a quint8 asymmetric 0..1 range. // CHECK-LABEL: fakeQuantArgs_Quint8_0_1 func @fakeQuantArgs_Quint8_0_1(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> { @@ -46,6 +76,36 @@ func @fakeQuantArgs_Quint8_SymmetricRange(tensor<8x4x3xf32>) -> tensor<8x4x3xf32 } // ----- +// Verifies a qint8 single point. +// CHECK-LABEL: fakeQuantArgs_Qint8_0 +func @fakeQuantArgs_Qint8_0(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> { +^bb0(%arg0: tensor<8x4x3xf32>): + // CHECK: %[[qc:.*]] = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>) + // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<i8:f32, 1.000000e+00:-128>> + // CHECK-NEXT: "quant.dcast"(%[[qc]]) : (tensor<8x4x3x!quant.uniform<i8:f32, 1.000000e+00:-128>>) + // CHECK-SAME: -> tensor<8x4x3xf32> + %0 = "quant.const_fake_quant"(%arg0) { + min = 0.0 : f32, max = 0.0 : f32, num_bits = 8, is_signed = true + } : (tensor<8x4x3xf32>) -> tensor<8x4x3xf32> + return %0 : tensor<8x4x3xf32> +} + +// ----- +// Verifies a qint8 single point (with narrow_range = true). +// CHECK-LABEL: fakeQuantArgs_Qint8_0_NarrowRange +func @fakeQuantArgs_Qint8_0_NarrowRange(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> { +^bb0(%arg0: tensor<8x4x3xf32>): + // CHECK: %[[qc:.*]] = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>) + // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<i8<-127:127>:f32, 1.000000e+00:-127>> + // CHECK-NEXT: "quant.dcast"(%[[qc]]) : (tensor<8x4x3x!quant.uniform<i8<-127:127>:f32, 1.000000e+00:-127>>) + // CHECK-SAME: -> tensor<8x4x3xf32> + %0 = "quant.const_fake_quant"(%arg0) { + min = 0.0 : f32, max = 0.0 : f32, num_bits = 8, narrow_range = true, is_signed = true + } : (tensor<8x4x3xf32>) -> tensor<8x4x3xf32> + return %0 : tensor<8x4x3xf32> +} + +// ----- // Verifies a qint8 asymmetric 0..1 range. // CHECK-LABEL: fakeQuantArgs_Qint8_0_1 func @fakeQuantArgs_Qint8_0_1(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> { |