Release notes
This page is rendered from the repository CHANGELOG.md, which release-please writes from the conventional-commit type of every squashed pull request. Releases are newest first. The 6 most recent releases are here in full; the whole history is in CHANGELOG.md.
0.33.0 (2026-10-19)
Section titled “0.33.0 (2026-10-19)”⚠ BREAKING CHANGES
Section titled “⚠ BREAKING CHANGES”- A looping –log-file symbolic link now exits 2 instead of producing a traceback with exit 1.
Bug Fixes
Section titled “Bug Fixes”- close pre-1.0 test gaps and small error-handling issues (#901) (462f0ef), refs #845 #846 #888 #892 #896 #898 #899 #902 #903 #904 #812
Documentation
Section titled “Documentation”0.32.0 (2026-10-19)
Section titled “0.32.0 (2026-10-19)”⚠ BREAKING CHANGES
Section titled “⚠ BREAKING CHANGES”- add ConversionResult views and pass the 0-based layer index, not the AIR node id, as the operator callback’s op (C API 1.1.0)
- make the custom-operator plugin, platform registration, interpreter and RegistryBundle names provisional
- rename enum members to UPPER_CASE; the lowercase names remain aliases, but member.name is now uppercase
- make ConversionResult compare by identity
- make compiler helpers on promised classes private, and remove Registry.unfreeze and RegistryContext.unfreeze
- move <prefix>_context_init from the public to the advanced generated C API
- narrow the promised generated file names to the integration headers, the cmake, zephyr and nsx manifests and the plan, report and residency files
- require ns-cmsis-nn 7.47.0 in generated modules
- remove <prefix>_compiler.h from generated modules
- start resource variables at their CALL_ONCE initial values
- reject models LiteRT refuses: mismatched quantization on CONCATENATION, PACK, UNPACK, SPACE_TO_BATCH_ND, BATCH_TO_SPACE_ND, REDUCE_MAX, REDUCE_MIN, EXPAND_DIMS and FILL, a fused activation on CONCATENATION, and plain CALL
- refuse an MVE build of a module converted without MVE when its kernels would differ
- exit 2 for every rejected input, including a missing or unreadable model, an existing output without –force and a missing golden archive
- let an operator or tensor rule that names an id outrank a rule that names only a type
- stage constants from cold memory when a rule sets only constant_destination_memory
- require unique decimal operator ids from custom parsers and transforms (OperatorIdError)
- raise ModelLoadError for a missing model, and RegistryFrozenError and DuplicateRegistrationError from registries
- raise UnsupportedModelError for STRIDED_SLICE ellipsis and new-axis masks and for a customCode with no letter or digit
- check free-form custom-operator rules for unknown and removed keys
- make –verbose 0 show errors only, including warnings raised while the configuration is read
- reject a module directory that is a symbolic link, and a module.path component, module.name, module.prefix or golden-data name longer than 255 characters, with exit 2 on every OS
Features
Section titled “Features”- add ConversionResult views and pass the 0-based layer index, not the AIR node id, as the operator callback’s op (C API 1.1.0) (240db0a)
- count TRANSPOSE_CONV and BATCH_MATMUL MACs, and stop counting rewritten transpose convolutions four times (240db0a)
- deprecate platform.speeds and reject the former AirTensor field names (240db0a)
- keep the verbose levels 0 to 3 and mark the cmsis_pack module type experimental (240db0a)
- make compiler helpers on promised classes private, and remove Registry.unfreeze and RegistryContext.unfreeze (240db0a)
- make ConversionResult compare by identity (240db0a)
- make the custom-operator plugin, platform registration, interpreter and RegistryBundle names provisional (240db0a)
- move <prefix>_context_init from the public to the advanced generated C API (240db0a)
- narrow the promised generated file names to the integration headers, the cmake, zephyr and nsx manifests and the plan, report and residency files (240db0a)
- remove <prefix>_compiler.h from generated modules (240db0a)
- rename enum members to UPPER_CASE; the lowercase names remain aliases, but member.name is now uppercase (240db0a)
- require ns-cmsis-nn 7.47.0 in generated modules (240db0a)
- reserve status codes 1000-1999 for custom operators and pin the generated C API by digest (240db0a)
Bug Fixes
Section titled “Bug Fixes”- check free-form custom-operator rules for unknown and removed keys (240db0a)
- deliver configuration and preflight warnings to –log-file (240db0a)
- exit 2 for every rejected input, including a missing or unreadable model, an existing output without –force and a missing golden archive (240db0a)
- let an operator or tensor rule that names an id outrank a rule that names only a type (240db0a)
- make –verbose 0 show errors only, including warnings raised while the configuration is read (240db0a)
- migrate former keys in memory.tensors attribute rules and reject two former spellings of one setting given together (240db0a)
- raise ModelLoadError for a missing model, and RegistryFrozenError and DuplicateRegistrationError from registries (240db0a)
- raise UnsupportedModelError for STRIDED_SLICE ellipsis and new-axis masks and for a customCode with no letter or digit (240db0a)
- refuse an MVE build of a module converted without MVE when its kernels would differ (240db0a)
- reject a module directory that is a symbolic link, and a module.path component, module.name, module.prefix or golden-data name longer than 255 characters, with exit 2 on every OS (240db0a)
- reject models LiteRT refuses: mismatched quantization on CONCATENATION, PACK, UNPACK, SPACE_TO_BATCH_ND, BATCH_TO_SPACE_ND, REDUCE_MAX, REDUCE_MIN, EXPAND_DIMS and FILL, a fused activation on CONCATENATION, and plain CALL (240db0a)
- report user mistakes in paths, logs and models as typed errors instead of tracebacks (240db0a)
- require unique decimal operator ids from custom parsers and transforms (OperatorIdError) (240db0a)
- share storage between resource-variable handles that name one variable (240db0a)
- stage constants from cold memory when a rule sets only constant_destination_memory (240db0a)
- start resource variables at their CALL_ONCE initial values (240db0a)
Documentation
Section titled “Documentation”- correct the user documentation against 0.31.0 and record the 0.32.0 changes (240db0a)
0.31.0 (2026-10-19)
Section titled “0.31.0 (2026-10-19)”⚠ BREAKING CHANGES
Section titled “⚠ BREAKING CHANGES”list-targetsandtarget-infoare deprecated: they print a warning on stderr and are removed in 2.0; useplatforms listandplatforms show NAME.AotConverter.convert()returns aConversionResult(output,prefix,plan,report,work_dir) instead of the internal code generation context; read those fields, or the residency report, instead of the context’s attributes, andresult.work_dir(set withkeep_work_dir) instead of the context’swork_path.ConvertArgs.from_yamlraisesInvalidConfigError, aConfigValueError, for a file it cannot load or a key or value that does not validate; catchConfigValueErrorinstead ofFileNotFoundError,ValueErrororValidationError.model_validatestill raises pydantic’sValidationError.ConfigValueErrorno longer takes anexit_codeargument; raiseInvalidConfigErrorfor a configuration rejected on its own or against the target, which exits 2.UnsupportedModelErroris now aConfigValueError, soexcept ConfigValueErrorandisinstance(error, ConfigValueError)also take unsupported models; put anexcept UnsupportedModelErrorbefore anexcept ConfigValueError.ModelLoadErroris anOSErrorand no longer aFileNotFoundError; catchModelLoadErrororOSErrorfor a model that cannot be loaded.helia_aotno longer lists subpackages in__all__, and each name is promised at one import path: importAotConverterandConvertArgsfromhelia_aot,RegistryContext,RegistryBundleandbuild_default_registry_contextfromhelia_aot.registry,AotOperator,CtxBufUsage,OperatorAttributesandOpCapabilityfromhelia_aot.aot.operators, the memory types fromhelia_aot.memory, andValidCVarNameTypeandValidModuleNameTypefromhelia_aot.defines.- the plan’s
platform.coreand each report measurement’scoreare now written ascpu. Readplan.platform.cpuandrecord.cpu, and callmeasurements_for(setting, target, cpu). A plan or report that still sayscorereads as before.OptimizationPlanandOptimizationReportno longer reject unknown fields, knobs, knob values or members. To check that a file holds only what one release writes, validate it against thejson_schemaobject in that release’splan-schema.jsonorreport-schema.json(indocs/src/data/generated/at the release’s tag); the files themselves are export envelopes and accept anything. The rename keepsschema_version1, an exception made once before 1.0: a script that reads the raw JSON should readcpuand fall back tocore, and heliaAOT 0.30 and earlier cannot read a plan or report this release writes.PlanOptimization.goalis now the string written, not anOptimizationGoalmember; it still compares equal to the member. - generated modules no longer build against ns-cmsis-nn older than 7.46.0. Projects on 7.45.x or earlier must update ns-cmsis-nn before rebuilding a regenerated module.
Features
Section titled “Features”- let the accumulation knob select the FP16 depthwise entry (#852) (2a2a10b)
- mark the generated module’s public C API and emit an API version (7dfb0a5), refs #845 #812
- one deprecation mechanism, strict built-in operator attributes, and no dead settings (0270e7b), refs #844 #812
- one source for errors and exit codes, a 1.0-sized Python API, and a public convert() result (017e8d2), refs #846 #812
- read plans and reports from newer 1.x releases and name the plan’s CPU field cpu (f8a81ee), refs #843 #812
- require ns-cmsis-nn 7.46.0 in generated modules (cf0adf3), refs #812 #356
Bug Fixes
Section titled “Bug Fixes”- aot: compile non-finite test-case values and classify floats by bit pattern (559d611), refs #820 #812
- aot: emit constant initializers for per-tensor FULLY_CONNECTED (0aeab73), refs #851 #812
- aot: end every generated file with a newline (341cb39), refs #831 #812
- aot: generate valid C for models with no outputs (00b24be), refs #839 #812
- convert the release probe model under one name (#803) (49f16db), refs #339
- docs: classify the shared activations header as internal (e6dc537), refs #845 #812
- e2e: verify toolchain downloads against pinned digests and reinstall stale trees (5f0043f), refs #804
- follow LiteRT when an int8 LSTM cell clip quantizes to zero (af2af9f), refs #822 #812
- lower float REDUCE_MAX/MIN to the TFLite-exact CORE entries (ada9fef)
- lower float REDUCE_MAX/MIN to the TFLite-exact CORE entries (ada9fef), refs #810
- make the declared dependency floors work, and test Python 3.12/3.13 and host clang (5729053), refs #836 #812
- reject int8 LSTMs whose hidden intermediate quantization differs from the output state (9e2b2ce), refs #817 #812
- release: bundle LiteRT in the Windows binary and smoke every binary before upload (ccc8e2b), refs #830 #812
- release: keep release PRs from closing issues and pin what verification installs (972545c), refs #842 #847 #812
- release: verify releases under the commit’s generation time and fail on missing goldens (6207368), refs #804 #339
- write UTF-8 generated text, keep CLI output console-safe, and type malformed input errors (f36ae2f), refs #812
Documentation
Section titled “Documentation”0.30.0 (2026-10-17)
Section titled “0.30.0 (2026-10-17)”Features
Section titled “Features”- allow concatenation with more than ten inputs (296c7ab), closes #723
- export explicit arena storage contracts (#773) (ef690b2)
- expose generated CORE calls in optimization reports (#775) (4f836e9), closes #587 #336
- lower Boolean operators to Core kernels (#774) (5b7ed69), closes #356
- lower FP32 and FP16 DIV to Core kernels (#780) (a363f55), closes #356
- lower FP32 and FP16 NEG to Core kernels (#786) (4774c0d), closes #356
- lower FP32 and FP16 squared difference to Core (#788) (f0a105c), closes #356
- lower INT32 comparisons and SELECT_V2 to Core (#787) (f127c26), closes #356
- record each operator’s CORE calls in the optimization report (#799) (6648614), closes #587 #336
- record the remaining operators’ CORE calls (#801) (737b908), closes #587 #336
- support INT16 transpose convolution (1e4e068), closes #657
Bug Fixes
Section titled “Bug Fixes”- clarify fully connected and slice validation errors (c1e2759), closes #703 #732
- clarify memory budgets and retained residency report paths (6a63d33)
- clarify omitted operands and excess filter skips (#771) (79a92a5), closes #703
- contain native golden-generation failures (1e1b74e)
- declare Apollo510B EVB PSRAM (8fe74dc), closes #684
- document root CLI options and reject malformed README markers (1120db1), closes #710 #727
- enforce model options and reference execution error contracts (ac72c97)
- honor partial STRIDED_SLICE vectors (514ca5e)
- offer feasible memory budget remedies (efc1c44), closes #709
- preserve importer payload consumers and diagnostics (fbc5183)
- preserve resolved CORE dependency requirements (#795) (5d66018), closes #356 #336
- reject unsupported int16 depthwise geometry (a343653), closes #714
- reserve FP16 depthwise patch-row scratch (#781) (ff5ec3a), closes #779
- retain direct depthwise kernels for the size policy (#772) (2781b0a), closes #529 #587
- share binary floating shape validation (#766) (c833d41)
- share floating mean shape validation (#767) (ab9bfac), closes #694
- share unary floating shape validation (#759) (a463ff5)
- support eager root version discovery (7177f1f)
- validate fully connected operand references (1f68b45), closes #703
- validate LiteRT tensor sources and scalar ranks (ff3c0f5)
- validate selected CORE kernel argument domains (#793) (48f5129)
Performance Improvements
Section titled “Performance Improvements”- precompute SVDF kernel sums and resolve SVDF through a CORE provider plan (#800) (22ae96b), closes #336 #587
- route int8 bilinear resize to direct Core kernels (#758) (d4379d6)
- route int8 bilinear resize to direct Core kernels. (d4379d6), closes #356
Documentation
Section titled “Documentation”0.29.0 (2026-10-12)
Section titled “0.29.0 (2026-10-12)”⚠ BREAKING CHANGES
Section titled “⚠ BREAKING CHANGES”- require CORE 7.44.2 for corrected LiteRT conversions
Features
Section titled “Features”- require CORE 7.44.2 for corrected LiteRT conversions (c8a9520)
Bug Fixes
Section titled “Bug Fixes”- reject invalid configuration and proven shape operands (22695e3)
0.28.0 (2026-10-12)
Section titled “0.28.0 (2026-10-12)”⚠ BREAKING CHANGES
Section titled “⚠ BREAKING CHANGES”- The module type default, the memory planner default and the neuralspot module type change. module.type now defaults to cmake instead of neuralspot. A conversion that does not set it emits CMakeLists.txt instead of module.mk, and <prefix>_platform.h no longer includes ns_ambiqsuite_harness.h or maps <PREFIX>_PRINTF to ns_lp_printf, SRAM data to AM_SHARED_RW, DTCM data to NS_PUT_IN_TCM, ITCM data to .itcm_text or MRAM data to const, and <PREFIX>_PUT_CODE_IN_ITCM is empty, so operators with code_placement ITCM stay in the default code section. To migrate, a conversion that relied on the neuralspot default sets module.type to cmake (or nsx or zephyr) and defines the <PREFIX>PUT_IN*, <PREFIX>_PUT_CODE_IN_ITCM and <PREFIX>_PRINTF hooks the application needs; without them the arenas and code follow the linker’s default placement and logging is silent. memory.planner now defaults to hill_climb instead of greedy. It emits greedy’s plan unless its own scratch arena in every memory is no larger and the total is strictly smaller, so arena sizes are the same or smaller in every memory, while tensor offsets and the memory of an individual tensor can change. A conversion that already selects hill_climb now gets greedy’s plan in those cases, and its search stops after 50 iterations without improvement. To migrate, set memory.planner: greedy to keep the previous layout. The neuralspot module type is removed, and a configuration that sets the module type to neuralspot is rejected. To migrate, change it to cmake, nsx or zephyr.
- a configuration with an unknown key no longer converts. This includes unknown transforms[].options and memory.planner_options keys, options given to a built-in transform that takes none (such as PRUNE_IDENTITY_OPS’s identity_ops, which was always ignored), and options on the wildcard transforms entry; a transform listed more than once in transforms is an error; planner-option typos now exit 2 instead of 1. A custom transform whose OPTIONS is not a pydantic model or pydantic dataclass fails with TypeError when defined. Rename the key or delete it; the error names the nearest valid key.
Features
Section titled “Features”- add platform discovery commands and JSON output (#728) (f5677cd), closes #726
- broadcast float ADD through arm_elementwise_add_broadcast (#733) (441ceb0), closes #722
- default to CMake modules and hill_climb, and remove neuralspot (#699) (257c086), closes #604
- generate self-contained offline model reports (#712) (e562e74), closes #702
Bug Fixes
Section titled “Bug Fixes”- check golden data and attribute values at load; atomic zip export (#719) (d79cc74), closes #704
- check shapes against kernels, pad TRANSPOSE_CONV as LiteRT does (#715) (71b35b7)
- emit a zero DEQUANTIZE scale as given (#687) (6fe1310), closes #672
- fail the ty hook when no environment can type-check (#692) (721204d), closes #593
- give each pooling geometry rejection its own hint (#691) (d2bfe9d), closes #591
- hold dtype, scale and quantization rules to LiteRT’s (#718) (325c778), closes #678 #689 #623 #616 #668 #679 #604 #698 #699
- let data movers forward a zero-scale constant (#696) (8cd4543), closes #673
- name apollo510L for NSX and give apollo510_evb its 64 MB of PSRAM (#683) (3dc79cd), closes #636 #637
- read LiteRT constants stored by buffer offset (#734) (454c3b0), closes #730
- reject unknown configuration keys (#695) (af46b77), closes #604
- report unsupported operators and unreadable models as typed errors (#682) (c3d4585), closes #679
- say where to get ns-cmsis-nn and fix each module type’s setup steps (#685) (363bf3c), closes #679
Documentation
Section titled “Documentation”Earlier releases are in CHANGELOG.md.