# helia_aot.air.shape_propagation

## helia_aot.air.shape_propagation.ShapeRuleResult

`class` · `python`

```python
ShapeRuleResult()
```

Base type for shape propagation rule outcomes.

Source: `helia_aot/air/shape_propagation.py:55`

## helia_aot.air.shape_propagation.NotApplicable

`class` · `python`

```python
NotApplicable() -> None
```

`dataclass`

Rule does not own this operator case and generic fallback may run.

Source: `helia_aot/air/shape_propagation.py:59`

## helia_aot.air.shape_propagation.Updated

`class` · `python`

```python
Updated(shapes: dict[str, tuple[int, ...]]) -> None
```

`dataclass`

Rule produced concrete output shape updates.

Source: `helia_aot/air/shape_propagation.py:64`

### helia_aot.air.shape_propagation.Updated.shapes

`attribute` · `python`

```python
shapes: dict[str, tuple[int, ...]]
```

Source: `helia_aot/air/shape_propagation.py:68`

## helia_aot.air.shape_propagation.NoUpdate

`class` · `python`

```python
NoUpdate(reason: str = '') -> None
```

`dataclass`

Rule owns this operator case and no shape update is required.

Source: `helia_aot/air/shape_propagation.py:75`

### helia_aot.air.shape_propagation.NoUpdate.reason

`attribute` · `python`

```python
reason: str = ''
```

Source: `helia_aot/air/shape_propagation.py:79`

## helia_aot.air.shape_propagation.Blocked

`class` · `python`

```python
Blocked(reason: str) -> None
```

`dataclass`

Rule owns this operator case and cannot safely infer an update.

Source: `helia_aot/air/shape_propagation.py:82`

### helia_aot.air.shape_propagation.Blocked.reason

`attribute` · `python`

```python
reason: str
```

Source: `helia_aot/air/shape_propagation.py:86`

## helia_aot.air.shape_propagation.ShapeInferenceResult

`class` · `python`

```python
ShapeInferenceResult(
    changed_tensor_ids: set[str] = set(),
    confirmed_tensor_ids: set[str] = set(),
    evaluated_tensor_ids: set[str] = set(),
    unresolved_tensor_ids: set[str] = set(),
    deferred_conflict_tensor_ids: set[str] = set(),
    diagnostics: list[str] = list(),
) -> None
```

`dataclass`

Shape propagation outcome.

Source: `helia_aot/air/shape_propagation.py:92`

### helia_aot.air.shape_propagation.ShapeInferenceResult.changed_tensor_ids

`attribute` · `python`

```python
changed_tensor_ids: set[str] = field(default_factory=set)
```

Tensor IDs whose shapes changed during propagation.

Source: `helia_aot/air/shape_propagation.py:114`

### helia_aot.air.shape_propagation.ShapeInferenceResult.confirmed_tensor_ids

`attribute` · `python`

```python
confirmed_tensor_ids: set[str] = field(default_factory=set)
```

Tensor IDs whose shapes a rule computed from proven
operands, whether or not the stored shape changed, plus concrete graph
inputs with a dynamic signature. A dynamic-signature tensor whose
inferred shape already matched is resolved, not unresolved.

Source: `helia_aot/air/shape_propagation.py:115`

### helia_aot.air.shape_propagation.ShapeInferenceResult.evaluated_tensor_ids

`attribute` · `python`

```python
evaluated_tensor_ids: set[str] = field(default_factory=set)
```

Shape-expression tensors whose compile-time value
propagation computed and stored in ``AirTensor.inferred_value``.

Source: `helia_aot/air/shape_propagation.py:116`

### helia_aot.air.shape_propagation.ShapeInferenceResult.unresolved_tensor_ids

`attribute` · `python`

```python
unresolved_tensor_ids: set[str] = field(default_factory=set)
```

Dynamic tensor IDs that remain unresolved.

Source: `helia_aot/air/shape_propagation.py:117`

### helia_aot.air.shape_propagation.ShapeInferenceResult.deferred_conflict_tensor_ids

`attribute` · `python`

```python
deferred_conflict_tensor_ids: set[str] = field(default_factory=set)
```

Unresolved tensor IDs whose inferred shape
conflicted with their declared contract while computed from an
unresolved operand. Such a shape can come from a placeholder, so the
update was dropped rather than raised.

Source: `helia_aot/air/shape_propagation.py:118`

### helia_aot.air.shape_propagation.ShapeInferenceResult.diagnostics

`attribute` · `python`

```python
diagnostics: list[str] = field(default_factory=list)
```

Human-readable diagnostics describing inference updates and unresolved
tensors. Skip diagnostics (rule/fallback skipped) are only included when DEBUG
logging is enabled to avoid unbounded growth on large graphs.

Source: `helia_aot/air/shape_propagation.py:119`

## helia_aot.air.shape_propagation.propagate_shapes

`function` · `python`

```python
propagate_shapes(model: AirModel, *, strict: bool = False, warn_unresolved: bool = True) -> ShapeInferenceResult
```

Infer tensor shapes and shape-expression values over the graph until fixed point.

Shapes and values depend on each other: ``SHAPE`` turns a tensor's shape
into a value, and a RESHAPE turns its target value back into a shape. Both
are facts in the same worklist, so a chain of any depth resolves without a
fixed pass order. Values are computed only for ``SHAPE`` and for
STRIDED_SLICE and PACK nodes over shape-derived tensors (see
``shape_expressions``), and only from proven shapes, so a placeholder can
never become a value. A shape the model declares fully static counts as
proven, so a value can come from declared metadata as well as from the
graph-input shapes. Each value is stored in ``AirTensor.inferred_value``,
never in ``data``, and the graph structure is left unchanged;
``FoldStaticShapeExpressions`` turns the values into constants afterwards.

**Parameters**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| model | AirModel | Required | AIR model to update in place. |
| strict | bool | False | If True, raise when unresolved dynamic tensors remain. |
| warn_unresolved | bool | True | If True, log unresolved tensors when not raising. |

**Returns**

| Name | Type | Description |
| --- | --- | --- |
|  | ShapeInferenceResult | Shape inference result with updated tensors and diagnostics. |

**Raises**

| Name | Description |
| --- | --- |
| UnsupportedModelError | If ``strict`` is True and unresolved dynamic tensors remain, or if a shape or value computed from proven inputs contradicts a tensor's declared contract. |
| TypeError | If an operator's options type does not match its shape rule's contract, or a rule returns an unknown result type. |

Source: `helia_aot/air/shape_propagation.py:1273`
