Portable C runtime for TiGrIS. It
loads compatible .tgrs plans and executes them against caller-owned memory
arenas. The reference runtime has no dependency beyond the C library and does
not call a general-purpose allocator during inference.
A plan records the operator order, tensor metadata, stage boundaries, and tile strategy selected by the compiler. At runtime, TiGrIS:
- validates the plan version and structural limits before exposing its tables;
- assigns activation addresses from caller-provided fast and slow arenas;
- executes normal, spatially tiled, and streamed-chain stages;
- reads uncompressed weights in place or decompresses stage blocks into the fast arena; and
- reports allocation, tiling, and kernel failures to the caller.
The schedule and activation bound are compiled, but addresses are assigned by bounded bump allocation, reset, and compaction during execution. A finite arena can still be exhausted. The loader validates plan-version compatibility before exposing plan tables.
| Backend | Model dtype | Target | Dispatch |
|---|---|---|---|
reference |
float32 | Any C target | tigris_dispatch_kernel |
s8_ref |
int8 | Any C target | tigris_dispatch_kernel_s8 |
esp-nn |
int8 | ESP32 family | tigris_dispatch_kernel_esp_nn |
cmsis-nn |
int8 | Cortex-M family | tigris_dispatch_kernel_cmsis_nn |
Accelerated adapters fall back to s8_ref for explicitly supported
non-native variants. They are not interchangeable with arbitrary plans:
generate a harness with tigris codegen --backend ... so the compiler can
validate the selected dtype/operator route.
ESP-NN and CMSIS-NN also require a successful preparation call after
tigris_mem_init() and before inference. ESP-NN preparation obtains
platform-managed workspace; CMSIS-NN reserves scratch from the top of the fast
buffer and reduces mem.fast_size. ESP preparation may be repeated safely to
replace its workspace and tigris_esp_nn_deinit() releases it after inference.
CMSIS preparation is idempotent for the same arena when its existing scratch
is sufficient; call tigris_cmsis_nn_deinit() before changing arena or plan.
The caller owns:
- a fast arena, normally SRAM;
- a slow arena, normally PSRAM or another writable RAM region; and
- one
void *entry per tensor.
The plan's budget is the modeled activation requirement. Add
tigris_weight_decompression_overhead() for compressed plans, account for
base-alignment padding, and provision any backend workspace separately.
Optimized Cortex-M builds require the plan base and tensors to satisfy
TIGRIS_TENSOR_ALIGN (16 bytes with DSP enabled).
The core executor performs no unbounded heap fallback. Normal stages may spill
to the supplied slow arena; if neither bounded arena can satisfy an operation,
tigris_run() returns an error. mem.fast_peak records the measured core
fast-arena high-water mark.
cmake -S . -B build
cmake --build build
ctest --test-dir build --output-on-failureCTest registers only self-contained tests. Fixture-driven executables are built but require plans generated by the compiler. Generate them with:
pip install tigris-ml
tigris gen-fixtures model.onnx -o test/fixtures/ -m 256K
./test/run_all.sh test/fixturesThe top-level build also compiles the canonical POSIX int8 integration example:
./build/tigris_posix_example model.tgrsSee examples/posix/main.c for checked loader, arena,
input, execution, and output handling. Production integrations normally use
the harness emitted by tigris codegen.
The ESP-IDF example lives in examples/esp32:
cd examples/esp32
idf.py set-target esp32s3
idf.py build
idf.py flashThe example's portable int8 path is the default. With the espressif/esp-nn
managed component available, pass -DTIGRIS_ENABLE_ESP_NN=ON to build the
ESP-NN adapter.
The plan should live in a memory-mapped flash partition. Allocate the fast
arena from internal SRAM and the slow arena from PSRAM when available. When
using ESP-NN, call tigris_esp_nn_prepare() and check its return value before
tigris_run(), then call tigris_esp_nn_deinit() after the final inference.