| // RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file | FileCheck %s |
| |
| // ----- |
| // All per-layer params specified: |
| // [signed] storageType, storageTypeMin, storageTypeMax, expressedType, scale, zeroPoint |
| // CHECK: !quant.uniform<i8<-8:7>:f32, 9.987200e-01:127> |
| !qalias = !quant.uniform<i8<-8:7>:f32, 0.99872:127> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Trailing whitespace. |
| // CHECK: !quant.uniform<i8<-8:7>:f32, 9.987200e-01:127> |
| !qalias = !quant.uniform<i8<-8:7>:f32, 0.99872:127 > |
| func.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 = !quant.uniform<u8:f32, 0.99872> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Exponential scale (-) |
| // CHECK: !quant.uniform<u8:f32, 2.000000e-02> |
| !qalias = !quant.uniform<u8:f32, 2.0e-2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Exponential scale (+) |
| // CHECK: !quant.uniform<u8:f32, 2.000000e+02> |
| !qalias = !quant.uniform<u8:f32, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: i16 |
| // CHECK: !quant.uniform<i16:f32, 2.000000e+02> |
| !qalias = !quant.uniform<i16:f32, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: u16 |
| // CHECK: !quant.uniform<u16:f32, 2.000000e+02> |
| !qalias = !quant.uniform<u16:f32, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: i32 |
| // CHECK: !quant.uniform<i32:f32, 2.000000e+02> |
| !qalias = !quant.uniform<i32:f32, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: u32 |
| // CHECK: !quant.uniform<u32:f32, 2.000000e+02> |
| !qalias = !quant.uniform<u32:f32, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Expressed type: f32 |
| // CHECK: !quant.uniform<u8:f32, 2.000000e+02> |
| !qalias = !quant.uniform<u8:f32, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Expressed type: f32 |
| // CHECK: !quant.uniform<u8:f32, 0x41646ABBA0000000:128> |
| !qalias = !quant.uniform<u8:f32, 0x41646ABBA0000000:128> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Expressed type: f16 |
| // CHECK: !quant.uniform<u8:f16, 2.000000e+02> |
| !qalias = !quant.uniform<u8:f16, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Expressed type: f64 |
| // CHECK: !quant.uniform<u8:f64, 2.000000e+02> |
| !qalias = !quant.uniform<u8:f64, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Expressed type: bf16 |
| // CHECK: !quant.uniform<u8:bf16, 2.000000e+02> |
| !qalias = !quant.uniform<u8:bf16, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: ui8 (explicit unsigned) |
| // CHECK: !quant.uniform<ui8:f32, 1.000000e+00> |
| !qalias = !quant.uniform<ui8:f32, 1.0> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: si8 (explicit signed) |
| // CHECK: !quant.uniform<si8:f32, 1.000000e+00> |
| !qalias = !quant.uniform<si8:f32, 1.0> |
| func.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 = !quant.uniform<u8:f32:1, {2.0e+2:-120,0.99872:127}> |
| func.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 = !quant.uniform<i8:f32:1, {2.0e+2,0.99872}> |
| func.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 = !quant.uniform<i8:f32:1, {2.0e+2,0.99872:120}> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Sub-channel scales and zero points (mixed affine and fixedpoint) |
| // CHECK: !quant.uniform<u8:f32:{0:1, 1:2}, {{\{}}{2.000000e+00:120, 3.000000e+00:127}, {4.000000e+00, 5.000000e+00}}> |
| !qalias = !quant.uniform<u8:f32:{0:1, 1:2}, {{2.0:120,3.0:127}, {4.0,5.0}}> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Empty block-size information in sub-channel quantization |
| // CHECK: !quant.uniform<u8:f32:{}, {{\{}}{2.000000e+00:120, 3.000000e+00:127}, {4.000000e+00, 5.000000e+00}}> |
| !qalias = !quant.uniform<u8:f32:{}, {{2.0:120,3.0:127}, {4.0,5.0}}> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Default min/max value optimization for f8E5M2. |
| // CHECK: !quant.uniform<f8E5M2:f32, 9.987200e-01:127> |
| !qalias = !quant.uniform<f8E5M2<-57344:57344>:f32, 0.99872:127 > |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: f8E5M2 |
| // CHECK: !quant.uniform<f8E5M2:f32, 2.000000e+02> |
| !qalias = !quant.uniform<f8E5M2:f32, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Default min/max value optimization for f8E4M3FN. |
| // CHECK: !quant.uniform<f8E4M3FN:f32, 9.987200e-01:127> |
| !qalias = !quant.uniform<f8E4M3FN<-448:448>:f32, 0.99872:127 > |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: f8E4M3FN |
| // CHECK: !quant.uniform<f8E4M3FN:f32, 2.000000e+02> |
| !qalias = !quant.uniform<f8E4M3FN:f32, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| |
| // ----- |
| // Default min/max value optimization for f4E2M1FN. |
| // CHECK: !quant.uniform<f4E2M1FN:f32, 9.987200e-01:127> |
| !qalias = !quant.uniform<f4E2M1FN<-6:6>:f32, 0.99872:127 > |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: f4E2M1FN |
| // CHECK: !quant.uniform<f4E2M1FN:f32, 2.000000e+02> |
| !qalias = !quant.uniform<f4E2M1FN:f32, 2.0e+2> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: QuantileType with narrowed explicit range `-6:6` (13 representable values). |
| // CHECK: !quant.uniform<!quant.quantile<f4E2M1FN:f16, {-1.000000e+00,-8.750000e-01,-7.500000e-01,-6.250000e-01,-5.000000e-01,-2.500000e-01,0.000000e+00,2.500000e-01,5.000000e-01,6.250000e-01,7.500000e-01,8.750000e-01,1.000000e+00}, <-6:6>>:f32, 9.987200e-01:127> |
| !qalias = !quant.uniform<!quant.quantile<f4E2M1FN:f16, {-1.0,-0.875,-0.75,-0.625,-0.5,-0.25,0.0,0.25,0.5,0.625,0.75,0.875,1.0}, <-6:6>>:f32, 0.99872:127> |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |
| // ----- |
| // Storage type: QuantileType |
| // CHECK: !quant.uniform<!quant.quantile<f4E2M1FN:f16, { |
| !qalias = !quant.uniform<!quant.quantile<f4E2M1FN:f16, {-1.0000,-0.8667,-0.7333,-0.6000,-0.4667,-0.3333,-0.2000,-0.0667,0.0667,0.2000,0.3333,0.4667,0.6000,0.7333,0.8667,1.0000}>:f32, 2.0e+2 > |
| func.func @parse() -> !qalias { |
| %0 = "foo"() : () -> !qalias |
| return %0 : !qalias |
| } |
| |