9#ifndef MLIR_DIALECT_QUANT_UTILS_UNIFORMSUPPORT_H_
10#define MLIR_DIALECT_QUANT_UTILS_UNIFORMSUPPORT_H_
18#include "llvm/ADT/APFloat.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/APSInt.h"
66 uniformType.getScale(),
68 static_cast<double>(uniformType.getStorageTypeMin()),
69 static_cast<double>(uniformType.getStorageTypeMax()),
70 uniformType.getStorageTypeIntegralWidth(), uniformType.isSigned()) {
71 assert(isa<FloatType>(uniformType.getExpressedType()));
72 assert(uniformType.getStorageType().isSignlessInteger());
76 double clampMin,
double clampMax,
77 uint32_t storageBitWidth,
bool isSigned)
78 : scale(scale), zeroPoint(zeroPoint), clampMin(clampMin),
79 clampMax(clampMax), scaleDouble(scale), zeroPointDouble(zeroPoint),
80 clampMinDouble(clampMin), clampMaxDouble(clampMax),
81 storageBitWidth(storageBitWidth), isSigned(isSigned),
82 roundMode(APFloat::rmNearestTiesToAway) {}
85 const APFloat &clampMin,
86 const APFloat &clampMax,
87 uint32_t storageBitWidth,
bool isSigned)
88 : scale(scale), zeroPoint(zeroPoint), clampMin(clampMin),
89 clampMax(clampMax), scaleDouble(scale), zeroPointDouble(zeroPoint),
90 clampMinDouble(clampMin.convertToDouble()),
91 clampMaxDouble(clampMax.convertToDouble()),
92 storageBitWidth(storageBitWidth), isSigned(isSigned),
93 roundMode(APFloat::rmNearestTiesToAway) {}
100 if (&expressedValue.getSemantics() == &APFloat::IEEEsingle() &&
101 storageBitWidth == 8 &&
102 roundMode == llvm::APFloatBase::rmNearestTiesToAway) {
103 return quantizeF32ToInt8(expressedValue);
107 expressedValue.convert(scale.getSemantics(), roundMode, &lossy);
110 APFloat scaled = (expressedValue / scale);
111 scaled.roundToIntegral(roundMode);
112 scaled.add(zeroPoint, roundMode);
113 APFloat fixedpoint = llvm::minimum(scaled, clampMax);
114 fixedpoint = llvm::maximum(fixedpoint, clampMin);
116 llvm::APSInt
result(storageBitWidth, !isSigned);
117 fixedpoint.convertToInteger(
result, roundMode, &lossy);
124 return isSigned ? qValue.getSExtValue() : qValue.getZExtValue();
132 virtual APInt quantizeF32ToInt8(APFloat expressedValue)
const {
133 assert(&expressedValue.getSemantics() == &APFloat::IEEEsingle());
134 assert(storageBitWidth == 8);
135 assert(roundMode == llvm::APFloatBase::rmNearestTiesToAway);
137 const float realValue = expressedValue.convertToFloat();
139 const double scaled = realValue / scaleDouble + zeroPointDouble;
141 const double scaledRounded = std::round(scaled);
142 const double clamped =
143 std::min(std::max(scaledRounded, clampMinDouble), clampMaxDouble);
145 uint64_t signlessResult;
147 int64_t clampedInt =
static_cast<int8_t
>(clamped);
148 memcpy(&signlessResult, &clampedInt,
sizeof(clampedInt));
150 signlessResult =
static_cast<uint8_t
>(clamped);
152 return APInt(storageBitWidth, signlessResult);
159 const APFloat zeroPoint;
160 const APFloat clampMin;
161 const APFloat clampMax;
163 const double scaleDouble;
164 const double zeroPointDouble;
165 const double clampMinDouble;
166 const double clampMaxDouble;
168 const uint32_t storageBitWidth;
170 const llvm::APFloat::roundingMode roundMode;
181 : scales(uniformType.getScales()),
182 zeroPoints(uniformType.getZeroPoints()),
183 clampMin(static_cast<double>(uniformType.getStorageTypeMin())),
184 clampMax(static_cast<double>(uniformType.getStorageTypeMax())),
185 storageBitWidth(uniformType.getStorageTypeIntegralWidth()),
186 isSigned(uniformType.isSigned()),
187 quantizationDim(uniformType.getQuantizedDimension()) {
188 assert(isa<FloatType>(uniformType.getExpressedType()));
189 assert(uniformType.getStorageType().isSignlessInteger());
190 assert(scales.size() == zeroPoints.size());
206 storageBitWidth, isSigned);
212 const APFloat clampMin;
213 const APFloat clampMax;
214 const uint32_t storageBitWidth;
216 int32_t quantizationDim;
static FailureOr< int64_t > getZeroPoint(Value val, bool signExtend)
Attributes are known-constant values of operations.
An attribute that represents a reference to a dense vector or tensor object.
An attribute that represents a reference to a dense float vector or tensor object.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Base class for all quantized types known to this dialect.
Include the generated interface declarations.
Performs type conversion from an arbitrary input type to a type that is expressed by a QuantizedType.
static ExpressedToQuantizedConverter forInputType(Type inputType)
Creates a converter for the given input type.
const Type inputType
The input type that is being converted from.
Type convert(QuantizedType elementalType) const
Converts the inputType to be based on the given elemental type, returning the new type (or nullptr an...
const Type expressedType
Supported, elemental expressed type (i.e.