summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeng Liu <fengliuai@google.com>2019-08-29 10:08:46 -0700
committerA. Unique TensorFlower <gardener@tensorflow.org>2019-08-29 10:09:22 -0700
commit6de6c2c13828742249377585fd1ef19d9cfd1773 (patch)
treedd0ef16c044bd319e82aa80edad5d9c4f62667fa
parent4bb6f8ecdb54f4ee096d8f92603d628d0cac4ed6 (diff)
downloadbcm5719-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.cpp2
-rw-r--r--mlir/test/Dialect/QuantOps/convert-const.mlir33
-rw-r--r--mlir/test/Dialect/QuantOps/convert-fakequant.mlir60
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> {
OpenPOWER on IntegriCloud