MLIR 24.0.0git
QuantTypes.cpp
Go to the documentation of this file.
1//===- QuantOps.cpp - Quantization Type and Ops Implementation --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "TypeDetail.h"
15
17#include "mlir/IR/MLIRContext.h"
18
19using namespace mlir;
20using namespace mlir::quant;
21using namespace mlir::quant::detail;
22
23namespace {
24
25// Return the minimum scale representable in a given float type
26double getMinScale(Type expressedType) {
27 auto floatType = cast<FloatType>(expressedType);
28 return APFloat::getSmallest(floatType.getFloatSemantics()).convertToDouble();
29}
30
31// Return the maximum scale representable in a given float type
32double getMaxScale(Type expressedType) {
33 auto floatType = cast<FloatType>(expressedType);
34 return APFloat::getLargest(floatType.getFloatSemantics()).convertToDouble();
35}
36
37} // namespace
38
39unsigned QuantizedType::getFlags() const {
40 return static_cast<ImplType *>(impl)->flags;
41}
42
48
49LogicalResult
51 unsigned flags, Type storageType,
52 Type expressedType, int64_t storageTypeMin,
53 int64_t storageTypeMax) {
54 if (auto quantStorageTypeInterface =
55 llvm::dyn_cast<QuantStorageTypeInterface>(storageType)) {
56 unsigned integralWidth = quantStorageTypeInterface.getStorageWidth();
57
58 // Verify storage width.
59 if (integralWidth == 0 || integralWidth > MaxStorageBits)
60 return emitError() << "illegal storage type size: " << integralWidth;
61
63 int64_t defaultMin = quantStorageTypeInterface.getDefaultMinimum(isSigned);
64 int64_t defaultMax = quantStorageTypeInterface.getDefaultMaximum(isSigned);
65
66 if (storageTypeMax - storageTypeMin <= 0 || storageTypeMin < defaultMin ||
67 storageTypeMax > defaultMax) {
68 return emitError() << "illegal storage min and storage max: ("
69 << storageTypeMin << ":" << storageTypeMax << ")";
70 }
71
72 return success();
73 }
74
75 return emitError() << "storage type must implement QuantStorageTypeInterface";
76}
77
79 return static_cast<ImplType *>(impl)->storageType;
80}
81
83 return static_cast<ImplType *>(impl)->storageTypeMin;
84}
85
87 return static_cast<ImplType *>(impl)->storageTypeMax;
88}
89
91 Type storageType = static_cast<ImplType *>(impl)->storageType;
92 auto quantStorageTypeInterface =
93 llvm::dyn_cast<QuantStorageTypeInterface>(storageType);
94
95 int64_t defaultMin = quantStorageTypeInterface.getDefaultMinimum(isSigned());
96 int64_t defaultMax = quantStorageTypeInterface.getDefaultMaximum(isSigned());
97
98 return defaultMin != getStorageTypeMin() || defaultMax != getStorageTypeMax();
99}
100
102 Type storageType = static_cast<ImplType *>(impl)->storageType;
103 auto quantStorageTypeInterface =
104 llvm::dyn_cast<QuantStorageTypeInterface>(storageType);
105
106 return quantStorageTypeInterface.getStorageWidth();
107}
108
110 return static_cast<ImplType *>(impl)->expressedType;
111}
112
113bool QuantizedType::isCompatibleExpressedType(Type candidateExpressedType) {
114 if (llvm::isa<ShapedType>(candidateExpressedType)) {
115 return llvm::cast<ShapedType>(candidateExpressedType).getElementType() ==
117 }
118 return candidateExpressedType == getExpressedType();
119}
120
123 if (llvm::isa<ShapedType>(primitiveOrContainerType)) {
124 Type elementType =
125 llvm::cast<ShapedType>(primitiveOrContainerType).getElementType();
126 return llvm::dyn_cast<QuantizedType>(elementType);
127 }
128 return llvm::dyn_cast<QuantizedType>(primitiveOrContainerType);
129}
130
132 if (candidateType == getStorageType()) {
133 // i.e. i8 -> quant<"uniform[i8:f32]{1.0}">
134 return *this;
135 }
136 if (llvm::isa<RankedTensorType>(candidateType)) {
137 // i.e. tensor<4xi8> -> tensor<4x!quant<"uniform[i8:f32]{1.0}">>
138 return RankedTensorType::get(
139 llvm::cast<RankedTensorType>(candidateType).getShape(),
141 }
142 if (llvm::isa<UnrankedTensorType>(candidateType)) {
143 // i.e. tensor<xi8> -> tensor<x!quant<"uniform[i8:f32]{1.0}">>
144 return UnrankedTensorType::get(getStorageType());
145 }
146 if (llvm::isa<VectorType>(candidateType)) {
147 // i.e. vector<4xi8> -> vector<4x!quant<"uniform[i8:f32]{1.0}">>
148 return VectorType::get(llvm::cast<VectorType>(candidateType).getShape(),
150 }
151
152 return nullptr;
153}
154
156 if (llvm::isa<QuantizedType>(quantizedType)) {
157 // i.e. quant<"uniform[i8:f32]{1.0}"> -> i8
158 return llvm::cast<QuantizedType>(quantizedType).getStorageType();
159 }
160 if (llvm::isa<ShapedType>(quantizedType)) {
161 // i.e. tensor<4xi8> -> tensor<4x!quant<"uniform[i8:f32]{1.0}">>
162 ShapedType sType = llvm::cast<ShapedType>(quantizedType);
163 if (!llvm::isa<QuantizedType>(sType.getElementType())) {
164 return nullptr;
165 }
166 Type storageType =
167 llvm::cast<QuantizedType>(sType.getElementType()).getStorageType();
168 if (llvm::isa<RankedTensorType>(quantizedType)) {
169 return RankedTensorType::get(sType.getShape(), storageType);
170 }
171 if (llvm::isa<UnrankedTensorType>(quantizedType)) {
172 return UnrankedTensorType::get(storageType);
173 }
174 if (llvm::isa<VectorType>(quantizedType)) {
175 return VectorType::get(sType.getShape(), storageType);
176 }
177 }
178
179 return nullptr;
180}
181
183 if (candidateType == getExpressedType()) {
184 // i.e. f32 -> quant<"uniform[i8:f32]{1.0}">
185 return *this;
186 }
187 if (llvm::isa<ShapedType>(candidateType)) {
188 ShapedType candidateShapedType = llvm::cast<ShapedType>(candidateType);
189 if (candidateShapedType.getElementType() != getExpressedType()) {
190 return nullptr;
191 }
192
193 if (llvm::isa<RankedTensorType>(candidateType)) {
194 // i.e. tensor<4xf32> -> tensor<4x!quant<"uniform[i8:f32]{1.0}">>
195 return RankedTensorType::get(candidateShapedType.getShape(), *this);
196 }
197 if (llvm::isa<UnrankedTensorType>(candidateType)) {
198 // i.e. tensor<xf32> -> tensor<x!quant<"uniform[i8:f32]{1.0}">>
199 return UnrankedTensorType::get(*this);
200 }
201 if (llvm::isa<VectorType>(candidateType)) {
202 // i.e. tensor<4xf32> -> tensor<4x!quant<"uniform[i8:f32]{1.0}">>
203 return VectorType::get(candidateShapedType.getShape(), *this);
204 }
205 }
206
207 return nullptr;
208}
209
211 if (llvm::isa<QuantizedType>(quantizedType)) {
212 // i.e. quant<"uniform[i8:f32]{1.0}"> -> f32
213 return llvm::cast<QuantizedType>(quantizedType).getExpressedType();
214 }
215 if (llvm::isa<ShapedType>(quantizedType)) {
216 // i.e. tensor<4xi8> -> tensor<4x!quant<"uniform[i8:f32]{1.0}">>
217 ShapedType sType = llvm::cast<ShapedType>(quantizedType);
218 if (!llvm::isa<QuantizedType>(sType.getElementType())) {
219 return nullptr;
220 }
221 Type expressedType =
222 llvm::cast<QuantizedType>(sType.getElementType()).getExpressedType();
223 if (llvm::isa<RankedTensorType>(quantizedType)) {
224 return RankedTensorType::get(sType.getShape(), expressedType);
225 }
226 if (llvm::isa<UnrankedTensorType>(quantizedType)) {
227 return UnrankedTensorType::get(expressedType);
228 }
229 if (llvm::isa<VectorType>(quantizedType)) {
230 return VectorType::get(sType.getShape(), expressedType);
231 }
232 }
233
234 return nullptr;
235}
236
238 Type expressedQuantizedType = castFromExpressedType(candidateType);
239 if (!expressedQuantizedType) {
240 return nullptr;
241 }
242 return QuantizedType::castToStorageType(expressedQuantizedType);
243}
244
245AnyQuantizedType AnyQuantizedType::get(unsigned flags, Type storageType,
246 Type expressedType,
247 int64_t storageTypeMin,
248 int64_t storageTypeMax) {
249 return Base::get(storageType.getContext(), flags, storageType, expressedType,
250 storageTypeMin, storageTypeMax);
251}
252
255 unsigned flags, Type storageType,
256 Type expressedType, int64_t storageTypeMin,
257 int64_t storageTypeMax) {
258 return Base::getChecked(emitError, storageType.getContext(), flags,
259 storageType, expressedType, storageTypeMin,
260 storageTypeMax);
261}
262
263LogicalResult
265 unsigned flags, Type storageType,
266 Type expressedType, int64_t storageTypeMin,
267 int64_t storageTypeMax) {
268 if (failed(QuantizedType::verifyInvariants(emitError, flags, storageType,
269 expressedType, storageTypeMin,
270 storageTypeMax))) {
271 return failure();
272 }
273
274 // Verify that the expressed type is floating point.
275 // If this restriction is ever eliminated, the parser/printer must be
276 // extended.
277 if (expressedType && !llvm::isa<FloatType>(expressedType))
278 return emitError() << "expressed type must be floating point";
279
280 return success();
281}
282
284 Type expressedType, double scale,
285 int64_t zeroPoint,
286 int64_t storageTypeMin,
287 int64_t storageTypeMax) {
288 return Base::get(storageType.getContext(), flags, storageType, expressedType,
289 scale, zeroPoint, storageTypeMin, storageTypeMax);
290}
291
293 function_ref<InFlightDiagnostic()> emitError, unsigned flags,
294 Type storageType, Type expressedType, double scale, int64_t zeroPoint,
295 int64_t storageTypeMin, int64_t storageTypeMax) {
296 return Base::getChecked(emitError, storageType.getContext(), flags,
297 storageType, expressedType, scale, zeroPoint,
298 storageTypeMin, storageTypeMax);
299}
300
302 function_ref<InFlightDiagnostic()> emitError, unsigned flags,
303 Type storageType, Type expressedType, double scale, int64_t zeroPoint,
304 int64_t storageTypeMin, int64_t storageTypeMax) {
305 if (failed(QuantizedType::verifyInvariants(emitError, flags, storageType,
306 expressedType, storageTypeMin,
307 storageTypeMax))) {
308 return failure();
309 }
310
311 // Uniform quantization requires fully expressed parameters, including
312 // expressed type.
313 if (!expressedType)
314 return emitError() << "uniform quantization requires expressed type";
315
316 // Verify that the expressed type is floating point.
317 // If this restriction is ever eliminated, the parser/printer must be
318 // extended.
319 if (!llvm::isa<FloatType>(expressedType))
320 return emitError() << "expressed type must be floating point";
321
322 // Verify scale.
323 double minScale = getMinScale(expressedType);
324 double maxScale = getMaxScale(expressedType);
325 if (scale < minScale || scale > maxScale)
326 return emitError() << "scale out of expressed type range [" << minScale
327 << ", " << maxScale << "]";
328
329 return success();
330}
331
332double UniformQuantizedType::getScale() const { return getImpl()->scale; }
333
335 return getImpl()->zeroPoint;
336}
337
339 unsigned flags, Type storageType, Type expressedType,
340 ArrayRef<double> scales, ArrayRef<int64_t> zeroPoints,
341 int32_t quantizedDimension, int64_t storageTypeMin,
342 int64_t storageTypeMax) {
343 return Base::get(storageType.getContext(), flags, storageType, expressedType,
344 scales, zeroPoints, quantizedDimension, storageTypeMin,
345 storageTypeMax);
346}
347
349 function_ref<InFlightDiagnostic()> emitError, unsigned flags,
350 Type storageType, Type expressedType, ArrayRef<double> scales,
351 ArrayRef<int64_t> zeroPoints, int32_t quantizedDimension,
352 int64_t storageTypeMin, int64_t storageTypeMax) {
353 return Base::getChecked(emitError, storageType.getContext(), flags,
354 storageType, expressedType, scales, zeroPoints,
355 quantizedDimension, storageTypeMin, storageTypeMax);
356}
357
359 function_ref<InFlightDiagnostic()> emitError, unsigned flags,
360 Type storageType, Type expressedType, ArrayRef<double> scales,
361 ArrayRef<int64_t> zeroPoints, int32_t quantizedDimension,
362 int64_t storageTypeMin, int64_t storageTypeMax) {
363 if (failed(QuantizedType::verifyInvariants(emitError, flags, storageType,
364 expressedType, storageTypeMin,
365 storageTypeMax))) {
366 return failure();
367 }
368
369 // Uniform quantization requires fully expressed parameters, including
370 // expressed type.
371 if (!expressedType)
372 return emitError() << "uniform quantization requires expressed type";
373
374 // Verify that the expressed type is floating point.
375 // If this restriction is ever eliminated, the parser/printer must be
376 // extended.
377 if (!llvm::isa<FloatType>(expressedType))
378 return emitError() << "expressed type must be floating point";
379
380 // Ensure that the number of scales and zeroPoints match.
381 if (scales.size() != zeroPoints.size())
382 return emitError() << "illegal number of scales and zeroPoints: "
383 << scales.size() << ", " << zeroPoints.size();
384
385 // Verify scale.
386 double minScale = getMinScale(expressedType);
387 double maxScale = getMaxScale(expressedType);
388 for (double scale : scales) {
389 if (scale < minScale || scale > maxScale)
390 return emitError() << "scale out of expressed type range [" << minScale
391 << ", " << maxScale << "]";
392 }
393
394 // Verify quantized dimension.
395 if (quantizedDimension < 0)
396 return emitError() << "illegal quantized dimension: " << quantizedDimension;
397
398 return success();
399}
400
402 return getImpl()->getScales();
403}
404
406 return getImpl()->getZeroPoints();
407}
408
410 return getImpl()->quantizedDimension;
411}
412
414 unsigned flags, Type storageType, Type expressedType,
415 DenseElementsAttr scales, DenseElementsAttr zeroPoints,
416 ArrayRef<int32_t> quantizedDimensions, ArrayRef<int64_t> blockSizes,
417 int64_t storageTypeMin, int64_t storageTypeMax) {
418 return Base::get(storageType.getContext(), flags, storageType, expressedType,
419 scales, zeroPoints, quantizedDimensions, blockSizes,
420 storageTypeMin, storageTypeMax);
421}
422
424 function_ref<InFlightDiagnostic()> emitError, unsigned flags,
425 Type storageType, Type expressedType, DenseElementsAttr scales,
426 DenseElementsAttr zeroPoints, ArrayRef<int32_t> quantizedDimensions,
427 ArrayRef<int64_t> blockSizes, int64_t storageTypeMin,
428 int64_t storageTypeMax) {
429 return Base::getChecked(emitError, storageType.getContext(), flags,
430 storageType, expressedType, scales, zeroPoints,
431 quantizedDimensions, blockSizes, storageTypeMin,
432 storageTypeMax);
433}
434
436 function_ref<InFlightDiagnostic()> emitError, unsigned flags,
437 Type storageType, Type expressedType, DenseElementsAttr scales,
438 DenseElementsAttr zeroPoints, ArrayRef<int32_t> quantizedDimensions,
439 ArrayRef<int64_t> blockSizes, int64_t storageTypeMin,
440 int64_t storageTypeMax) {
441 if (failed(QuantizedType::verifyInvariants(emitError, flags, storageType,
442 expressedType, storageTypeMin,
443 storageTypeMax))) {
444 return failure();
445 }
446
447 // Uniform quantization requires fully expressed parameters, including
448 // expressed type.
449 if (!expressedType)
450 return emitError() << "uniform quantization requires expressed type";
451
452 // Verify that the expressed type is floating point.
453 // If this restriction is ever eliminated, the parser/printer must be
454 // extended.
455 if (!llvm::isa<FloatType>(expressedType))
456 return emitError() << "expressed type must be floating point";
457
458 // Verify scale type to match expressedType.
459 if (scales.getType().getElementType() != expressedType) {
460 return emitError() << "type of scale values "
461 << scales.getType().getElementType()
462 << " must match the expressed type " << expressedType;
463 }
464
465 // Verify zero-point type to match storageType.
466 if (zeroPoints.getType().getElementType() != storageType) {
467 return emitError() << "type of zero point values "
468 << zeroPoints.getType().getElementType()
469 << " must match the storage type " << storageType;
470 }
471
472 // Ensure that the shape of scales and zeroPoints match.
473 if (scales.getType().getShape() != zeroPoints.getType().getShape())
474 return emitError() << "shape of scales and zeroPoints ("
475 << scales.getType().getShape() << " vs "
476 << zeroPoints.getType().getShape() << ") does not match";
477
478 // Ensure that the number of quantized-dimensions and block-sizes match.
479 if (quantizedDimensions.size() != blockSizes.size())
480 return emitError() << "number of quantized dimensions and block sizes ("
481 << scales.size() << " vs " << zeroPoints.size()
482 << ") does not match";
483
484 // Verify quantized dimension.
485 for (auto quantizedDimension : quantizedDimensions) {
486 if (quantizedDimension < 0)
487 return emitError() << "illegal quantized dimension: "
488 << quantizedDimension;
489 }
490
491 // Verify block sizes.
492 for (auto blockSize : blockSizes) {
493 if (blockSize <= 0)
494 return emitError() << "illegal block size: " << blockSize;
495 }
496
497 return success();
498}
499
503
505 return getImpl()->getZeroPoints();
506}
507
510 return getImpl()->getQuantizedDimensions();
511}
512
514 return getImpl()->getBlockSizes();
515}
516
520 result.reserve(getQuantizedDimensions().size());
521
522 for (auto [dim, size] :
523 llvm::zip(getQuantizedDimensions(), getBlockSizes())) {
524 result.push_back({dim, size});
525 }
526
527 return result;
528}
529
531 double min, double max) {
532 return Base::get(expressedType.getContext(), expressedType, min, max);
533}
534
537 double min, double max) {
538 return Base::getChecked(emitError, expressedType.getContext(), expressedType,
539 min, max);
540}
541
544 double min, double max) {
545 // Verify that the expressed type is floating point.
546 // If this restriction is ever eliminated, the parser/printer must be
547 // extended.
548 if (!llvm::isa<FloatType>(expressedType))
549 return emitError() << "expressed type must be floating point";
550 if (max <= min)
551 return emitError() << "illegal min and max: (" << min << ":" << max << ")";
552
553 return success();
554}
555
556double CalibratedQuantizedType::getMin() const { return getImpl()->min; }
557
558double CalibratedQuantizedType::getMax() const { return getImpl()->max; }
559
561 mlir::Type quantileType,
562 ArrayRef<double> quantiles,
563 std::optional<int64_t> storageMin,
564 std::optional<int64_t> storageMax) {
565 return Base::get(ctx, storageType, quantileType, quantiles, storageMin,
566 storageMax);
567}
568
571 mlir::Type storageType, mlir::Type quantileType, ArrayRef<double> quantiles,
572 std::optional<int64_t> storageMin, std::optional<int64_t> storageMax) {
573 return Base::getChecked(emitError, ctx, storageType, quantileType, quantiles,
574 storageMin, storageMax);
575}
576
579 Type quantileType, ArrayRef<double> quantiles,
580 std::optional<int64_t> storageMin, std::optional<int64_t> storageMax) {
581 if (!storageType.isIntOrFloat())
582 return emitError() << "storage type must be an integer or float type";
583 if (!llvm::isa<mlir::FloatType>(quantileType) &&
584 !llvm::isa<mlir::IntegerType>(quantileType))
585 return emitError() << "quantile type must be a float or integer type";
586 if (quantiles.empty())
587 return emitError() << "quantile values must not be empty";
588 if (storageMin.has_value() != storageMax.has_value())
589 return emitError()
590 << "storage min and max must both be specified or both omitted";
591 if (storageMin && storageMax && *storageMin >= *storageMax)
592 return emitError() << "storage min must be less than storage max";
593
594 unsigned width = storageType.getIntOrFloatBitWidth();
595 bool isSigned = !llvm::isa<mlir::IntegerType>(storageType) ||
596 llvm::cast<mlir::IntegerType>(storageType).isSigned();
597 auto effectiveMin =
598 storageMin.value_or(isSigned ? -(1LL << (width - 1)) : 0LL);
599 auto effectiveMax = storageMax.value_or(isSigned ? (1LL << (width - 1)) - 1
600 : (1LL << width) - 1);
601 auto expectedSize = effectiveMax - effectiveMin + 1;
602 if (static_cast<decltype(expectedSize)>(quantiles.size()) != expectedSize)
603 return emitError() << "quantile LUT size (" << quantiles.size()
604 << ") must equal the number of representable storage "
605 "values ("
606 << expectedSize << ")";
607
608 for (double v : quantiles)
609 if (std::isnan(v) || std::isinf(v))
610 return emitError()
611 << "quantile values must be finite (no NaN or infinity)";
612
613 return success();
614}
615
619
621 return static_cast<ImplType *>(impl)->getStorageType();
622}
623
625 return static_cast<ImplType *>(impl)->getQuantileType();
626}
627
629 return static_cast<ImplType *>(impl)->getQuantiles();
630}
631
632std::optional<int64_t> QuantileType::getStorageMin() const {
633 return static_cast<ImplType *>(impl)->getStorageMin();
634}
635
636std::optional<int64_t> QuantileType::getStorageMax() const {
637 return static_cast<ImplType *>(impl)->getStorageMax();
638}
639
641 if (auto intType = mlir::dyn_cast<mlir::IntegerType>(getStorageType()))
642 return intType.isSigned();
643 // Float types default to signed.
644 return true;
645}
646
650
652 if (auto explicitMax = getStorageMax())
653 return *explicitMax;
654 if (isSigned)
655 return (1LL << (getStorageWidth() - 1)) - 1;
656 return (1LL << getStorageWidth()) - 1;
657}
658
660 if (auto explicitMin = getStorageMin())
661 return *explicitMin;
662 if (isSigned)
663 return -(1LL << (getStorageWidth() - 1));
664 return 0;
665}
666
667std::string QuantileType::getStorageTypeName(bool isSigned) const {
668 std::string result = "!quant.quantile<";
669 llvm::raw_string_ostream os(result);
670 os << getStorageType() << ":" << getQuantileType() << ", {";
671 ArrayRef<double> quantiles = this->getQuantiles();
672 llvm::interleave(
673 llvm::seq<size_t>(0, quantiles.size()), os,
674 [&](size_t index) { os << quantiles[index]; }, ",");
675 os << "}";
676 if (auto minVal = getStorageMin())
677 if (auto maxVal = getStorageMax())
678 os << ", <" << *minVal << ":" << *maxVal << ">";
679 os << ">";
680 os.flush();
681 return result;
682}
683
684bool QuantileType::isPacked() const { return getStorageWidth() <= 4; }
685
687
689 unsigned width = getStorageWidth();
690 return width > 0 ? 8 / width : 0;
691}
692
693std::optional<unsigned> QuantileType::getPreferredAlignmentBytes() const {
694 return std::nullopt;
695}
return success()
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
static Value min(ImplicitLocOpBuilder &builder, Value value, Value bound)
static ArrayRef< int64_t > getShape(Type type)
Returns the shape of the given type.
Definition Traits.cpp:117
An attribute that represents a reference to a dense vector or tensor object.
int64_t size() const
Returns the number of elements held by this attribute.
ShapedType getType() const
Return the type of this ElementsAttr, guaranteed to be a vector or tensor with static shape.
This class represents a diagnostic that is inflight and set to be reported.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
static TypeID get()
Construct a type info object for the given type T.
Definition TypeID.h:245
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
Definition Types.cpp:35
bool isIntOrFloat() const
Return true if this is an integer (of any signedness) or a float type.
Definition Types.cpp:118
TypeID getTypeID()
Return a unique identifier for the concrete type.
Definition Types.h:101
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
Definition Types.cpp:124
A quantized type that maps storage to/from expressed types in an unspecified way.
Definition QuantTypes.h:204
static AnyQuantizedType get(unsigned flags, Type storageType, Type expressedType, int64_t storageTypeMin, int64_t storageTypeMax)
Gets an instance of the type with all parameters specified but not checked.
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, unsigned flags, Type storageType, Type expressedType, int64_t storageTypeMin, int64_t storageTypeMax)
Verifies construction invariants and issues errors/warnings.
static AnyQuantizedType getChecked(function_ref< InFlightDiagnostic()> emitError, unsigned flags, Type storageType, Type expressedType, int64_t storageTypeMin, int64_t storageTypeMax)
Gets an instance of the type with all specified parameters checked.
A quantized type that infers its range from given min/max values.
Definition QuantTypes.h:525
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, Type expressedType, double min, double max)
Verifies construction invariants and issues errors/warnings.
static CalibratedQuantizedType get(Type expressedType, double min, double max)
Gets an instance of the type with all parameters specified but not checked.
static CalibratedQuantizedType getChecked(function_ref< InFlightDiagnostic()> emitError, Type expressedType, double min, double max)
Gets an instance of the type with all specified parameters checked.
unsigned getLogicalBitWidth() const
static QuantileType getChecked(function_ref< InFlightDiagnostic()> emitError, mlir::MLIRContext *ctx, Type storageType, Type quantileType, ArrayRef< double > quantiles, std::optional< int64_t > storageMin=std::nullopt, std::optional< int64_t > storageMax=std::nullopt)
static bool classof(mlir::Type type)
Methods for support type inquiry through isa, cast, and dyn_cast.
unsigned getStorageWidth() const
std::optional< int64_t > getStorageMin() const
Return the explicit storage minimum, if set.
int64_t getDefaultMinimum(bool isSigned) const
unsigned getElementsPerByte() const
std::string getStorageTypeName(bool isSigned) const
detail::QuantileTypeStorage ImplType
Definition QuantTypes.h:610
bool shouldDefaultToSigned() const
int64_t getDefaultMaximum(bool isSigned) const
static QuantileType get(mlir::MLIRContext *ctx, Type storageType, Type quantileType, ArrayRef< double > quantiles={}, std::optional< int64_t > storageMin=std::nullopt, std::optional< int64_t > storageMax=std::nullopt)
ArrayRef< double > getQuantiles() const
Return the quantile table of this float type.
std::optional< unsigned > getPreferredAlignmentBytes() const
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, Type storageType, Type quantileType, ArrayRef< double > quantiles, std::optional< int64_t > storageMin, std::optional< int64_t > storageMax)
std::optional< int64_t > getStorageMax() const
Return the explicit storage maximum, if set.
Base class for all quantized types known to this dialect.
Definition QuantTypes.h:51
Type getExpressedType() const
Gets the original expressed type that this quantized type approximates.
static constexpr unsigned MaxStorageBits
The maximum number of bits supported for storage types.
Definition QuantTypes.h:57
bool hasStorageTypeBounds() const
Return whether the storage type has explicit min or max boundaries different from the minimum and max...
static Type castToStorageType(Type quantizedType)
Casts from a type based on a QuantizedType to a corresponding type based on the storageType (returns ...
Type castExpressedToStorageType(Type candidateType)
Casts from a type based on the expressedType to the equivalent type based on storageType by way of th...
detail::QuantizedTypeStorage ImplType
Definition QuantTypes.h:53
static Type castToExpressedType(Type quantizedType)
Casts from a type based on QuantizedType to a corresponding type based on the expressedType (returns ...
bool isSigned() const
Whether the storage type should be interpreted as a signed quantity (true) or an unsigned value (fals...
Definition QuantTypes.h:104
constexpr Type()=default
static QuantizedType getQuantizedElementType(Type primitiveOrContainerType)
Returns the element type as a QuantizedType or nullptr if it is not a quantized type.
unsigned getFlags() const
Gets the flags associated with this type.
int64_t getStorageTypeMax() const
The maximum value that storageType can take.
unsigned getStorageTypeIntegralWidth() const
Gets the integral bit width that the underlying storage type can exactly represent.
static bool classof(Type type)
Support method to enable LLVM-style type casting.
Type castFromStorageType(Type candidateType)
Casts from a type based on the storageType to a corresponding type based on this type (returns nullpt...
int64_t getStorageTypeMin() const
The minimum value that storageType can take.
Type getStorageType() const
Gets the underlying type used for to store values.
Type castFromExpressedType(Type candidateType)
Casts from a type based on the expressedType to a corresponding type based on this type (returns null...
bool isCompatibleExpressedType(Type candidateExpressedType)
Returns whether the candidateExpressedType is a match for this QuantizedType.
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, unsigned flags, Type storageType, Type expressedType, int64_t storageTypeMin, int64_t storageTypeMax)
Represents per-axis (also known as per-channel quantization).
Definition QuantTypes.h:325
static UniformQuantizedPerAxisType getChecked(function_ref< InFlightDiagnostic()> emitError, unsigned flags, Type storageType, Type expressedType, ArrayRef< double > scales, ArrayRef< int64_t > zeroPoints, int32_t quantizedDimension, int64_t storageTypeMin, int64_t storageTypeMax)
Gets an instance of the type with all specified parameters checked.
static UniformQuantizedPerAxisType get(unsigned flags, Type storageType, Type expressedType, ArrayRef< double > scales, ArrayRef< int64_t > zeroPoints, int32_t quantizedDimension, int64_t storageTypeMin, int64_t storageTypeMax)
Gets an instance of the type with all parameters specified but not checked.
int32_t getQuantizedDimension() const
Specifies the dimension of the Tensor's shape that the scales and zero_points correspond to.
ArrayRef< int64_t > getZeroPoints() const
Gets the storage values corresponding to the real value 0 in the affine equation.
ArrayRef< double > getScales() const
Gets the quantization scales.
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, unsigned flags, Type storageType, Type expressedType, ArrayRef< double > scales, ArrayRef< int64_t > zeroPoints, int32_t quantizedDimension, int64_t storageTypeMin, int64_t storageTypeMax)
Verifies construction invariants and issues errors/warnings.
Represents sub-channel (also known as blockwise quantization).
Definition QuantTypes.h:410
ArrayRef< int32_t > getQuantizedDimensions() const
Gets the quantized dimensions.
DenseElementsAttr getZeroPoints() const
Gets the quantization zero-points.
ArrayRef< int64_t > getBlockSizes() const
Gets the block sizes for the quantized dimensions.
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, unsigned flags, Type storageType, Type expressedType, DenseElementsAttr scales, DenseElementsAttr zeroPoints, ArrayRef< int32_t > quantizedDimensions, ArrayRef< int64_t > blockSizes, int64_t storageTypeMin, int64_t storageTypeMax)
Verifies construction invariants and issues errors/warnings.
const SmallVector< std::pair< int32_t, int64_t > > getBlockSizeInfo() const
Gets the block size information.
static UniformQuantizedSubChannelType getChecked(function_ref< InFlightDiagnostic()> emitError, unsigned flags, Type storageType, Type expressedType, DenseElementsAttr scales, DenseElementsAttr zeroPoints, ArrayRef< int32_t > quantizedDimensions, ArrayRef< int64_t > blockSizes, int64_t storageTypeMin, int64_t storageTypeMax)
Gets an instance of the type with all specified parameters checked.
static UniformQuantizedSubChannelType get(unsigned flags, Type storageType, Type expressedType, DenseElementsAttr scales, DenseElementsAttr zeroPoints, ArrayRef< int32_t > quantizedDimensions, ArrayRef< int64_t > blockSizes, int64_t storageTypeMin, int64_t storageTypeMax)
Gets an instance of the type with all parameters specified but not checked.
DenseElementsAttr getScales() const
Gets the quantization scales.
Represents a family of uniform, quantized types.
Definition QuantTypes.h:265
double getScale() const
Gets the scale term.
int64_t getZeroPoint() const
Gets the storage value corresponding to the real value 0 in the affine equation.
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, unsigned flags, Type storageType, Type expressedType, double scale, int64_t zeroPoint, int64_t storageTypeMin, int64_t storageTypeMax)
Verifies construction invariants and issues errors/warnings.
static UniformQuantizedType getChecked(function_ref< InFlightDiagnostic()> emitError, unsigned flags, Type storageType, Type expressedType, double scale, int64_t zeroPoint, int64_t storageTypeMin, int64_t storageTypeMax)
Gets an instance of the type with all specified parameters checked.
static UniformQuantizedType get(unsigned flags, Type storageType, Type expressedType, double scale, int64_t zeroPoint, int64_t storageTypeMin, int64_t storageTypeMax)
Gets an instance of the type with all parameters specified but not checked.
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::function_ref< Fn > function_ref
Definition LLVM.h:147