Skip to content

Attributes

Attributes let you tune how HeliosAOT compiles and lays out your model without changing the graph. You can set them from the command line or in a YAML configuration file. It is recommended to use YAML for more complex setups.


What can I target?

An attribute rule targets a set of entities in your model:

  • Operators (by type like CONV_2D, ADD, …, or by a specific operator id)
  • Tensors (by type like SCRATCH, PERSISTENT, CONSTANT, …, or by a specific tensor id)

A rule has three top-level keys:

  • type: the entity “type” selector
    • Operators: e.g. CONV_2D, ADD, …
    • Tensors: e.g. SCRATCH, PERSISTENT, CONSTANT
    • Special: * to match all entities
  • id: the entity identifier(s) (string or list of strings)
    • Use the exact operator/tensor ids from the model
  • attributes: a mapping of the options you want to apply

Note: The attribute id in your YAML corresponds to the entity id (operator or tensor). If you provide multiple ids, the rule applies to all of them.


How rules are applied (specificity)

When multiple rules match the same entity, HeliosAOT merges them in a predictable order:

  1. All matching rules are collected.
  2. They’re sorted by specificity and then by their order in the YAML file. Specificity (higher beats lower):

    • (1, 1) → both type and id are specified and match
    • (1, 0) → only type is specified
    • (0, 1) → only id is specified
    • (0, 0) → neither is specified (*)
  3. The rules are merged in that order, so later rules override earlier ones on a field-by-field basis.

☝️ Tie-breaker: if two rules have the same specificity, the one that appears later in your YAML wins.


What can I set?

You’ll find the complete field lists on the dedicated pages:

HeliosAOT accepts a small, focused core of fields and will safely ignore unknown keys where configured (we default to being forgiving so you can evolve your configs).


How do I determine entity IDs?

HeliosAOT matches operator IDs and tensor IDs to the original model by default (IDs are normalized to strings). There are a few easy ways to find them:

1) From your source model (Netron / Model Explorer)

  • Open the model in Netron or your Model Explorer.
  • Each operator/node and each tensor/edge has an identifier/id.
  • Use those exact identifiers in your attributes YAML (operator/tensor IDs are treated as strings).

2) From the generated offline module docs

The C inference module’s offline site includes:

  • A Model page that includes:
    • Input Tensor Table and Output Tensor Table listing their IDs, types, shapes, and quantization.
    • Operator Connectivity Table including Operator ID and Tensor IDs (inputs, outputs, and locals)
    • Model Diagram with operator IDs and tensor IDs annotated.
  • A Memory page that includes:
    • Tensor Table listing their IDs, memory location/offset, and operator lifetime.

Note: The tables are searchable/filterable by all fields. Use the search box to quickly locate the exact operator or tensor id you want to target in your YAML.

3) From the generated source code

The generated C code includes a _tensor.c file that includes a tensor descriptor for every tensor in the model. This descriptor contains all the relevant information about each tensor, including its ID, type, shape, and quantization. The tensor enum contains the id in format tensor.


Examples

1) Pin all constant tensors to MRAM

tensors:
    - type: CONSTANT
    attributes:
        memory: MRAM

2) Place CONV_2D code in ITCM

operators:
    - type: CONV_2D
    attributes:
        code_placement: ITCM
        scratch_placement: SRAM

3) Override a specific operator (beats the broad rule above)

operators:
    - type: CONV_2D
    id: "1"
    attributes:
        code_placement: ITCM
        scratch_placement: DTCM

4) Target a list of tensors by id and put them in SRAM

tensors:
    - type: SCRATCH
    id: ["17", "conv_2d_0_scratch"]
    attributes:
        memory: SRAM

Tips & best practices

  • Start broad, refine later. Add a general rule (type: CONV_2D) first, then add per-id overrides as needed.
  • Place hot scratch in fast RAM. Keep large constants and persistent buffers in NVM/PSRAM when practical.
  • Be explicit on critical paths. Use per-id rules for your tightest loops.
  • Keep YAML readable. Prefer short rule blocks with clear comments over one giant catch-all.

Troubleshooting

  • "My setting didn’t ‘stick’." → Check if a more specific or later rule overrides it.
  • "This operator/tensor didn’t match." → Verify the exact id and type name you used are correct for your model.
  • "Unknown key warnings." → They’re safe to ignore if you’re experimenting; remove keys once you settle on a config.

If you’re ready to dive into the exact fields, continue with: