# Residency

> USearch for Mojo

Where the payload lives is the constructor's name, as in the C lifecycle verbs, so a residency an index lacks has no constructor to call.
Each takes only the placement its own hardware has, one shard per entry, and leaving it out derives one.

```mojo
var domains = [Int32(0), Int32(1)]
var in_ram = DenseIndex.init_ram(library, options, RamOptions.on(domains))  # one graph per socket
var devices = [Int32(0), Int32(1), Int32(2), Int32(3)]
var in_vram = DenseIndex.init_vram(library, options, VramOptions.on(devices))  # sharded, never replicated
var on_nvme = DenseIndex.view_nvme(Executor.for_nvme(library), "index.safegraphs")
```

An NVMe index is only ever viewed: external-memory graphs are never modified in place.
Until NVMe checkpoints carry keys, `view_nvme` answers `Status.UNSUPPORTED`.

`from usearch import Residency, RamOptions, VramOptions, …`

## Residency

Where an index's payload lives and which engine traverses it - `usearch_residency_t`.

```mojo
struct Residency
```

Each lifecycle verb names its residency, as [`DenseIndex.init_vram`](https://www.unum.cloud/docs/usearch/mojo/metrics.md#init_vram) does, so this tag only travels
through the name tables: [`Library.residency_name`](https://www.unum.cloud/docs/usearch/mojo/introspection.md#residency_name) and [`Library.residency_from_name`](https://www.unum.cloud/docs/usearch/mojo/introspection.md#residency_from_name).

- `RAM` = `Residency(Int32(1))`: Volatile memory traversed by CPU threads - the concurrent baseline.
- `VRAM` = `Residency(Int32(2))`: Accelerator memory traversed by GPU warps on the chosen devices.
- `NVME` = `Residency(Int32(3))`: Persisted storage traversed through pluggable I/O engines, sized past RAM.
- `code` `c_int`: The raw `usearch_residency_t` value the ABI exchanges.

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

## RamOptions

The host memory domains a RAM-resident index places its shards in - `usearch_ram_options_t`.

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

One shard per named NUMA node, so a dual-socket box names two and gets two graphs whose
traversals stay local to the cores that walk them. The engine's payload blocks always claim
huge pages, falling back to base pages where none are provisioned.

- `origin` (comptime): The borrowed node-id array, named so it outlives the constructor that reads it.

- `memory_domains` `Address`: The `int32_t` node ids to place shards on; `NULL_ADDRESS` derives every node the process may use.
- `memory_domains_count` `c_size_t`: How many ids the array holds; zero derives.
- `shard_capacity` `c_size_t`: Entries one shard holds before the index opens another shard generation; zero derives.
- `cpu_class` `CpuClass`: The class to dispatch as; [`UNKNOWN`](https://www.unum.cloud/docs/usearch/mojo/introspection.md#UNKNOWN) derives the CPU's own.
- `memory_limit` `c_size_t`: Bytes an NVMe view's key tables may take on each named domain; zero sets no ceiling.

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

## __init__

Derives every memory domain the process may allocate on.

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

## on

Names the NUMA nodes explicitly, borrowing the caller's array for the call.

```mojo
def on[domains_origin: ImmOrigin, //](
    memory_domains: Span[Int32, domains_origin]
) -> RamOptions[domains_origin]
```

- `domains_origin` (comptime): The run's origin, inferred from the argument.
- `memory_domains`: The node ids to place one shard on apiece.

## *

The same options with the borrow erased - the one instantiation the ABI signature names.

```mojo
def untracked(self) -> RamOptions
```

## VramOptions

The devices a VRAM-resident index places its shards in - `usearch_vram_options_t`.

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

Sharded and never replicated, so eight devices host eight slices of one graph rather than eight
copies of it. Planes are device-resident: an index outgrowing the named devices fails rather
than paging to the host, and the answer is to name more devices.

- `origin` (comptime): The borrowed ordinal array, named so it outlives the constructor that reads it.

- `devices` `Address`: The CUDA ordinals to place shards on; `NULL_ADDRESS` derives one free device.
- `devices_count` `c_size_t`: How many ordinals the array holds; zero derives.
- `shard_capacity` `c_size_t`: Entries one shard holds before the index opens another shard generation; zero derives.
- `gpu_class` `GpuClass`: The class to dispatch as; [`UNKNOWN`](https://www.unum.cloud/docs/usearch/mojo/introspection.md#UNKNOWN) derives the devices' own.

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

## __init__

Derives one free device.

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

## on

Names the device ordinals explicitly, borrowing the caller's array for the call.

```mojo
def on[devices_origin: ImmOrigin, //](
    devices: Span[Int32, devices_origin]
) -> VramOptions[devices_origin]
```

- `devices_origin` (comptime): The run's origin, inferred from the argument.
- `devices`: The CUDA ordinals to place one shard on apiece.

## NvmeOptions

The devices an NVMe-resident index places its shards on - `usearch_nvme_options_t`.

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

A path is whatever identifies a device to the engine that can reach it, so the string is the
extension point rather than a field per transport: a filesystem path names a kernel device, a
transport identifier names a namespace the kernel no longer owns, and a FUSE mount is a path
too. Naming nothing opens every shard where its manifest already points and moves no bytes.

- `origin` (comptime): The borrowed path array, named so it outlives the constructor that reads it.

- `paths` `Address`: A `usearch_bytes_view_t` array; `NULL_ADDRESS` leaves every shard where its manifest points.
- `paths_count` `c_size_t`: How many paths the array holds; zero derives.
- `cpu_class` `CpuClass`: The class to dispatch as; [`UNKNOWN`](https://www.unum.cloud/docs/usearch/mojo/introspection.md#UNKNOWN) derives the CPU's own.

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

## __init__

Leaves every shard where its own manifest points.

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

## on

Names the devices or directories explicitly, borrowing the caller's array for the call.

```mojo
def on[paths_origin: ImmOrigin, //](
    paths: Span[BytesView, paths_origin]
) -> NvmeOptions[paths_origin]
```

- `paths_origin` (comptime): The run's origin, inferred from the argument.
- `paths`: The device or directory names, one shard apiece.

