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/Int8MatrixAccumulator32.lvt
namespace Livt.ML.Linear
/**
* Retained INT8 matrix sums with signed int32 activations and checked int64 updates.
* One owner serializes calls and holds the live row stable until each returns.
* The native core uses synchronous active-high reset; reset all participants
* across a rising edge. Call Begin before use after construction or reset.
* Numeric scaling, weight layout and memory transport belong to the caller.
*/
component Int8MatrixAccumulator32<ACTIVATION_BITS: int = 32, PRODUCT_STAGES: int = 1>
{
static assert ACTIVATION_BITS >= 2 && ACTIVATION_BITS <= 32, "activation range must be 2..32 bits"
static assert PRODUCT_STAGES == 1 || PRODUCT_STAGES == 2, "product stages must be 1 or 2"
// Physical bank capacity; Begin selects the number of accessible output rows.
public const MAX_ROWS: int = 1024
// Commands shared with the native worker.
const OP_BEGIN: int = 0
const OP_LOAD: int = 1
const OP_ACCUMULATE: int = 2
const OP_READ: int = 3
const OP_SEED: int = 4
// Four sixteen-int32 blocks load activations; a weight row holds 64 signed bytes.
public values: in logic[512]
public busy: out logic
// Owned native arithmetic, storage and producer completion phase.
primitive: Int8MatrixAccumulator32Primitive
request: logic
/**
* Owns one worker in the caller's clock/reset domain; Begin initializes its bank.
*/
new()
{
primitive = new Int8MatrixAccumulator32Primitive()
}
/**
* Waits for completion without copying a wide result through the dispatcher.
*/
fn Submit(operation: int, index: int)
{
state {
primitive.operation = operation
primitive.index = index
}
request = !request
primitive.request = request
while (primitive.acknowledge != request) {
state {
}
}
}
/**
* Clears 1..MAX_ROWS sums, invalidates activations and recovers from failure.
* Invalid row counts invalidate the bank. Completion includes all RAM writes.
*/
public fn Begin(rows: int) bool
{
Submit(OP_BEGIN, rows)
return (primitive.result >> 64) == 0
}
/**
* Loads block 0..3 from values; every lane must fit ACTIVATION_BITS.
* Rejected loads invalidate the selected block. Load all four before updates.
*/
public fn LoadActivations(block: int) bool
{
Submit(OP_LOAD, block)
return (primitive.result >> 64) == 0
}
/**
* Adds one exact 64-element dot product to row 0..rows-1 of the active bank.
* Requires four valid activation blocks; true means the write has committed.
* Overflow is checked at the block-update boundary. Failure poisons the bank
* until Begin/reset, so a later cancelling update cannot hide an overflow.
*/
public fn Accumulate(row: int) bool
{
Submit(OP_ACCUMULATE, row)
return (primitive.result >> 64) == 0
}
/**
* Waits for row 0..rows-1 of the active bank and returns its signed int64 sum.
* Bit 64 reports failure; failed payloads are zero.
* An invalid read fails without poisoning an otherwise valid bank.
*/
public fn Read(row: int) logic[65]
{
Submit(OP_READ, row)
return primitive.result
}
/**
* Sets row 0..rows-1 of the active bank to a signed int64 bias bit pattern.
* True means the write has committed; invalid writes poison the bank.
*/
public fn Seed(row: int, value: logic[64]) bool
{
primitive.seed = value
Submit(OP_SEED, row)
return (primitive.result >> 64) == 0
}
/**
* Shares a retained caller row and immutable numeric configuration.
*/
process Connect[]()
{
primitive.count = 0
primitive.rowValid = 0b0
primitive.streamError = 0b0
primitive.values = values
primitive.activationBits = ACTIVATION_BITS
primitive.productStages = PRODUCT_STAGES
busy = primitive.busy
}
}