cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
366 lines
15 KiB
C
366 lines
15 KiB
C
//===- quant.c - Test of Quant dialect C API ------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM
|
|
// Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// RUN: mlir-capi-quant-test 2>&1 | FileCheck %s
|
|
|
|
#include "mlir-c/Dialect/Quant.h"
|
|
#include "mlir-c/BuiltinAttributes.h"
|
|
#include "mlir-c/BuiltinTypes.h"
|
|
#include "mlir-c/IR.h"
|
|
|
|
#include <assert.h>
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
// CHECK-LABEL: testTypeHierarchy
|
|
static void testTypeHierarchy(MlirContext ctx) {
|
|
fprintf(stderr, "testTypeHierarchy\n");
|
|
|
|
MlirType i8 = mlirIntegerTypeGet(ctx, 8);
|
|
MlirType any = mlirTypeParseGet(
|
|
ctx, mlirStringRefCreateFromCString("!quant.any<i8<-8:7>:f32>"));
|
|
MlirType uniform =
|
|
mlirTypeParseGet(ctx, mlirStringRefCreateFromCString(
|
|
"!quant.uniform<i8<-8:7>:f32, 0.99872:127>"));
|
|
MlirType perAxis = mlirTypeParseGet(
|
|
ctx, mlirStringRefCreateFromCString(
|
|
"!quant.uniform<i8:f32:1, {2.0e+2,0.99872:120}>"));
|
|
MlirType calibrated = mlirTypeParseGet(
|
|
ctx,
|
|
mlirStringRefCreateFromCString("!quant.calibrated<f32<-0.998:1.2321>>"));
|
|
|
|
// The parser itself is checked in C++ dialect tests.
|
|
assert(!mlirTypeIsNull(any) && "couldn't parse AnyQuantizedType");
|
|
assert(!mlirTypeIsNull(uniform) && "couldn't parse UniformQuantizedType");
|
|
assert(!mlirTypeIsNull(perAxis) &&
|
|
"couldn't parse UniformQuantizedPerAxisType");
|
|
assert(!mlirTypeIsNull(calibrated) &&
|
|
"couldn't parse CalibratedQuantizedType");
|
|
|
|
// CHECK: i8 isa QuantizedType: 0
|
|
fprintf(stderr, "i8 isa QuantizedType: %d\n", mlirTypeIsAQuantizedType(i8));
|
|
// CHECK: any isa QuantizedType: 1
|
|
fprintf(stderr, "any isa QuantizedType: %d\n", mlirTypeIsAQuantizedType(any));
|
|
// CHECK: uniform isa QuantizedType: 1
|
|
fprintf(stderr, "uniform isa QuantizedType: %d\n",
|
|
mlirTypeIsAQuantizedType(uniform));
|
|
// CHECK: perAxis isa QuantizedType: 1
|
|
fprintf(stderr, "perAxis isa QuantizedType: %d\n",
|
|
mlirTypeIsAQuantizedType(perAxis));
|
|
// CHECK: calibrated isa QuantizedType: 1
|
|
fprintf(stderr, "calibrated isa QuantizedType: %d\n",
|
|
mlirTypeIsAQuantizedType(calibrated));
|
|
|
|
// CHECK: any isa AnyQuantizedType: 1
|
|
fprintf(stderr, "any isa AnyQuantizedType: %d\n",
|
|
mlirTypeIsAAnyQuantizedType(any));
|
|
// CHECK: uniform isa UniformQuantizedType: 1
|
|
fprintf(stderr, "uniform isa UniformQuantizedType: %d\n",
|
|
mlirTypeIsAUniformQuantizedType(uniform));
|
|
// CHECK: perAxis isa UniformQuantizedPerAxisType: 1
|
|
fprintf(stderr, "perAxis isa UniformQuantizedPerAxisType: %d\n",
|
|
mlirTypeIsAUniformQuantizedPerAxisType(perAxis));
|
|
// CHECK: calibrated isa CalibratedQuantizedType: 1
|
|
fprintf(stderr, "calibrated isa CalibratedQuantizedType: %d\n",
|
|
mlirTypeIsACalibratedQuantizedType(calibrated));
|
|
|
|
// CHECK: perAxis isa UniformQuantizedType: 0
|
|
fprintf(stderr, "perAxis isa UniformQuantizedType: %d\n",
|
|
mlirTypeIsAUniformQuantizedType(perAxis));
|
|
// CHECK: uniform isa CalibratedQuantizedType: 0
|
|
fprintf(stderr, "uniform isa CalibratedQuantizedType: %d\n",
|
|
mlirTypeIsACalibratedQuantizedType(uniform));
|
|
fprintf(stderr, "\n");
|
|
}
|
|
|
|
// CHECK-LABEL: testAnyQuantizedType
|
|
void testAnyQuantizedType(MlirContext ctx) {
|
|
fprintf(stderr, "testAnyQuantizedType\n");
|
|
|
|
MlirType anyParsed = mlirTypeParseGet(
|
|
ctx, mlirStringRefCreateFromCString("!quant.any<i8<-8:7>:f32>"));
|
|
|
|
MlirType i8 = mlirIntegerTypeGet(ctx, 8);
|
|
MlirType f32 = mlirF32TypeGet(ctx);
|
|
MlirType any =
|
|
mlirAnyQuantizedTypeGet(mlirQuantizedTypeGetSignedFlag(), i8, f32, -8, 7);
|
|
|
|
// CHECK: flags: 1
|
|
fprintf(stderr, "flags: %u\n", mlirQuantizedTypeGetFlags(any));
|
|
// CHECK: signed: 1
|
|
fprintf(stderr, "signed: %u\n", mlirQuantizedTypeIsSigned(any));
|
|
// CHECK: storage type: i8
|
|
fprintf(stderr, "storage type: ");
|
|
mlirTypeDump(mlirQuantizedTypeGetStorageType(any));
|
|
fprintf(stderr, "\n");
|
|
// CHECK: expressed type: f32
|
|
fprintf(stderr, "expressed type: ");
|
|
mlirTypeDump(mlirQuantizedTypeGetExpressedType(any));
|
|
fprintf(stderr, "\n");
|
|
// CHECK: storage min: -8
|
|
fprintf(stderr, "storage min: %" PRId64 "\n",
|
|
mlirQuantizedTypeGetStorageTypeMin(any));
|
|
// CHECK: storage max: 7
|
|
fprintf(stderr, "storage max: %" PRId64 "\n",
|
|
mlirQuantizedTypeGetStorageTypeMax(any));
|
|
// CHECK: storage width: 8
|
|
fprintf(stderr, "storage width: %u\n",
|
|
mlirQuantizedTypeGetStorageTypeIntegralWidth(any));
|
|
// CHECK: quantized element type: !quant.any<i8<-8:7>:f32>
|
|
fprintf(stderr, "quantized element type: ");
|
|
mlirTypeDump(mlirQuantizedTypeGetQuantizedElementType(any));
|
|
fprintf(stderr, "\n");
|
|
|
|
// CHECK: equal: 1
|
|
fprintf(stderr, "equal: %d\n", mlirTypeEqual(anyParsed, any));
|
|
// CHECK: !quant.any<i8<-8:7>:f32>
|
|
mlirTypeDump(any);
|
|
fprintf(stderr, "\n\n");
|
|
}
|
|
|
|
// CHECK-LABEL: testUniformType
|
|
void testUniformType(MlirContext ctx) {
|
|
fprintf(stderr, "testUniformType\n");
|
|
|
|
MlirType uniformParsed =
|
|
mlirTypeParseGet(ctx, mlirStringRefCreateFromCString(
|
|
"!quant.uniform<i8<-8:7>:f32, 0.99872:127>"));
|
|
|
|
MlirType i8 = mlirIntegerTypeGet(ctx, 8);
|
|
MlirType f32 = mlirF32TypeGet(ctx);
|
|
MlirType uniform = mlirUniformQuantizedTypeGet(
|
|
mlirQuantizedTypeGetSignedFlag(), i8, f32, 0.99872, 127, -8, 7);
|
|
|
|
// CHECK: scale: 0.998720
|
|
fprintf(stderr, "scale: %lf\n", mlirUniformQuantizedTypeGetScale(uniform));
|
|
// CHECK: zero point: 127
|
|
fprintf(stderr, "zero point: %" PRId64 "\n",
|
|
mlirUniformQuantizedTypeGetZeroPoint(uniform));
|
|
// CHECK: fixed point: 0
|
|
fprintf(stderr, "fixed point: %d\n",
|
|
mlirUniformQuantizedTypeIsFixedPoint(uniform));
|
|
|
|
// CHECK: equal: 1
|
|
fprintf(stderr, "equal: %d\n", mlirTypeEqual(uniform, uniformParsed));
|
|
// CHECK: !quant.uniform<i8<-8:7>:f32, 9.987200e-01:127>
|
|
mlirTypeDump(uniform);
|
|
fprintf(stderr, "\n\n");
|
|
}
|
|
|
|
// CHECK-LABEL: testUniformPerAxisType
|
|
void testUniformPerAxisType(MlirContext ctx) {
|
|
fprintf(stderr, "testUniformPerAxisType\n");
|
|
|
|
MlirType perAxisParsed = mlirTypeParseGet(
|
|
ctx, mlirStringRefCreateFromCString(
|
|
"!quant.uniform<i8:f32:1, {2.0e+2,0.99872:120}>"));
|
|
|
|
MlirType i8 = mlirIntegerTypeGet(ctx, 8);
|
|
MlirType f32 = mlirF32TypeGet(ctx);
|
|
double scales[] = {200.0, 0.99872};
|
|
int64_t zeroPoints[] = {0, 120};
|
|
MlirType perAxis = mlirUniformQuantizedPerAxisTypeGet(
|
|
mlirQuantizedTypeGetSignedFlag(), i8, f32,
|
|
/*nDims=*/2, scales, zeroPoints,
|
|
/*quantizedDimension=*/1,
|
|
mlirQuantizedTypeGetDefaultMinimumForInteger(/*isSigned=*/true,
|
|
/*integralWidth=*/8),
|
|
mlirQuantizedTypeGetDefaultMaximumForInteger(/*isSigned=*/true,
|
|
/*integralWidth=*/8));
|
|
|
|
// CHECK: num dims: 2
|
|
fprintf(stderr, "num dims: %" PRIdPTR "\n",
|
|
mlirUniformQuantizedPerAxisTypeGetNumDims(perAxis));
|
|
// CHECK: scale 0: 200.000000
|
|
fprintf(stderr, "scale 0: %lf\n",
|
|
mlirUniformQuantizedPerAxisTypeGetScale(perAxis, 0));
|
|
// CHECK: scale 1: 0.998720
|
|
fprintf(stderr, "scale 1: %lf\n",
|
|
mlirUniformQuantizedPerAxisTypeGetScale(perAxis, 1));
|
|
// CHECK: zero point 0: 0
|
|
fprintf(stderr, "zero point 0: %" PRId64 "\n",
|
|
mlirUniformQuantizedPerAxisTypeGetZeroPoint(perAxis, 0));
|
|
// CHECK: zero point 1: 120
|
|
fprintf(stderr, "zero point 1: %" PRId64 "\n",
|
|
mlirUniformQuantizedPerAxisTypeGetZeroPoint(perAxis, 1));
|
|
// CHECK: quantized dim: 1
|
|
fprintf(stderr, "quantized dim: %" PRId32 "\n",
|
|
mlirUniformQuantizedPerAxisTypeGetQuantizedDimension(perAxis));
|
|
// CHECK: fixed point: 0
|
|
fprintf(stderr, "fixed point: %d\n",
|
|
mlirUniformQuantizedPerAxisTypeIsFixedPoint(perAxis));
|
|
|
|
// CHECK: equal: 1
|
|
fprintf(stderr, "equal: %d\n", mlirTypeEqual(perAxis, perAxisParsed));
|
|
// CHECK: !quant.uniform<i8:f32:1, {2.000000e+02,9.987200e-01:120}>
|
|
mlirTypeDump(perAxis);
|
|
fprintf(stderr, "\n\n");
|
|
}
|
|
|
|
// CHECK-LABEL: testUniformSubChannelType
|
|
void testUniformSubChannelType(MlirContext ctx) {
|
|
fprintf(stderr, "testUniformSubChannelType\n");
|
|
|
|
MlirType subChannelParsed =
|
|
mlirTypeParseGet(ctx, mlirStringRefCreateFromCString(
|
|
"!quant.uniform<i8:f32:{0:1, 1:2}, "
|
|
"{{2.0:10, 3.0:20}, {4.0:30, 5.0:40}}>"));
|
|
|
|
MlirType i8 = mlirIntegerTypeGet(ctx, 8);
|
|
MlirType f32 = mlirF32TypeGet(ctx);
|
|
|
|
// block-size information
|
|
int32_t quantizedDimensions[] = {0, 1};
|
|
int64_t blockSizes[] = {1, 2};
|
|
int64_t numBlockSizes = 2;
|
|
|
|
// quantization parameters
|
|
int64_t quantParamShape[] = {2, 2};
|
|
int64_t quantParamRank = 2;
|
|
int64_t numQuantizationParams = 4;
|
|
MlirAttribute scales[] = {mlirFloatAttrDoubleGet(ctx, f32, 2.0),
|
|
mlirFloatAttrDoubleGet(ctx, f32, 3.0),
|
|
mlirFloatAttrDoubleGet(ctx, f32, 4.0),
|
|
mlirFloatAttrDoubleGet(ctx, f32, 5.0)};
|
|
MlirAttribute zeroPoints[] = {
|
|
mlirIntegerAttrGet(i8, 10), mlirIntegerAttrGet(i8, 20),
|
|
mlirIntegerAttrGet(i8, 30), mlirIntegerAttrGet(i8, 40)};
|
|
|
|
MlirType scalesType =
|
|
mlirRankedTensorTypeGet(quantParamRank, quantParamShape, f32,
|
|
/*encoding=*/mlirAttributeGetNull());
|
|
MlirType zeroPointsType = mlirRankedTensorTypeGet(
|
|
quantParamRank, quantParamShape, i8, /*encoding=*/mlirAttributeGetNull());
|
|
MlirAttribute denseScalesAttr =
|
|
mlirDenseElementsAttrGet(scalesType, numQuantizationParams, scales);
|
|
MlirAttribute denseZeroPointsAttr = mlirDenseElementsAttrGet(
|
|
zeroPointsType, numQuantizationParams, zeroPoints);
|
|
|
|
MlirType subChannel = mlirUniformQuantizedSubChannelTypeGet(
|
|
mlirQuantizedTypeGetSignedFlag(), i8, f32, denseScalesAttr,
|
|
denseZeroPointsAttr, numBlockSizes, quantizedDimensions, blockSizes,
|
|
mlirQuantizedTypeGetDefaultMinimumForInteger(/*isSigned=*/true,
|
|
/*integralWidth=*/8),
|
|
mlirQuantizedTypeGetDefaultMaximumForInteger(/*isSigned=*/true,
|
|
/*integralWidth=*/8));
|
|
|
|
MlirAttribute arrayScalesAttr =
|
|
mlirArrayAttrGet(ctx, numQuantizationParams, scales);
|
|
MlirAttribute arrayZeroPointsAttr =
|
|
mlirArrayAttrGet(ctx, numQuantizationParams, zeroPoints);
|
|
MlirType illegalSubChannel = mlirUniformQuantizedSubChannelTypeGet(
|
|
mlirQuantizedTypeGetSignedFlag(), i8, f32, arrayScalesAttr,
|
|
arrayZeroPointsAttr, numBlockSizes, quantizedDimensions, blockSizes,
|
|
mlirQuantizedTypeGetDefaultMinimumForInteger(/*isSigned=*/true,
|
|
/*integralWidth=*/8),
|
|
mlirQuantizedTypeGetDefaultMaximumForInteger(/*isSigned=*/true,
|
|
/*integralWidth=*/8));
|
|
|
|
// CHECK: is null sub-channel type: 1
|
|
fprintf(stderr, "is null sub-channel type: %d\n",
|
|
mlirTypeIsNull(illegalSubChannel));
|
|
|
|
// CHECK: num dims: 2
|
|
fprintf(stderr, "num dims: %" PRIdPTR "\n",
|
|
mlirUniformQuantizedSubChannelTypeGetNumBlockSizes(subChannel));
|
|
|
|
// CHECK: axis-block-size-pair[0]: 0:1
|
|
fprintf(
|
|
stderr, "axis-block-size-pair[0]: %" PRId32 ":%" PRId64 "\n",
|
|
mlirUniformQuantizedSubChannelTypeGetQuantizedDimension(subChannel, 0),
|
|
mlirUniformQuantizedSubChannelTypeGetBlockSize(subChannel, 0));
|
|
|
|
// CHECK: axis-block-size-pair[1]: 1:2
|
|
fprintf(
|
|
stderr, "axis-block-size-pair[1]: %" PRId32 ":%" PRId64 "\n",
|
|
mlirUniformQuantizedSubChannelTypeGetQuantizedDimension(subChannel, 1),
|
|
mlirUniformQuantizedSubChannelTypeGetBlockSize(subChannel, 1));
|
|
|
|
denseScalesAttr = mlirUniformQuantizedSubChannelTypeGetScales(subChannel);
|
|
denseZeroPointsAttr =
|
|
mlirUniformQuantizedSubChannelTypeGetZeroPoints(subChannel);
|
|
scalesType = mlirAttributeGetType(denseScalesAttr);
|
|
zeroPointsType = mlirAttributeGetType(denseZeroPointsAttr);
|
|
|
|
// CHECK: tensor<2x2xf32>
|
|
mlirTypeDump(scalesType);
|
|
// CHECK: tensor<2x2xi8>
|
|
mlirTypeDump(zeroPointsType);
|
|
|
|
// CHECK: number of quantization parameters: 4
|
|
fprintf(stderr, "number of quantization parameters: %" PRId64 "\n",
|
|
mlirElementsAttrGetNumElements(denseScalesAttr));
|
|
|
|
// CHECK: quantization-parameter[0]: 2.000000:10
|
|
fprintf(stderr, "quantization-parameter[0]: %lf:%" PRId8 "\n",
|
|
mlirDenseElementsAttrGetFloatValue(denseScalesAttr, 0),
|
|
mlirDenseElementsAttrGetInt8Value(denseZeroPointsAttr, 0));
|
|
|
|
// CHECK: quantization-parameter[1]: 3.000000:20
|
|
fprintf(stderr, "quantization-parameter[1]: %lf:%" PRId8 "\n",
|
|
mlirDenseElementsAttrGetFloatValue(denseScalesAttr, 1),
|
|
mlirDenseElementsAttrGetInt8Value(denseZeroPointsAttr, 1));
|
|
|
|
// CHECK: quantization-parameter[2]: 4.000000:30
|
|
fprintf(stderr, "quantization-parameter[2]: %lf:%" PRId8 "\n",
|
|
mlirDenseElementsAttrGetFloatValue(denseScalesAttr, 2),
|
|
mlirDenseElementsAttrGetInt8Value(denseZeroPointsAttr, 2));
|
|
|
|
// CHECK: quantization-parameter[3]: 5.000000:40
|
|
fprintf(stderr, "quantization-parameter[3]: %lf:%" PRId8 "\n",
|
|
mlirDenseElementsAttrGetFloatValue(denseScalesAttr, 3),
|
|
mlirDenseElementsAttrGetInt8Value(denseZeroPointsAttr, 3));
|
|
|
|
// CHECK: equal: 1
|
|
fprintf(stderr, "equal: %d\n", mlirTypeEqual(subChannel, subChannelParsed));
|
|
|
|
// CHECK: !quant.uniform<i8:f32:{0:1, 1:2},
|
|
// {{.*}}2.000000e+00:10, 3.000000e+00:20},
|
|
// {4.000000e+00:30, 5.000000e+00:40{{.*}}}}>
|
|
mlirTypeDump(subChannel);
|
|
fprintf(stderr, "\n\n");
|
|
}
|
|
|
|
// CHECK-LABEL: testCalibratedType
|
|
void testCalibratedType(MlirContext ctx) {
|
|
fprintf(stderr, "testCalibratedType\n");
|
|
|
|
MlirType calibratedParsed = mlirTypeParseGet(
|
|
ctx,
|
|
mlirStringRefCreateFromCString("!quant.calibrated<f32<-0.998:1.2321>>"));
|
|
|
|
MlirType f32 = mlirF32TypeGet(ctx);
|
|
MlirType calibrated = mlirCalibratedQuantizedTypeGet(f32, -0.998, 1.2321);
|
|
|
|
// CHECK: min: -0.998000
|
|
fprintf(stderr, "min: %lf\n", mlirCalibratedQuantizedTypeGetMin(calibrated));
|
|
// CHECK: max: 1.232100
|
|
fprintf(stderr, "max: %lf\n", mlirCalibratedQuantizedTypeGetMax(calibrated));
|
|
|
|
// CHECK: equal: 1
|
|
fprintf(stderr, "equal: %d\n", mlirTypeEqual(calibrated, calibratedParsed));
|
|
// CHECK: !quant.calibrated<f32<-0.998:1.232100e+00>>
|
|
mlirTypeDump(calibrated);
|
|
fprintf(stderr, "\n\n");
|
|
}
|
|
|
|
int main(void) {
|
|
MlirContext ctx = mlirContextCreate();
|
|
mlirDialectHandleRegisterDialect(mlirGetDialectHandle__quant__(), ctx);
|
|
testTypeHierarchy(ctx);
|
|
testAnyQuantizedType(ctx);
|
|
testUniformType(ctx);
|
|
testUniformPerAxisType(ctx);
|
|
testUniformSubChannelType(ctx);
|
|
testCalibratedType(ctx);
|
|
mlirContextDestroy(ctx);
|
|
return EXIT_SUCCESS;
|
|
}
|