# Inputs and Outputs

> USearch for Wolfram

### Arenas

Every output whose length only the call knows, such as matches, rows, products and monoliths, lands in an arena you pass.
`ArenaInit["Executor"->executor]` places it where that executor computes, decided once, and `ArenaInit[]` makes host pages for the kernel's own thread.
Each call rewinds its arena and copies its outputs into Wolfram arrays, so a steady loop allocates once and every result outlives the next call.
An arena serves one call at a time, so a second concurrent call fails as `contended`.
LibraryLink cannot alias memory it did not allocate, so the results stay valid after the arena is released too.
An arena from a VRAM executor holds device memory, which these functions refuse with `device`.

```wolfram
arena = ArenaInit["Executor"->executor];
total = 0;
Do[
    matches = DenseSearch[DenseIndexOn[index, executor], batch, 10, arena];    (* rewinds, allocates once *)
    total += Total[Flatten[matches["Scores"]]],
    {batch, batches}];
found = DenseSearch[index, {query}, 10, arena];
vectors = DenseGet[index, #, arena] & /@ First[found["Keys"]];               (* found is a copy, so one arena serves both *)
```

The arena is the last required argument, options follow it, and a call without one stays unevaluated.
Fixed-size reports such as descriptions, audits and counts stay plain values and take no arena.

### Rows & Scalars

Packed real lists cross as `f64`; `NumericArray` inputs keep their `Real32` or `Real64` storage.
LibraryLink borrows both as read-only `"Constant"` arguments for the blocking call, so an existing packed list or typed array needs no input copy at this boundary.
The engine still converts the input into the index's quantization.

```wolfram
vectors = NumericArray[{{1., 2., 3.}, {3., 2., 1.}}, "Real32"];
DenseInsert[index, {41, 42}, vectors];
DenseSearch[index, vectors, 2, arena]
```

A matrix is a batch of rows, so a whole batch crosses in one call rather than one crossing per vector, and `DenseInsert` and `DenseMultiply` also take a single vector as a batch of one.
The input's own width crosses with the rows, and the engine refuses one that differs from the frozen geometry as `shape-mismatch`.
Metrics are `inner`, `angular`, `euclidean`, `hamming`, and `jaccard`; quantizations are `bf16`, `f16`, `e5m2`, `e4m3`, `e3m2`, `e2m3`, `i8`, `i4x2`, `u8`, `u4x2`, and `u1x8`.

- `DenseReserve[receiver, capacity]` reserves the total capacity, including the current size, and `DenseClear[receiver]` erases every entry, keeping it.
- `DenseInsert[receiver, keys, vectors]` admits one row per key and fails as `shape-mismatch` when the counts differ.

No `NumericArray` holds zero keys, so `DenseInsert[receiver, {}, {}]` answers `Null` in the package without reaching the library, as the C call would.

### Search

`DenseSearch[receiver, queries, wanted, arena]` answers `<|"Keys"->…, "Scores"->…|>`, one list per query, holding the matches it found, nearest first.
A query that finds fewer than `wanted` matches is not an error, and its lists are just shorter.
No tensor holds zero rows either, so a search with no queries answers `<|"Keys"->{}, "Scores"->{}|>` in the package.

The breadth of the candidates rides each call in the C interface rather than the handle, so it is an `"ExpansionFactor"` option on every verb that walks the graph, zero deriving it.
`"Traversal"->"scan"` skips the walk and scores every entry exactly, on RAM and NVMe handles:

```wolfram
DenseSearch[index, queries, 10, arena, "ExpansionFactor"->64]
DenseSearch[index, queries, 10, arena, "Traversal"->"scan"]
```

`Needs["USearch`"]`

## Arena

`Arena[id]` holds the outputs a verb writes, rewound by every call writing into it and freed once nothing references it.

```mathematica
Arena[id]
```

## ArenaInit

`ArenaInit[]` makes an arena for verb outputs, placed where its "Executor" computes; None, the default, holds host memory for calls on the calling thread.

```mathematica
ArenaInit[OptionsPattern[]]
```

- `"Executor"`: Default: `None`

## DenseInsert

`DenseInsert[receiver, keys, vectors]` adds vectors, one row per key, under keys, each an integer below 2^128.

```mathematica
DenseInsert[receiver, keys, vectors, OptionsPattern[]]
```

"ExpansionFactor" sets the breadth of the candidates the walk explores, 0 deriving it.

- `"ExpansionFactor"`: Default: `0`

## DenseSearch

`DenseSearch[receiver, queries, wanted, arena]` finds up to wanted nearest entries for each query row, answering their "Keys" and "Scores" per query.

```mathematica
DenseSearch[receiver, queries, wanted, arena, OptionsPattern[]]
```

"ExpansionFactor" sets the breadth of the candidates the walk explores, 0 deriving it, and "Traversal" is "walk", the default, or "scan", an exact pass over every entry.

- `"ExpansionFactor"`: Default: `0`
- `"Traversal"`: Default: `"walk"`

## DenseValues

`DenseValues[receiver, keys, values]` prepares immutable value rows, one per key, in the index's quantization, for DenseAttend.

```mathematica
DenseValues[receiver, keys, values]
```

