Quickstart
Take a supported ONNX model, compile it for a bounded SRAM budget, and generate the target integration code. This walkthrough uses the matched INT8 MobileNetV1 model from the benchmark repository and a 64 KiB fast-memory budget. Exact stage counts and tiling decisions are compiler results, so they may improve between releases. Independently captured measurements remain in Introducing TiGrIS.
Prerequisites
Section titled “Prerequisites”- Python 3.10+ with
tigris-mlinstalled - A supported float32 or fully quantized INT8 ONNX model. A dimension the
model leaves free, such as the batch dimension of a stock export, is bound
to 1;
--input-shape input:4x3x224x224compiles for a different one
pip install tigris-mlTo reproduce this walkthrough, run python models/prepare.py from the root of
tigris-bench, then copy
models/output/mobilenet_v1_matched.onnx into your working directory. That
model is reconstructed from the benchmark’s TFLite model so its weights and
quantization match the hardware comparison. For supported operators and
backend qualifications, see
Operator and Backend Support.
Step 1: Analyze
Section titled “Step 1: Analyze”Check whether the model fits within a 64 KB SRAM + 8 MB PSRAM budget (typical for an ESP32-S3):
tigris analyze mobilenet_v1_matched.onnx -m 64K -m 8M -f 16Mmobilenet_v1_matched.onnx int8, 31 operators input input 1x3x128x128 float32, stored as int8 at scale 0.0392704, zero point -1 output l33_dq 1x10 float32, stored as int8 at scale 0.00390625, zero point -128fits 64.00 KiB fast memory, 13 stages, 12 tiled
memory unscheduled 384.00 KiB largest tensor 256.00 KiB 1x64x64x64 this plan 64.00 KiB 0 B headroom slow memory 192.00 KiB budget 8.00 MiB slow traffic 767.38 KiB per inference: 208.01 KiB written, 559.38 KiB read also fits at 32.00 KiB 25 stages, 24 tiled also fits at 16.00 KiB 29 stages, 28 tiled does not fit at 8.00 KiB
flash plan 3.35 MiB weights 3.09 MiB, overhead 269.93 KiB flash budget 16.00 MiB fitsContinue when the verdict line starts with fits. The flash section confirms the
plan fits the 16 MiB flash budget. No hardware is required for analysis.
Step 2: Compile
Section titled “Step 2: Compile”Generate a binary execution plan:
tigris compile mobilenet_v1_matched.onnx -m 64K -m 8M -f 16M --xip -o mobilenet.tgrs| Flag | Meaning |
|---|---|
-m 64K -m 8M |
Memory pools, fast to slow. First is SRAM budget, second is PSRAM. The compiler decides what goes where. |
-f 16M |
Flash budget. Fails if the plan doesn’t fit. |
--xip |
Execute-in-place. Weights are read from flash at runtime, not copied to SRAM. |
-o mobilenet.tgrs |
Output path for the binary plan. |
Multi-stage models keep the tensors that cross stage boundaries in the slow arena, normally PSRAM or another writable RAM region. Flash cannot serve, because it is read-only.
Step 3: Check the plan on your machine (optional)
Section titled “Step 3: Check the plan on your machine (optional)”On a platform wheel of tigris-ml, the bundled reference runtime executes the
plan without a board. inspect shows the interface the plan expects:
tigris inspect mobilenet.tgrsThe input is declared as float32 in stored NHWC order, 1x128x128x3, so
one input is 49152 float32 values, 196608 bytes. A smoke run with an all-zero
input:
head -c 196608 /dev/zero > input.bintigris run mobilenet.tgrs --input input.bin --output prediction.binThis runs the portable reference kernels and confirms the plan loads and
executes; it does not test ESP-NN numerics or device latency. See
tigris run for real inputs and the Python API.
Step 4: Generate C code
Section titled “Step 4: Generate C code”Use codegen to produce a backend-specific C harness:
tigris codegen mobilenet.tgrs --backend esp-nn -o mobilenet.c| Backend | Target |
|---|---|
reference |
Portable C99 (any platform) |
esp-nn |
Espressif optimized kernels (ESP32 family) |
cmsis-nn |
Arm optimized kernels (Cortex-M family) |
Same plan, different kernels. codegen writes target-specific runtime glue;
the .tgrs plan remains a separate deployment artifact loaded from a file,
flash partition, or linker-provided flash symbols depending on the backend.
To start from a precompiled model instead, tigris zoo fetch downloads a plan
with its runtime requirements; see tigris zoo.
See Runtime Integration for
manual loading details.
Step 5: Trace the plan (optional)
Section titled “Step 5: Trace the plan (optional)”Run the plan once on the host runtime and see what it does:
tigris analyze mobilenet_v1_matched.onnx -m 64K -m 8M --traceThis prints, per stage, the tiles, the bytes read from and written to slow memory,
and the highest fast memory use, as measured by the runtime. Add -v for every
load, spill and kernel call.
Step 6: Deploy
Section titled “Step 6: Deploy”The .tgrs plan contains the operator schedule, memory map, tiling parameters, and weights. On your target:
- Add the generated source to the firmware project.
- Store the plan at the location expected by the selected generated harness.
- Supply the generated integration with the required fast and slow arenas.
- Initialize the selected backend, fill every model input, and check the generated run function’s result before reading model outputs.
The generated source is the maintained starting point: compiler CI syntax-checks
a fresh portable C99 harness against the matching runtime headers. Applications
that need custom ownership, RTOS task-local workspaces, or their own entry point
should use codegen --format core. The complete checked manual sequence,
including plan-sized executor workspace and backend preparation, is in
Runtime Integration.
What’s next
Section titled “What’s next”- Core Concepts: tiling strategies, memory pools, execute-in-place
- CLI Reference: supported commands and flags
- Runtime Integration: full C API and firmware integration