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/QLinearMatMul256x10Ram.lvt
namespace Livt.ML.Linear
using Livt.ML.Numeric
using Livt.ML.Storage
/**
* RAM-backed non-streaming ONNX per-column QLinearMatMul reference.
* Initialize all inputs before Compute; Clear preserves the input vector.
*/
component QLinearMatMul256x10Ram
{
// 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: ByteTensorRam2048
// Configured coefficients and numeric scaling parameters.
weights: ByteTensorRam4096
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 input and weight RAMs plus local output accumulators. Configure weights,
* quantization parameters, and the full input before Compute; RAM contents are not
* initialized by construction.
*/
new()
{
requantize = new ScheduledRequantizeUInt8()
this.inputValues = new ByteTensorRam2048(INPUT_SIZE)
this.weights = new ByteTensorRam4096(2560)
}
/**
* 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
}
this.inputValues.Write(index, value as byte)
}
/**
* Clears all weights, quantization parameters, accumulators, and outputs.
*/
public fn Clear()
{
for (var index = 0; index < 2560; index++) {
this.weights.Write(index, 0x00)
}
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
}
}
/**
* 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
}
this.weights.Write(column * 256 + row, value as byte)
}
/**
* 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++) {
var activation = (this.inputValues.Read(row) as int) - inputZeroPoints[column]
var weightBits: logic[8] = this.weights.Read(column * 256 + row)
var centeredWeight = (weightBits as int) - weightZeroPoints[column]
accumulator = accumulator + activation * centeredWeight
}
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]
}
}