# Inputs and Outputs

> USearch for Mojo

### Arenas

Every output whose length only the call knows, such as matches, rows, products, monoliths and cursor or stream batches, lands in an `Arena` you pass, and the verb answers a view over it without copying.
`Arena(executor)` places it where that executor computes, decided once, and `Arena(library)` makes host pages for the calling thread.
Each call rewinds its arena, so the previous call's views die and a steady loop allocates once.
To keep a result past the next call, or to read one while making the next, pass that call another arena.
An arena serves one call at a time, so each deferred call needs its own.
A view's origin keeps its arena alive, and reading a stale one raises `Status.UNINITIALIZED`.
An arena from a VRAM executor holds device memory, which host accessors refuse with `Status.DEVICE`, and serves only that executor's calls, keeping the executor alive until the arena goes.

```mojo
var arena = Arena(executor)  # Arena(library) makes host pages for the calling thread
for position in range(len(batches)):
    var matches = index.on(executor).search(batches[position], 10, arena)  # rewinds: the last batch's matches are gone
    total += matches.query_distances(0)[0]

var found = Arena(executor)
var fetched = Arena(executor)  # two live results, two arenas
var hits = index.on(executor).search(query, 10, found)
for key in hits.query_keys(0):
    rerank(key, index.on(executor).get[DType.float32](key, fetched))

var east_executor = Executor.for_ram(library, threads=4)
var west_executor = Executor.for_ram(library, threads=4)  # one executor and one arena per submitted call
var east_arena = Arena(east_executor)
var west_arena = Arena(west_executor)
var east = east_shard.deferred(east_executor).search(queries, 10, east_arena)
var west = west_shard.deferred(west_executor).search(queries, 10, west_arena)
print(east.wait().query_keys(0)[0], west.wait().query_keys(0)[0])
```

The arena is the verb's last required argument, before the optional config, on every receiver.
A call that finds its arena serving another call finishes with `Status.CONTENDED` and rewinds nothing, so the holder's views stay readable.
A call that fails for any other reason still rewinds it.

### Rows & Scalars

Every verb is a batch over strided rows, so a memory-mapped dataset reaches the index with no reshape and no copy, and a single vector is a one-row view.
A `RowsView` borrows a caller-owned run as rows of equal width, and it is the shape every batch argument takes.
`RowsView.of` derives the row count and the byte pitch from a packed run, and the scalar kind from its element type.

```mojo
var vectors = RowsView.of(embeddings, 768)  # Float32 elements, so ScalarKind.F32
```

The library converts on ingest and on export, so the scalar kind of the input is independent of the index's own quantization, and a `Float32` query searches an `I8` index without a conversion pass of your own.
Sub-byte kinds count logical dimensions rather than bytes and name their kind explicitly, so 128 dimensions of `U1X8` occupy sixteen bytes per row:

```mojo
var packed = List[UInt8](unsafe_uninit_length=rows * 16)  # filled before the call
var bits = RowsView.of(packed, 128, ScalarKind.U1X8)
```

A dataset whose rows are padded to a wider pitch builds the view field by field, with its own `stride` in bytes.

### Search

Every verb with optional knobs takes a config named after its C argument structure, such as `DenseInsertConfig`, `DenseSearchConfig` or `DenseMultiplyConfig`, where every field left out derives what the C interface derives.
So the bare call takes none, and naming a field reaches a knob:

```mojo
var stats = DenseTraversalStats()
_ = index.on(executor).search(queries, 10, arena, DenseSearchConfig(expansion_factor=128, stats=Pointer(to=stats)))
print(stats.computed_distances, "distances computed")
```

A `stats` slot is overwritten whole by every call it is lent to, so a reused one reads the last call's figures rather than a running total.

A search answers `Matches`: a queries-by-`wanted` grid of keys, the distances paired with them, and one match count per query, all written into the arena.
`query_keys` and `query_distances` borrow one query's results, nearest first, trimmed to the count that query reported:

```mojo
var matches = index.search(queries, 10, arena)
for query in range(len(matches)):
    for rank in range(len(matches.query_keys(query))):
        print(query, matches.query_keys(query)[rank], matches.query_distances(query)[rank])
```

The breadth of the candidates rides each call as `expansion_factor` rather than the handle, so a recall sweep runs against one immutable index with no mutation between points.
`DenseSearchConfig(traversal=Traversal.SCAN)` scores every entry instead of walking, on RAM and NVMe handles, which gives that sweep its exact ground truth.

`from usearch import DenseTraversalStats, DenseInsertConfig, DenseSearchConfig, …`

## DenseTraversalStats

Traversal telemetry - `usearch_traversal_stats_t`, a pure output.

```mojo
struct DenseTraversalStats
```

Fully overwritten by the call it is passed to, so a caller reusing one slot across calls reads
the last call's figures rather than a running total.

- `visited_members` `c_size_t`: Graph members visited while resolving the batch.
- `computed_distances` `c_size_t`: Distances computed while resolving the batch, diversity re-selections included.
- `restarts` `c_size_t`: Re-seedings after the frontier drained prematurely - a connectivity health signal.
- `missing_hints` `c_size_t`: Hint keys no shard held an entry under; zero unless a search was handed hints.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`

## __init__

Zeroes every counter, so an unwritten slot reads as an untaken walk.

```mojo
def __init__(out self)
```

## DenseInsertConfig

The knobs of `usearch_dense_insert_t`; zeroed or absent ones derive what the C interface derives.

```mojo
struct DenseInsertConfig[stats_origin: MutOrigin = MutUntrackedOrigin]
```

- `stats_origin` (comptime): The lent telemetry slot's origin, inferred where one is lent.

- `expansion_factor` `Int`: The breadth of the candidates the build walk explores; zero derives.
- `stats` `Optional[Pointer[DenseTraversalStats, stats_origin]]`: Receives this call's traversal telemetry, fully overwritten; absent skips reporting.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`

## __init__

Names only the knobs that differ from the derived ones.

```mojo
def __init__(
    out self,
    *,
    expansion_factor: Int = Int(0),
    stats: Optional[Pointer[DenseTraversalStats, stats_origin]] = Optional()
)
```

- `expansion_factor`: The breadth of the candidates the build walk explores; zero derives.
- `stats`: Receives this call's traversal telemetry; absent skips reporting.

## DenseSearchConfig

The knobs of `usearch_dense_search_t`; zeroed or absent ones derive what the C interface derives.

```mojo
struct DenseSearchConfig[stats_origin: MutOrigin = MutUntrackedOrigin]
```

A `predicate` narrows the matches to the entries it admits: the address of a
`usearch_predicate_callback_t` compiled in C, which installs unchanged. Non-matching entries still
route the traversal, so the predicate judges every scored candidate, a quad of them per call,
concurrently from the executor's threads.

- `stats_origin` (comptime): The lent telemetry slot's origin, inferred where one is lent.

- `expansion_factor` `Int`: The breadth of the candidates the walk explores; zero derives.
- `traversal` `Traversal`: A walk, or an exact scan of every entry on RAM and NVMe handles; VRAM answers [`UNSUPPORTED`](https://www.unum.cloud/docs/usearch/mojo/errors.md#UNSUPPORTED).
- `predicate` `Address`: A `usearch_predicate_callback_t` that must outlive the call; `NULL_ADDRESS` admits all.
- `predicate_state` `Address`: The opaque state forwarded into every predicate call.
- `stats` `Optional[Pointer[DenseTraversalStats, stats_origin]]`: Receives this call's traversal telemetry, fully overwritten; absent skips reporting.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`

## __init__

Names only the knobs that differ from the derived ones.

```mojo
def __init__(
    out self,
    *,
    expansion_factor: Int = Int(0),
    traversal: Traversal = Traversal.WALK,
    predicate: Int = Int(0),
    predicate_state: Int = Int(0),
    stats: Optional[Pointer[DenseTraversalStats, stats_origin]] = Optional()
)
```

- `expansion_factor`: The breadth of the candidates the walk explores; zero derives.
- `traversal`: A walk, or an exact scan of every entry on RAM and NVMe handles.
- `predicate`: A `usearch_predicate_callback_t` that must outlive the call; `NULL_ADDRESS` admits all.
- `predicate_state`: The opaque state forwarded into every predicate call.
- `stats`: Receives this call's traversal telemetry; absent skips reporting.

## ScalarKind

The scalar types the indexes store and exchange - `usearch_scalar_t`, named by width.

```mojo
struct ScalarKind
```

Ordered by shrinking dynamic range, floats first, then signed and unsigned integers. The `xN`
suffixes spell how many logical dimensions share one byte. [`Library.scalar_name`](https://www.unum.cloud/docs/usearch/mojo/introspection.md#scalar_name) spells each one
as the engine does.

- `UNKNOWN` = `ScalarKind(Int32(0))`: No scalar named - an unset field, or a custom metric owning its own storage.
- `F64` = `ScalarKind(Int32(1))`: IEEE-754 binary64.
- `F32` = `ScalarKind(Int32(2))`: IEEE-754 binary32.
- `BF16` = `ScalarKind(Int32(3))`: Truncated f32 - f32's range on a 7-bit mantissa.
- `F16` = `ScalarKind(Int32(4))`: IEEE-754 binary16.
- `E5M2` = `ScalarKind(Int32(5))`: FP8 with a 5-bit exponent - f16's range on two mantissa bits.
- `E4M3` = `ScalarKind(Int32(6))`: FP8 with a 4-bit exponent, no infinities.
- `E3M2` = `ScalarKind(Int32(7))`: FP6 with a 3-bit exponent, byte-aligned with two padding bits.
- `E2M3` = `ScalarKind(Int32(8))`: FP6 with a 2-bit exponent, byte-aligned with two padding bits.
- `I8` = `ScalarKind(Int32(10))`: 8-bit signed integer.
- `I4X2` = `ScalarKind(Int32(11))`: Two signed nibbles per byte, even dimensions in the low nibble.
- `I32` = `ScalarKind(Int32(12))`: 32-bit signed integer - the coordinates of geospatial points.
- `U8` = `ScalarKind(Int32(20))`: 8-bit unsigned integer.
- `U4X2` = `ScalarKind(Int32(21))`: Two unsigned nibbles per byte, even dimensions in the low nibble.
- `U1X8` = `ScalarKind(Int32(22))`: Eight single-bit dimensions per byte - what Hamming and Jaccard score.
- `code` `c_int`: The raw `usearch_scalar_t` value the ABI exchanges.

Conforms to: `Copyable`, `Deinitable`, `Equatable`, `ImplicitlyCopyable`, `Movable`, `RegisterPassable`, `TrivialRegisterPassable`

## of

The kind a Mojo scalar type stores one-to-one; the packed and FP6 kinds have none. Binding-only.

```mojo
def of[dtype: DType]() -> Self
```

- `dtype` (comptime): The element type of the caller's storage.

## bits_per_scalar

How many bits one logical dimension occupies, which sub-byte kinds share.

```mojo
def bits_per_scalar(self) -> Int
```

## bytes_for_columns

The natural width of one row, rounding a sub-byte packing up to whole bytes.

```mojo
def bytes_for_columns(self, columns: Int) -> Int
```

- `columns`: Logical scalars in the row, as the caller counts them.

## stores

Whether rows of this kind read as whole `dtype` elements: equal widths, or bytes for packed kinds. Binding-only.

```mojo
def stores[dtype: DType](self) -> Bool
```

- `dtype` (comptime): The element type the caller reads the rows as.

## Traversal

How a search reaches the indexed entries it scores - `usearch_traversal_t`.

```mojo
struct Traversal
```

- `WALK` = `Traversal(Int32(1))`: Walk the graph, scoring the entries the expansion reaches - approximate, the default.
- `SCAN` = `Traversal(Int32(2))`: Score every entry published when the query's scan starts - exact, on RAM and NVMe handles.
- `code` `c_int`: The raw `usearch_traversal_t` value the ABI exchanges.

Conforms to: `Copyable`, `Deinitable`, `Equatable`, `ImplicitlyCopyable`, `Movable`, `RegisterPassable`, `TrivialRegisterPassable`

## RowsView

A borrowed run of rows of one width - `usearch_rows_view_t`, the batch currency every verb reads.

```mojo
struct RowsView[origin: ImmOrigin = ImmUntrackedOrigin]
```

One vector is a one-row view. The row count becomes the verb's [`count`](https://www.unum.cloud/docs/usearch/mojo/executors.md#count), and the column count
crosses with the rows, so the engine checks it against the geometry the index froze. The row
and column counts are scalars and `stride` alone is in bytes; a zero stride repeats the first
row for every one of them, as BLAS reads it.

- `origin` (comptime): The borrowed rows, named so they outlive every call this view crosses.

- `data` `Pointer[NoneType, ImmUntrackedOrigin]`: Base pointer of the first row; non-null, since a Mojo pointer cannot be otherwise.
- `rows` `c_size_t`: Rows the view carries, which the verb takes as its [`count`](https://www.unum.cloud/docs/usearch/mojo/executors.md#count).
- `columns` `c_size_t`: Logical scalars per row, as the caller counts them.
- `stride` `c_size_t`: Bytes between the starts of consecutive rows; zero repeats the first row.
- `scalar` `ScalarKind`: The scalar type the rows hold, converted on the way in where it differs.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`, `RegisterPassable`, `TrivialRegisterPassable`

## of

Reads a flat run of scalars as contiguous rows of the given width. Binding-only.

```mojo
def of[dtype: DType, rows_origin: ImmOrigin, //](
    rows: Span[Scalar[dtype], rows_origin],
    columns: Int,
    scalar: ScalarKind = ScalarKind.of[dtype]()
) -> RowsView[rows_origin]
```

The row count comes from the bytes the run spans divided by the bytes one row of
`scalar` occupies, so a kind that disagrees with `dtype` is refused here rather than
read past the end by the engine. A sub-byte kind counts logical dimensions, so eight
[`U1X8`](#U1X8) columns are one `UInt8`.

- `dtype` (comptime): The scalar type of the run, inferred from the argument.
- `rows_origin` (comptime): The run's origin, inferred with it.
- `rows`: The scalars, laid out row after row with no padding between them.
- `columns`: Logical scalars per row, which must divide the run into whole rows.
- `scalar`: How the engine should read those scalars; the kind `dtype` stores by default.

Raises: [`Error`](https://www.unum.cloud/docs/usearch/mojo/errors.md#Error) when the run does not divide into whole rows of that width and kind.

## arguments

The batch-axis form the verbs take, its row count moved into the call's [`count`](https://www.unum.cloud/docs/usearch/mojo/executors.md#count).

```mojo
def arguments(self) -> RowsViewArguments
```

## Matches

A ranked run a call wrote into its arena - `usearch_matches_view_t`, read in place.

```mojo
struct Matches[origin: MutOrigin]
```

Every ranking verb - the search, late interaction, and a stream pull - answers exactly this. Each
count is the number of matches written for its query, never more than `wanted`.

- `origin` (comptime): The arena the run lives in, which this result borrows.

- `arena` `Pointer[Arena, origin]`: The arena holding the run.
- `generation` `Int`: The arena's call this run came from, so a read after a later call is refused.
- `view` `MatchesViewArguments`: Where the engine wrote the keys, scores and counts, inside the arena.
- `queries` `Int`: Queries the call answered.

Conforms to: `Deinitable`, `Movable`, `Sized`

## __len__

The queries the call answered.

```mojo
def __len__(self) -> Int
```

## query_keys

One query's keys, nearest first, trimmed to the matches that query found.

```mojo
def query_keys(ref self, query: Int) -> Span[Key, origin_of(self)]
```

- `query`: The query's offset in the batch, below `len(self)`.

Raises: [`Error`](https://www.unum.cloud/docs/usearch/mojo/errors.md#Error) with [`UNINITIALIZED`](https://www.unum.cloud/docs/usearch/mojo/errors.md#UNINITIALIZED) once a later call rewound the arena, or [`DEVICE`](https://www.unum.cloud/docs/usearch/mojo/errors.md#DEVICE) over VRAM.

## query_distances

One query's scores, paired positionally with [`query_keys`](#query_keys).

```mojo
def query_distances(ref self, query: Int) -> Span[Float64, origin_of(self)]
```

- `query`: The query's offset in the batch, below `len(self)`.

Raises: [`Error`](https://www.unum.cloud/docs/usearch/mojo/errors.md#Error) with [`UNINITIALIZED`](https://www.unum.cloud/docs/usearch/mojo/errors.md#UNINITIALIZED) once a later call rewound the arena, or [`DEVICE`](https://www.unum.cloud/docs/usearch/mojo/errors.md#DEVICE) over VRAM.

## Arena

The memory every output whose length scales with a call lands in - `usearch_arena_t`, freed when it goes out of scope.

```mojo
struct Arena
```

Made where an executor computes, host pages or the memory of its GPU, decided once; nothing is
allocated until a call writes into it. Every call handed it rewinds and refills it, which
invalidates the previous call's outputs, so a steady loop allocates once. One arena serves one
call at a time; a second concurrent use is refused by the engine as [`CONTENDED`](https://www.unum.cloud/docs/usearch/mojo/errors.md#CONTENDED), which leaves
the holder's results readable.

Every verb takes it as its last required argument, deferred ones too, and the result borrows it
in turn, so the arena outlives both; a failed call leaves it valid.

A result refuses every read with [`UNINITIALIZED`](https://www.unum.cloud/docs/usearch/mojo/errors.md#UNINITIALIZED) once a later call rewinds its arena, and a
result over a VRAM arena refuses every host read with [`DEVICE`](https://www.unum.cloud/docs/usearch/mojo/errors.md#DEVICE). A VRAM arena serves only calls on
the executor that made it, and keeps that executor alive until it is freed.

Conforms to: `Deinitable`, `Movable`

## __init__

Host pages for calls on the calling thread. Calls `usearch_arena_init`.

```mojo
def __init__(out self, library: Library)
```

```mojo
def __init__(out self, executor: Executor)
```

Memory where `executor` computes - host pages, or the memory of its GPU - serving the calls of its residency. Calls `usearch_arena_init`.

- `library`: The loaded engine, kept so the shared object stays mapped.
- `executor`: The executor whose calls it serves; host pages may outlive it, and a VRAM arena keeps it alive.

Raises: [`Error`](https://www.unum.cloud/docs/usearch/mojo/errors.md#Error) if the engine cannot allocate the handle.

## __deinit__

Frees the arena and every output in it, then lets a VRAM arena's executor go. Calls `usearch_arena_free`.

```mojo
def __deinit__(deinit self)
```

The executor and the loader reference are surrendered only after the call, for the reason
`_ExecutorHandle` records.

## residency

Where its memory lives, decided once by the executor that made it. Binding-only.

```mojo
def residency(self) -> Residency
```

