Livt packages
Livt.ML
Version 1.6.1
Fixed-size quantized inference, tensor storage, attention, and transformer building blocks for Livt.
Published files (132)
src/attention/KVCache.lvt
namespace Livt.ML.Attention
/**
* Four-slot FIFO cache for fixed 8-element key and value vectors.
*/
component KVCache
{
// Maximum number of key/value pairs retained by the cache.
public const CACHE_SIZE: int = 4
// Number of integer elements in each key and value vector.
public const VECTOR_SIZE: int = 8
// Owned key/value cache and circular-buffer positions.
keys: int[4, 8]
vals: int[4, 8]
// Owned key/value cache and circular-buffer positions.
head: int
tail: int
size: int
/**
* Appends a key/value pair, evicting the oldest pair when the cache is full.
*/
public fn Write(key: int[8], val: int[8])
{
if (size == CACHE_SIZE) {
head = (head + 1) % CACHE_SIZE
}
if (size < CACHE_SIZE) {
size++
}
for (var i = 0; i < VECTOR_SIZE; i++) {
keys[tail, i] = key[i]
vals[tail, i] = val[i]
}
tail = (tail + 1) % CACHE_SIZE
}
/**
* Returns one key element from the logical cache slot.
*/
public fn GetKeyElement(slot: int, elem: int) int
{
if (slot < 0 || slot >= size) {
return 0
}
if (elem < 0 || elem >= VECTOR_SIZE) {
return 0
}
var physSlot = (head + slot) % CACHE_SIZE
return keys[physSlot, elem]
}
/**
* Returns one value element from the logical cache slot.
*/
public fn GetValueElement(slot: int, elem: int) int
{
if (slot < 0 || slot >= size) {
return 0
}
if (elem < 0 || elem >= VECTOR_SIZE) {
return 0
}
var physSlot = (head + slot) % CACHE_SIZE
return vals[physSlot, elem]
}
/**
* Returns the number of key/value pairs currently stored.
*/
public fn GetSize() int
{
return size
}
/**
* Returns true when the cache contains no key/value pairs.
*/
public fn IsEmpty() bool
{
return size == 0
}
/**
* Returns true when the cache contains CACHE_SIZE key/value pairs.
*/
public fn IsFull() bool
{
return size == CACHE_SIZE
}
/**
* Removes all cached key/value pairs and resets FIFO indexes.
*/
public fn Clear()
{
head = 0
tail = 0
size = 0
}
}