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/FixedPointAccumulator.lvt
namespace Livt.ML.Linear
using Livt.Math.Arithmetic
/**
* Bounded serial dot product; products remain wide until the final rounding.
*/
component FixedPointAccumulator<TERMS: int = 1024, BITS: int = 24, FRACTION: int = 12>
{
static assert TERMS > 0 && TERMS <= 65536, "term count must be 1..65536"
static assert BITS >= 2 && BITS <= 30, "activation bits must be 2..30"
static assert FRACTION >= 0 && FRACTION < BITS, "invalid fraction"
static assert 2 * BITS + Bits.RequiredFor(TERMS) <= 64, "unsafe accumulator width"
// Symmetric raw activation magnitude allowed by the configured bit width.
public const LIMIT: int = (1 << (BITS - 1)) - 1
// Owned arithmetic worker used by serialized operations.
math: WideArithmetic<BITS>
// Reduction state and validity for the current operation.
accumulator: logic[64]
count: int
failed: bool
/**
* Creates the owned wide arithmetic worker. Begin starts each reduction; serialize access
* to this accumulator.
*/
new()
{
math = new WideArithmetic<BITS>()
}
/**
* Begin a new reduction; reset also invalidates prior state.
*/
public fn Begin()
{
accumulator = 0
count = 0
failed = false
}
/**
* Reject excessive terms or values outside the declared symmetric format.
*/
public fn Accumulate(a: int, b: int)
{
if (failed) {
return
}
if (count >= TERMS || a < -LIMIT || a > LIMIT || b < -LIMIT || b > LIMIT) {
failed = true
return
}
var product = math.Multiply(a as logic[64], b as logic[64])
accumulator = math.Add(accumulator, product)
failed = math.Failed()
count++
}
/**
* Finish a nonempty partial or full reduction; invalid results are zero.
*/
public fn Finish() int
{
if (failed || count == 0) {
failed = true
return 0
}
var rounded = math.DivideEven(accumulator, (1 << FRACTION) as logic[64])
return math.Clamp(rounded)
}
/**
* Reports a rejected term or invalid reduction; Begin clears this status for the next
* reduction.
*/
public fn Failed() bool
{
return failed
}
/**
* Returns the signed 64-bit accumulated product bits before rescaling. This observation
* neither finishes nor clears the reduction.
*/
public fn Raw() logic[64]
{
return accumulator
}
}