operator
Classes
CtxBufUsage
How an operator's lowering uses cmsis_nn_context::buf.
Every registered operator declares one of these via
:attr:AotOperator.CTX_BUF_USAGE. The declaration is the machine-checkable
half of a rule that used to live only in reviewers' heads: a kernel that
dereferences ctx->buf must never be handed a context whose buf is
NULL. Templates set ctx.buf = NULL whenever the operator allocated
no scratch tensor, so an operator whose scratch sizing returns 0 for a
dtype/target combination that still reaches a buf-reading kernel emits a
guaranteed NULL dereference -- either a silent memory-corrupting write (for
the kernels with no NULL guard) or a runtime ARM_CMSIS_NN_ARG_ERROR that
leaves the output stale. See
:meth:AotOperator._assert_ctx_buf_backed for why neither is caught before
silicon without a resolve-time check.
Attributes:
-
NO_CTX–The template passes no
cmsis_nn_contextto any kernel -- either it calls no CMSIS-NN kernel at all, or every kernel it dispatches takes no context argument. -
IGNORED–A context is passed, but no dispatchable kernel dereferences
buf(typically an explicit(void)ctx;upstream). -
REQUIRED–At least one dispatchable kernel dereferences
ctx->buffor every configuration the operator supports. -
CONDITIONAL–Whether
bufis dereferenced depends on dtype, target capability, or operator options. Subclasses declaring this MUST override :meth:AotOperator.ctx_buf_required.
AotOperator
AotOperator(op: AirOperator, model: AirModel, platform: SocPlatform, prefix: str = 'aot', attributes: dict[str, Any] | None = None)
Base class for all AOT operators.
Execution flow:
1. Initialize the operator.
2. Call resolve() to validate and prepare the operator.
3. Call plan() to set up any necessary planning.
4. Call emit() to generate the operator's code.
Parameters:
-
(opAirOperator) –The AIR operator to wrap.
-
(modelAirModel) –The AIR model.
-
(platformSocPlatform) –The target platform for code generation.
-
(prefixstr, default:'aot') –Prefix for generated code files. Defaults to "aot".
-
(attributesdict[str, Any] | None, default:None) –Attributes for template values.
Attributes
has_init
property
Whether this operator emits a per-instance _init function.
Operators whose initialization is a no-op may opt out by returning
False. When an operator opts out, it must not emit an _init
function/declaration in its templates, and the dispatch table records a
NULL init slot (the model init loop skips the call while preserving
the init callback contract). Defaults to True so existing operators
keep emitting their own init unchanged.
Returns:
-
bool–Trueif a per-instance_initfunction is emitted.
capabilities
property
Return the operator's effective optimization capabilities.
The effective set is the declared :attr:CAPABILITIES widened by the
capabilities implied by the operator's runtime behavior, so the legacy
seams remain the source of truth during migration and no operator has to
declare a capability twice:
not self.has_initimplies :attr:OpCapability.STATELESS.- A non-empty :meth:
shared_kernel_helpersor :meth:shared_activation_helpersimplies :attr:OpCapability.DESCRIPTOR_DRIVENand :attr:OpCapability.SHARED_KERNEL.
Because some seams are dtype-dependent (e.g. fully-connected only routes through a shared kernel for int8 per-channel quantization), this is an instance property rather than a class constant: it reflects the concrete resolved operator. It performs no model mutation and does not change emitted code.
Returns:
-
OpCapability–The effective :class:
OpCapabilityflag set.
direct_dispatch
property
Return the direct shared-kernel call target for static scheduling.
Under static scheduling the model schedule can call a descriptor
driven operator's shared kernel helper directly, eliding the thin
per-node _run thunk (the main .text reclaim described in RFC
0003 Stage 4). This is only valid for operators whose _run body is
exactly return helper(ctx, &desc); -- i.e. operators that route
through a single shared kernel helper with the uniform
helper(ctx, const desc_t *) signature (ADD/MUL/per-channel
int8 FULLY_CONNECTED). Shared activation helpers marshal flattened
arguments and keep mutable file-scope state, so they are intentionally
excluded and keep their _run thunk.
Returns:
Functions
typed_options
Return self.op.options checked against the operator's options class.
AirOperator.options is typed as the AirOperatorOptions marker
base; each AOT operator knows its concrete class and reads through
this so field access is type-checked and a mismatch (a mis-registered
parser, a hand-built graph) fails with a clear error.
Parameters:
-
(options_typetype[_OptionsT]) –The
AirXxxOptionsclass this operator expects.
Returns:
-
_OptionsT–The options object, typed as
options_type.
Raises:
-
TypeError–If the operator carries options of a different class.
float_io_dtypes
cmsis_float_dependencies
Float dtypes for which this operator needs the ns-cmsis-nn float API.
A returned dtype means the emitted C references the float-only
arm_nnfunctions_flt.h API (a gated arm_*_f32 / arm_*_f16
kernel or the float16_t / float32_t types it introduces) for
that precision, so the ns-cmsis-nn build must enable
ARM_NN_ENABLE_F32 / ARM_NN_ENABLE_F16.
The base implementation derives the set from
:attr:USES_CMSIS_FLOAT_KERNEL: operators that dispatch to a gated
float kernel advertise every float dtype on their IO; everything else
(integer kernels, byte movers, portable conversions) advertises none.
Operators with a per-instance dependency override this method.
Returns:
cmsis_nn_version_requirement
Minimum ns-cmsis-nn version this operator instance requires.
The base implementation applies :attr:MIN_CMSIS_NN_VERSION_FLOAT
only when the operator actually takes its float path, reusing the
same :meth:cmsis_float_dependencies contract that drives the float
header include and the ARM_NN_ENABLE_F32 / ARM_NN_ENABLE_F16
build defines. An int8 ABS therefore imposes no floor while an fp32
ABS does, so integer-only modules keep building against the older
library they have always supported.
Operators with an unconditional floor, or one that varies by something other than float dispatch, override this.
Returns:
tensor_zero_point
staticmethod
intern_constant_array
intern_constant_array(name: str, data: ndarray, *, role: AirTensorKind = AirTensorKind.CONSTANT, alignment: int | None = None) -> TensorId
Promote an operator-local constant array into a model tensor.
This routes operator metadata (e.g. per-channel quantization tables)
through the same machinery as ordinary constants: memory planning,
duplicate-constant interning (storage dedup), cold/staged residency,
and uniform tensor-pointer resolution. The tensor is registered under
op.named_tensors[name] so templates can reference it via
ctx->tensor_ptrs[...] like any other tensor.
The operation is idempotent: a previously interned tensor with the same deterministic id is replaced.
Parameters:
-
(namestr) –Local tensor name; also used to build the deterministic id.
-
(datandarray) –Array payload, stored as a contiguous copy.
-
(roleAirTensorKind, default:CONSTANT) –Tensor kind/bucket. Defaults to
CONSTANT. -
(alignmentint | None, default:None) –Optional alignment hint in bytes.
Returns:
-
TensorId(TensorId) –The id of the registered tensor.
resolve
Public entry point—only runs once, even if called repeatedly.
This method validates the AIR operator and performs any model mutations needed.
Raises:
-
ValueError–If the operator declares that a kernel reads through a
cmsis_nn_contextbuffer but allocated no backing for it (see :meth:_assert_ctx_buf_backed).
ctx_buf_required
Whether this concrete operator's lowering dereferences ctx->buf.
Only meaningful for operators declaring
:attr:CtxBufUsage.CONDITIONAL, which MUST override this. Evaluate it
against the same inputs the operator's scratch sizing uses (dtype,
options, platform capability) so the two can never disagree: the guard
exists precisely to catch the case where sizing says "0 bytes" and the
dispatched kernel says "I read that buffer".
Returns:
-
bool–Trueif at least one kernel this operator can dispatch reads or -
bool–writes through
ctx->buf.
Raises:
-
NotImplementedError–If called on an operator that did not declare :attr:
CtxBufUsage.CONDITIONALand override this method.
shared_kernel_helpers
Return the shared operator-kernel helpers this operator requires.
This mirrors :meth:shared_activation_helpers but for general operator
kernels (e.g. elementwise ADD/MUL or FULLY_CONNECTED). An
operator that routes its _run body through a shared runtime helper
(instead of an inlined per-node call site) declares the helper
descriptors here so the code generator emits each distinct helper
exactly once. Helpers are keyed by signature, so distinct operator
variants map to distinct helpers and never collide. The base
implementation requires no shared kernels.
Returns:
-
list[KernelHelper]–A list of :class:
KernelHelperdescriptors (see -
list[KernelHelper]–mod:
helia_aot.aot.operators.kernel_runtime). Empty for operators -
list[KernelHelper]–that do not use a shared kernel helper.
shared_activation_helpers
Return the shared LUT-activation helpers this operator requires.
Operators that emit their hot loop via a shared runtime helper (rather than an inlined per-node body) declare the helper descriptors here so the code generator can emit each distinct helper exactly once. The base implementation requires no shared helpers.
Returns:
compute_values
emit
Generate the source code for the operator.
This method should be overridden by subclasses.
Parameters:
-
(save_pathPath) –Path to save the generated source code.