[Mlir-commits] [mlir] QuantileType relax quantileType conditions and inheritance issue (PR #204793)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Jun 24 03:49:05 PDT 2026
https://github.com/vsimion26 updated https://github.com/llvm/llvm-project/pull/204793
>From 996908e3ab38c772d67e6d6c453e7f1020ce503b Mon Sep 17 00:00:00 2001
From: vsimion26 <vlad.simion at intel.com>
Date: Fri, 19 Jun 2026 11:32:13 +0100
Subject: [PATCH 1/4] QuantileType relax quantileType conditions and
inheritance
---
mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h | 10 +++++-----
mlir/lib/Dialect/Quant/IR/QuantTypes.cpp | 8 +++++---
mlir/test/Dialect/Quant/invalid-quantile-types.mlir | 4 ++--
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h b/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h
index 2001178d5939c..98c912024a6a7 100644
--- a/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h
+++ b/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h
@@ -551,13 +551,14 @@ class CalibratedQuantizedType
/*Syntax:
```
- quantile-type ::= `!quant.quantile` `<` type `:` type `,` `{` float-list `}`
+ quantile-type ::= `!quant.quantile` `<` type `:` type `,` `{` float-list /
+ int-list `}`
(`,` `<` int `,` int `>`)? `>`
```
A quantile type represents a quantile-based floating point encoding, where
- discrete storage values are totally defined by the floating-point values
- entries in a quantile lookup table of F8/F16/F32/F64.
+ discrete storage values are totally defined by the floating-point or integer
+ values entries in a quantile lookup table of F8/F16/F32/F64 or integer types.
Optionally, explicit minimum and maximum storage values can be specified
after the LUT as `<min:max>`.
@@ -587,8 +588,7 @@ class CalibratedQuantizedType
*/
class QuantileType
- : public Type::TypeBase<QuantileType, QuantizedType,
- detail::QuantileTypeStorage,
+ : public Type::TypeBase<QuantileType, Type, detail::QuantileTypeStorage,
mlir::QuantStorageTypeInterface::Trait> {
public:
using ImplType = detail::QuantileTypeStorage;
diff --git a/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp b/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp
index c150c151e1e11..adabb49aea003 100644
--- a/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp
+++ b/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp
@@ -41,7 +41,8 @@ unsigned QuantizedType::getFlags() const {
}
bool QuantizedType::classof(Type type) {
- return llvm::isa<QuantDialect>(type.getDialect());
+ return llvm::isa<QuantDialect>(type.getDialect()) &&
+ !llvm::isa<QuantileType>(type);
}
LogicalResult
@@ -578,8 +579,9 @@ LogicalResult QuantileType::verifyInvariants(
std::optional<int64_t> storageMin, std::optional<int64_t> storageMax) {
if (!storageType.isIntOrFloat())
return emitError() << "storage type must be an integer or float type";
- if (!llvm::isa<mlir::FloatType>(quantileType))
- return emitError() << "quantile type must be a float type";
+ if (!llvm::isa<mlir::FloatType>(quantileType) &&
+ !llvm::isa<mlir::IntegerType>(quantileType))
+ return emitError() << "quantile type must be a float or integer type";
if (quantiles.empty())
return emitError() << "quantile values must not be empty";
if (storageMin.has_value() != storageMax.has_value())
diff --git a/mlir/test/Dialect/Quant/invalid-quantile-types.mlir b/mlir/test/Dialect/Quant/invalid-quantile-types.mlir
index faf16d01a9cd5..4a7703fd0e553 100644
--- a/mlir/test/Dialect/Quant/invalid-quantile-types.mlir
+++ b/mlir/test/Dialect/Quant/invalid-quantile-types.mlir
@@ -11,8 +11,8 @@ func.func private @invalid_storage_type() -> !quant.quantile<tensor<1xf32>:f32,
// -----
// Quantile (expressed) type must be a float.
-// expected-error @+1 {{quantile type must be a float type}}
-func.func private @invalid_quantile_type() -> !quant.quantile<ui4:i8, {1.0, 0.0, -1.0}>
+// expected-error @+1 {{quantile type must be a float or integer type}}
+func.func private @invalid_quantile_type() -> !quant.quantile<ui4:tensor<1xf32>, {1.0, 0.0, -1.0}>
// -----
>From 664cf30902464db0530ce501da93776f06e7597d Mon Sep 17 00:00:00 2001
From: vsimion26 <vlad.simion at intel.com>
Date: Wed, 24 Jun 2026 08:05:51 +0100
Subject: [PATCH 2/4] lit test update
---
.../test/Dialect/Quant/invalid-quantile-types.mlir | 2 +-
mlir/test/Dialect/Quant/quantile-types.mlir | 14 ++++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/mlir/test/Dialect/Quant/invalid-quantile-types.mlir b/mlir/test/Dialect/Quant/invalid-quantile-types.mlir
index 4a7703fd0e553..08a739d45e120 100644
--- a/mlir/test/Dialect/Quant/invalid-quantile-types.mlir
+++ b/mlir/test/Dialect/Quant/invalid-quantile-types.mlir
@@ -10,7 +10,7 @@ func.func private @invalid_storage_type() -> !quant.quantile<tensor<1xf32>:f32,
// -----
-// Quantile (expressed) type must be a float.
+// Quantile (expressed) type must be a float or integer type.
// expected-error @+1 {{quantile type must be a float or integer type}}
func.func private @invalid_quantile_type() -> !quant.quantile<ui4:tensor<1xf32>, {1.0, 0.0, -1.0}>
diff --git a/mlir/test/Dialect/Quant/quantile-types.mlir b/mlir/test/Dialect/Quant/quantile-types.mlir
index c8840a7b3d3f2..a879acd7b3126 100644
--- a/mlir/test/Dialect/Quant/quantile-types.mlir
+++ b/mlir/test/Dialect/Quant/quantile-types.mlir
@@ -6,6 +6,20 @@
// CHECK-SAME: !quant.quantile<ui4:f16, {
func.func private @quantile_ui4_f16(!quant.quantile<ui4:f16, {-1.0,-0.8667,-0.7333,-0.6,-0.4667,-0.3333,-0.2,-0.0667,0.0667,0.2,0.3333,0.4667,0.6,0.7333,0.8667,1.0}>) -> ()
+
+// -----
+// Quantile type: ui4 storage-type with si8 expressed-type, 16 entries (default range 0..15).
+// CHECK-LABEL: func private @quantile_ui4_si8
+// CHECK-SAME: !quant.quantile<ui4:si8, {
+func.func private @quantile_ui4_si8(!quant.quantile<ui4:si8, {-1.0,-0.8667,-0.7333,-0.6,-0.4667,-0.3333,-0.2,-0.0667,0.0667,0.2,0.3333,0.4667,0.6,0.7333,0.8667,1.0}>) -> ()
+
+
+// -----
+// Quantile type: ui4 storage-type with ui8 expressed-type, 16 entries (default range 0..15).
+// CHECK-LABEL: func private @quantile_ui4_ui8
+// CHECK-SAME: !quant.quantile<ui4:ui8, {
+func.func private @quantile_ui4_ui8(!quant.quantile<ui4:ui8, {0.0,0.0667,0.1333,0.2,0.2667,0.3333,0.4,0.4667,0.5333,0.6,0.6667,0.7333,0.8,0.8667,0.9333,1.0}>) -> ()
+
// -----
// Quantile type: si8 storage-type with f32 expressed-type, explicit range -2:2 (5 entries).
// CHECK: func private @quantile_si8_f32(!quant.quantile<si8:f32, {-1.000000e+00,-5.000000e-01,0.000000e+00,5.000000e-01,1.000000e+00}, <-2:2>>)
>From e65ce462fb56fc4bb099d027631f20262487cc60 Mon Sep 17 00:00:00 2001
From: vsimion26 <vlad.simion at intel.com>
Date: Wed, 24 Jun 2026 10:56:55 +0100
Subject: [PATCH 3/4] removed QuantileType redundant check in
QuantizedType::classof
---
mlir/lib/Dialect/Quant/IR/QuantTypes.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp b/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp
index adabb49aea003..508594c73aefc 100644
--- a/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp
+++ b/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp
@@ -41,8 +41,7 @@ unsigned QuantizedType::getFlags() const {
}
bool QuantizedType::classof(Type type) {
- return llvm::isa<QuantDialect>(type.getDialect()) &&
- !llvm::isa<QuantileType>(type);
+ return llvm::isa<QuantDialect>(type.getDialect());
}
LogicalResult
>From 04d61e75e28bb62d7e4f1a9dc59afac2db083574 Mon Sep 17 00:00:00 2001
From: vsimion26 <vlad.simion at intel.com>
Date: Wed, 24 Jun 2026 11:48:46 +0100
Subject: [PATCH 4/4] added more examples and some clarifications
---
mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h b/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h
index 98c912024a6a7..82914c631e42d 100644
--- a/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h
+++ b/mlir/include/mlir/Dialect/Quant/IR/QuantTypes.h
@@ -571,6 +571,8 @@ class CalibratedQuantizedType
MLIR:
!quant.quantile<ui4:f16, {-1.0,-0.696,0.0,0.079,1.0}>
!quant.quantile<ui4:f16, {-1.0,-0.696,0.0,0.079,1.0}, <-8,7>>
+ !quant.quantile<ui4:si8, {-1.0,-0.696,0.0,0.079,1.0}>
+ !quant.quantile<ui4:ui8, {0.0,0.079,0.696,1.0}>
As an additional explanation for better understanding and readability of the
above example, the quantile type can be broken down as follows:
@@ -585,6 +587,20 @@ class CalibratedQuantizedType
- `, <-8,7>`: This optional part specifies the explicit minimum and maximum
storage values. In this case, the minimum storage value is -8 and the maximum
storage value is 7.
+ - The number of quantile values in the LUT has to be equal to the number of
+ discrete values that can be represented by the storage type. For example, for
+ `ui4`, there are 16 discrete values, so the LUT must contain
+ exactly 16 quantile values. If the number of quantile values in the LUT does
+ not match the number of discrete values that can be represented by the
+ storage type, it will result in an error during type verification. Otherwise,
+ we can specify a storageMin and storageMax to match the number of quantile
+ values in the LUT. For example, for `ui4`, we can specify a storageMin of 0
+ and a storageMax of 5, which allows us to have 6 discrete values that can be
+ represented by the storage type.
+
+ The above examples showcase how a quantile type would look like in MLIR,
+ with the mention that the LUT size is not correct for the given storage
+ types, but it is just for demonstration purposes.
*/
class QuantileType
More information about the Mlir-commits
mailing list