Livt packages
Livt.ML
Version 1.6.1
Fixed-size quantized inference, tensor storage, attention, and transformer building blocks for Livt.
Published files (132)
- DotProduct.lvt
- FixedPointAccumulator.lvt
- Int8BroadcastMac64x8.lvt
- Int8BroadcastMac64x8Primitive.lvt
- Int8BroadcastMac64x8Primitive.vhd
- Int8Dot64x8.lvt
- Int8Dot64x8Primitive.lvt
- Int8Dot64x8Primitive.vhd
- Int8Linear4x8.lvt
- Int8Linear8x3.lvt
- Int8LinearAccumulator.lvt
- Int8Mac8.lvt
- Int8MatrixAccumulator32.lvt
- Int8MatrixAccumulator32Primitive.lvt
- Int8MatrixAccumulator32Primitive.vhd
- Int8MatrixAccumulator32Stream.lvt
- Linear8x8.lvt
- MatrixVectorMultiplication.lvt
- QLinearMatMul256x10.lvt
- QLinearMatMul256x10Ram.lvt
- QLinearMatMul256x10Stream.lvt
- QuantizedMatrix.lvt
- VecAdd.lvt
src/linear/QLinearMatMul256x10.lvt
namespace Livt.ML.Linear
using Livt.ML.Numeric
/**
* Applies an ONNX per-column QLinearMatMul from 256 uint8 inputs to ten outputs.
*/
component QLinearMatMul256x10
{
// Owned scheduled requantizer; processing holds input acceptance until completion.
requantize: ScheduledRequantizeUInt8
// Compile-time dimensions, bounds, and numeric constants.
public const INPUT_SIZE: int = 256
public const OUTPUT_SIZE: int = 10
// Input tensor storage; populate the required span before computation.
inputValues: int[256]
// Configured coefficients and numeric scaling parameters.
weights: int[10, 256]
multipliers: int[10]
divisors: int[10]
inputZeroPoints: int[10]
weightZeroPoints: int[10]
outputZeroPoints: int[10]
// Wide output accumulators before final output conversion.
accumulators: int[10]
// Latest computed result, retained for the caller.
output: int[10]
/**
* Owns one scheduled requantizer for serialized processing.
*/
new()
{
requantize = new ScheduledRequantizeUInt8()
}
/**
* Stores one flattened uint8 input value and ignores an invalid index.
*/
public fn SetInput(index: int, value: int)
{
if (index < 0) {
return
}
if (index >= INPUT_SIZE) {
return
}
inputValues[index] = value
}
/**
* Clears all weights, quantization parameters, accumulators, and outputs.
*/
public fn Clear()
{
for (var column = 0; column < OUTPUT_SIZE; column++) {
multipliers[column] = 0
divisors[column] = 1
inputZeroPoints[column] = 0
weightZeroPoints[column] = 0
outputZeroPoints[column] = 0
accumulators[column] = 0
output[column] = 0
for (var row = 0; row < INPUT_SIZE; row++) {
weights[column, row] = 0
}
}
}
/**
* Stores one signed-int8 column weight and ignores an invalid index.
*/
public fn SetWeight(column: int, row: int, value: int)
{
if (column < 0) {
return
}
if (column >= OUTPUT_SIZE) {
return
}
if (row < 0) {
return
}
if (row >= INPUT_SIZE) {
return
}
weights[column, row] = value
}
/**
* Stores the rational scale and tensor zero points for one output column.
*/
public fn SetColumnParameters(
column: int, multiplier: int, divisor: int,
inputZeroPoint: int, weightZeroPoint: int, outputZeroPoint: int)
{
if (column < 0) {
return
}
if (column >= OUTPUT_SIZE) {
return
}
multipliers[column] = multiplier
divisors[column] = divisor
inputZeroPoints[column] = inputZeroPoint
weightZeroPoints[column] = weightZeroPoint
outputZeroPoints[column] = outputZeroPoint
}
/**
* Computes ten uint8 outputs using ONNX-style centered multiplication.
*/
public fn Compute()
{
for (var column = 0; column < OUTPUT_SIZE; column++) {
var accumulator = 0
for (var row = 0; row < INPUT_SIZE; row++) {
state {
var centeredInput = inputValues[row] - inputZeroPoints[column]
var centeredWeight = weights[column, row] - weightZeroPoints[column]
var product = centeredInput * centeredWeight
accumulator = accumulator + product
}
}
state {
accumulators[column] = accumulator
output[column] = requantize.ApplyRational(
accumulator, multipliers[column], divisors[column], outputZeroPoints[column])
}
}
}
/**
* Returns one int32 accumulator, or zero for an invalid index.
*/
public fn GetAccumulator(index: int) int
{
if (index < 0) {
return 0
}
if (index >= OUTPUT_SIZE) {
return 0
}
return accumulators[index]
}
/**
* Returns one quantized output, or zero for an invalid index.
*/
public fn GetOutput(index: int) int
{
if (index < 0) {
return 0
}
if (index >= OUTPUT_SIZE) {
return 0
}
return output[index]
}
}