# Ethos-U

Convert a Vela-compiled model for the Ethos-U NPU on `atomiq110`.
heliaAOT consumes the command stream Vela produces; it does not call Vela.

| Field | Value |
| --- | --- |
| Model | a compatible Vela-compiled LiteRT model you supply |
| Target | `atomiq110` |
| Shows | The Ethos-U operator, the driver dependency, and the platform gate |
| CI | Manual. The input needs Arm Vela, and the Ethos-U85 path this platform targets has no automated coverage ([#78](https://github.com/AmbiqAI/helia-aot/issues/78)). |

The model is whatever `VELA_MODEL` points at. Neither Vela nor a Vela artifact
is supplied by this example. This is a converter-stage recipe, not an
end-to-end Vela or board bring-up tutorial. Record your Vela version,
accelerator configuration, input/output hashes and matching driver/platform
versions before using it. A tested complete U85 setup is not established here.

## Prerequisites

Use a repository checkout with Bash and the environment from [Running examples](https://ambiqai.github.io/helia-aot/examples/): `uv sync --frozen --group ci`, then activate `.venv`. Supply a compatible Vela-compiled model and run the commands below from this example directory. This step converts on the host; building and running the module also requires the matching Ethos-U driver and target environment.

## Run it

```sh
VELA_MODEL=/path/to/vela_model.tflite ./run.sh
```

[config.yaml](https://github.com/AmbiqAI/helia-aot/blob/cf2246a7ad439fa38d57462118e7840e5497a685/examples/ethos-u/config.yaml) selects `atomiq110` as the target. Vela has already
partitioned the model and produced the accelerator command stream; selecting
a target in heliaAOT does not offload an ordinary graph to the NPU.

Successful conversion writes the configured module under `out/`; inspect its
ETHOS_U source and build dependencies. Compilation and actual accelerator
execution are separate checks. The supplied model still has to satisfy the
converter’s supported tensor/shape/operator contracts.

## What happens

Every Ethos-U-supported subgraph arrives as a single `ETHOS_U` operator whose
first input is the command stream. The generated module wraps the driver's
invoke call and wires up the command stream and the base addresses for inputs,
outputs and Vela's auxiliary buffers. Operators Vela did not take stay
ordinary kernels.

Buffer alignment is handled for you. Where Vela emitted its own offline memory
allocation, heliaAOT honours those offsets rather than re-planning the region,
so the addresses the command stream was compiled against stay valid.

## The driver is a hard dependency

A module containing `ETHOS_U` operators will not compile without the driver
header on the include path; the generated translation unit stops with an
`#error`. This is deliberate. A missing header used to compile a stub that
returned success without touching the accelerator, so an integrator could ship
a passing build whose accelerator never ran.

A non-functional stub is still available for host-side codegen tests and for
bring-up without a driver tree, and it has to be asked for explicitly with
`-DHELIA_ETHOSU_ALLOW_STUB=1`. Never use it in a build expected to run the
model.

## The platform gate

Converting a Vela model against a platform that declares no accelerator is
rejected at conversion time. Simulation is the legitimate exception, most
often an Arm fixed virtual platform that provides the accelerator itself. Opt
out per operator, in the configuration file only:

```yaml
operators:
  - type: ETHOS_U
    attributes:
      require_platform_npu: "false"
```

`--operators` is a nested-model flag and rejects inline values on the command
line.

## Support status

End-to-end tests exercise Ethos-U55 on an Arm Corstone-300 fixed virtual
platform, with the gate opted out as above. The Ethos-U85 path that
`atomiq110` targets is not covered by CI, which is why this example is manual.

## Next

- [Targets and silicon](https://ambiqai.github.io/helia-aot/guide/targets/)
  for the platform families and the full Ethos-U section.
