# Receivers and Deferred Calls

> UForm for Rust

The receiver decides where a verb runs and how it completes, while the verb and its arguments stay the same:

- `model.text_encode(..)` runs on the calling thread, through `&Model`.
- `model.on(&executor).text_encode(..)` blocks on the executor, failing `Contended` while another call holds it.
- `model.deferred(&executor).text_encode(..)` submits the call and answers a `Deferred`.

`ModelVerbs` and `EncodeVerbs` write every verb once for all three, and `TrainVerbs` does so for a trainer's two receivers.
A blocking verb returns its `Result` directly, so nothing about asynchrony reaches a caller who never asks for it.
An `On` borrows the model and the executor, so neither it nor a `Deferred` it submits can outlive them.

```rust
let texts = vec![String::from("a cat on a mat"), String::from("a dog in the fog")];
let call = model.deferred(&executor).text_encode(texts, Outputs::EMBEDDINGS, Scalar::F32, &mut arena)?;
if call.status() == Err(Status::Deferred) {
    // other work
}
let encoded = call.await?;                                    // or: call.wait()?
```

A `Deferred` owns the inputs the library reads until the call is final, and borrows the model and the arena, as a blocking call does.
`status` answers `Ok(())` once the call succeeded, `Err(Status::Deferred)` while it is not final, and its failure otherwise.
Inside an `async` block, `.await` polls the call's status until it is final, so other tasks run meanwhile, while `wait` blocks the thread without spinning.
The crate starts no thread, so waiting off-thread goes through a scoped thread, as `std::thread::scope(|scope| scope.spawn(move || call.wait()).join())` does.
Dropping an unfinished `Deferred` waits for the call, and a panic a progress handler raised resurfaces from `wait`, `.await`, or a drop outside unwinding.

The library reads a deferred call's inputs after the verb returns, so a deferred receiver takes owned inputs: items in a `Vec` or an array of owned or `'static` values, a tape as `(Vec<_>, Vec<usize>)`, a `PathBuf`, `String` or `'static` path, and `'static` configs and handlers.
Lending `&Vec<String>` fails to compile with "a deferred receiver needs owned inputs", and a config borrowing a local fails as "does not live long enough".
A deferred call allocates one box holding its outcome, argument struct and inputs until it is final.
An executor without threads of its own may hold a deferred call until its `wait`, its next `drain` or blocking call, or the drop of what it names, so `drain` it before an `.await` there.
A call finding another one holding its executor finishes at once with `Status::Contended`.

`use uform::Blocking;`

`use uform::Deferred;`

`use uform::Deferring;`

`use uform::Mood;`

`use uform::On;`

`use uform::Wait;`

`use uform::*;`

## ProgressCallback

A periodic report of finished and total units; `Break` stops the call at the next slice.

```rust
pub type ProgressCallback<'a> = dyn FnMut(usize, usize) -> ControlFlow<()> + Send + 'a;
```

It runs on whichever thread advanced the work, never on two at once, so it owes `Send` and
may be `FnMut`. A panic inside it stops the call like a `Break` and is re-raised once the
call is final.

Mirrors `uform_progress_callback_t`.

## Blocking

The completion of a blocking receiver, whose verbs return once their call is final and answer what it produced.

```rust
pub struct Blocking;
```

Rust-only.

Implements: `Debug`

## Deferred

A submitted call, which owns its outcome, argument struct and inputs in one box the library reads until the call is final, and borrows its arena as a blocking call does.

```rust
pub struct Deferred<'handle, Verb: Calling>
```

[`Deferred::status`](#status) polls without blocking, and [`Deferred::wait`](#wait) blocks until the call is
final and hands back what it produced, while `.await` polls it from async code. Dropping an
unfinished one waits for it, then frees the box.
A panic a handler raised resurfaces from [`wait`](#wait), `.await`, or a drop outside unwinding.
`'handle` is the borrow of the [`On`](#On) that submitted it.

Rust-only; waiting and dropping call `uform_outcome_wait`.

Implements: `Drop`, `Debug`, `Send`, `IntoFuture`

## status

`Err(Status::Deferred)` until the call is final, then its final status, read without blocking.

```rust
pub fn status(&self) -> Result<(), Status>
```

Calls `uform_outcome_status`.

## wait

Blocks until the call is final, then hands back what it produced.

```rust
pub fn wait(self) -> Result<Verb::Output>
```

Calls `uform_outcome_wait`.

## Deferring

The completion of a deferring receiver, whose verbs return once their call is submitted and answer a [`Deferred`](https://www.unum.cloud/docs/uform/rust/errors.md#Deferred).

```rust
pub struct Deferring;
```

Rust-only.

Implements: `Debug`

## Mood

What an executor does with its threads or streams once it goes idle.

```rust
pub enum Mood
```

Mirrors `uform_mood_t`.

- `Parked` = `0`: Sleep on futexes or events, freeing the core; the next call pays a wake-up.
- `Spinning` = `1`: Poll them, trading a core for the lowest wake-up latency.

Implements: `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`, `Debug`, `Default`, `Hash`, `Display`, `FromStr`

## On

A model or a trainer borrowed with the executor its calls run on and how they complete.

```rust
pub struct On<'handle, Handle, Completion = Blocking>
```

Neither the receiver nor a [`Deferred`](https://www.unum.cloud/docs/uform/rust/errors.md#Deferred) it submits outlives the handle or the executor.

Rust-only.

Implements: `[EncodeVerbs](https://www.unum.cloud/docs/uform/rust/encoding.md#EncodeVerbs)<'model>`, `[ModelVerbs](https://www.unum.cloud/docs/uform/rust/models.md#ModelVerbs)<'model>`, `[TrainVerbs](https://www.unum.cloud/docs/uform/rust/training.md#TrainVerbs)<'trainer>`, `Debug`, `Clone`, `Copy`

## text_encode

Encodes UTF-8 texts through one forward, a token per byte.

```rust
fn text_encode<'config, 'arena, Texts: TapeView<u8>>(
    self,
    texts: Texts,
    outputs: Outputs,
    config: impl Into<TextEncodeConfig<'config>>,
    arena: &'arena mut Arena,
) -> <<Self as ModelVerbs<'model>>::Completion as Completion>::Answer<'model, TextEncode<'config, 'arena, Texts>>
where
    Self::Completion: Accepts<Texts> + Accepts<TextEncodeConfig<'config>>,
```

Calls `uform_text_encode`.

## text_choose

Scores each item's legal choices through one forward: `texts` are UTF-8 states, each ending where its choice goes, and `choices` holds each item's legal bytes, one choice per byte.

```rust
fn text_choose<'config, 'arena, Texts: TapeView<u8>, Choices: TapeView<u8>>(
    self,
    texts: Texts,
    choices: Choices,
    config: impl Into<TextChooseConfig<'config>>,
    arena: &'arena mut Arena,
) -> <<Self as ModelVerbs<'model>>::Completion as Completion>::Answer<'model, TextChoose<'config, 'arena, Texts, Choices>>
where
    Self::Completion: Accepts<Texts> + Accepts<Choices> + Accepts<TextChooseConfig<'config>>,
```

Answers one probability per choice in `choices` order, a softmax over the item's choices
alone at its question type's calibrated inverse temperature.

A state longer than the model's context loses its head, never its end, and a model without
the byte decoder fails the call with [`Status::Unsupported`](https://www.unum.cloud/docs/uform/rust/errors.md#Unsupported).

Calls `uform_text_choose`.

## image_encode

Decodes and encodes JPEG, PNG or WebP files; an undecodable file fails the call with [`Status::Malformed`](https://www.unum.cloud/docs/uform/rust/errors.md#Malformed).

```rust
fn image_encode<'config, 'arena, Images: TapeView<u8>>(
    self,
    images: Images,
    outputs: Outputs,
    config: impl Into<ImageEncodeConfig<'config>>,
    arena: &'arena mut Arena,
) -> <<Self as ModelVerbs<'model>>::Completion as Completion>::Answer<'model, ImageEncode<'config, 'arena, Images>>
where
    Self::Completion: Accepts<Images> + Accepts<ImageEncodeConfig<'config>>,
```

Calls `uform_image_encode`.

## image_encode_pixels

Encodes decoded images of interleaved 8-bit RGB, item `i` holding `heights[i]` rows of `widths[i]` pixels; an item of another length fails with [`Status::ShapeMismatch`](https://www.unum.cloud/docs/uform/rust/errors.md#ShapeMismatch).

```rust
fn image_encode_pixels<'config, 'arena, Pixels: TapeView<u8>, Heights: AsRef<[u32]>, Widths: AsRef<[u32]>>(
    self,
    pixels: Pixels,
    heights: Heights,
    widths: Widths,
    outputs: Outputs,
    config: impl Into<ImageEncodePixelsConfig<'config>>,
    arena: &'arena mut Arena,
) -> <<Self as ModelVerbs<'model>>::Completion as Completion>::Answer<'model, ImageEncodePixels<'config, 'arena, Pixels, Heights, Widths>>
where
    Self::Completion: Accepts<Pixels> + Accepts<Heights> + Accepts<Widths> + Accepts<ImageEncodePixelsConfig<'config>>,
```

Calls `uform_image_encode_pixels`.

## video_encode

Decodes and encodes MP4 or WebM clips.

```rust
fn video_encode<'config, 'arena, Videos: TapeView<u8>>(
    self,
    videos: Videos,
    outputs: Outputs,
    config: impl Into<VideoEncodeConfig<'config>>,
    arena: &'arena mut Arena,
) -> <<Self as ModelVerbs<'model>>::Completion as Completion>::Answer<'model, VideoEncode<'config, 'arena, Videos>>
where
    Self::Completion: Accepts<Videos> + Accepts<VideoEncodeConfig<'config>>,
```

Calls `uform_video_encode`.

## audio_encode

Decodes and encodes WAV, FLAC, MP3 or Opus recordings, resampled to mono.

```rust
fn audio_encode<'config, 'arena, Recordings: TapeView<u8>>(
    self,
    recordings: Recordings,
    outputs: Outputs,
    config: impl Into<AudioEncodeConfig<'config>>,
    arena: &'arena mut Arena,
) -> <<Self as ModelVerbs<'model>>::Completion as Completion>::Answer<'model, AudioEncode<'config, 'arena, Recordings>>
where
    Self::Completion: Accepts<Recordings> + Accepts<AudioEncodeConfig<'config>>,
```

Calls `uform_audio_encode`.

## audio_encode_samples

Encodes decoded mono recordings sharing one `sample_rate`, resampled to the model's rate where it differs.

```rust
fn audio_encode_samples<'config, 'arena, Samples: TapeView<f32>>(
    self,
    samples: Samples,
    sample_rate: u32,
    outputs: Outputs,
    config: impl Into<AudioEncodeSamplesConfig<'config>>,
    arena: &'arena mut Arena,
) -> <<Self as ModelVerbs<'model>>::Completion as Completion>::Answer<'model, AudioEncodeSamples<'config, 'arena, Samples>>
where
    Self::Completion: Accepts<Samples> + Accepts<AudioEncodeSamplesConfig<'config>>,
```

Calls `uform_audio_encode_samples`.

## handles

The model this receiver reaches and the executor its calls run on.

```rust
fn handles(&self) -> Handles
```

## describe

Reports the model's geometry and placement in one call.

```rust
fn describe(
    self,
) -> <<Self as ModelVerbs<'model>>::Completion as Completion>::Answer<'model, ModelDescribe>
```

Calls `uform_model_describe`.

## step

Applies one optimizer step over this process's items and every peer's: forward, losses, backward, the world gradient reduction, and the update.

```rust
fn step<'config, 'arena, Modalities: AsRef<[Modality]>, Contents: TapeView<u8>>(
    self,
    modalities: Modalities,
    contents: Contents,
    config: impl Into<TrainerStepConfig<'config, 'arena>>,
) -> <<Self as TrainVerbs<'trainer>>::Completion as Completion>::Answer<'trainer, TrainerStep<'config, 'arena, Modalities, Contents>>
where
    Self::Completion: Accepts<Modalities> + Accepts<Contents> + Accepts<TrainerStepConfig<'config, 'arena>>,
```

Every process of the run calls it
once per step, with one modality per item and each item's bytes in `contents`.

Answers the pooled embeddings when the config names an arena.

Calls `uform_trainer_step`.

## save

Writes the weights and the step, which the model loads serve and [`Trainer::init_vram`](https://www.unum.cloud/docs/uform/rust/training.md#init_vram) resumes; only the process of index zero writes, the rest return at once.

```rust
fn save<'config, Location: AsRef<Path>>(
    self,
    config: impl Into<TrainerSaveConfig<'config, Location>>,
) -> <<Self as TrainVerbs<'trainer>>::Completion as Completion>::Answer<'trainer, TrainerSave<'config, Location>>
where
    Self::Completion: Accepts<TrainerSaveConfig<'config, Location>>,
```

Calls `uform_trainer_save`.

## Wait

A [`Deferred`](https://www.unum.cloud/docs/uform/rust/errors.md#Deferred) being awaited: every poll reads its status, and one not yet final asks to be polled again.

```rust
pub struct Wait<'handle, Verb: Calling>(_);
```

The C library has no wake-up, so an executor re-polls it while other tasks run, spinning only
when nothing else is ready; [`Deferred::wait`](#wait) blocks without spinning.

Rust-only; the final poll calls `uform_outcome_wait`, which returns at once.

Implements: `Future`

