Skip to content
v0.12.0

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.

--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.

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.

Executable operators after graph normalization
OperatorPortable CESP-NN (int8)CMSIS-NN (int8)
ConvFloat32 + int8Native*Native*
DepthwiseConvFloat32 + int8Native*Native*
ReluFloat32 + int8Portable fallbackPortable fallback
Relu6Float32 + int8Portable fallbackPortable fallback
MaxPoolFloat32 + int8Portable fallbackPortable fallback
AveragePoolFloat32 + int8Native*Native*
AddFloat32 + int8Portable fallbackPortable fallback
MulFloat32 + int8Native*Native*
GemmFloat32 + int8NativeNative
SoftmaxFloat32 + int8Portable fallbackPortable fallback
SigmoidFloat32 + int8Portable fallbackPortable fallback
ConcatFloat32 + int8Portable fallbackPortable fallback
PadFloat32 + int8Portable fallbackPortable fallback
GlobalAveragePoolFloat32 + int8Portable fallbackNative*
FlattenFloat32 + int8Portable fallbackPortable fallback
ReshapeFloat32 + int8Portable fallbackPortable fallback
SubFloat32 + int8Portable fallbackPortable fallback
DivFloat32 + int8Portable fallbackPortable fallback
TanhFloat32 + int8Portable fallbackPortable fallback
LeakyReluFloat32 + int8Portable fallbackPortable fallback
ConvTransposeFloat32 + int8Portable fallbackPortable fallback
MatMulFloat32 + int8Portable fallbackPortable fallback
ReduceMeanFloat32 + int8Portable fallbackPortable fallback
TransposeFloat32 + int8Portable fallbackPortable fallback
ResizeFloat32 + int8Portable fallbackPortable fallback
GlobalMaxPoolFloat32 + int8Portable fallbackPortable fallback
Conv1DFloat32 + int8Portable fallbackPortable fallback
LayerNormalizationFloat32 + int8Portable fallbackPortable fallback
ErfFloat32 + int8Portable fallbackPortable fallback
SplitFloat32 + int8Portable fallbackPortable fallback
ResizeLinearFloat32 + int8Portable fallbackPortable fallback
HardSwishFloat32 + int8Portable fallbackPortable fallback
AbsFloat32 + int8Portable fallbackPortable fallback
RsqrtFloat32 + int8Portable fallbackPortable fallback
SquaredDifferenceFloat32 + int8Portable fallbackPortable fallback
MaxFloat32 + int8Portable fallbackNative*
MinFloat32 + int8Portable fallbackNative*
NegFloat32UnsupportedUnsupported
ExpFloat32UnsupportedUnsupported
LogFloat32UnsupportedUnsupported
SqrtFloat32UnsupportedUnsupported
SquareFloat32UnsupportedUnsupported
FloorFloat32UnsupportedUnsupported
CeilFloat32UnsupportedUnsupported
RoundFloat32UnsupportedUnsupported
SinFloat32UnsupportedUnsupported
CosFloat32UnsupportedUnsupported
FloorDivFloat32UnsupportedUnsupported
FloorModFloat32UnsupportedUnsupported
PReluFloat32 + int8Portable fallbackPortable fallback
EluFloat32 + int8Portable fallbackPortable fallback
LogSoftmaxFloat32 + int8Portable fallbackPortable fallback
L2NormalizationFloat32 + int8Portable fallbackPortable fallback
L2PoolFloat32UnsupportedUnsupported
ReduceMaxFloat32 + int8Portable fallbackPortable fallback
ReduceMinFloat32 + int8Portable fallbackPortable fallback
ReduceSumFloat32 + int8Portable fallbackPortable fallback
CumSumFloat32 + int8Portable fallbackPortable fallback
ArgMaxFloat32 + int8Portable fallbackPortable fallback
ArgMinFloat32 + int8Portable fallbackPortable fallback
GatherFloat32 + int8Portable fallbackPortable fallback
GatherNDFloat32 + int8Portable fallbackPortable fallback
StridedSliceFloat32 + int8Portable fallbackPortable fallback
MirrorPadFloat32 + int8Portable fallbackPortable fallback
ReverseV2Float32 + int8Portable fallbackPortable fallback
EmbeddingLookupFloat32 + int8Portable fallbackPortable fallback
DynamicUpdateSliceFloat32 + int8Portable fallbackPortable fallback
EqualFloat32 + int8Portable fallbackPortable fallback
LessFloat32 + int8Portable fallbackPortable fallback
LessOrEqualFloat32 + int8Portable fallbackPortable fallback
GreaterFloat32 + int8Portable fallbackPortable fallback
GreaterOrEqualFloat32 + int8Portable fallbackPortable fallback
AndFloat32 + int8Portable fallbackPortable fallback
OrFloat32 + int8Portable fallbackPortable fallback
NotFloat32 + int8Portable fallbackPortable fallback
WhereFloat32 + int8Portable fallbackPortable fallback
CastFloat32 + int8Portable fallbackPortable fallback
SumFloat32 + int8Portable fallbackPortable fallback
ReduceAllFloat32 + int8Portable fallbackPortable fallback
SvdfFloat32 + int8Portable fallbackPortable fallback
LstmFloat32 + int8Portable fallbackPortable fallback
IfFloat32 + int8Portable fallbackPortable fallback
WhileFloat32 + int8Portable fallbackPortable fallback
DetectionPostProcessFloat32 + int8Portable fallbackPortable fallback
QuantizeFloat32 + int8Portable fallbackPortable fallback
DequantizeFloat32 + int8Portable fallbackPortable fallback
GeluFloat32 + int8Portable fallbackPortable fallback

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.

OperatorImplemented form
DepthwiseConvone group per input channel with a channel multiplier
Relurank-3 pointwise length tiling on serialized axis 1
Relu6rank-3 pointwise length tiling on serialized axis 1
MaxPoolexplicit or auto_pad padding, floor or ceil output sizing, unit dilation, and no indices output
AveragePoolexplicit or auto_pad padding, floor or ceil output sizing, unit dilation, and count_include_pad=0 wherever padding is non-zero
Addeach 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
Addstandalone rank-3 pointwise length tiling on serialized axis 1
Addint32 operands and result together, wrapping on overflow, untiled and without an activation
Muleach 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
Mulstandalone rank-3 pointwise length tiling on serialized axis 1
Mulint32 operands and result together, wrapping on overflow, untiled and without an activation
Softmaxfinal axis only; tiling on serialized axis 1, each tile holding whole rows
Sigmoidrank-3 pointwise length tiling on serialized axis 1
Concatrank-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
Padconstant mode with non-negative pads and a constant fill; int8 keeps its quantization; untiled execution
GlobalAveragePoolrank-4 height tiling: each band of rows is added into the per-channel sums
Subeach 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
Subint32 operands and result together, wrapping on overflow, untiled and without an activation
Diveach 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
Divint8 rejects zero centered denominators and negative rounding exponents; rounding exponents >= 32 use wide mask/remainder/threshold arithmetic
Tanhrank-3 pointwise length tiling on serialized axis 1
ReduceMeanrank-3 mean over one axis; independent height or row bands. A rank-4 mean over both spatial axes is rewritten to GlobalAveragePool instead
Transposea concrete, valid permutation is stored in schema 4+ plans
Resizerank-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
Conv1Dstandalone rank-3 length tiling on serialized axis 1; may compose with shape-preserving unary pointwise operators
Splitparts along any stored axis; untiled execution
ResizeLinearrank-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
HardSwishrank-3 pointwise length tiling on serialized axis 1
Absint8 requantization must stay within the 32-bit reference arithmetic domain
Rsqrtint8 requires nonnegative centered inputs and reference shifts in range
SquaredDifferenceeach 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
SquaredDifferenceint8 requantization must stay within the 32-bit reference arithmetic domain
Maxeach 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
Mineach 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
FloorDiveach 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
FloorModeach 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
PReluconstant 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
Elualpha=1
LogSoftmaxfinal stored axis; int8 output scale 1/16 and zero point 127
L2Normalizationfinal stored axis; int8 output scale 1/128 and zero point 0
L2Poolfloat32 square root of the mean of valid squared samples
ReduceMaxone axis of a rank-3 tensor; independent height or row bands; rank-4 spatial max with keepdims uses GlobalMaxPool; int8 quantization must match
ReduceMinone axis of a rank-3 tensor; independent height or row bands; int8 quantization must match
ReduceSumone axis of a rank-3 tensor; independent height or row bands; int8 rejects reference arithmetic overflow
CumSumone axis of a rank-3 tensor; independent height or row bands; exclusive and reverse; int8 input zero point 0
ArgMaxone 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
ArgMinone 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
Gatherconstant or runtime int32 indices; independent bands with constant indices; identical int8 quantization
GatherNDconstant or runtime int32 indices; independent bands with constant indices; identical int8 quantization
StridedSliceconstant indices or bounds; bands along an unchanged axis; identical int8 quantization
MirrorPadconstant indices or bounds; bands along an unchanged axis; identical int8 quantization
ReverseV2constant indices or bounds; bands along an unchanged axis; identical int8 quantization
EmbeddingLookupconstant or runtime int32 indices; independent bands with constant indices; identical int8 quantization
DynamicUpdateSliceconstant or runtime int32 starts, clamped to the update domain; bands require constant starts and a dynamic update spanning the band axis; identical int8 quantization
Equaldata or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1
Lessdata or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1
LessOrEqualdata or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1
Greaterdata or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1
GreaterOrEqualdata or int32 inputs, bool output; broadcasting and one constant operand; int8 input scales strictly between 0 and 1
Andbool inputs and output; broadcasting and one constant operand
Orbool inputs and output; broadcasting and one constant operand
Notone dynamic bool input and bool output
Wherebool condition and data branches; three-operand broadcasting through rank 5; at most one constant; int8 branches and output share quantization
Castdynamic bool to float32, or to int8 quantizing 0 and 1 into the output encoding; int32 to float32
Sumequal-shaped dynamic data inputs; int8 input quantization must match, with all partial sums proven within int32
ReduceAllone axis of a rank-3 bool tensor; independent height or row bands
Svdfstate kept between runs; int8 with int16 state and time weights; untiled
Lstmhidden and cell state kept between runs; every gate, no peepholes, projection or layer normalization; tanh cell activation; int8 with an int16 cell state; untiled
Ifone 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
Whilea 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
DetectionPostProcessSSD 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
Quantizefloat32, 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
Dequantizea per-tensor int8 encoding to float32 as TFLite Micro's DEQUANTIZE; only where an int8 plan keeps a control-flow boundary in float32; pointwise

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:

BackendOperatorFallback condition
cmsis-nnConvfalls back for dilation other than 1
esp-nnConvfalls back for dilation other than 1; asymmetric padding falls back when its preparation-time workspace is insufficient
cmsis-nnDepthwiseConvfalls back for tiled dilation other than 1; channel multipliers fall back with CMSIS_NN_USE_SINGLE_ROUNDING
esp-nnDepthwiseConvfalls back for dilation other than 1; channel multipliers require batch 1
cmsis-nnAveragePoolfalls back when tiled or when input/output quantization differs
esp-nnAveragePoolfalls back when tiled or when input/output quantization differs
cmsis-nnMulfalls 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-nnMulfalls back for constants, broadcasting, non-per-tensor quantization, requantization shifts outside [-31, 15], or width, row or rolled tiles
cmsis-nnGlobalAveragePoolfalls back when tiled or when input/output quantization differs
cmsis-nnMaxfalls 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-nnMinfalls 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

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.

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.