# helia_aot.memory.defines

Memory planning data model.

Describes what a planner consumes and produces: arena roles and usage, tensor
bindings, lifetimes and allocations, the placement constraints read from
configuration, and the resulting :class:`MemoryPlan`.

## helia_aot.memory.defines.ArenaRole

`class` · `python`

```python
ArenaRole()
```

Logical role of a memory arena.

Every tensor in a :class:`MemoryPlan` lives in an arena tagged
with one of these roles. Roles partition the planner output so
scratch reuse, persistent zero-init, and constant residency can
be reasoned about independently.

Source: `helia_aot/memory/defines.py:18`

### helia_aot.memory.defines.ArenaRole.scratch

`attribute` · `python`

```python
scratch = auto()
```

Writable activation/scratch arena (whole-program
lifetime shared by ops, slots reused via liveness
analysis).

Source: `helia_aot/memory/defines.py:38`

### helia_aot.memory.defines.ArenaRole.persistent

`attribute` · `python`

```python
persistent = auto()
```

Whole-program-live writable storage (resource
variables and similar).

Source: `helia_aot/memory/defines.py:39`

### helia_aot.memory.defines.ArenaRole.constant

`attribute` · `python`

```python
constant = auto()
```

Read-only weight storage. Can be cold (the arena
buffer is the cold-storage blob and kernels read it in
place) or staged (the arena buffer is a writable runtime
copy hydrated from a separate source blob).

Source: `helia_aot/memory/defines.py:40`

## helia_aot.memory.defines.TensorBinding

`class` · `python`

```python
TensorBinding()
```

Planner's emit intent for a single tensor's storage.

Every tensor in a :class:`MemoryPlan` is bound to an arena slot at
``(role, memory, offset)``. There are no per-tensor C symbols
anymore — scratch, persistent, and constant tensors are all
descriptors against arena buffers exposed via
``arena_buffers[region]``.

Constant arenas come in two shapes, distinguished purely by
whether ``source_memory`` matches ``memory``:

- **Cold** (``source_memory == memory``): the arena buffer itself
  is a ``static const`` blob in cold storage. Kernels read it
  directly; no hydration is required.
- **Staged** (``source_memory != memory``): the arena buffer is a
  writable runtime copy in ``memory``; a separate read-only
  source blob lives in ``source_memory`` and the caller (or the
  weak ``<prefix>_hydrate_constants`` helper) copies it in
  before the first ``model_run``.

Scratch and persistent bindings always have
``source_memory == memory`` (they are writable arenas with no
cold-storage source).

Source: `helia_aot/memory/defines.py:43`

### helia_aot.memory.defines.TensorBinding.role

`attribute` · `python`

```python
role: ArenaRole = Field(..., description='Logical role of the storage region.')
```

Logical role of the storage region.

Source: `helia_aot/memory/defines.py:80`

### helia_aot.memory.defines.TensorBinding.memory

`attribute` · `python`

```python
memory: MemoryType = Field(..., description='Runtime memory of the arena slot.')
```

Runtime (kernel-visible) memory of the
arena slot.

Source: `helia_aot/memory/defines.py:81`

### helia_aot.memory.defines.TensorBinding.source_memory

`attribute` · `python`

```python
source_memory: MemoryType = Field(..., description='Cold-storage memory the slot is sourced from.')
```

Cold-storage memory the slot is
sourced from. Equals ``memory`` for scratch, persistent,
and cold constants; differs from ``memory`` for staged
constants.

Source: `helia_aot/memory/defines.py:82`

### helia_aot.memory.defines.TensorBinding.offset

`attribute` · `python`

```python
offset: int = Field(default=0, description='Byte offset within the arena.')
```

Byte offset within the arena.

Source: `helia_aot/memory/defines.py:83`

## helia_aot.memory.defines.TensorLifetime

`class` · `python`

```python
TensorLifetime()
```

Tensor operator lifetime.

Source: `helia_aot/memory/defines.py:86`

### helia_aot.memory.defines.TensorLifetime.tensor_id

`attribute` · `python`

```python
tensor_id: TensorId = Field(..., description='Unique identifier for the tensor')
```

Unique identifier for the tensor

Source: `helia_aot/memory/defines.py:96`

### helia_aot.memory.defines.TensorLifetime.start_op

`attribute` · `python`

```python
start_op: int = Field(..., description='Index of the first operator that uses/defines it')
```

Index of the first operator that uses/defines it

Source: `helia_aot/memory/defines.py:97`

### helia_aot.memory.defines.TensorLifetime.end_op

`attribute` · `python`

```python
end_op: int = Field(..., description='Index of the last operator that uses it')
```

Index of the last operator that uses it

Source: `helia_aot/memory/defines.py:98`

### helia_aot.memory.defines.TensorLifetime.add_op

`method` · `python`

```python
add_op(op_idx: int)
```

Add an operator index to the lifetime.

**Parameters**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| op_idx | int | Required | Operator index to add |

Source: `helia_aot/memory/defines.py:100`

### helia_aot.memory.defines.TensorLifetime.merge

`method` · `python`

```python
merge(other: TensorLifetime)
```

Merge another lifetime into this one.

This updates the start and end operators to encompass both lifetimes.
Useful when tensors have aliases.

**Parameters**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| other | TensorLifetime | Required | Another tensor lifetime to merge |

Source: `helia_aot/memory/defines.py:109`

## helia_aot.memory.defines.TensorAllocation

`class` · `python`

```python
TensorAllocation()
```

Metadata for a tensor allocation.

Source: `helia_aot/memory/defines.py:126`

### helia_aot.memory.defines.TensorAllocation.tensor_id

`attribute` · `python`

```python
tensor_id: TensorId = Field(..., description='Unique identifier for the tensor')
```

Unique identifier for the tensor

Source: `helia_aot/memory/defines.py:146`

### helia_aot.memory.defines.TensorAllocation.memory

`attribute` · `python`

```python
memory: MemoryType = Field(..., description='Memory type for the allocation')
```

Memory type for the allocation (runtime
/ kernel-visible memory of the arena slot)

Source: `helia_aot/memory/defines.py:147`

### helia_aot.memory.defines.TensorAllocation.offset

`attribute` · `python`

```python
offset: int = Field(default=0, description='Offset within the memory arena')
```

Offset within the arena

Source: `helia_aot/memory/defines.py:148`

### helia_aot.memory.defines.TensorAllocation.size

`attribute` · `python`

```python
size: int = Field(default=0, description='Size of the allocation in bytes')
```

Size of the allocation in bytes

Source: `helia_aot/memory/defines.py:149`

### helia_aot.memory.defines.TensorAllocation.binding

`attribute` · `python`

```python
binding: TensorBinding | None = Field(default=None, description="Planner-assigned binding describing how this tensor's storage is materialized.")
```

Planner's binding describing
``(role, memory, offset, source_memory)`` for the slot.
Defaults to ``None`` for callers that construct
:class:`TensorAllocation` directly; the bundled
:class:`GreedyMemoryPlanner` always populates it. Emit
templates dispatch on ``binding.role`` and on the
``binding.source_memory == binding.memory`` predicate
(cold vs staged constant).

Source: `helia_aot/memory/defines.py:150`

## helia_aot.memory.defines.ArenaUsage

`class` · `python`

```python
ArenaUsage()
```

Metadata for a memory arena.

Source: `helia_aot/memory/defines.py:156`

### helia_aot.memory.defines.ArenaUsage.memory

`attribute` · `python`

```python
memory: MemoryType = Field(..., description='Runtime memory of the arena.')
```

Runtime (kernel-visible) memory of the
arena.

Source: `helia_aot/memory/defines.py:177`

### helia_aot.memory.defines.ArenaUsage.total_size

`attribute` · `python`

```python
total_size: int = Field(default=0, description='Total bytes in this arena')
```

Total bytes in this arena.

Source: `helia_aot/memory/defines.py:178`

### helia_aot.memory.defines.ArenaUsage.used

`attribute` · `python`

```python
used: int = Field(default=0, description='Bytes actually used')
```

Bytes actually used. For bump-allocated arenas
(constant, persistent) this equals ``total_size``.

Source: `helia_aot/memory/defines.py:179`

### helia_aot.memory.defines.ArenaUsage.role

`attribute` · `python`

```python
role: ArenaRole = Field(default=ArenaRole.scratch, description='Logical role of the arena (scratch | persistent | constant).')
```

Logical role of the arena.

Source: `helia_aot/memory/defines.py:180`

### helia_aot.memory.defines.ArenaUsage.source_memory

`attribute` · `python`

```python
source_memory: MemoryType = Field(default=None, description="Cold-storage source memory for the arena's contents. Equals ``memory`` for scratch, persistent, and cold constant arenas; differs from ``memory`` for staged constant arenas where bytes are copied at boot from this source memory into the writable runtime arena. Defaults to None for backward compatibility with callers that construct ArenaUsage directly; the bundled GreedyPlanner always populates it.")
```

The cold-storage memory the
arena's contents are sourced from. For scratch and
persistent arenas this equals ``memory`` (purely runtime,
no source blob). For constant arenas it equals ``memory``
in the cold case (arena buffer is the cold blob in place)
and differs from ``memory`` in the staged case (arena
buffer is a writable runtime copy of a source blob in
``source_memory``).

Source: `helia_aot/memory/defines.py:184`

### helia_aot.memory.defines.ArenaUsage.alignment

`attribute` · `python`

```python
alignment: int = Field(default=16, description='Resolved alignment of the arena base symbol (and floor for slot offsets within it). Stamped by the planner from max(implementation floor, platform.min_alignment, MemoryConstraint.arena_alignment).')
```

Source: `helia_aot/memory/defines.py:197`

### helia_aot.memory.defines.ArenaUsage.is_staged

`attribute` · `python`

```python
is_staged: bool
```

True iff this arena has a distinct cold source memory.

Equivalent to ``source_memory is not None and source_memory !=
memory``. Centralizes the cold-vs-staged predicate so
templates and handlers do not duplicate it.

For scratch and persistent arenas this is always ``False``
(they have no cold source). For constant arenas it
distinguishes the two emit shapes:

- ``False`` (cold): the arena buffer itself is a
  ``static const`` blob in cold storage.
- ``True`` (staged): the arena buffer is a writable runtime
  copy hydrated from a separate source blob in
  ``source_memory``.

Source: `helia_aot/memory/defines.py:216`

### helia_aot.memory.defines.ArenaUsage.allocate

`method` · `python`

```python
allocate(size: int) -> int
```

Allocate a segment of the arena and return its offset

Source: `helia_aot/memory/defines.py:207`

## helia_aot.memory.defines.MemoryConstraint

`class` · `python`

```python
MemoryConstraint()
```

User-defined memory constraint

Source: `helia_aot/memory/defines.py:236`

### helia_aot.memory.defines.MemoryConstraint.name

`attribute` · `python`

```python
name: MemoryType = Field(..., description='Memory type (e.g., DTCM, ITCM)')
```

Memory type (e.g., DTCM, ITCM)

Source: `helia_aot/memory/defines.py:259`

### helia_aot.memory.defines.MemoryConstraint.max_size

`attribute` · `python`

```python
max_size: int | None = Field(default=None, description='Maximum size in bytes, or None for no limit')
```

Maximum size in bytes, or None for no limit

Source: `helia_aot/memory/defines.py:260`

### helia_aot.memory.defines.MemoryConstraint.arena_alignment

`attribute` · `python`

```python
arena_alignment: int | None = Field(default=None, description='Optional per-arena alignment floor in bytes. When set, applied to both the arena base symbol and every slot. When None, only the 16-byte implementation floor applies to the base; per-slot alignment is driven by platform / dtype / tensor hints.')
```

Optional per-arena alignment floor
in bytes. When set, the planner uses
``max(arena_alignment, platform.min_alignment)`` for both
the arena base symbol and the per-slot offset of every
tensor packed into it. When ``None`` (the default), only
the implementation floor (16 bytes) is applied to the
arena **base** symbol; per-slot alignment continues to use
``max(platform.min_alignment, dtype_alignment_floor,
tensor.alignment_hint)`` so dtype-natural and
kernel-driven alignment are still honored. Bump
``arena_alignment`` above the default for memories that
back DMA-driven hydration paths needing stronger
alignment than the platform's MVE/Helium floor (e.g.
cacheline-sized PSRAM transfers).

Source: `helia_aot/memory/defines.py:261`

## helia_aot.memory.defines.MemoryPlan

`class` · `python`

```python
MemoryPlan()
```

Top-level memory plan for tensors.

Every tensor allocation is a slot in some arena. Three arena maps
partition storage by role:

- :attr:`arena_usages` — writable scratch arenas (one per
  writable memory bank).
- :attr:`persistent_arenas` — writable persistent arenas (one
  per writable memory bank that received a persistent tensor).
  Separate from scratch so the scratch arena stays purely
  transient and may be aliased across models.
- :attr:`constant_arenas` — constant arenas. Two shapes share the
  same map:

    * **Cold**: ``arena.source_memory == arena.memory``. The
      arena buffer itself is the read-only blob in cold storage;
      kernels read it directly. No hydration required.
    * **Staged**: ``arena.source_memory != arena.memory``. The
      arena buffer is a writable runtime copy; a separate source
      blob in ``arena.source_memory`` is hydrated into it before
      the first ``model_run``.

Source: `helia_aot/memory/defines.py:293`

### helia_aot.memory.defines.MemoryPlan.tensor_allocs

`attribute` · `python`

```python
tensor_allocs: dict[str, TensorAllocation] = Field(..., default_factory=dict, description='Tensor allocations')
```

Tensor
allocations. Each carries a :class:`TensorBinding`
recording ``(role, memory, offset, source_memory)``.

Source: `helia_aot/memory/defines.py:335`

### helia_aot.memory.defines.MemoryPlan.arena_usages

`attribute` · `python`

```python
arena_usages: dict[MemoryType, ArenaUsage] = Field(..., default_factory=dict, description='Memory arena usages')
```

Scratch arenas,
keyed by ``MemoryType``.

Source: `helia_aot/memory/defines.py:336`

### helia_aot.memory.defines.MemoryPlan.constant_arenas

`attribute` · `python`

```python
constant_arenas: dict[MemoryType, ArenaUsage] = Field(..., default_factory=dict, description='Per-bank constant arenas (one per runtime memory).')
```

Constant
arenas, keyed by *runtime* (destination)
``MemoryType``. Per-arena single-source-memory invariant
holds (every constant in the same arena has the same
``source_memory``) so cold arenas and staged arenas are
both guaranteed to be a single contiguous source blob.

Source: `helia_aot/memory/defines.py:337`

### helia_aot.memory.defines.MemoryPlan.persistent_arenas

`attribute` · `python`

```python
persistent_arenas: dict[MemoryType, ArenaUsage] = Field(..., default_factory=dict, description='Per-bank persistent (resource-variable) arenas.')
```

Persistent
arenas, keyed by writable ``MemoryType``.

Source: `helia_aot/memory/defines.py:342`

### helia_aot.memory.defines.MemoryPlan.tensor_lifetimes

`attribute` · `python`

```python
tensor_lifetimes: dict[TensorId, TensorLifetime] = Field(..., default_factory=dict, description='Tensor lifetimes')
```

Tensor
lifetimes.

Source: `helia_aot/memory/defines.py:347`

### helia_aot.memory.defines.MemoryPlan.get_allocation

`method` · `python`

```python
get_allocation(tensor_id: str) -> TensorAllocation
```

Get the allocation metadata for a given tensor ID.

**Parameters**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| tensor_id | str | Required | The tensor ID to look up. |

**Returns**

| Name | Type | Description |
| --- | --- | --- |
| TensorAllocation | TensorAllocation | The allocation metadata for the tensor. |

**Raises**

| Name | Description |
| --- | --- |
| KeyError | If the tensor ID is not found in the allocations. |

Source: `helia_aot/memory/defines.py:349`

## helia_aot.memory.defines.MemoryPlannerType

`class` · `python`

```python
MemoryPlannerType()
```

Memory planner type

Selecting an experimental planner is an explicit act: the default
layout of an existing conversion is unchanged until one is opted
into.

All planners honor user-specified memory-region placement: per-tensor
``memory`` pins and ``constant_destination_memory`` routing from
``memory.tensors`` rules, and per-memory ``max_size`` budgets from
``memory.constraints``. The rules are identical; the outcomes are
not necessarily. Unpinned scratch spills to the next writable bank
when the current one fills, so a different visit order can move a
tensor between banks — an access-latency change, not only a
footprint one.

Source: `helia_aot/memory/defines.py:364`

### helia_aot.memory.defines.MemoryPlannerType.greedy

`attribute` · `python`

```python
greedy: str = auto()
```

First-fit planner in lifetime-start order. The
default, and the only non-experimental strategy.

Source: `helia_aot/memory/defines.py:393`

### helia_aot.memory.defines.MemoryPlannerType.greedy_by_size

`attribute` · `python`

```python
greedy_by_size: str = auto()
```

Experimental, opt-in largest-first offset
packing; typically a lower scratch high-water mark on models
with heterogeneous tensor sizes.

Source: `helia_aot/memory/defines.py:394`

### helia_aot.memory.defines.MemoryPlannerType.hill_climb

`attribute` · `python`

```python
hill_climb: str = auto()
```

Experimental, opt-in local search over
greedy-by-size placement orders; its scratch high-water
mark is never worse than ``greedy_by_size``. Tunable via
``memory.planner_options`` (``iterations``, ``seed``,
``max_stall_iterations``).

Source: `helia_aot/memory/defines.py:395`

## helia_aot.memory.defines.TensorAttributes

`class` · `python`

```python
TensorAttributes()
```

This class provides the baseline set of tensor attribute rules.

Source: `helia_aot/memory/defines.py:398`

### helia_aot.memory.defines.TensorAttributes.memory

`attribute` · `python`

```python
memory: MemoryType = Field(default=MemoryType.DTCM, description='Memory placement for tensors')
```

Memory placement for tensors. For
constants this is the **source** (cold-storage) memory
where the tensor's bytes live in the image. When
``constant_destination_memory`` is set and differs from
``memory``, the runtime arena lives in that destination
memory and a hydration copy is required; otherwise the
arena lives in ``memory`` itself and is read-only (cold).

Source: `helia_aot/memory/defines.py:421`

### helia_aot.memory.defines.TensorAttributes.constant_destination_memory

`attribute` · `python`

```python
constant_destination_memory: MemoryType | None = Field(default=None, description='Per-tensor runtime destination memory for constants. When None (default) the constant is read in place from its source memory; when set the constant is hydrated into a writable arena slot in the destination memory.')
```

Override the
runtime (kernel-visible) memory for a constant. Required
only when the runtime memory must differ from the source
memory (e.g. weights stored in MRAM but read from
DTCM/SRAM at runtime). When ``None`` (default), the
runtime memory equals ``memory`` and no hydration step
is needed. Must reference a writable memory of the
target platform when set.

Source: `helia_aot/memory/defines.py:422`
