return false;
break;
case ')':
- if (nestedPunctuation.pop_back_val() != ')')
+ if (nestedPunctuation.pop_back_val() != '(')
return false;
break;
case '}':
- if (nestedPunctuation.pop_back_val() != '}')
+ if (nestedPunctuation.pop_back_val() != '{')
return false;
break;
default:
enum class TokenKind {
error,
eof,
- l_bracket,
- r_bracket,
l_brace,
r_brace,
- l_paren,
- r_paren,
+ l_angle,
+ r_angle,
colon,
comma,
alpha_ident,
return emitError(tokStart, "unexpected character");
- case '[':
- return formToken(TokenKind::l_bracket, tokStart);
- case ']':
- return formToken(TokenKind::r_bracket, tokStart);
+ case '<':
+ return formToken(TokenKind::l_angle, tokStart);
+ case '>':
+ return formToken(TokenKind::r_angle, tokStart);
case '{':
return formToken(TokenKind::l_brace, tokStart);
case '}':
return formToken(TokenKind::r_brace, tokStart);
- case '(':
- return formToken(TokenKind::l_paren, tokStart);
- case ')':
- return formToken(TokenKind::r_paren, tokStart);
case ':':
return formToken(TokenKind::colon, tokStart);
case ',':
/// Parses a UniformQuantizedType.
///
-/// uniform_type ::= `uniform` type_spec quant_param_spec
-///
-/// type_spec ::= `[` storage-spec `:` expressed-type (quant-dim)? `]`
-/// quant-dim ::= `:` integer-literal
-/// storage-spec ::= storage-type (`(` storage-range `)`)?
+/// uniform_type ::= uniform_per_layer
+/// | uniform_per_axis
+/// uniform_per_layer ::= `uniform<` storage-spec `,` scale-zero `>`
+/// uniform_per_axis ::= `uniform<` storage-spec axis-spec
+/// `,` scale-zero-list `>`
+/// storage-spec ::= storage-type (`<` storage-range `>`)?
/// storage-range ::= integer-literal `:` integer-literal
/// storage-type ::= (`i` | `u`) integer-literal
-/// expressed-type ::= (`f16` | `f32` | `f64` | `bf16`)
-///
-/// quant_param_spec ::= `{` scale-zero (`,` scale-zero )* `}`
+/// axis-spec ::= `:` integer-literal
/// scale-zero ::= float-literal `:` integer-literal
+/// scale-zero-list ::= `{` scale-zero (`,` scale-zero)* `}`
Type TypeParser::parseUniformType() {
IntegerType storageType;
FloatType expressedType;
SmallVector<int64_t, 1> zeroPoints;
// Type specification.
- if (!consumeIf(TokenKind::l_bracket)) {
+ if (!consumeIf(TokenKind::l_angle)) {
return (emitError("unrecognized token: " + curToken.spelling), nullptr);
}
isSigned, storageType.getWidth());
int64_t defaultIntegerMax = QuantizedType::getDefaultMaxinumForInteger(
isSigned, storageType.getWidth());
- if (consumeIf(TokenKind::l_paren)) {
+ if (consumeIf(TokenKind::l_angle)) {
// Explicit storage min and storage max.
if (curToken.kind != TokenKind::integer_literal) {
return (emitError("expected storage type minimum"), nullptr);
}
consumeToken(TokenKind::integer_literal);
- if (!consumeIf(TokenKind::r_paren)) {
+ if (!consumeIf(TokenKind::r_angle)) {
return (emitError("unrecognized token: " + curToken.spelling), nullptr);
}
} else {
isPerAxis = true;
}
- if (!consumeIf(TokenKind::r_bracket)) {
+ // Comma leading into range_spec.
+ if (!consumeIf(TokenKind::comma)) {
return (emitError("unrecognized token: " + curToken.spelling), nullptr);
}
// Parameter specification.
- if (!consumeIf(TokenKind::l_brace)) {
- return (emitError("unrecognized token: " + curToken.spelling), nullptr);
+ // For per-axis, ranges are in a {} delimitted list.
+ if (isPerAxis) {
+ if (!consumeIf(TokenKind::l_brace)) {
+ return (emitError("unrecognized token: " + curToken.spelling), nullptr);
+ }
}
// Parse scales/zeroPoints.
if (parseQuantParams(scales.back(), zeroPoints.back())) {
return nullptr;
}
- } while (consumeIf(TokenKind::comma));
+ } while (isPerAxis && consumeIf(TokenKind::comma));
- if (!consumeIf(TokenKind::r_brace)) {
+ if (isPerAxis) {
+ if (!consumeIf(TokenKind::r_brace)) {
+ return (emitError("unrecognized token: " + curToken.spelling), nullptr);
+ }
+ }
+
+ if (!consumeIf(TokenKind::r_angle)) {
return (emitError("unrecognized token: " + curToken.spelling), nullptr);
}
QuantizedType::getDefaultMaxinumForInteger(isSigned, storageWidth);
if (defaultIntegerMin != type.getStorageTypeMin() ||
defaultIntegerMax != type.getStorageTypeMax()) {
- out << "(" << type.getStorageTypeMin() << ":" << type.getStorageTypeMax()
- << ")";
+ out << "<" << type.getStorageTypeMin() << ":" << type.getStorageTypeMax()
+ << ">";
}
}
/// Helper that prints a UniformQuantizedType.
static void printUniformQuantizedType(UniformQuantizedType type,
raw_ostream &out) {
- out << "uniform[";
+ out << "uniform<";
printStorageType(type, out);
out << ":";
printExpressedType(type, out);
- out << "]";
+ out << ", ";
// scheme specific parameters
- out << "{";
printQuantParams(type.getScale(), type.getZeroPoint(), out);
- out << "}";
+ out << ">";
}
/// Helper that prints a UniformQuantizedPerAxisType.
static void printUniformQuantizedPerAxisType(UniformQuantizedPerAxisType type,
raw_ostream &out) {
- out << "uniform[";
+ out << "uniform<";
printStorageType(type, out);
out << ":";
printExpressedType(type, out);
out << ":";
out << type.getQuantizedDimension();
- out << "]";
+ out << ", ";
// scheme specific parameters
ArrayRef<double> scales = type.getScales();
out << ",";
}
}
- out << "}";
+ out << "}>";
}
/// Print a type registered to this dialect.
// -----
// Verify lowering when operands and result have the same fixedpoint scale.
// CHECK-LABEL: real_addew_fixedpoint_isomorphic
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
func @real_addew_fixedpoint_isomorphic(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
- // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
- // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
+ // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
+ // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
// CHECK-NEXT: %2 = "fxpmath.convertis"(%0) : (tensor<4xi8>) -> tensor<4xi16>
// CHECK-NEXT: %3 = "fxpmath.convertis"(%1) : (tensor<4xi8>) -> tensor<4xi16>
// CHECK-NEXT: %4 = addi %2, %3 : tensor<4xi16>
// CHECK-NEXT: %5 = "fxpmath.clampis"(%4) {clamp_max: 127 : i16, clamp_min: -128 : i16} : (tensor<4xi16>) -> tensor<4xi16>
// CHECK-NEXT: %6 = "fxpmath.convertis"(%5) : (tensor<4xi16>) -> tensor<4xi8>
- // CHECK-NEXT: %7 = "quant.scast"(%6) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>
- // CHECK-NEXT: return %7 : tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>
+ // CHECK-NEXT: %7 = "quant.scast"(%6) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>
+ // CHECK-NEXT: return %7 : tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>
%0 = "fxpmath.real_add_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
return %0 : !type_result
}
// Verify lowering when operands and result have the same fixedpoint scale
// and non-zero zero points.
// CHECK-LABEL: real_addew_affine_isomorphic
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-5}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-5}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-5}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-5>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-5>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-5>>
func @real_addew_affine_isomorphic(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
// CHECK-NEXT: %cst = constant splat<tensor<4xi16>, 5> : tensor<4xi16>
- // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02:-5}">>) -> tensor<4xi8>
- // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02:-5}">>) -> tensor<4xi8>
+ // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02:-5>>) -> tensor<4xi8>
+ // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02:-5>>) -> tensor<4xi8>
// CHECK-NEXT: %2 = "fxpmath.convertis"(%0) : (tensor<4xi8>) -> tensor<4xi16>
// CHECK-NEXT: %3 = "fxpmath.convertis"(%1) : (tensor<4xi8>) -> tensor<4xi16>
// CHECK-NEXT: %4 = addi %2, %3 : tensor<4xi16>
// CHECK-NEXT: %5 = addi %4, %cst : tensor<4xi16>
// CHECK-NEXT: %6 = "fxpmath.clampis"(%5) {clamp_max: 127 : i16, clamp_min: -128 : i16} : (tensor<4xi16>) -> tensor<4xi16>
// CHECK-NEXT: %7 = "fxpmath.convertis"(%6) : (tensor<4xi16>) -> tensor<4xi8>
- // CHECK-NEXT: %8 = "quant.scast"(%7) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{6.250000e-02:-5}">>
- // CHECK-NEXT: return %8 : tensor<4x!quant<"uniform[i8:f32]{6.250000e-02:-5}">>
+ // CHECK-NEXT: %8 = "quant.scast"(%7) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 6.250000e-02:-5>>
+ // CHECK-NEXT: return %8 : tensor<4x!quant.uniform<i8:f32, 6.250000e-02:-5>>
%0 = "fxpmath.real_add_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
return %0 : !type_result
}
// The RHS quant parameters proscribe a range of [-8..8) so an explicit clamp
// of [-4..4] should result in an integral clamp range of [-64..64].
// CHECK-LABEL: real_addew_fixedpoint_clamp
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
func @real_addew_fixedpoint_clamp(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
- // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
- // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
+ // CHECK-NEXT: %0 = "quant.scast"(%arg0) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
+ // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
// CHECK-NEXT: %2 = "fxpmath.convertis"(%0) : (tensor<4xi8>) -> tensor<4xi16>
// CHECK-NEXT: %3 = "fxpmath.convertis"(%1) : (tensor<4xi8>) -> tensor<4xi16>
// CHECK-NEXT: %4 = addi %2, %3 : tensor<4xi16>
// CHECK-NEXT: %5 = "fxpmath.clampis"(%4) {clamp_max: 64 : i16, clamp_min: -64 : i16} : (tensor<4xi16>) -> tensor<4xi16>
// CHECK-NEXT: %6 = "fxpmath.convertis"(%5) : (tensor<4xi16>) -> tensor<4xi8>
- // CHECK-NEXT: %7 = "quant.scast"(%6) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>
- // CHECK-NEXT: return %7 : tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>
+ // CHECK-NEXT: %7 = "quant.scast"(%6) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>
+ // CHECK-NEXT: return %7 : tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>
%0 = "fxpmath.real_add_ew"(%arg0, %arg1) { clamp_min:-4.0, clamp_max:4.0 }
: (!type_lhs, !type_rhs) -> (!type_result)
return %0 : !type_result
// CHECK-LABEL: real_addew_unquantized_lhs
// Verifies that leaves as-is for unquantized lhs.
!type_lhs = type tensor<4xf32>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
func @real_addew_unquantized_lhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
// CHECK: %0 = "fxpmath.real_add_ew"(%arg0, %arg1)
%0 = "fxpmath.real_add_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
// -----
// CHECK-LABEL: real_addew_unquantized_rhs
// Verifies that leaves as-is for unquantized rhs.
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
!type_rhs = type tensor<4xf32>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
func @real_addew_unquantized_rhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
// CHECK: %0 = "fxpmath.real_add_ew"(%arg0, %arg1)
%0 = "fxpmath.real_add_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
// -----
// CHECK-LABEL: real_addew_unquantized_result
// Verifies that leaves as-is for unquantized result.
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
!type_result = type tensor<4xf32>
func @real_addew_unquantized_result(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
// CHECK: %0 = "fxpmath.real_add_ew"(%arg0, %arg1)
// -----
// Verify lowering when operands and result have the same fixedpoint scale.
// CHECK-LABEL: real_mulew_fixedpoint
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{3.875e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{1.065e-1}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 3.875e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 1.065e-1>>
func @real_mulew_fixedpoint(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
- // CHECK: %0 = "quant.scast"(%arg0) : (tensor<4x!quant<"uniform[i8:f32]{6.250000e-02}">>) -> tensor<4xi8>
- // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant<"uniform[i8:f32]{3.875000e-02}">>) -> tensor<4xi8>
+ // CHECK: %0 = "quant.scast"(%arg0) : (tensor<4x!quant.uniform<i8:f32, 6.250000e-02>>) -> tensor<4xi8>
+ // CHECK-NEXT: %1 = "quant.scast"(%arg1) : (tensor<4x!quant.uniform<i8:f32, 3.875000e-02>>) -> tensor<4xi8>
// CHECK-NEXT: %2 = "fxpmath.convertis"(%0) : (tensor<4xi8>) -> tensor<4xi32>
// CHECK-NEXT: %3 = "fxpmath.convertis"(%1) : (tensor<4xi8>) -> tensor<4xi32>
// CHECK-NEXT: %4 = muli %2, %3 : tensor<4xi32>
// CHECK-NEXT: %6 = "fxpmath.rounding_divide_by_potis"(%5) {exponent: 5 : i32} : (tensor<4xi32>) -> tensor<4xi32>
// CHECK-NEXT: %7 = "fxpmath.clampis"(%6) {clamp_max: 127 : i32, clamp_min: -128 : i32} : (tensor<4xi32>) -> tensor<4xi32>
// CHECK-NEXT: %8 = "fxpmath.convertis"(%7) : (tensor<4xi32>) -> tensor<4xi8>
- // CHECK-NEXT: %9 = "quant.scast"(%8) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{1.065000e-01}">>
- // CHECK-NEXT: return %9 : tensor<4x!quant<"uniform[i8:f32]{1.065000e-01}">>
+ // CHECK-NEXT: %9 = "quant.scast"(%8) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 1.065000e-01>>
+ // CHECK-NEXT: return %9 : tensor<4x!quant.uniform<i8:f32, 1.065000e-01>>
%0 = "fxpmath.real_mul_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
return %0 : !type_result
}
// Verify lowering when operands and result have the same fixedpoint scale
// and non-zero zero points.
// CHECK-LABEL: real_mulew_affine_clamp
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-3}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-5}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2:-9}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-3>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-5>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2:-9>>
func @real_mulew_affine_clamp(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
// Just verify that the affine adds/constants and clamps are present.
// CHECK: %cst = constant splat<tensor<4xi32>, 3> : tensor<4xi32>
// CHECK-LABEL: real_mulew_unquantized_lhs
// Verifies that leaves as-is for unquantized lhs.
!type_lhs = type tensor<4xf32>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
func @real_mulew_unquantized_lhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
// CHECK: %0 = "fxpmath.real_mul_ew"(%arg0, %arg1)
%0 = "fxpmath.real_mul_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
// -----
// CHECK-LABEL: real_mulew_unquantized_rhs
// Verifies that leaves as-is for unquantized rhs.
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
!type_rhs = type tensor<4xf32>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
func @real_mulew_unquantized_rhs(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
// CHECK: %0 = "fxpmath.real_mul_ew"(%arg0, %arg1)
%0 = "fxpmath.real_mul_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
// -----
// CHECK-LABEL: real_mulew_unquantized_result
// Verifies that leaves as-is for unquantized result.
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
!type_result = type tensor<4xf32>
func @real_mulew_unquantized_result(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
// CHECK: %0 = "fxpmath.real_mul_ew"(%arg0, %arg1)
// Note that the multiplier = lhs_scale * rhs_scale / result_scale
// = 22.740610328638496
// CHECK-LABEL: real_mulew_multiplier_gt_1
-!type_lhs = type tensor<4x!quant<"uniform[i8:f32]{6.25e-2}">>
-!type_rhs = type tensor<4x!quant<"uniform[i8:f32]{3.875e-2}">>
-!type_result = type tensor<4x!quant<"uniform[i8:f32]{1.065e-4}">>
+!type_lhs = type tensor<4x!quant.uniform<i8:f32, 6.25e-2>>
+!type_rhs = type tensor<4x!quant.uniform<i8:f32, 3.875e-2>>
+!type_result = type tensor<4x!quant.uniform<i8:f32, 1.065e-4>>
func @real_mulew_multiplier_gt_1(%arg0 : !type_lhs, %arg1: !type_rhs) -> !type_result {
// expected-warning@+1 {{unimplemented: cannot multiply with multipler > 1.0}}
%0 = "fxpmath.real_mul_ew"(%arg0, %arg1) : (!type_lhs, !type_rhs) -> (!type_result)
// CHECK-NEXT: constant splat<tensor<4xi8>, 10>
// CHECK-NEXT: return
%cst = constant splat<tensor<4xi8>, 5> : tensor<4xi8>
- %1 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
- %2 = "quant.scast"(%1) : (tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>) -> tensor<4xi8>
+ %1 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
+ %2 = "quant.scast"(%1) : (tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>) -> tensor<4xi8>
%3 = addi %2, %2 : tensor<4xi8>
return %3 : tensor<4xi8>
}
// -----
// CHECK-LABEL: non_redundant_scast
-func @non_redundant_scast() -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">> {
+func @non_redundant_scast() -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>> {
// CHECK-NEXT: constant splat<tensor<4xi8>, 5>
// CHECK-NEXT: scast
// CHECK-NEXT: return
%cst = constant splat<tensor<4xi8>, 5> : tensor<4xi8>
- %1 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
- return %1 : tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
+ %1 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
+ return %1 : tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
}
// CHECK-LABEL: constant_splat_tensor_u8_affine
func @constant_splat_tensor_u8_affine() -> tensor<4xf32> {
// CHECK: %cst = constant splat<tensor<4xi8>, -64> : tensor<4xi8>
- // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
+ // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
%cst = constant splat<tensor<4xf32>, 0.5> : tensor<4xf32>
- %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
- %2 = "quant.dcast"(%1) : (tensor<4x!quant<"uniform[u8:f32]{7.812500e-03:128}">>) -> (tensor<4xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>
+ %2 = "quant.dcast"(%1) : (tensor<4x!quant.uniform<u8:f32, 7.812500e-03:128>>) -> (tensor<4xf32>)
return %2 : tensor<4xf32>
}
// CHECK-LABEL: constant_splat_tensor_i8_affine
func @constant_splat_tensor_i8_affine() -> tensor<4xf32> {
// CHECK: %cst = constant splat<tensor<4xi8>, 63> : tensor<4xi8>
- // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03:-1}">>
+ // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03:-1>>
%cst = constant splat<tensor<4xf32>, 0.5> : tensor<4xf32>
- %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03:-1}">>
- %2 = "quant.dcast"(%1) : (tensor<4x!quant<"uniform[i8:f32]{7.812500e-03:-1}">>) -> (tensor<4xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03:-1>>
+ %2 = "quant.dcast"(%1) : (tensor<4x!quant.uniform<i8:f32, 7.812500e-03:-1>>) -> (tensor<4xf32>)
return %2 : tensor<4xf32>
}
// CHECK-LABEL: const_splat_tensor_i8_fixedpoint
func @const_splat_tensor_i8_fixedpoint() -> tensor<4xf32> {
// CHECK: %cst = constant splat<tensor<4xi8>, 64> : tensor<4xi8>
- // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>
+ // CHECK-NEXT: %0 = "quant.scast"(%cst) : (tensor<4xi8>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>
%cst = constant splat<tensor<4xf32>, 0.5> : tensor<4xf32>
- %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>
- %2 = "quant.dcast"(%1) : (tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>) -> (tensor<4xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>
+ %2 = "quant.dcast"(%1) : (tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>) -> (tensor<4xf32>)
return %2 : tensor<4xf32>
}
func @const_splat_tensor_i8_fixedpoint_neg() -> tensor<4xf32> {
// CHECK: %cst = constant splat<tensor<4xi8>, -64> : tensor<4xi8>
%cst = constant splat<tensor<4xf32>, -0.5> : tensor<4xf32>
- %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>
- %2 = "quant.dcast"(%1) : (tensor<4x!quant<"uniform[i8:f32]{7.812500e-03}">>) -> (tensor<4xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<4xf32>) -> tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>
+ %2 = "quant.dcast"(%1) : (tensor<4x!quant.uniform<i8:f32, 7.812500e-03>>) -> (tensor<4xf32>)
return %2 : tensor<4xf32>
}
func @const_dense_tensor_i8_fixedpoint() -> tensor<7xf32> {
// CHECK: %cst = constant dense<tensor<7xi8>, [-128, -128, -64, 0, 64, 127, 127]> : tensor<7xi8>
%cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
- %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[i8:f32]{7.812500e-03}">>
- %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[i8:f32]{7.812500e-03}">>) -> (tensor<7xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i8:f32, 7.812500e-03>>
+ %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i8:f32, 7.812500e-03>>) -> (tensor<7xf32>)
return %2 : tensor<7xf32>
}
%cst = constant sparse<tensor<7x2xf32>,
[[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6]],
[-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7x2xf32>
- %1 = "quant.qcast"(%cst) : (tensor<7x2xf32>) -> tensor<7x2x!quant<"uniform[i8:f32]{7.812500e-03}">>
- %2 = "quant.dcast"(%1) : (tensor<7x2x!quant<"uniform[i8:f32]{7.812500e-03}">>) -> (tensor<7x2xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<7x2xf32>) -> tensor<7x2x!quant.uniform<i8:f32, 7.812500e-03>>
+ %2 = "quant.dcast"(%1) : (tensor<7x2x!quant.uniform<i8:f32, 7.812500e-03>>) -> (tensor<7x2xf32>)
return %2 : tensor<7x2xf32>
}
// CHECK-LABEL: const_primitive_float_i8_fixedpoint
func @const_primitive_float_i8_fixedpoint() -> f32 {
// CHECK: %c64_i8 = constant 64 : i8
- // CHECK-NEXT: %0 = "quant.scast"(%c64_i8) : (i8) -> !quant<"uniform[i8:f32]{7.812500e-03}">
+ // CHECK-NEXT: %0 = "quant.scast"(%c64_i8) : (i8) -> !quant.uniform<i8:f32, 7.812500e-03>
%cst = constant 0.5 : f32
- %1 = "quant.qcast"(%cst) : (f32) -> !quant<"uniform[i8:f32]{7.812500e-03}">
- %2 = "quant.dcast"(%1) : (!quant<"uniform[i8:f32]{7.812500e-03}">) -> (f32)
+ %1 = "quant.qcast"(%cst) : (f32) -> !quant.uniform<i8:f32, 7.812500e-03>
+ %2 = "quant.dcast"(%1) : (!quant.uniform<i8:f32, 7.812500e-03>) -> (f32)
return %2 : f32
}
// NOTE: Unsigned quantities printed by MLIR as signed.
// CHECK: %cst = constant dense<tensor<7xi4>, [0, 0, 4, -8, -4, -1, -1]> : tensor<7xi4>
%cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
- %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[u4:f32]{1.250000e-01:8}">>
- %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[u4:f32]{1.250000e-01:8}">>) -> (tensor<7xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<u4:f32, 1.250000e-01:8>>
+ %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<u4:f32, 1.250000e-01:8>>) -> (tensor<7xf32>)
return %2 : tensor<7xf32>
}
// NOTE: Unsigned quantities printed by MLIR as signed.
// CHECK: %cst = constant dense<tensor<7xi4>, [-8, -8, -5, -1, 3, 7, 7]> : tensor<7xi4>
%cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
- %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[i4:f32]{1.250000e-01:-1}">>
- %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[i4:f32]{1.250000e-01:-1}">>) -> (tensor<7xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i4:f32, 1.250000e-01:-1>>
+ %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i4:f32, 1.250000e-01:-1>>) -> (tensor<7xf32>)
return %2 : tensor<7xf32>
}
func @const_dense_tensor_i4_fixedpoint() -> tensor<7xf32> {
// CHECK: %cst = constant dense<tensor<7xi4>, [-8, -8, -4, 0, 4, 7, 7]> : tensor<7xi4>
%cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
- %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[i4:f32]{1.250000e-01}">>
- %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[i4:f32]{1.250000e-01}">>) -> (tensor<7xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i4:f32, 1.250000e-01>>
+ %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i4:f32, 1.250000e-01>>) -> (tensor<7xf32>)
return %2 : tensor<7xf32>
}
func @const_custom_storage_range_i8_fixedpoint() -> tensor<7xf32> {
// CHECK: %cst = constant dense<tensor<7xi8>, [-100, -100, -64, 0, 64, 100, 100]> : tensor<7xi8>
%cst = constant dense<tensor<7xf32>, [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0]> : tensor<7xf32>
- %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant<"uniform[i8(-100:100):f32]{7.812500e-03}">>
- %2 = "quant.dcast"(%1) : (tensor<7x!quant<"uniform[i8(-100:100):f32]{7.812500e-03}">>) -> (tensor<7xf32>)
+ %1 = "quant.qcast"(%cst) : (tensor<7xf32>) -> tensor<7x!quant.uniform<i8<-100:100>:f32, 7.812500e-03>>
+ %2 = "quant.dcast"(%1) : (tensor<7x!quant.uniform<i8<-100:100>:f32, 7.812500e-03>>) -> (tensor<7xf32>)
return %2 : tensor<7xf32>
}
func @fakeQuantArgs_Quint8_0_1(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
^bb0(%arg0: tensor<8x4x3xf32>):
// CHECK: %0 = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>)
- // CHECK-SAME: -> tensor<8x4x3x!quant<"uniform[u8:f32]{0.0039215686274509803}">>
- // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant<"uniform[u8:f32]{0.0039215686274509803}">>)
+ // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<u8:f32, 0.0039215686274509803>>
+ // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant.uniform<u8:f32, 0.0039215686274509803>>)
// CHECK-SAME: -> tensor<8x4x3xf32>
%0 = "quant.const_fake_quant"(%arg0) {
min: 0.0 : f32, max: 1.0 : f32, num_bits: 8
func @fakeQuantArgs_Quint8_NarrowRange(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
^bb0(%arg0: tensor<8x4x3xf32>):
// CHECK: %0 = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>)
- // CHECK-SAME: -> tensor<8x4x3x!quant<"uniform[u8(1:255):f32]{0.003937007874015748:1}">>
- // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant<"uniform[u8(1:255):f32]{0.003937007874015748:1}">>)
+ // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<u8<1:255>:f32, 0.003937007874015748:1>>
+ // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant.uniform<u8<1:255>:f32, 0.003937007874015748:1>>)
// CHECK-SAME: -> tensor<8x4x3xf32>
%0 = "quant.const_fake_quant"(%arg0) {
min: 0.0 : f32, max: 1.0 : f32, num_bits: 8, narrow_range: true
func @fakeQuantArgs_Quint8_SymmetricRange(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
^bb0(%arg0: tensor<8x4x3xf32>):
// CHECK: %0 = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>)
- // CHECK-SAME: -> tensor<8x4x3x!quant<"uniform[u8:f32]{7.812500e-03:128}">>
- // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant<"uniform[u8:f32]{7.812500e-03:128}">>)
+ // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<u8:f32, 7.812500e-03:128>>
+ // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant.uniform<u8:f32, 7.812500e-03:128>>)
// CHECK-SAME: -> tensor<8x4x3xf32>
%0 = "quant.const_fake_quant"(%arg0) {
min: -1.0 : f32, max: 0.9921875 : f32, num_bits: 8, narrow_range: false
func @fakeQuantArgs_Qint16_Symmetric(tensor<8x4x3xf32>) -> tensor<8x4x3xf32> {
^bb0(%arg0: tensor<8x4x3xf32>):
// CHECK: %0 = "quant.qcast"(%arg0) : (tensor<8x4x3xf32>)
- // CHECK-SAME: -> tensor<8x4x3x!quant<"uniform[i16:f32]{3.0517578125E-5}">>
- // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant<"uniform[i16:f32]{3.0517578125E-5}">>)
+ // CHECK-SAME: -> tensor<8x4x3x!quant.uniform<i16:f32, 3.0517578125E-5>>
+ // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<8x4x3x!quant.uniform<i16:f32, 3.0517578125E-5>>)
// CHECK-SAME: -> tensor<8x4x3xf32>
%0 = "quant.const_fake_quant"(%arg0) {
min: -1.0 : f32, max: 0.999969482 : f32, num_bits: 16
func @fakeQuantArgs_UnrankedTensor(tensor<f32>) -> tensor<f32> {
^bb0(%arg0: tensor<f32>):
// CHECK: %0 = "quant.qcast"(%arg0) : (tensor<f32>)
- // CHECK-SAME: -> tensor<!quant<"uniform[u8:f32]{0.0039215686274509803}">>
- // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<!quant<"uniform[u8:f32]{0.0039215686274509803}">>)
+ // CHECK-SAME: -> tensor<!quant.uniform<u8:f32, 0.0039215686274509803>>
+ // CHECK-NEXT: %1 = "quant.dcast"(%0) : (tensor<!quant.uniform<u8:f32, 0.0039215686274509803>>)
// CHECK-SAME: -> tensor<f32>
%0 = "quant.const_fake_quant"(%arg0) {
min: 0.0 : f32, max: 1.0 : f32, num_bits: 8
// -----
// Invalid type.
// expected-error@+1 {{unknown quantized type foobar}}
-!qalias = type !quant<"foobar">
+!qalias = type !quant.foobar
// -----
// Unrecognized token: illegal token
-// expected-error@+1 {{unrecognized token: %}}
-!qalias = type !quant<"%%">
+// expected-error@+1 {{unrecognized token: _}}
+!qalias = type !quant.__
// -----
// Unrecognized token: trailing
// expected-error@+1 {{unrecognized token: 23}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.99872:127} 23">
-
-// -----
-// Unrecognized token: type open
-// expected-error@+1 {{unrecognized token: (}}
-!qalias = type !quant<"uniform(i8(-4:3):f32){0.99872:127}">
+!qalias = type !quant.uniform<i8<-4:3>:f32, 0.99872:127 23>
// -----
// Unrecognized token: missing storage type maximum
-// expected-error@+1 {{expected storage type maximum}}
-!qalias = type !quant<"uniform[i8(16:f32]{0.99872:127}">
+// expected-error@+1 {{unrecognized token: >}}
+!qalias = type !quant.uniform<i8<16>:f32, 0.99872:127>
// -----
-// Unrecognized token: missing closing paren
+// Unrecognized token: missing closing angle bracket
// expected-error@+1 {{unrecognized token: :}}
-!qalias = type !quant<"uniform[i8(-4:3:f32]{0.99872:127}">
+!qalias = type !quant<"uniform<i8<-4:3:f32, 0.99872:127>">
// -----
// Unrecognized token: missing type colon
// expected-error@+1 {{unrecognized token: f}}
-!qalias = type !quant<"uniform[i8(-4:3)f32]{0.99872:127}">
-
-// -----
-// Unrecognized token: missing closing bracket
-// expected-error@+1 {{unrecognized token: {}}
-!qalias = type !quant<"uniform[i8(-4:3):f32{0.99872:127}">
+!qalias = type !quant.uniform<i8<-4:3>f32, 0.99872:127>
// -----
-// Unrecognized token: wrong opening brace
-// expected-error@+1 {{unrecognized token: (}}
-!qalias = type !quant<"uniform[i8(-4:3):f32](0.99872:127}">
+// Unrecognized token: missing comma
+// expected-error@+1 {{unrecognized token: 0.99872}}
+!qalias = type !quant.uniform<i8<-4:3>:f32 0.99872:127>
// -----
// Unrecognized storage type: illegal prefix
// expected-error@+1 {{illegal storage type prefix: int}}
-!qalias = type !quant<"uniform[int8(-4:3):f32]{0.99872:127}">
+!qalias = type !quant.uniform<int8<-4:3>:f32, 0.99872:127>
// -----
// Unrecognized storage type: no width
// expected-error@+1 {{expected storage type width}}
-!qalias = type !quant<"uniform[i(-4:3):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i<-4:3>:f32, 0.99872:127>
// -----
// Unrecognized storage type: storage size > 32
// expected-error@+1 {{illegal storage type size: 33}}
-!qalias = type !quant<"uniform[i33:f32]{0.99872:127}">
+!qalias = type !quant.uniform<i33:f32, 0.99872:127>
// -----
// Unrecognized storage type: storage size < 0
// expected-error@+1 {{illegal storage type size: -1}}
-!qalias = type !quant<"uniform[i-1(-4:3):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i-1<-4:3>:f32, 0.99872:127>
// -----
// Unrecognized storage type: storage size == 0
// expected-error@+1 {{illegal storage type size: 0}}
-!qalias = type !quant<"uniform[i0(-4:3):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i0<-4:3>:f32, 0.99872:127>
// -----
// Illegal storage min/max: max - min < 0
// expected-error@+1 {{illegal storage min and storage max: (2:1)}}
-!qalias = type !quant<"uniform[i8(2:1):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i8<2:1>:f32, 0.99872:127>
// -----
// Illegal storage min/max: max - min == 0
// expected-error@+1 {{illegal storage min and storage max: (1:1)}}
-!qalias = type !quant<"uniform[i8(1:1):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i8<1:1>:f32, 0.99872:127>
// -----
// Illegal storage min/max: max > defaultMax
// expected-error@+1 {{illegal storage type maximum: 9}}
-!qalias = type !quant<"uniform[i4(-1:9):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i4<-1:9>:f32, 0.99872:127>
// -----
// Illegal storage min/max: min < defaultMin
// expected-error@+1 {{illegal storage type minimum: -9}}
-!qalias = type !quant<"uniform[i4(-9:1):f32]{0.99872:127}">
+!qalias = type !quant.uniform<i4<-9:1>:f32, 0.99872:127>
// -----
// Illegal uniform params: invalid scale
// expected-error@+1 {{expected valid uniform scale. got: abc}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{abc:127}">
+!qalias = type !quant.uniform<i8<-4:3>:f32, abc:127>
// -----
// Illegal uniform params: invalid zero point separator
// expected-error@+1 {{unrecognized token: abc}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.1abc}">
+!qalias = type !quant.uniform<i8<-4:3>:f32, 0.1abc>
// -----
// Illegal uniform params: missing zero point
-// expected-error@+1 {{expected integer uniform zero point. got: }}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.1:}">
+// expected-error@+1 {{expected integer uniform zero point. got: >}}
+!qalias = type !quant.uniform<i8<-4:3>:f32, 0.1:>
// -----
// Illegal uniform params: invalid zero point
// expected-error@+1 {{expected integer uniform zero point. got: abc}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.1:abc}">
-
-// -----
-// Illegal uniform params: missing closing brace
-// expected-error@+1 {{unrecognized token: )}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{0.1:0)">
+!qalias = type !quant.uniform<i8<-4:3>:f32, 0.1:abc>
// -----
// Illegal expressed type: f33
// expected-error@+1 {{unrecognized expressed type: f33}}
-!qalias = type !quant<"uniform[i8(-4:3):f33]{0.99872:127}">
+!qalias = type !quant.uniform<i8<-4:3>:f33, 0.99872:127>
// -----
// Illegal scale: negative
// expected-error@+1 {{illegal scale: -1.000000}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{-1.0:127}">
+!qalias = type !quant.uniform<i8<-4:3>:f32, -1.0:127>
// -----
// Illegal uniform params: missing quantized dimension
// expected-error@+1 {{expected quantized dimension}}
-!qalias = type !quant<"uniform[i8(-4:3):f32:]{2.000000e+02:-19.987200e-01:1}">
+!qalias = type !quant.uniform<i8<-4:3>:f32:, {2.000000e+02:-19.987200e-01:1}>
// -----
// Illegal uniform params: unspecified quantized dimension, when multiple scales
// provided.
-// expected-error@+1 {{multiple scales/zeroPoints provided, but quantizedDimension wasn't specified}}
-!qalias = type !quant<"uniform[i8(-4:3):f32]{2.000000e+02,-19.987200e-01:1}">
+// expected-error@+1 {{expected valid uniform scale. got: {}}
+!qalias = type !quant.uniform<i8<-4:3>:f32, {2.000000e+02,-19.987200e-01:1}>
// -----
// All per-layer params specified:
// [signed] storageType, storageTypeMin, storageTypeMax, expressedType, scale, zeroPoint
-// CHECK: !quant<"uniform[i8(-8:7):f32]{9.987200e-01:127}">
-!qalias = type !quant<"uniform[i8(-8:7):f32]{0.99872:127}">
+// CHECK: !quant.uniform<i8<-8:7>:f32, 9.987200e-01:127>
+!qalias = type !quant.uniform<i8<-8:7>:f32, 0.99872:127>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Trailing whitespace.
-// CHECK: !quant<"uniform[i8(-8:7):f32]{9.987200e-01:127}">
-!qalias = type !quant<"uniform[i8(-8:7):f32]{0.99872:127} ">
+// CHECK: !quant.uniform<i8<-8:7>:f32, 9.987200e-01:127>
+!qalias = type !quant.uniform<i8<-8:7>:f32, 0.99872:127 >
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Required per-layer params specified:
// [unsigned] storageType, expressedType, scale
-// CHECK: !quant<"uniform[u8:f32]{9.987200e-01}">
-!qalias = type !quant<"uniform[u8:f32]{0.99872}">
+// CHECK: !quant.uniform<u8:f32, 9.987200e-01>
+!qalias = type !quant.uniform<u8:f32, 0.99872>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Exponential scale (-)
-// CHECK: !quant<"uniform[u8:f32]{2.000000e-02}">
-!qalias = type !quant<"uniform[u8:f32]{2.0e-2}">
+// CHECK: !quant.uniform<u8:f32, 2.000000e-02>
+!qalias = type !quant.uniform<u8:f32, 2.0e-2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Exponential scale (+)
-// CHECK: !quant<"uniform[u8:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:f32]{2.0e+2}">
+// CHECK: !quant.uniform<u8:f32, 2.000000e+02>
+!qalias = type !quant.uniform<u8:f32, 2.0e+2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Storage type: i16
-// CHECK: !quant<"uniform[i16:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[i16:f32]{2.0e+2}">
+// CHECK: !quant.uniform<i16:f32, 2.000000e+02>
+!qalias = type !quant.uniform<i16:f32, 2.0e+2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Storage type: u16
-// CHECK: !quant<"uniform[u16:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[u16:f32]{2.0e+2}">
+// CHECK: !quant.uniform<u16:f32, 2.000000e+02>
+!qalias = type !quant.uniform<u16:f32, 2.0e+2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Storage type: i32
-// CHECK: !quant<"uniform[i32:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[i32:f32]{2.0e+2}">
+// CHECK: !quant.uniform<i32:f32, 2.000000e+02>
+!qalias = type !quant.uniform<i32:f32, 2.0e+2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Storage type: u32
-// CHECK: !quant<"uniform[u32:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[u32:f32]{2.0e+2}">
+// CHECK: !quant.uniform<u32:f32, 2.000000e+02>
+!qalias = type !quant.uniform<u32:f32, 2.0e+2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Expressed type: f32
-// CHECK: !quant<"uniform[u8:f32]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:f32]{2.0e+2}">
+// CHECK: !quant.uniform<u8:f32, 2.000000e+02>
+!qalias = type !quant.uniform<u8:f32, 2.0e+2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Expressed type: f16
-// CHECK: !quant<"uniform[u8:f16]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:f16]{2.0e+2}">
+// CHECK: !quant.uniform<u8:f16, 2.000000e+02>
+!qalias = type !quant.uniform<u8:f16, 2.0e+2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Expressed type: f64
-// CHECK: !quant<"uniform[u8:f64]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:f64]{2.0e+2}">
+// CHECK: !quant.uniform<u8:f64, 2.000000e+02>
+!qalias = type !quant.uniform<u8:f64, 2.0e+2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Expressed type: bf16
-// CHECK: !quant<"uniform[u8:bf16]{2.000000e+02}">
-!qalias = type !quant<"uniform[u8:bf16]{2.0e+2}">
+// CHECK: !quant.uniform<u8:bf16, 2.000000e+02>
+!qalias = type !quant.uniform<u8:bf16, 2.0e+2>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Per-axis scales and zero points (affine)
-// CHECK: !quant<"uniform[u8:f32:1]{2.000000e+02:-120,9.987200e-01:127}">
-!qalias = type !quant<"uniform[u8:f32:1]{2.0e+2:-120,0.99872:127}">
+// CHECK: !quant.uniform<u8:f32:1, {2.000000e+02:-120,9.987200e-01:127}>
+!qalias = type !quant.uniform<u8:f32:1, {2.0e+2:-120,0.99872:127}>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Per-axis scales and no zero points (fixedpoint)
-// CHECK: !quant<"uniform[i8:f32:1]{2.000000e+02,9.987200e-01}">
-!qalias = type !quant<"uniform[i8:f32:1]{2.0e+2,0.99872}">
+// CHECK: !quant.uniform<i8:f32:1, {2.000000e+02,9.987200e-01}>
+!qalias = type !quant.uniform<i8:f32:1, {2.0e+2,0.99872}>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias
// -----
// Per-axis scales and zero points (mixed affine and fixedpoint)
-// CHECK: !quant<"uniform[i8:f32:1]{2.000000e+02,9.987200e-01:120}">
-!qalias = type !quant<"uniform[i8:f32:1]{2.0e+2,0.99872:120}">
+// CHECK: !quant.uniform<i8:f32:1, {2.000000e+02,9.987200e-01:120}>
+!qalias = type !quant.uniform<i8:f32:1, {2.0e+2,0.99872:120}>
func @parse() -> !qalias {
%0 = "foo"() : () -> !qalias
return %0 : !qalias