neura-decoder 0.7.4

Assembling the decoder only models a gguf weighs onto the graph
Documentation
use neura_abi::Element;
use neura_graph::{AttentionOptions, Graph, Init, Shape, Value};

pub struct Cache {
    keys: Value,
    values: Value,
    seat: Value,
    heads: u32,
    width: u32,
    capacity: u32,
    rows: u32,
}

impl Cache {
    pub fn new(graph: &Graph, heads: u32, width: u32, capacity: u32, rows: u32) -> Self {
        assert!(
            heads > 0 && width > 0,
            "a cache of {heads} heads of {width} numbers holds no key",
        );
        assert!(capacity > 0, "a cache of {capacity} positions holds no key");
        assert!(
            rows > 0 && rows <= capacity,
            "a cache of {capacity} positions takes {rows} rows at a time, and a chunk of more rows than the cache holds walks past the slots it fills",
        );
        let held = Shape::of([heads, 1, capacity, width]);
        Self {
            keys: graph.state(held, Init::Zero, Element::Single),
            values: graph.state(held, Init::Zero, Element::Single),
            seat: crate::layout::seat(graph, heads, capacity, rows),
            heads,
            width,
            capacity,
            rows,
        }
    }

    pub fn states(&self) -> [Value; 2] {
        [self.keys, self.values]
    }

    pub fn rows(&self) -> u32 {
        self.rows
    }

    pub fn write(&self, graph: &Graph, cursor: Value, keys: Value, values: Value) {
        for (held, what) in [(keys, "key"), (values, "value")] {
            assert_eq!(
                graph.shape(held).dims(),
                [self.heads, 1, self.rows, self.width],
                "a {what} of {} heads of {} numbers walks {:?} where a cache of {} positions takes {} rows of a chunk",
                self.heads,
                self.width,
                graph.shape(held).dims(),
                self.capacity,
                self.rows,
            );
        }
        let slots = graph.add(self.seat, cursor);
        for (held, stored) in [(keys, self.keys), (values, self.values)] {
            graph.write_into(stored, slots, held);
        }
    }

    pub fn attend(&self, graph: &Graph, query: Value, cursor: Value, scale: Value) -> Value {
        let shape = graph.shape(query).dims();
        assert_eq!(
            shape[2], self.rows,
            "a query of {} rows weighs the keys a cache of {} rows writes, and {:?} walks another count",
            shape[2], self.rows, shape,
        );
        assert_eq!(
            shape[3], self.width,
            "a query of {} numbers walks {shape:?} where the cache it reads holds keys of {} numbers",
            shape[3], self.width,
        );
        assert!(
            shape[0].is_multiple_of(self.heads),
            "a query of {} heads reads a cache of {} key heads, and every key head serves a whole group of queries",
            shape[0],
            self.heads,
        );
        graph.attention(
            query,
            self.keys,
            self.values,
            AttentionOptions {
                scale: Some(scale),
                causal: true,
                origin: Some(cursor),
                segments: None,
                reach: None,
                query_segments: None,
                bias: None,
            },
        )
    }
}