# Arenas

> UForm for Rust

Every output whose length only the call knows, the embeddings, the states and their offsets, lands in an `Arena` you pass, and the verb answers views over it without copying.
`Arena::new_in(&executor)` places it where that executor computes, decided once, and `Arena::new()` 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.
Every call, blocking or deferred, borrows the arena as `&mut Arena` and its result borrows it in turn, so the borrow checker refuses a stale view at compile time.
To keep a result past the next call, pass that call another arena; an arena serves one call at a time, so each deferred call needs its own.
An arena from a VRAM executor holds device memory, which host accessors refuse with `Status::Device`, while `as_ptr` still hands the rows to another library, such as a USearch VRAM index.

```rust
let mut arena = Arena::new_in(&executor)?;
for batch in &batches {
    let encoded = model.on(&executor).text_encode(batch, Outputs::EMBEDDINGS, Scalar::F32, &mut arena)?;
    consume(encoded.embeddings.map(|rows| rows.values::<f32>()).transpose()?); // rewinds next iteration
}
```

The library never frees an arena under a call: dropping one waits for the calls writing into it, and a call naming an arena that serves another call finishes with `Status::Contended`, so even a leaked `Deferred` leaves it safe.

`use uform::Arena;`

`use uform::ArenaDescription;`

## Arena

Memory the library writes every output whose length scales with a call into, reused across calls.

```rust
pub struct Arena
```

An executor places it where it computes, host pages or its GPU's memory, decided once, and
nothing is allocated until a call writes into it. Every call rewinds and refills it,
invalidating the previous call's outputs, so a steady loop allocates once. Every verb, blocking
or deferred, borrows it as `&mut Arena` and answers outputs that borrow it in turn. An arena
from a VRAM executor holds device memory, so the host accessors of its outputs refuse with
[`Status::Device`](https://www.unum.cloud/docs/uform/rust/errors.md#Device). It grows, fills and frees on the first stream of the executor that made it,
so it serves only calls on that executor and holds the executor until it drops.

Mirrors `uform_arena_t`; dropping it calls `uform_arena_free`, which waits for the calls
still writing into it.

Implements: `Debug`, `Send`, `Sync`, `Drop`

## new

Makes an arena of host pages for calls on the calling thread.

```rust
pub fn new() -> Result<Self>
```

Calls `uform_arena_init`.

## new_in

Makes an arena where `executor` computes, serving the calls of its residency, or only those on `executor` itself for a GPU arena.

```rust
pub fn new_in(executor: &Executor) -> Result<Self>
```

Calls `uform_arena_init`.

## describe

Where the outputs live, as the executor that made the arena decided.

```rust
pub fn describe(&self) -> Result<ArenaDescription>
```

Calls `uform_arena_describe`.

## ArenaDescription

Where an [`Arena`](#Arena)'s outputs live.

```rust
pub struct ArenaDescription
```

- `residency` `Residency`: [`Residency::Ram`](https://www.unum.cloud/docs/uform/rust/models.md#Ram) for host pages, [`Residency::Vram`](https://www.unum.cloud/docs/uform/rust/models.md#Vram) for one device's memory.
- `device` `Option<u32>`: The device ordinal, as [`Executor::for_vram`](https://www.unum.cloud/docs/uform/rust/executors.md#for_vram) takes it; [`None`](https://www.unum.cloud/docs/uform/rust/training.md#None) for host pages.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Hash`

