Three verbs, multiply, maxsim and attend, treat the index as a sparse operand rather than as a kNN store, each folding its arithmetic into the graph walk instead of materializing a match list.
All three read logits rather than distances, so they refuse anything but an inner-product index with Error.ConfigMismatch.
multiply is a sparse matrix product: every left row is walked against the index, and how many pairs it scores is known only once the walk ends, so the products come back as a ragged DenseProducts: keys, scores and their Apache Arrow offsets, all in the arena.
maxsim is late interaction: every query row takes its best match within a key, and those maxima sum to that key’s score.
A document is one key holding its token rows, which is what a values_per_key above one exists for, and the outputs are sized over documents rather than rows.
The keys land as a DenseProducts, one run per query, largest score first, and a zero wanted keeps every key a query scored.
attend is Flash Attention folded into the walk: every key it scores enters an online softmax, with no top-k cut, and the outputs come back as wide as the keys and divided by the partition.
The index stores no values, so a ValueLookup resolves each scored key to its row, as wide as the keys and stored in the index’s quantization.
Its trampoline checks the kind and width every batch states, so a missing row, or one of another kind or width, refuses the call with Error.ShapeMismatch.
It runs on the executor’s threads, so it must tolerate concurrent calls.
That trampoline is a host function, which serves RAM and NVMe indexes; a VRAM walk calls the lookup on the device, so a VRAM index takes a ValueLookup whose callback is device-callable, set directly.
The head_count query heads of grouped-query attention share one walk per token, row t · head_count + h being head h of token t, and a carry of one DenseSoftmaxState per query row, lent rather than written in the arena, folds this branch into another over the same queries.
The attended rows land in the arena as the queries’ own scalar type, or as the config’s outputs_scalar.
DenseSoftmaxStateThe online-softmax carry of one query row - Flash Attention's running maximum and partition.
pub const DenseSoftmaxState = extern struct
Mirrors usearch_dense_softmax_state_t.
The two are one concept: a maximum without its partition is a number nothing can rescale, so
they share an element rather than travelling as two arrays a caller could supply half of.
Fields
maximum_score
f32
The largest logit seen so far - the recurrence's m.
partition
f32
The sum of exponentials taken against that maximum - the recurrence's l.
The query heads sharing the index's key-value head, and with it one walk per token: row t · head_count + h is head h of token t. It must divide the rows; zero means one.
Pass {} for a lookup needing no context, and a
single-item pointer otherwise.
A row must be as wide as the keys, stored in the index's quantization, and alive until the
call is final. The trampoline checks the scalar and columns each batch states, so a null
row, or one of another kind or width, refuses the call with Error.ShapeMismatch. It runs
concurrently from the executor's threads.
The trampoline is a host function, so it serves RAM and NVMe handles only: a VRAM walk calls
callback on the device, so a VRAM handle needs a device-callable one set directly.
StructDenseProductsThe ragged output of DenseIndex.multiply or DenseIndex.maxsim in an arena, laid out as Apache Arrow does: query i spans pairs offsets[i] up to offsets[i + 1] of keys and scores.5
Left-hand rows the call multiplied, or queries it scored.
written
usize
Pairs written across every query.
required
usize
Pairs scored across every left row, or keys across every query for a maxsim, before wanted cut any.
queryThe pairs of one left row in traversal order, or one query's keys largest first for a maxsim, refusing a position past queries with Error.InvalidArgument, a stale view with Error.Uninitialized, and device memory with Error.Device.