This content is for v0.12.0. Switch to the latest version for up-to-date documentation.
Choosing a Kernel Backend
TiGrIS plans are target-independent. The backend selected with tigris codegen
chooses the kernels used by the generated integration code; it does not change
the model or plan format.
For initial integration and host testing, use reference. For an int8 deployment,
select esp-nn on ESP32-S3 or cmsis-nn on Cortex-M. Both accelerated backends
fall back to TiGrIS’s portable int8 kernels when a vendor kernel cannot preserve
the plan’s semantics. Float32 operators inside an int8 plan use the portable
float kernels on either backend.
At a glance
Section titled “At a glance”--backend |
Intended target | Float32 plan | Int8 plan |
|---|---|---|---|
reference |
POSIX, tests, portable deployments | Portable C | Portable C |
esp-nn |
ESP32-S3 | Portable C | ESP-NN with portable fallback |
cmsis-nn |
Arm Cortex-M | Portable C | CMSIS-NN with portable fallback |
ESP-NN and CMSIS-NN accelerate int8 only. Selecting either for a float32 plan explicitly uses the portable float implementation.
Supported operators
Section titled “Supported operators”The table covers the plan operators that remain after TiGrIS normalizes an ONNX graph or converts a TFLite model; TFLite operator names and their limits are in Compiling a TFLite Model. Native means the vendor library is normally used. Portable fallback remains supported but does not receive vendor acceleration. The ESP-NN and CMSIS-NN columns describe int8 routes; float sections use the portable float32 route.
| Operator | Portable C | ESP-NN (int8) | CMSIS-NN (int8) |
|---|---|---|---|
Conv | Float32 + int8 | Native* | Native* |
DepthwiseConv | Float32 + int8 | Native* | Native* |
Relu | Float32 + int8 | Portable fallback | Portable fallback |
Relu6 | Float32 + int8 | Portable fallback | Portable fallback |
MaxPool | Float32 + int8 | Portable fallback | Portable fallback |
AveragePool | Float32 + int8 | Native* | Native* |
Add | Float32 + int8 | Portable fallback | Portable fallback |
Mul | Float32 + int8 | Native* | Native* |
Gemm | Float32 + int8 | Native | Native |
Softmax | Float32 + int8 | Portable fallback | Portable fallback |
Sigmoid | Float32 + int8 | Portable fallback | Portable fallback |
Concat | Float32 + int8 | Portable fallback | Portable fallback |
Pad | Float32 + int8 | Portable fallback | Portable fallback |
GlobalAveragePool | Float32 + int8 | Portable fallback | Native* |
Flatten | Float32 + int8 | Portable fallback | Portable fallback |
Reshape | Float32 + int8 | Portable fallback | Portable fallback |
Sub | Float32 + int8 | Portable fallback | Portable fallback |
Div | Float32 + int8 | Portable fallback | Portable fallback |
Tanh | Float32 + int8 | Portable fallback | Portable fallback |
LeakyRelu | Float32 + int8 | Portable fallback | Portable fallback |
ConvTranspose | Float32 + int8 | Portable fallback | Portable fallback |
MatMul | Float32 + int8 | Portable fallback | Portable fallback |
ReduceMean | Float32 + int8 | Portable fallback | Portable fallback |
Transpose | Float32 + int8 | Portable fallback | Portable fallback |
Resize | Float32 + int8 | Portable fallback | Portable fallback |
GlobalMaxPool | Float32 + int8 | Portable fallback | Portable fallback |
Conv1D | Float32 + int8 | Portable fallback | Portable fallback |
LayerNormalization | Float32 + int8 | Portable fallback | Portable fallback |
Erf | Float32 + int8 | Portable fallback | Portable fallback |
Split | Float32 + int8 | Portable fallback | Portable fallback |
ResizeLinear | Float32 + int8 | Portable fallback | Portable fallback |
HardSwish | Float32 + int8 | Portable fallback | Portable fallback |
Abs | Float32 + int8 | Portable fallback | Portable fallback |
Rsqrt | Float32 + int8 | Portable fallback | Portable fallback |
SquaredDifference | Float32 + int8 | Portable fallback | Portable fallback |
Max | Float32 + int8 | Portable fallback | Native* |
Min | Float32 + int8 | Portable fallback | Native* |
Neg | Float32 | Unsupported | Unsupported |
Exp | Float32 | Unsupported | Unsupported |
Log | Float32 | Unsupported | Unsupported |
Sqrt | Float32 | Unsupported | Unsupported |
Square | Float32 | Unsupported | Unsupported |
Floor | Float32 | Unsupported | Unsupported |
Ceil | Float32 | Unsupported | Unsupported |
Round | Float32 | Unsupported | Unsupported |
Sin | Float32 | Unsupported | Unsupported |
Cos | Float32 | Unsupported | Unsupported |
FloorDiv | Float32 | Unsupported | Unsupported |
FloorMod | Float32 | Unsupported | Unsupported |
PRelu | Float32 + int8 | Portable fallback | Portable fallback |
Elu | Float32 + int8 | Portable fallback | Portable fallback |
LogSoftmax | Float32 + int8 | Portable fallback | Portable fallback |
L2Normalization | Float32 + int8 | Portable fallback | Portable fallback |
L2Pool | Float32 | Unsupported | Unsupported |
ReduceMax | Float32 + int8 | Portable fallback | Portable fallback |
ReduceMin | Float32 + int8 | Portable fallback | Portable fallback |
ReduceSum | Float32 + int8 | Portable fallback | Portable fallback |
CumSum | Float32 + int8 | Portable fallback | Portable fallback |
ArgMax | Float32 + int8 | Portable fallback | Portable fallback |
ArgMin | Float32 + int8 | Portable fallback | Portable fallback |
Gather | Float32 + int8 | Portable fallback | Portable fallback |
GatherND | Float32 + int8 | Portable fallback | Portable fallback |
StridedSlice | Float32 + int8 | Portable fallback | Portable fallback |
MirrorPad | Float32 + int8 | Portable fallback | Portable fallback |
ReverseV2 | Float32 + int8 | Portable fallback | Portable fallback |
EmbeddingLookup | Float32 + int8 | Portable fallback | Portable fallback |
DynamicUpdateSlice | Float32 + int8 | Portable fallback | Portable fallback |
Equal | Float32 + int8 | Portable fallback | Portable fallback |
Less | Float32 + int8 | Portable fallback | Portable fallback |
LessOrEqual | Float32 + int8 | Portable fallback | Portable fallback |
Greater | Float32 + int8 | Portable fallback | Portable fallback |
GreaterOrEqual | Float32 + int8 | Portable fallback | Portable fallback |
And | Float32 + int8 | Portable fallback | Portable fallback |
Or | Float32 + int8 | Portable fallback | Portable fallback |
Not | Float32 + int8 | Portable fallback | Portable fallback |
Where | Float32 + int8 | Portable fallback | Portable fallback |
Cast | Float32 + int8 | Portable fallback | Portable fallback |
Sum | Float32 + int8 | Portable fallback | Portable fallback |
ReduceAll | Float32 + int8 | Portable fallback | Portable fallback |
Svdf | Float32 + int8 | Portable fallback | Portable fallback |
Lstm | Float32 + int8 | Portable fallback | Portable fallback |
If | Float32 + int8 | Portable fallback | Portable fallback |
While | Float32 + int8 | Portable fallback | Portable fallback |
DetectionPostProcess | Float32 + int8 | Portable fallback | Portable fallback |
Quantize | Float32 + int8 | Portable fallback | Portable fallback |
Dequantize | Float32 + int8 | Portable fallback | Portable fallback |
Gelu | Float32 + int8 | Portable fallback | Portable fallback |
Important operator limits
Section titled “Important operator limits”The matrix uses the runtime’s NLC/NHWC layouts. For rank-3 and rank-4 ONNX activations, the channel axis becomes the runtime’s final dimension; this is the supported Softmax axis.
| Operator | Implemented form |
|---|---|
DepthwiseConv | one group per input channel with a channel multiplier |
Relu | rank-3 pointwise length tiling on serialized axis 1 |
Relu6 | rank-3 pointwise length tiling on serialized axis 1 |
MaxPool | explicit or auto_pad padding, floor or ceil output sizing, unit dilation, and no indices output |
AveragePool | explicit or auto_pad padding, floor or ceil output sizing, unit dilation, and count_include_pad=0 wherever padding is non-zero |
Add | each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand; a constant operand, on either side, float or per-tensor int8; one per element runs untiled |
Add | standalone rank-3 pointwise length tiling on serialized axis 1 |
Add | int32 operands and result together, wrapping on overflow, untiled and without an activation |
Mul | each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand; a constant operand, on either side, float or per-tensor int8; one per element runs untiled |
Mul | standalone rank-3 pointwise length tiling on serialized axis 1 |
Mul | int32 operands and result together, wrapping on overflow, untiled and without an activation |
Softmax | final axis only; tiling on serialized axis 1, each tile holding whole rows |
Sigmoid | rank-3 pointwise length tiling on serialized axis 1 |
Concat | rank-3 and rank-4 concatenation on any stored axis but the batch axis, tiled only on the last one; a constant part only as the leading operand of a float concatenation on the last stored axis |
Pad | constant mode with non-negative pads and a constant fill; int8 keeps its quantization; untiled execution |
GlobalAveragePool | rank-4 height tiling: each band of rows is added into the per-channel sums |
Sub | each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand; a constant operand, on either side, float or per-tensor int8; one per element runs untiled |
Sub | int32 operands and result together, wrapping on overflow, untiled and without an activation |
Div | each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand; a constant operand, on either side, float or per-tensor int8; one per element runs untiled; int8 requires per-tensor quantization |
Div | int8 rejects zero centered denominators and negative rounding exponents; rounding exponents >= 32 use wide mask/remainder/threshold arithmetic |
Tanh | rank-3 pointwise length tiling on serialized axis 1 |
ReduceMean | rank-3 mean over one axis; independent height or row bands. A rank-4 mean over both spatial axes is rewritten to GlobalAveragePool instead |
Transpose | a concrete, valid permutation is stored in schema 4+ plans |
Resize | rank-4 nearest-neighbor H/W resizing with asymmetric floor, half-pixel centers or align-corners rounding; height tiling as the stage's single spatial op, never in a chain |
Conv1D | standalone rank-3 length tiling on serialized axis 1; may compose with shape-preserving unary pointwise operators |
Split | parts along any stored axis; untiled execution |
ResizeLinear | rank-4 bilinear H/W resizing with half-pixel, asymmetric or align-corners coordinates; height tiling as the stage's single spatial op, never in a chain |
HardSwish | rank-3 pointwise length tiling on serialized axis 1 |
Abs | int8 requantization must stay within the 32-bit reference arithmetic domain |
Rsqrt | int8 requires nonnegative centered inputs and reference shifts in range |
SquaredDifference | each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand; a constant operand, on either side, float or per-tensor int8; one per element runs untiled |
SquaredDifference | int8 requantization must stay within the 32-bit reference arithmetic domain |
Max | each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand; a constant operand, on either side, float or per-tensor int8; one per element runs untiled; int8 quantization must match |
Min | each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand; a constant operand, on either side, float or per-tensor int8; one per element runs untiled; int8 quantization must match |
FloorDiv | each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand; a constant operand, on either side, float or per-tensor int8; one per element runs untiled; zero denominators are rejected |
FloorMod | each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand; a constant operand, on either side, float or per-tensor int8; one per element runs untiled |
PRelu | constant broadcast alpha, rank at most 4; each operand has the output's shape or broadcasts to it, a tensor operand at the output's rank; tiled only when every operand is dense, a repeating constant, or one value per channel as the second operand |
Elu | alpha=1 |
LogSoftmax | final stored axis; int8 output scale 1/16 and zero point 127 |
L2Normalization | final stored axis; int8 output scale 1/128 and zero point 0 |
L2Pool | float32 square root of the mean of valid squared samples |
ReduceMax | one axis of a rank-3 tensor; independent height or row bands; rank-4 spatial max with keepdims uses GlobalMaxPool; int8 quantization must match |
ReduceMin | one axis of a rank-3 tensor; independent height or row bands; int8 quantization must match |
ReduceSum | one axis of a rank-3 tensor; independent height or row bands; int8 rejects reference arithmetic overflow |
CumSum | one axis of a rank-3 tensor; independent height or row bands; exclusive and reverse; int8 input zero point 0 |
ArgMax | one axis of a tensor of rank 1 to 6; independent height or row bands; int32 indices in model outputs or index operands; first index wins ties |
ArgMin | one axis of a tensor of rank 1 to 6; independent height or row bands; int32 indices in model outputs or index operands; first index wins ties |
Gather | constant or runtime int32 indices; independent bands with constant indices; identical int8 quantization |
GatherND | constant or runtime int32 indices; independent bands with constant indices; identical int8 quantization |
StridedSlice | constant indices or bounds; bands along an unchanged axis; identical int8 quantization |
MirrorPad | constant indices or bounds; bands along an unchanged axis; identical int8 quantization |
ReverseV2 | constant indices or bounds; bands along an unchanged axis; identical int8 quantization |
EmbeddingLookup | constant or runtime int32 indices; independent bands with constant indices; identical int8 quantization |
DynamicUpdateSlice | constant or runtime int32 starts, clamped to the update domain; bands require constant starts and a dynamic update spanning the band axis; identical int8 quantization |
Equal | data or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1 |
Less | data or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1 |
LessOrEqual | data or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1 |
Greater | data or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1 |
GreaterOrEqual | data or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1 |
And | bool inputs and output; broadcasting and one constant operand |
Or | bool inputs and output; broadcasting and one constant operand |
Not | one dynamic bool input and bool output |
Where | bool condition and data branches; three-operand broadcasting through rank 5; at most one constant; int8 branches and output share quantization |
Cast | dynamic bool to float32, or to int8 quantizing 0 and 1 into the output encoding; int32 to float32 |
Sum | equal-shaped dynamic data inputs; int8 input quantization must match, with all partial sums proven within int32 |
ReduceAll | one axis of a rank-3 bool tensor; independent height or row bands |
Svdf | state kept between runs; int8 with int16 state and time weights; untiled |
Lstm | hidden and cell state kept between runs; every gate, no peepholes, projection or layer normalization; tanh cell activation; int8 with an int16 cell state; untiled |
If | one bool condition; branches run as their own stages; float32 or int32 operands, also in int8 plans, where the boundary stays float32 between a Dequantize and a Quantize; nests within the runtime's TIGRIS_MAX_SUBGRAPH_DEPTH and TIGRIS_MAX_SUBGRAPHS |
While | a condition giving one bool and a body, each run as its own stages; float32 or int32 loop variables, also in int8 plans, where the boundary stays float32 between a Dequantize and a Quantize, each from an input or a constant (uncompressed plans); nests within the runtime's TIGRIS_MAX_SUBGRAPH_DEPTH and TIGRIS_MAX_SUBGRAPHS |
DetectionPostProcess | SSD center-size box decoding and fast or regular non-max suppression as TFLite Micro runs them; float32 anchors; int8 or float32 encodings and scores; float32 results no operator reads; one class per detection in the fast form; untiled |
Quantize | float32, or int8 in another encoding, to a per-tensor int8 encoding as TFLite Micro's QUANTIZE; float32 only where an int8 plan keeps a control-flow boundary in float32; pointwise |
Dequantize | a per-tensor int8 encoding to float32 as TFLite Micro's DEQUANTIZE; only where an int8 plan keeps a control-flow boundary in float32; pointwise |
When native acceleration falls back
Section titled “When native acceleration falls back”An asterisk in the support table means the vendor adapter is used for the common case, while these variants deliberately take the portable int8 path:
| Backend | Operator | Fallback condition |
|---|---|---|
cmsis-nn | Conv | falls back for dilation other than 1 |
esp-nn | Conv | falls back for dilation other than 1; asymmetric padding falls back when its preparation-time workspace is insufficient |
cmsis-nn | DepthwiseConv | falls back for tiled dilation other than 1; channel multipliers fall back with CMSIS_NN_USE_SINGLE_ROUNDING |
esp-nn | DepthwiseConv | falls back for dilation other than 1; channel multipliers require batch 1 |
cmsis-nn | AveragePool | falls back when tiled or when input/output quantization differs |
esp-nn | AveragePool | falls back when tiled or when input/output quantization differs |
cmsis-nn | Mul | falls back for constants, broadcasting, non-per-tensor quantization, requantization shifts outside [-31, 15], width, row or rolled tiles, or CMSIS_NN_USE_SINGLE_ROUNDING |
esp-nn | Mul | falls back for constants, broadcasting, non-per-tensor quantization, requantization shifts outside [-31, 15], or width, row or rolled tiles |
cmsis-nn | GlobalAveragePool | falls back when tiled or when input/output quantization differs |
cmsis-nn | Max | falls back unless dynamic operands have identical shapes and both inputs and output have equal per-tensor scales and zero points; width, row and rolled tiles fall back |
cmsis-nn | Min | falls back unless dynamic operands have identical shapes and both inputs and output have equal per-tensor scales and zero points; width, row and rolled tiles fall back |
Operators not directly executable
Section titled “Operators not directly executable”These names have reserved plan opcodes but no kernel route. Normalization may fold or rewrite some of them; code generation rejects a plan if one remains:
Clip, BatchNormalization, InstanceNormalization, Squeeze, Unsqueeze.
The compiler still validates each model’s shapes, attributes, quantization, tiling, and memory requirements. A listed operator does not imply support for every ONNX attribute combination.
Keeping this page accurate
Section titled “Keeping this page accurate”These tables are rendered from the compiler’s capability contract,
operator-capabilities-v1.json. Compiler and runtime CI check that contract
against the runtime’s dispatch tables on every change. This page shows the
contract of the integration branch; each archived version in the version
selector shows the one its release shipped.