Skip to content

render_plan

Render-side projection of a :class:~helia_aot.memory.MemoryPlan.

The memory planner produces a :class:MemoryPlan describing how tensors map into arenas. Templates and emit handlers historically reached directly into that structure to recompute derived facts (cold-vs-staged predicates, sidecar filenames, packed blob bytes, etc.). That coupling made it impossible to swap a different planner backend without re-deriving every predicate in the templates, and it scattered the same logic across multiple sites.

This module introduces a small set of frozen render dataclasses that sit between the planner and the codegen. The builder (:func:build_render_plan) is the only place that knows how to turn a :class:MemoryPlan into render-ready records:

  • :class:RenderArena — one arena (scratch, persistent, or constant) with all derived predicates pre-resolved (is_staged, role) and an explicit, deterministic region_id.
  • :class:RenderConstantBlob — one packed byte image for a constant arena, ready to be written as a sidecar or embedded inline.
  • :class:RenderMemoryPlan — top-level container holding the arenas and constant blobs, plus a plan_hash that fingerprints the schema-relevant region layout for ABI drift detection.

The DTO is additive: CodeGenContext.memory_plan is unchanged and templates that have not been migrated continue to work. Migration proceeds incrementally.

Classes

RenderArena dataclass

RenderArena(region_id: int, role: ArenaRoleStr, memory: MemoryType, source_memory: MemoryType, size: int, alignment: int, is_staged: bool)

Render-side projection of one :class:ArenaUsage.

Attributes:

  • region_id (int) –

    Stable region index used as the C enumerator value. Assigned by :func:build_render_plan from a deterministic policy (role priority then memory.name ascending) so two independent re-plans of the same model produce identical region IDs.

  • role (ArenaRoleStr) –

    Logical role as a plain string (scratch, persistent, or constant). Stable across planner backends and friendly for template comparisons.

  • memory (MemoryType) –

    Runtime (kernel-visible) memory of the arena.

  • source_memory (MemoryType) –

    Cold-storage source memory. Equals memory for non-staged arenas; different for staged constants.

  • size (int) –

    Bytes used (==arena.used). For bump-allocated constant/persistent arenas this also equals total_size.

  • alignment (int) –

    Resolved alignment of the arena base symbol.

  • is_staged (bool) –

    True iff source_memory differs from memory. Centralized so every consumer (template, handler, doc snippet) reads the same predicate.

RenderConstantBlob dataclass

RenderConstantBlob(memory: MemoryType, is_staged: bool, sidecar_filename: str, payload: bytes)

One packed byte image for a constant arena.

Attributes:

  • memory (MemoryType) –

    Runtime memory of the destination arena.

  • is_staged (bool) –

    True iff the arena is staged (copy at boot) rather than cold (read in place).

  • sidecar_filename (str) –

    Filename to use when writing the byte image as a sidecar in external-arena builds. Already includes the module prefix and the __blob / __source suffix that matches the corresponding C symbol.

  • payload (bytes) –

    Packed bytes including alignment padding between constants.

RenderMemoryPlan dataclass

RenderMemoryPlan(scratch_arenas: tuple[RenderArena, ...] = tuple(), persistent_arenas: tuple[RenderArena, ...] = tuple(), constant_arenas: tuple[RenderArena, ...] = tuple(), constant_blobs: tuple[RenderConstantBlob, ...] = tuple(), plan_hash: str = '', tensor_layout_hash: str = '')

Render-ready projection of a :class:MemoryPlan.

Attributes:

  • scratch_arenas (tuple[RenderArena, ...]) –

    Scratch arenas in deterministic order.

  • persistent_arenas (tuple[RenderArena, ...]) –

    Persistent arenas in deterministic order.

  • constant_arenas (tuple[RenderArena, ...]) –

    Constant arenas in deterministic order.

  • constant_blobs (tuple[RenderConstantBlob, ...]) –

    One packed byte image per constant arena, ordered to match constant_arenas.

  • plan_hash (str) –

    Hex digest fingerprinting the arena envelope only: per-region (role, memory, source_memory, size, alignment, is_staged) in region_id order. Stable across re-plans of the same model; changes when any region's envelope shape differs. Emitted into the generated header as <PREFIX>_PLAN_HASH so downstream binaries can detect arena-ABI drift at link time. Does not cover per-tensor placement (a planner change that re-shuffles tensors within the same arena envelope leaves plan_hash unchanged); use :attr:tensor_layout_hash for the per-tensor layer.

  • tensor_layout_hash (str) –

    Hex digest fingerprinting per-tensor placement: each tensor's (tensor_id, role, memory, offset, size) in sorted tensor_id order. Captures drift the arena-envelope hash can miss (e.g. two tensors swapping offsets within the same arena). Surfaced in the residency JSON; not currently emitted as a C macro.

Attributes

staged_constant_arenas property
staged_constant_arenas: tuple[RenderArena, ...]

Constant arenas with a distinct cold source memory.

Convenience for templates that gate hydration emission on the presence of any staged-constant residency.

has_staged_constants property
has_staged_constants: bool

True iff any constant arena is staged.

all_arenas property
all_arenas: tuple[RenderArena, ...]

Every arena in region_id order.

Concatenation of scratch_arenas + persistent_arenas + constant_arenas; the index in the returned tuple equals arena.region_id for every entry. This is the canonical iteration order for any consumer that needs region IDs to match the C enumerator values (size table, alignment table, bind table).

Functions

build_render_plan

build_render_plan(plan: MemoryPlan, model: 'Model', *, module_prefix: str) -> RenderMemoryPlan

Project a :class:MemoryPlan into a :class:RenderMemoryPlan.

All cold-vs-staged decisions, sidecar filename construction, constant-blob byte assembly, and region-id assignment happen here. Downstream consumers (templates, sidecar emit) read the resolved fields directly.

Region IDs follow an explicit policy: scratch arenas first, then persistent, then constant. Within each role, arenas are sorted by memory.name ascending. The generated plan_hash fingerprints the schema-relevant fields so a downstream binary can detect when its compiled-against region layout no longer matches a freshly-planned one.

Parameters:

  • plan

    (MemoryPlan) –

    The planner output to project.

  • model

    ('Model') –

    The model the plan was produced for; needed to materialize constant byte payloads.

  • module_prefix

    (str) –

    Module prefix used when constructing sidecar filenames.

Returns:

Raises:

  • ValueError

    If the planner output is missing emit-critical bindings (e.g. a constant tensor with no allocation, a constant arena whose slots disagree on their cold source memory). See :func:_validate_plan_completeness for the full set of contracts.