Silicon Labs documentation on Machine Learning version 3.0.0.

Documentation source: https://docs.silabs.com/machine-learning/3.0.0

# Machine Learning

## Developing with Silicon Labs Machine Learning (AI/ML)

Machine learning is a subset of artificial intelligence (AI) that enables systems to learn from data and improve their performance without being explicitly programmed. It involves algorithms that identify patterns and make decisions based on input data. Deep learning, a specialized branch of machine learning, uses neural networks with many layers to model complex patterns and achieve high accuracy in tasks like image and speech recognition. Together, these technologies power many modern applications, from recommendation systems to autonomous vehicles. As part of the broader AI field, machine learning and deep learning are key to creating systems that can adapt, reason, and act intelligently.

![Machine Learning](/aiml-developing-with/3.0.0/images/ml-overview.png)

Silicon Labs currently supports TensorFlow Lite for Microcontrollers (TFLM) and associated software as an extension to SiSDK.

The content on these pages is intended for those who want to experiment with or are already developing a Machine Learning application using Silicon Labs technology.

**For Silicon Labs Machine Learning product information**: See the [product pages on silabs.com](https://www.silabs.com/applications/artificial-intelligence-machine-learning).

**For background on Machine Learning**: The [Fundamentals section](/machine-learning/3.0.0/aiml-fundamentals) is a good place to start.

**To get started with development**: See the [Getting Started section](/machine-learning/3.0.0/aiml-getting-started) to get started working with example applications.

**If you are already in development**: See the [Developer's Guide](/machine-learning/3.0.0/aiml-developers-guide).

**If you are using the Machine Learning SDK version 1.3.x or earlier**: See the [AI/ML Extension Setup](/machine-learning/3.0.0/aiml-developers-guide/aiml-extension-setup) guide to transition from v1.x to v2.x of the AI/ML SDK. The earlier versions were supported as a software component of SiSDK, the stack has been moved into an extension now.

**For Silicon Labs AI/ML Extension Source Code**: See the [AI/ML Extension](https://github.com/SiliconLabsSoftware/aiml-extension) link to GitHub.

## Release Notes

### Simplicity Machine Learning Version 1.1.0-beta Release Notes (Jun 23, 2026)

The Artificial Intelligence and Machine Learning (AI/ML) tools include Simplicity Machine Learning (formerly ML Profiler), the model graph viewer, and the model converter. Use these tools to prepare and profile models on the host system.

#### Release Summary

[Key Features](#key-features) | [Bug Fixes](#bug-fixes) | [Chip Enablement](#chip-enablement)

##### Key Features

- The "ML Profiler" tool was renamed to "Simplicity Machine Learning".
- Added an option to choose kernels when profiling a model.
- Improved central processing unit (CPU) and accelerator cycle counts in the profiler.
- Added a model graph viewer to Simplicity Machine Learning based on [Model Explorer](https://developers.google.com/edge/model-explorer).
- Added an alpha release of the ML Model Converter to convert PyTorch and Open Neural Network Exchange (ONNX) models to TensorFlow Lite (TFLite).

##### Bug Fixes

None.

##### Chip Enablement

None.

#### Key Features

[New Features](#new-features) | [Enhancements](#enhancements) | [Removed Features](#removed-features) | [Deprecated Features](#deprecated-features)

> **Note:** See [Feature Matrix](#feature-matrix) for a list of any applicable application programming interfaces (APIs), examples, software variants, modes, hardware, and host interfaces for each feature.

##### New Features

- **Simplicity Machine Learning profiler:** Renamed from "ML Profiler" to "Simplicity Machine Learning". This host-side tool profiles ML models on target hardware.
- **Kernel selection:** Added an option to choose kernels when profiling a model.
- **Model graph viewer:** Integrated a model graph viewer in Simplicity Machine Learning based on [Model Explorer](https://developers.google.com/edge/model-explorer). Linux and macOS are supported natively; Windows is supported through Windows Subsystem for Linux (WSL).
- **ML Model Converter:** Added a unified graphical user interface (GUI) and command-line interface (CLI) to convert PyTorch and ONNX models to TFLite.
- **`manifest.json` output:** When `--save-manifest` command line argument is passed on the CLI, a `manifest.json` file is saved with conversion metadata including conversion time, conversion ratio, input shape, and output shape. The GUI generates this file every time.

##### Enhancements

- **Profiler metrics:** Improved CPU and accelerator cycle count reporting in Simplicity Machine Learning.

##### Removed Features

None.

##### Deprecated Features

|Deprecated Feature|Planned Removal Date|
|---|---|
|"ML Profiler" tool|Superseded by Simplicity Machine Learning|

The "ML Profiler" tool will not receive any updates. In Simplicity Studio, search for **Simplicity Machine Learning (GUI)** or **Simplicity Machine Learning (CLI)**.

#### Bug Fixes

None.

#### Chip Enablement

None.

#### Known Issues and Limitations

Refer to the [ML Profiler Troubleshooting](https://docs.silabs.com/simplicity-machine-learning/{build-docspace-version}/simplicity-machine-learning-guide/profiler#troubleshooting) section for known issues and their solutions.

Refer to the [ML Model Converter Troubleshooting](/simplicity-machine-learning/{build-docspace-version}/simplicity-machine-learning-guide/converter#troubleshooting) section for known issues and their solutions.

- The model graph viewer is not supported natively on Windows; use WSL to launch the GUI tool.
- The model converter is not supported natively on Windows; use WSL to launch the GUI tool.  
  - ONNX models are converted using `onnx2tf`. Non-self-contained ONNX models with external weights are rejected with a clear message  
  - PyTorch models with dynamic graphs require an explicit input shape input.  
  - Quantization is not applied.  
  - Output models are generated in float32.

##### Installation and Use

Refer to the [Getting Started](https://docs.silabs.com/simplicity-machine-learning/{build-docspace-version}/simplicity-machine-learning-start) guide for installation and usage instructions.

For information about Secure Vault Integration, see [Secure Vault](https://www.silabs.com/security/secure-vault).

##### Help and Feedback

- Contact [Silicon Labs Support](https://www.silabs.com/support).
- To use the **Ask AI** tool, see the search field at the top of [this page](https://docs.silabs.com/).
- Get help from our [developer community](https://community.silabs.com/s/?language=en_US).

#### Feature Matrix

[Supported Features](#supported-features) | [Unsupported Features](#unsupported-features)

##### Supported Features

<table>
    <thead>
        <tr>
            <th>Feature Name</th>
            <th>Description</th>
            <th>Quality</th>
            <th>Related API Names</th>
            <th>Supported Software Variants, Hardware, Modes, Host Interfaces</th>
            <th>Related Example Names</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>ML Model profiler</td>
            <td>Profile ML models on target hardware. Choose kernels when profiling. Improved CPU and accelerator cycle counts.</td>
            <td>Beta</td>
            <td>
                <ul>
                    <li><a href="https://docs.silabs.com/simplicity-machine-learning/latest/simplicity-machine-learning-guide/ml-profiler">Simplicity Machine Learning</a></li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>Host tool</li>
                    <li>EFR32 (BRD2601A, BRD2608A), SiWG917 (BRD2605A)</li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>None</li>
                </ul>
            </td>
        </tr>
        <tr>
            <td>Model graph viewer</td>
            <td>Integrated model graph viewer in Simplicity Machine Learning based on <a href="https://developers.google.com/edge/model-explorer">Model Explorer</a>.</td>
            <td>Beta</td>
            <td>
                <ul>
                    <li><a href="https://docs.silabs.com/simplicity-machine-learning/latest/simplicity-machine-learning-guide/ml-profiler">Simplicity Machine Learning</a></li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>Host tool (native support for Linux and macOS. Windows supported through WSL)</li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>None</li>
                </ul>
            </td>
        </tr>
        <tr>
            <td>ML Model converter</td>
            <td>Convert PyTorch and ONNX models to TFLite on the host. Optional <code>manifest.json</code> output with conversion metadata.</td>
            <td>Alpha</td>
            <td>
                <ul>
                    <li><a href="https://docs.silabs.com/simplicity-machine-learning/latest/simplicity-machine-learning-guide/converter">sml-convert</a></li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>Host tool (native support for Linux and macOS. Windows supported through WSL)</li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>None</li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

##### Unsupported Features

- The model graph viewer is not supported natively on Windows. Use WSL to launch the GUI tool.
- The model converter is not supported natively on Windows. Use WSL to launch the GUI tool.

#### SDK Release and Maintenance Policy

See our [SDK Release and Maintenance Policy](https://www.silabs.com/developer-tools/sdk-release-and-maintenance-policy).

### AI/ML SDK

#### Silicon Labs AI/ML Version 3.0.0 - Release Notes (Jun 23, 2026)

[**Simplicity SDK Version 2026.6.0**](/sisdk-release-notes/2026.6.0/sisdk-release-notes-overview)

The Silicon Labs AI/ML SDK enables machine learning development on Series 2 (EFR and SiWG917) devices using the Tensorflow Lite for Microcontrollers (TFLM) framework.

##### Release Summary

<table>
    <thead>
        <tr>
            <th>Release Item</th>
            <th>Version</th>
            <th>Release Date</th>
            <th>Release Notes</th>
            <th>Key Features</th>
            <th>API Changes</th>
            <th>Bug Fixes</th>
            <th>Chip Enablement</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>AI/ML SDK</p>
            </td>
            <td>
                <p>3.0.0</p>
            </td>
            <td>
                <p>Jun 23, 2026</p>
            </td>
            <td>
                <p><a href="sisdk-mc-learning-sdk-release-notes">Release Notes</a></p>
            </td>
            <td>
                <ul>
                    <li>New DX for adding ML Models to new or existing projects.</li>
                    <li>New APIs to initialize, execute, and de-initialize ML models.</li>
                    <li>Project upgrades require manual effort. See the <a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-developers-guide/aiml-3-migration#ai-assisted-migration-prompt">AI-assisted migration prompt</a>.</li>
                    <li>New optimizations to enable faster inference with <code>.tflite</code> models.</li>
                    <li>Model code generation now triggers on <code>.mlconf</code> files instead of <code>.tflite</code> files.</li>
                    <li>Multiple-Model feature to add and execute multiple ML models in a project.</li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>New: <code>sl_ml_model_init()</code>, <code>sl_ml_model_run()</code>, and <code>sl_ml_model_deinit()</code> APIs support adding Multiple Models.</li>
                    <li>Deprecated: Legacy model-specific APIs and TFLite Micro init/tensor APIs for application use.</li>
                    <li>Changed: Use <code>ml_model</code> as the starter component instead of adding <code>tensorflow_lite_micro</code> directly.</li>
                </ul>
            </td>
            <td>
                <ul>
                    Fixed microphone integration on SiWG917 (BRD2605A) using ULP_I2S interface.
                </ul>
            </td>
            <td>
                <ul>
                    Added support for EFM32 devices.
                </ul>
            </td>
        </tr>
        <tr>
            <td>
                <p>MVP Math Library</p>
            </td>
            <td>
                <p>6.0.0</p>
            </td>
            <td>
                <p>Jun 23, 2026</p>
            </td>
            <td>
                <p><a href="sisdk-mc-learning-mvp-math-release-notes">Release Notes</a></p>
            </td>
            <td>
                <ul>
                    <li>MVP Math Library release notes moved from Platform to AI/ML.</li>
                    <li>NN kernels moved from MVP Math Library to AI/ML SDK.</li>
                    <li>Renamed "MVP Math Demo" sample application to "Compute - SoC Math MVP EFR32".</li>
                </ul>
            </td>
            <td>
                <p>None.</p>
            </td>
            <td>
                <p>None.</p>
            </td>
            <td>
                <p>None.</p>
            </td>
        </tr>
    </tbody>
</table>

##### Impact of Release Changes

[Impact Statements](#impact-statements) | [Migration Guide](#migration-guide)

###### Impact Statements

Breaking changes in this release require project migration. See the [AI/ML 3.0 Migration Guide](https://docs.silabs.com/machine-learning/3.0.0/aiml-developers-guide/aiml-3-migration) for step-by-step instructions.

<table>
    <thead>
        <tr>
            <th>Change</th>
            <th>Impact</th>
            <th>Affected Software Variants if applicable</th>
            <th>Affected Modes</th>
            <th>Affected OPNs / Boards / OPN Combinations</th>
            <th>Affected Host Interfaces</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <p>New <code>ml_model</code> component and <code>.mlconf</code> workflow</p>
            </td>
            <td>
                <ul>
                    <li>Existing projects cannot be upgraded automatically. Manual migration is required.</li>
                    <li>Use <code>ml_model</code> as the starter component instead of adding <code>tensorflow_lite_micro</code> directly. The <code>ml_model</code> component requires <code>tensorflow_lite_micro</code>, which is not removed and brings in the generic model APIs.</li>
                    <li>Model code generation now triggers on <code>.mlconf</code> files instead of <code>.tflite</code> files.</li>
                    <li>Use the <a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-developers-guide/aiml-3-migration#ai-assisted-migration-prompt">AI-assisted migration prompt</a> to help migrate existing projects.</li>
                </ul>
            </td>
            <td>
                <p>Standard</p>
            </td>
            <td>
                <p>SoC</p>
            </td>
            <td>
                <p>EFR32, SiWG917, EFM32</p>
            </td>
            <td>
                <p>None.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>New <code>sl_ml_model_*</code> runtime APIs</p>
            </td>
            <td>
                <ul>
                    <li>Replace per-model init/run APIs and TFLite Micro Interpreter based execution with <code>sl_ml_model_init()</code>, <code>sl_ml_model_run()</code>, and <code>sl_ml_model_deinit()</code>.</li>
                    <li>Use instance-based handles (<code>sl_ml_&lt;model&gt;_model_handle</code>) instead of legacy per-model globals and <code>sl_tflite_micro_*</code> APIs.</li>
                    <li>See <a href="sisdk-mc-learning-sdk-release-notes#deprecated-apis">Deprecated APIs</a> in the AI/ML SDK release notes for the full migration map.</li>
                </ul>
            </td>
            <td>
                <p>Standard</p>
            </td>
            <td>
                <p>SoC</p>
            </td>
            <td>
                <p>EFR32, SiWG917, EFM32</p>
            </td>
            <td>
                <p>None.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>GCC 14.2 Rel1</p>
            </td>
            <td>
                <p>GCC updated from 12.2.1 to 14.2 Rel1. On Windows and macOS (Apple Silicon), use the Silicon Labs-provided GCC 14.2 Rel1 toolchain to build with LTO-enabled SDK libraries. Using the ARM-released GCC toolchain on these platforms with LTO enabled may result in link-time errors.</p>
            </td>
            <td>
                <p>None.</p>
            </td>
            <td>
                <p>None.</p>
            </td>
            <td>
                <p>EFR32, SiWG917, EFM32</p>
            </td>
            <td>
                <p>None.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>IAR 9.70.3 (EFR32 only)</p>
            </td>
            <td>
                <p>IAR 9.70.3 is supported on EFR32 devices only. SiWG917 IAR support is not available yet. Rebuild all EFR32 projects after upgrading the toolchain.</p>
            </td>
            <td>
                <p>Standard</p>
            </td>
            <td>
                <p>SoC</p>
            </td>
            <td>
                <p>EFR32</p>
            </td>
            <td>
                <p>None.</p>
            </td>
        </tr>
        <tr>
            <td>
                <p>NN kernels moved to AI/ML SDK</p>
            </td>
            <td>
                <p>Neural network kernels previously provided by the MVP Math Library are now part of the AI/ML SDK. Applications that used NN kernels from the MVP Math Library should use AI/ML SDK components instead.</p>
            </td>
            <td>
                <p>Standard</p>
            </td>
            <td>
                <p>SoC</p>
            </td>
            <td>
                <p>EFR32xG24, EFR32xG26, EFR32xG28, SiWG917</p>
            </td>
            <td>
                <p>None.</p>
            </td>
        </tr>
    </tbody>
</table>

###### Migration Guide

Click [here](https://docs.silabs.com/machine-learning/3.0.0/aiml-developers-guide/aiml-3-migration) for the migration guide for deprecated, removed, and modified items.

##### Using This Release

[What's in the Release?](#what-s-in-the-release) | [Compatible Software](#compatible-software) | [Installation and Use](#installation-and-use) | [Help and Feedback](#help-and-feedback)

###### What's in the Release?

This release includes:

- **AI/ML SDK 3.0.0** — On-device ML runtime, Multiple-Model support, new model APIs, sample applications, and compiler upgrades.
- **MVP Math Library 6.0.0** — Matrix and vector operations using the Matrix Vector Processor, now delivered as part of the AI/ML SDK.

###### Compatible Software

<table>
    <thead>
        <tr>
            <th>Software</th>
            <th>Compatible Version or Variant</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                Software Development Kit (SDK)
            </td>
            <td>
                <ul>
                    <li>Simplicity SDK: 2026.6.0</li>
                    <li>WiSeConnect SDK: 4.1.0</li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

###### Installation and Use

To upgrade your existing software with the latest features included in this release, update Simplicity Studio to the latest version, Simplicity SDK to v2026.6.0, WiSeConnect SDK to v4.1.0, and AI/ML SDK to v3.0.0 using Studio installation manager. Alternatively, download the SDKs from the links listed in the [Compatible Software](#compatible-software) section above.

To run your first demo, see our [Getting Started](https://docs.silabs.com/machine-learning/latest/aiml-getting-started/)

To kick start your development, see our [Developer's Guide](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/)
For information about Secure Vault Integration, see [Secure Vault](https://www.silabs.com/security/secure-vault).

To review Security and Software Advisory notifications and manage your notification preferences:

1. Go to [https://community.silabs.com/](https://community.silabs.com/).
2. Log in with your account credentials.
3. Click your profile icon in the upper-right corner of the page.
4. Select **Notifications** from the dropdown menu.
5. In the Notifications section, go to the **My Product Notifications** tab to review historical Security and Software Advisory notifications.
6. To manage your preferences, use the **Manage Notifications** tab to customize which product updates and advisories you receive.

To learn more about the software in this release, dive into our [online documentation](https://docs.silabs.com/machine-learning/latest/aiml-developing-with/)

###### Help and Feedback

- Contact [Silicon Labs Support](https://www.silabs.com/support).
- To use our **Ask AI** tool to get answers, see the search field at the top of [this page](https://docs.silabs.com/).  
  > **Note:** **Ask AI** is experimental.
- Get help from our [developer community](https://community.silabs.com/s/?language=en_US).

##### Feature Matrix

[Supported Features](#supported-features) | [Unsupported Features](#unsupported-features)

See the detailed feature matrix in each component release notes page:

- [AI/ML SDK Supported Features](sisdk-mc-learning-sdk-release-notes#supported-features)
- [MVP Math Library Supported Features](sisdk-mc-learning-mvp-math-release-notes#supported-features)
- [AI/ML Tools Supported Features](sisdk-mc-learning-tools-release-notes#supported-features)

###### Supported Features

<table>
    <thead>
        <tr>
            <th>Feature Name</th>
            <th>Description</th>
            <th>Quality</th>
            <th>Related API Names</th>
            <th>Supported Software Variants, Hardware, Modes, Host Interfaces</th>
            <th>Related Example Names</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>ML model runtime APIs</td>
            <td>Initialize, execute, and de-initialize ML models using instance-based handles.</td>
            <td>Alpha</td>
            <td>
                <li><a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model">sl_ml_model_init()</a></li>
                <li><a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model">sl_ml_model_run()</a></li>
                <li><a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model">sl_ml_model_deinit()</a></li>
            </td>
            <td>
                <ul>
                    <li>Standard</li>
                    <li>EFR32/EFM32, SiWG917</li>
                    <li>SoC</li>
                </ul>
            </td>
            <td>AI/ML sample and demo applications</td>
        </tr>
        <tr>
            <td>Multiple-Model</td>
            <td>Add and execute multiple ML models in a single project.</td>
            <td>Alpha</td>
            <td>
                <ul>
                    <li><a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model">sl_ml_model_init()</a></li>
                    <li><a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model">sl_ml_model_run()</a></li>
                    <li><a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model">sl_ml_model_deinit()</a></li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>Standard</li>
                    <li>EFR32, SiWG917</li>
                    <li>SoC</li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>AI/ML - SoC Voice Control Light + Sine Blink concurrent MicriumOS EFR32</li>
                    <li>AI/ML - SoC Voice Control Light + Sine Blink sequential MicriumOS EFR32</li>
                    <li>AI/ML - SoC Voice Control Light + Sine Blink concurrent SiWG917</li>
                    <li>AI/ML - SoC Voice Control Light + Sine Blink sequential SiWG917</li>
                </ul>
            </td>
        </tr>
        <tr>
            <td><code>ml_model</code> component and <code>.mlconf</code> workflow</td>
            <td>New starter component for adding ML models to projects. The <code>ml_model</code> component requires <code>tensorflow_lite_micro</code>, which is not removed and provides the underlying TFLM runtime and generic model APIs. Model code generation triggers on <code>.mlconf</code> files. Projects cannot be upgraded automatically and require manual migration.</td>
            <td>Alpha</td>
            <td><a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-developers-guide/add-ml-to-new-or-existing-project">ml_model component</a></td>
            <td>
                <ul>
                    <li>Standard</li>
                    <li>EFR32, SiWG917</li>
                    <li>SoC</li>
                </ul>
            </td>
            <td>AI/ML sample and demo applications</td>
        </tr>
        <tr>
            <td>Model optimization</td>
            <td>Software optimizations for faster inference with <code>.tflite</code> models.</td>
            <td>Alpha</td>
            <td>
                <a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-developers-guide/add-ml-to-new-or-existing-project">Model optimization</a>
            </td>
            <td>
                <ul>
                    <li>Standard</li>
                    <li>SiWG917</li>
                    <li>SoC</li>
                </ul>
            </td>
            <td>AI/ML sample and demo applications for SiWG917</td>
        </tr>
        <tr>
            <td>MVP Math Library</td>
            <td>Real and complex matrix and vector operations using the Matrix Vector Processor on supported EFR32 and SiWG917 devices. Alternative to CMSIS-DSP for matrix and vector math operations.</td>
            <td>Production</td>
            <td><a href="sisdk-mc-learning-mvp-math-release-notes">MVP Math Library</a></td>
            <td>
                <ul>
                    <li>Standard</li>
                    <li>EFR32xG24, EFR32xG26, EFR32xG28, SiWG917</li>
                    <li>SoC</li>
                </ul>
            </td>
            <td>Compute - SoC Math MVP EFR32</td>
        </tr>
        <tr>
            <td>Wi-Fi + ML applications</td>
            <td>Sample applications combining Wi-Fi connectivity and on-device ML inference on SiWG917.</td>
            <td>Experimental</td>
            <td>
                <ul>
                    <a href="https://docs.silabs.com/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model">ML model runtime APIs</a>
                </ul>
            </td>
            <td>
                <ul>
                    <li>Standard</li>
                    <li>SiWG917 (requires WiSeConnect SDK 4.1.0)</li>
                    <li>SoC</li>
                </ul>
            </td>
            <td>
                <ul>
                    <li>Voice Controlled Light over Wi-Fi</li>
                    <li><code>aiml_wifi_voice_control_light_siwg917_freertos_soc</code></li>
                    <li><code>aiml_wifi_switch_led_siwg917_freertos_soc</code></li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

###### Unsupported Features

- IAR 9.70.3 is supported on EFR32 devices only; SiWG917 IAR support is not available yet.
- Series 2 devices do not support new software optimizations for inference; due to their architecture, they remain at least as efficient as SiWG917.
- NN kernels are no longer provided by the MVP Math Library. Use AI/ML SDK components for neural network kernel operations.

##### SDK Release and Maintenance Policy

See our [SDK Release and Maintenance Policy](https://www.silabs.com/developer-tools/sdk-release-and-maintenance-policy).

#### Silicon Labs AI/ML SDK Version 3.0.0 - Release Notes (Jun 23, 2026)

[**Silicon Labs AI/ML Version 3.0.0**](.)

[**Simplicity SDK Version 2026.6.0**](/sisdk-release-notes/2026.6.0/sisdk-release-notes-overview)

The Silicon Labs AI/ML SDK is provided as an extension to the Simplicity SDK. It enables AI/ML development on Series 2 (EFR and SiWG917) devices using the Tensorflow Lite for Microcontrollers (TFLM) framework.

##### Release Summary

[Key Features](#key-features) | [API Changes](#api-changes) | [Bug Fixes](#bug-fixes) | [Chip Enablement](#chip-enablement)

###### Key Features

- Breaking Change: New DX for adding ML Models to new or existing projects.
- Breaking Change: New APIs to initialize, execute, and de-initialize ML models.
- Project upgrades require manual effort. See the [AI-assisted migration prompt](https://docs.silabs.com/machine-learning/3.0.0/aiml-developers-guide/aiml-3-migration#ai-assisted-migration-prompt).
- New optimization features to enable faster inference with `.tflite` models.
- Model code generation now triggers on `.mlconf` files instead of `.tflite` files.
- Multiple-Model feature to add and execute multiple ML models in a project.
- Added SiWG917 Multiple-Model sample applications: Voice control + blink (experimental).
- Compiler compatibility upgraded: GCC 14.2 Rel1 (all platforms) and IAR 9.70.3 (EFR32 only).
- Replaced "Tensorflow Lite Micro" with "ML Model" as the starter component.
- Added Voice Controlled Light over Wi-Fi sample application.
- Unified ML sample and demo application naming in Simplicity Studio.
- CMSIS-DSP upgraded to v1.16.2 from v1.15.0.

###### API Changes

- New: `sl_ml_model_init()`, `sl_ml_model_run()`, and `sl_ml_model_deinit()` APIs support adding Multiple Models.
- Deprecated: Legacy model-specific APIs (`sl_ml_<model>_model_init()` / `_run()`, `slx_ml_*` variants, and per-model globals).
- Deprecated: TFLite Micro init, tensor, arena, and interpreter APIs for application use (still present in SDK).
- Changed: Use `ml_model` as the starter component instead of adding `tensorflow_lite_micro` directly. The `ml_model` component requires `tensorflow_lite_micro` and brings in the generic model APIs.

###### Bug Fixes

- Fixed microphone integration on SiWG917 (BRD2605A) using ULP_I2S interface.

###### Chip Enablement

- Added support for EFM32 devices.

##### Key Features

[New Features](#new-features) | [Enhancements](#enhancements) | [Removed Features](#removed-features) | [Deprecated Features](#deprecated-features)

> **Note:** See [Feature Matrix](#feature-matrix) for a list of any applicable APIs, examples, software variants, modes, hardware, and host interfaces for each feature.

###### New Features

- **New developer experience for ML models:** The `ml_model` component is the new starter component for adding ML models to new or existing projects. It requires `tensorflow_lite_micro` and brings in the generic model APIs. Model code generation triggers on `.mlconf` files instead of `.tflite` files. Existing projects cannot be upgraded automatically and require manual migration. See the [AI/ML 3.0 Migration Guide](https://docs.silabs.com/machine-learning/3.0.0/aiml-developers-guide/aiml-3-migration).
- **Model runtime APIs:** New `sl_ml_model_init()`, `sl_ml_model_run()`, and `sl_ml_model_deinit()` APIs replace the TFLite Micro Interpreter based execution flow and legacy per-model init/run APIs. These APIs use instance-based model handles (`sl_ml_<model>_model_handle`) and support adding Multiple Models to a project.
- **Multiple-Model support:** Sample applications demonstrate Multiple-Model execution on EFR32 and SiWG917, including Voice control + blink on SiWG917.
- **Model optimization:** Software optimizations enable faster inference with `.tflite` models on SiWG917. Series 2 devices do not receive these new optimizations but remain at least as efficient due to their architecture.
- **Voice Controlled Light over Wi-Fi:** Added a new sample application combining on-device voice control with Wi-Fi connectivity on SiWG917.
- **EFM32 device support:** Added support for EFM32 devices.

###### Enhancements

- **Compiler support:** All AIML applications now build with GCC 14.2. IAR 9.70.3 is supported on EFR32 devices only. CMSIS-DSP and CMSIS-NN libraries are rebuilt with both GCC 14.2 and IAR 9.70.3.
- **CMSIS-DSP upgrade:** AI/ML now depends on CMSIS-DSP v1.16.2 (previously v1.15.0).
- **Starter component:** "ML Model" replaces "Tensorflow Lite Micro" as the starter component in Simplicity Studio for adding ML models to projects.
- **Component dependency:** The `ml_model` component requires the `tensorflow_lite_micro` component. The `tensorflow_lite_micro` component is not removed; it continues to provide the underlying TFLM runtime and is pulled in automatically when `ml_model` is used.
- **Application naming:** Unified ML sample and demo application names in Simplicity Studio. Project names follow the `aiml_<soc|wireless_tech>_<app-name>[_<micriumos|freertos>]` convention and display as `AI/ML - SoC [Wireless Technology] <App Name> [<MicriumOS | FreeRTOS>] <EFR32 | SiWG917>`.

###### Removed Features

|Removed Feature|Was Deprecated?|
|---|---|
|TFLite Micro Interpreter based application execution flow|No|
|Per-model autogenerated init/run API pattern (`sl_ml_<model>_model_init()` / `_run()`)|No|
|Using `tensorflow_lite_micro` directly as the project starter component|No|

Applications must migrate to the generic `sl_ml_model_init()`, `sl_ml_model_run()`, and `sl_ml_model_deinit()` APIs with instance-based handles. See the [AI/ML 3.0 Migration Guide](https://docs.silabs.com/machine-learning/3.0.0/aiml-developers-guide/aiml-3-migration).

###### Deprecated Features

None.

##### API Changes

[New APIs](#new-apis) | [Modified APIs](#modified-apis) | [Removed APIs](#removed-apis) | [Deprecated APIs](#deprecated-apis)

###### New APIs

|New API Signature|Deprecated API replaced by this (if any)|
|---|---|
|`sl_ml_model_init(sl_ml_<model>_model_handle&)`|`sl_ml_<model>_model_init()`, `sl_tflite_micro_init()`|
|`sl_ml_model_run(sl_ml_<model>_model_handle&)`|`sl_ml_<model>_model_run()`, TFLite Micro Interpreter based execution|
|`sl_ml_model_deinit(sl_ml_<model>_model_handle&)`|None.|
|`sl_ml_<model>_model_handle` (autogenerated)|`<model>_model`, per-model globals in `sl_ml_model_<model>.h`|
|`sl_ml_<model>_model_handle.model`|`<model>_model`|
|Return value of `sl_ml_model_init()` / `sl_ml_model_run()`|`<model>_model_status`|
|`sl_ml_<model>_model_handle.flatbuffer`|`<model>_model_flatbuffer`|
|`sl_ml_<model>_model_handle.flatbuffer_length`|`<model>_model_flatbuffer_length`|
|`sl_ml_<model>_model_handle.input_tensor(0)`|`sl_tflite_micro_get_input_tensor()`|
|`sl_ml_<model>_model_handle.output_tensor(0)`|`sl_tflite_micro_get_output_tensor()`|

###### Modified APIs

None.

###### Removed APIs

The following APIs and patterns are no longer generated or supported in application code. Use the replacements in [Deprecated APIs](#deprecated-apis).

|Removed API Name|Was Deprecated?|
|---|---|
|`sl_ml_<model>_model_init()`|No|
|`sl_ml_<model>_model_run()`|No|
|`slx_ml_<model>_model_init()` / `_run()`|No|
|`sl_ml_<model>_model_init()`|No|
|`sl_ml_<model>_model_run()`|No|
|`slx_ml_<model>_model_init()` / `_run()`|No|
|`<model>_model`|No|
|`<model>_model_status`|No|
|`<model>_model_flatbuffer`|No|
|`<model>_model_flatbuffer_length`|No|
|`sl_tflite_micro_init()`|No|
|`sl_tflite_micro_get_input_tensor()`|No|
|`sl_tflite_micro_get_output_tensor()`|No|
|`sl_tflite_micro_get_interpreter()`|No|
|`sl_tflite_micro_get_error_reporter()`|No|
|`sl_tflite_micro_estimate_arena_size()`|No|
|`sl_tflite_micro_allocate_tensor_arena()`|No|
|`sl_tflite_micro_opcode_resolver()`|No|
|`sl_tflite_micro_enable_debug_log()`|No|
|`sl_tflite_micro_is_debug_log_enabled()`|No|

###### Deprecated APIs

None.

##### Bug Fixes

<table>
    <thead>
        <tr>
            <th>ID</th>
            <th>Issue Description</th>
            <th>GitHub / Salesforce Reference</th>
            <th>Affected Software Variants, Hardware, Modes, Host Interfaces</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>—</td>
            <td>Fixed an issue where microphone integration on SiWG917 (BRD2605A) using the ULP_I2S interface was not functioning as expected.</td>
            <td>None</td>
            <td>
                <ul>
                    <li>SiWG917 (BRD2605A)</li>
                    <li>SoC</li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

##### Chip Enablements

<table>
    <thead>
        <tr>
            <th>Chip Family</th>
            <th>OPNs / Boards / OPN Combinations</th>
            <th>Supported Software Variants (if applicable)</th>
            <th>Supported Modes</th>
            <th>Supported Host Interfaces</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>EFM32</td>
            <td>
                <ul>
                    <li>EFM32 devices (new in this release)</li>
                </ul>
            </td>
            <td>Standard</td>
            <td>SoC</td>
            <td>
                <ul>
                    <li>UART</li>
                    <li>SPI</li>
                    <li>I2C</li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

##### Application Example Changes

[New Examples](#new-examples) | [Modified Examples](#modified-examples) | [Removed Examples](#removed-examples) | [Deprecated Examples](#deprecated-examples)

###### New Examples

|Example Name|Description|
|---|---|
|AI/ML - SoC Voice Control Light + Sine Blink concurrent MicriumOS EFR32|EFR32 Multiple-Model example running voice control and blink models concurrently.|
|AI/ML - SoC Voice Control Light + Sine Blink sequential MicriumOS EFR32|EFR32 Multiple-Model example running voice control and blink models sequentially.|
|AI/ML - SoC Voice Control Light + Sine Blink concurrent SiWG917|SiWG917 Multiple-Model example running voice control and blink models concurrently.|
|AI/ML - SoC Voice Control Light + Sine Blink sequential SiWG917|SiWG917 Multiple-Model example running voice control and blink models sequentially.|
|Voice Controlled Light over Wi-Fi|Sample application combining on-device voice control with Wi-Fi connectivity on SiWG917.|

###### Modified Examples

|Example Name|Changes|
|---|---|
|All AIML sample and demo applications|Unified naming convention in Simplicity Studio. Project names follow `aiml_<soc|wireless_tech>_<app-name>[_<micriumos|freertos>]` and display as `AI/ML - SoC [Wireless Technology] <App Name> [<MicriumOS | FreeRTOS>] <EFR32 | SiWG917>`.|

###### Removed Examples

None.

###### Deprecated Examples

None.

##### Known Issues and Limitations

- Series 2 devices do not support new software optimizations for inference. However, due to their architecture, they are still at least as efficient as SiWG917.
- IAR 9.70.3 is not supported on SiWG917 devices.

#### Silicon Labs MVP Math Library Version 6.0.0 - Release Notes (Jun 23, 2026)

[**Silicon Labs AI/ML Version 3.0.0**](.)

[**Simplicity SDK Version 2026.6.0**](/sisdk-release-notes/2026.6.0/sisdk-release-notes-overview)

MVP Math Library includes Real and Complex Matrix and Vector operations using the Matrix Vector Processor available on EFR32xG24/6/8 and SiWG917. The library is an alternative to CMSIS-DSP for Matrix and Vector math operations.

##### Release Summary

[Key Features](#key-features) | [API Changes](#api-changes) | [Bug Fixes](#bug-fixes) | [Chip Enablement](#chip-enablement)

###### Key Features

- MVP Math Library release notes moved from Platform to AI/ML.
- NN kernels moved from MVP Math Library to AI/ML SDK.
- Renamed "MVP Math Demo" sample application to "Compute - SoC Math MVP EFR32".

###### API Changes

None.

###### Bug Fixes

None.

###### Chip Enablement

None.

##### Key Features

[New Features](#new-features) | [Enhancements](#enhancements) | [Removed Features](#removed-features) | [Deprecated Features](#deprecated-features)

> **Note:** See [Feature Matrix](#feature-matrix) for a list of any applicable APIs, examples, software variants, modes, hardware, and host interfaces for each feature.

###### New Features

None.

###### Enhancements

- **Package relocation:** MVP Math Library is now delivered as part of the AI/ML SDK extension instead of the Platform SDK. Release notes are published under AI/ML instead of Platform.
- **Sample application rename:** Renamed "MVP Math Demo" to "Compute - SoC Math MVP EFR32" in Simplicity Studio.

###### Removed Features

|Removed Feature|Was Deprecated?|
|---|---|
|NN kernels (moved to AI/ML SDK)|No|

Neural network kernels previously provided by the MVP Math Library are now part of the AI/ML SDK. Applications that used NN kernels from the MVP Math Library should use the AI/ML SDK components instead.

###### Deprecated Features

None.

##### API Changes

[New APIs](#new-apis) | [Modified APIs](#modified-apis) | [Removed APIs](#removed-apis) | [Deprecated APIs](#deprecated-apis)

###### New APIs

None.

###### Modified APIs

None.

###### Removed APIs

|Removed API / Feature|Was Deprecated?|
|---|---|
|NN kernels in MVP Math Library|No|

###### Deprecated APIs

None.

##### Bug Fixes

None.

##### Chip Enablements

None.

##### Application Example Changes

[New Examples](#new-examples) | [Modified Examples](#modified-examples) | [Removed Examples](#removed-examples) | [Deprecated Examples](#deprecated-examples)

###### New Examples

None.

###### Modified Examples

|Example Name|Changes|
|---|---|
|Compute - SoC Math MVP EFR32|Renamed from "MVP Math Demo".|

###### Removed Examples

None.

###### Deprecated Examples

None.

##### Known Issues and Limitations

None.

## Getting Started

### Getting Started with Machine Learning

#### Introduction

##### Silicon Labs TensorFlow Lite for Microcontrollers Integration

Silicon Labs provides robust support for TensorFlow Lite for Microcontrollers (TFLM) as an extension to Simplicity Studio SDK (SiSDK), offering developers flexible options for deploying machine learning models on EFx32 and Si91x microcontrollers using [Project Configurator](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-developing-with-project-configurator/project-configurator) for Simplicity Studio. This guide covers how TensorFlow Lite for Microcontrollers is integrated with the SiSDK using AIML extension for use Silicon Labs' EFx32 and Si91x devices.

##### TensorFlow Lite for Microcontrollers

[TensorFlow](https://www.tensorflow.org) is a widely used deep learning framework, with capability for developing and executing neural networks across a variety of platforms. [TensorFlow Lite](https://ai.google.dev/edge/litert) provides an optimized set of tools specifically catered towards machine learning for mobile and embedded devices.

[TensorFlow Lite for Microcontrollers](https://ai.google.dev/edge/litert/microcontrollers/overview) (TFLM) specifically provides a C++ library for running machine learning models in embedded environments with tight memory constraints. Silicon Labs provides tools and support for loading and running pre-trained models that are compatible with this library.

##### AIML Extension

###### Installing the AI/ML Extension for Silicon Labs Simplicity Studio

For detailed instructions on installing the AI/ML extension, refer to the [AI/ML Extension Installation Guide](/machine-learning/3.0.0/aiml-developers-guide/aiml-extension-setup). This extension empowers developers to integrate machine learning capabilities into their Silicon Labs-based projects.

#### Training and Quantizing a Model

To perform neural network inference on a Silicon Labs device, one first needs a trained model in the TFLite Flatbuffer format. There are two approaches to consider for developers experienced with TensorFlow:

- Following published tutorials for training neural networks using TensorFlow, as outlined in [Developing a Model](/machine-learning/3.0.0/aiml-developers-guide/developing-a-model).
- Using Silicon Labs AI/ML partners. See the **AI/ML Partners** section on [Silicon Labs Machine Learning in IoT](https://www.silabs.com/applications/artificial-intelligence-machine-learning) page for more information.
- Using the [Silicon Labs Machine Learning Toolkit](https://siliconlabs.github.io/mltk/), a Python reference package that combines and simplifies all the necessary TensorFlow training steps.

#### Developing an Inference Application Using Simplicity Studio, SiSDK and AIML extension

After you have a trained and quantized TFLite model, the next step is to set up the TFLM libraries to run [inference](https://ai.google.dev/edge/litert/inference) on a Silicon Labs device.

##### Project Configurator Setup

The [Project Configurator](https://docs.silabs.com/simplicity-studio-5-users-guide/latest/ss-5-users-guide-developing-with-project-configurator/project-configurator) includes TFLM libraries as software components. These software components may be added to any existing project. They are described in the [SDK Component Overview](/machine-learning/3.0.0/aiml-fundamentals/index#sdk-component-overview). The core components needed for any machine learning project are as follows:

1. [TensorFlow Lite Micro](/machine-learning/3.0.0/aiml-fundamentals/index#tensor-flow-lite-micro). This is the core software component that pulls in all the TFLM dependencies.
2. A supported [TFLM kernel implementation](/machine-learning/3.0.0/aiml-fundamentals/index#kernel-implementations). A kernel is a specific hardware/platform implementation of a low level operation used by TensorFlow. Kernel selection can drastically change the performance and computation time of a neural network. By default, the best kernel implementation for the given device is selected automatically.
3. A supported [TFLM debug logger](/machine-learning/3.0.0/aiml-fundamentals/index#debug-logging-using-i-o-stream-disabled). The Project Configurator defaults to using the [I/O Stream](https://docs.silabs.com//gecko-platform/latest/platform-service/iostream) implementation of the logger. To disable logging entirely, add the **Debug Logging Disabled** component.

In addition to required TFLM components, software components for obtaining and pre-processing sensor data can be added to the project. As an example for audio applications, Silicon Labs provides an [audio feature generator component](/machine-learning/3.0.0/aiml-fundamentals/index#audio-feature-generator) that includes powerful DSP features to filter and extract features from raw audio data, to be used as a frontend for microphone-based applications. Silicon Labs developed drivers for [microphones](https://docs.silabs.com/gecko-platform/latest/platform-hardware-driver/mic), [accelerometers](https://docs.silabs.com/gecko-platform/latest/platform-hardware-driver/imu), and [other sensors](https://docs.silabs.com/gecko-platform/latest/platform-hardware-driver/) provide a simple interface for obtaining sensor data to feed to a network.

### Machine Learning on Silicon Labs Devices from Scratch

This guide assumes familiarity with the [Getting Started Guide](./). The following sections show how to add a **ML Model** (`ml_model`) component to a project and run inference on a `.tflite` model. To create an empty C++ project and open the **SOFTWARE COMPONENTS** tab, see [Add Machine Learning to a New or Existing Project](/machine-learning/3.0.0/aiml-developers-guide/add-ml-to-new-or-existing-project).

TensorFlow Lite models execute through _operations_, the computations performed by each layer in the network. A firmware image may register every supported operation, but this increases binary size (more than 100 kB). For production use, register only the operations required by the target model.
If you are new to `.tflite` inference on microcontrollers, or who need background on model format, input and output tensors, and the inference execution flow, refer to  [TensorFlow Lite Micro getting started guide](https://ai.google.dev/edge/litert/microcontrollers/get_started). This guide describes both operation and registration approaches.

#### Procedure

##### Step 1: Enable the AI/ML SDK Extension

1. Search for `ml_model`.
2. Click on **Silicon Labs AI/ML v3.x.x** and then click on **Enable Extension** to enable Silicon Labs AI/ML extension.

![Enable AI/ML SDK extension](/aiml-getting-started/3.0.0/images/enable-extension.png)

##### Step 2: Install the ML Model Component

1. With `ml_model` still in the search bar, Expand **Silicon Labs AI/ML** → **Machine Learning** and select **ML Model**
2. Click on **Install** to install the **ML Model** component and a **Create A Component Instance** dialog pops up.

![Install ML Model component](/aiml-getting-started/3.0.0/images/ml-model-component-enable.png)

##### Step 3: Name the Component Instance

1. Enter a name in **INSTANCE NAME** (for example `keyword_spotting` or `blink`). Use only valid C/POSIX filename characters — this name ends up in generated `#define` macros and handle names such as `sl_ml_keyword_spotting_model_handle`.
2. Click **Done**. ML Model component is now installed and and a new instance is created.

![Create ML Model component instance](/aiml-getting-started/3.0.0/images/ml-model-instance-creation-blink.png)

> **NOTE:** Each `.tflite` model requires its own **ML Model** component instance. After the **ML Model** component is installed, add another instance with a different name (for example `kws` and `blink`) and configure each model separately. For initialization and runtime behavior with multiple models, see [Multi-Model Support](/machine-learning/3.0.0/aiml-developers-guide/multi-model-support).

##### Step 4: Dismiss the Initial Generation Error

Studio should confirm the component was added. You may also see a generation error like this:

> **Failed to generate setup apack_aiml.mvp-compiler**
> 
> `ERROR:root:compile: pass a .tflite path as the model argument, or set "model" in your YAML/mlconf config.`

This error is expected because the project has not yet been configured with a `.tflite` file path. Dismiss the dialog and proceed to the next step.

![Ignore generation error and proceed](/aiml-getting-started/3.0.0/images/ignore-generation-error.png)

##### Step 5: Include the Model Headers

Configure the `.mlconf` file and verify generated project files as described in [Add Machine Learning to a New or Existing Project](/machine-learning/3.0.0/aiml-developers-guide/add-ml-to-new-or-existing-project) (Steps 7 to 8). Project generation produces embedded model artifacts in `autogen/`. Include the generated model header and the shared model API header in your application source file:

```c
#include "sl_ml_model_blink.h"
#include "sl_ml_tflite_micro_model.h"
```

Replace `blink` with your model instance name (for example, `keyword_spotting`). The generated header declares the model handle (for example `sl_ml_blink_model_handle`).

After configuring the `.mlconf` file, confirm the new headers appear under `autogen/`:

![Generated model headers in autogen](/aiml-getting-started/3.0.0/images/getting-started-blink-model-src.png)

##### Step 6: Initialize the Model

Call [sl_ml_model_init()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-init) during application startup in `app_init()`:

```c
sl_status_t status = sl_ml_model_init(&sl_ml_blink_model_handle);
if (status != SL_STATUS_OK) {
    return;
}
```

##### Step 7: Provide Input

In `app_process_action()`, copy or compute sensor data into the input tensor:

```c
TfLiteTensor* input = sl_ml_blink_model_handle.input_tensor(0);
/* ... fill input->data ... */
```

Match the shape and data type expected by the model.

##### Step 8: Run Inference

Call [sl_ml_model_run()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-run):

```c
status = sl_ml_model_run(&sl_ml_blink_model_handle);
if (status != SL_STATUS_OK) {
    sl_ml_model_deinit(&sl_ml_blink_model_handle);
    return;
}
```

##### Step 9: Read Output

Read results from the output tensor:

```c
TfLiteTensor* output = sl_ml_blink_model_handle.output_tensor(0);
/* ... process output->data ... */
```

Repeat Steps 7–9 on each iteration of `app_process_action()`. Call [sl_ml_model_deinit()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-deinit) when the model should be unloaded.

#### Full Code Snippet

After you complete these steps, the `app.cpp` file appears as follows:

```c
#include "sl_ml_model_blink.h"
#include "sl_ml_tflite_micro_model.h"

/***************************************************************************//**
 * Initialize application.
 ******************************************************************************/
void app_init(void)
{
    sl_status_t status = sl_ml_model_init(&sl_ml_blink_model_handle);
    if (status != SL_STATUS_OK) {
        return;
    }
}

/***************************************************************************//**
 * App ticking function.
 ******************************************************************************/
void app_process_action(void)
{
    sl_status_t status;

    TfLiteTensor* input = sl_ml_blink_model_handle.input_tensor(0);
    /* ... fill input->data ... */

    status = sl_ml_model_run(&sl_ml_blink_model_handle);
    if (status != SL_STATUS_OK) {
        sl_ml_model_deinit(&sl_ml_blink_model_handle);
        return;
    }

    TfLiteTensor* output = sl_ml_blink_model_handle.output_tensor(0);
    /* ... process output->data ... */
}
```

The pattern above applies to a single-model application: Call [sl_ml_model_init()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-init) during startup in `app_init()`, and then call [sl_ml_model_run()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-run) from `app_process_action()` while the model remains loaded.

Applications with more than one model should follow [Multiple-Model Support](/machine-learning/3.0.0/aiml-developers-guide/multiple-model-support) for concurrent or sequential initialization.

For API details, see the [ML TFLite Micro Model API reference](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model).

##### Examples

For example projects you can create in Simplicity Studio, please refer [AI/ML Sample Applications](/machine-learning/3.0.0/aiml-sample-apps).

### End-to-End Steps to Create a Voice-Controlled Light ML Application from Scratch

This guide details the process of creating a voice-controlled light application using TensorFlow Lite Micro (TFLM) on an EFR32xG24 Development Kit. This example uses the `keyword_spotting_on_off_v3.tflite` model (recommended) for "on" and "off" keyword detection. For more information on model creation, see the [MLTK tutorial](https://siliconlabs.github.io/mltk/mltk/tutorials/keyword_spotting_on_off.html).

- **Hardware**: EFR32xG24 Dev Kit Board (BRD2601B Rev A01)
- **Software**: Simplicity Studio (SiSDK 2024.12 or later)

#### 1. Install AI/ML Extension

1. Click **Install** on the top bar.  
   ![Install Button](/aiml-getting-started/3.0.0/images/project-wizard-1.png)
2. Click **Manage Installed Packages**.  
   ![Manage Packages](/aiml-getting-started/3.0.0/images/project-wizard-2.png)
3. Under **SDKs**, install the latest version of the AI/ML extension (available from SiSDK 2024.12 onwards).  
   ![AI/ML Extension](/aiml-getting-started/3.0.0/images/project-wizard-3.png)

#### 2. Start a New Simplicity Project

1. From the **File** menu, select **New > Silicon Labs Project Wizard**.  
   ![New Project Wizard](/aiml-getting-started/3.0.0/images/project-wizard-4.png)
2. Select the target board (EFR32xG24 Development Kit), SDK (Simplicity SDK v2024.12.0 or later), and IDE/Toolchain (e.g., GNU ARM v12.2.1). Click **Next**.  
   ![Select Board and SDK](/aiml-getting-started/3.0.0/images/project-wizard-5.png)
3. Choose **Empty C++ Project**. Click **Next**.
4. Give your project a name and click **Finish**.  
   ![Project Name and Finish](/aiml-getting-started/3.0.0/images/project-wizard-6.png)

#### 3. Add Machine Learning Software Component

1. Open your project file (the one with the `.slcp` extension).  
   ![Open SLCP File](/aiml-getting-started/3.0.0/images/project-wizard-7.png)
2. Under **Software Components**, search for "aiml".  
   ![Search for AIML](/aiml-getting-started/3.0.0/images/project-wizard-8.png)
3. Enable the AI/ML extension by clicking **Enable Extension**.  
   ![Enable AIML Extension](/aiml-getting-started/3.0.0/images/project-wizard-9.png)
4. Expand **AI/ML >> Machine Learning >> TensorFlow**. Select **TensorFlow Lite Micro** and click **Install**.  
   ![Install TFLM](/aiml-getting-started/3.0.0/images/project-wizard-10.png)
5. You will be prompted to select additional components:  
   ![Additional Components](/aiml-getting-started/3.0.0/images/project-wizard-11.png)  
   - **Debug Logging**: Choose **Debug Logging using IO Stream** (if needed) or **Debug Logging Disabled**. Click **Install**.  
   - **Kernels**: Select **MVPv1 Accelerated Kernels**. Click **Install**.  
   ![Select Kernels](/aiml-getting-started/3.0.0/images/project-wizard-12.png)

#### 4. Configure the TFLM Component

1. Click **Configure** in the TensorFlow Lite Micro Software Component.  
   ![Configure TFLM](/aiml-getting-started/3.0.0/images/project-wizard-13.png)
2. Set the **Arena Size**. For this example, enter "-1". This tells the system to dynamically determine the optimal arena size at runtime.  
   ![Set Arena Size](/aiml-getting-started/3.0.0/images/project-wizard-14.png)

#### 5. Include and Convert the Model

1. Create a `tflite` directory inside your project's `config` directory (optional but recommended).
2. Drag and drop the `keyword_spotting_on_off_v2.tflite` file into the `config/tflite` directory (or directly into `config` if you skipped creating the subdirectory).
3. The framework will automatically convert the `.tflite` file into a C array (`sl_tflite_micro_model.c` in the `autogen` directory). The TFLM interpreter is also initialized automatically.  
   ![TFLite Model Conversion](/aiml-getting-started/3.0.0/images/project-wizard-15.png)

#### 6. Profile the Model (Optional)

Model profiling can be helpful for optimization. For advanced users who want to analyze model performance, the [Model Profiler Utility](https://docs.silabs.com/simplicity-machine-learning/latest/simplicity-machine-learning-start/) can be used. This is not strictly required for this basic example.

#### 7. Run the Model

1. **Include TensorFlow Init API**: Add the necessary code to initialize the TFLM interpreter.
2. **Provide Input Data**:  
   - Get a pointer to the input tensor: `TfLiteTensor* input = sl_tflite_micro_get_input_tensor();`.  
   - Load your input data (microphone audio quantized to int8) into the input tensor: `input->data.int8f[0] = <input array from microphone quantized to int8>;` (See the [example code](https://github.com/SiliconLabsSoftware/aiml-extension/blob/v2.0.0/src/sl_ml_audio_feature_generation.c#L308-L334) for audio feature generation).
3. **Run Inference**:  
   - Invoke the interpreter: `TfLiteStatus invoke_status = sl_tflite_micro_get_interpreter()->Invoke();`  
   - Check for errors: `if (invoke_status != kTfLiteOk) { TF_LITE_REPORT_ERROR(sl_tflite_micro_get_error_reporter(), "bad input tensor parameters in model"); }`
4. **Read Output**:  
   - Get a pointer to the output tensor: `TfLiteTensor* output = sl_tflite_micro_get_output_tensor();`  
   - Access the output data: `int8_t value = output->data.int8_tf[0];`

#### 8. Implement Post-Processing

1. **Develop an Algorithm**: Create an algorithm to interpret the model's output (e.g., the `int8_t value`) and determine whether "on" or "off" was spoken.
2. **Trigger Events**: Based on the post-processed output, trigger actions like controlling the LED. Refer to the `voice_control_light.cc`, `recognize_commands.cc`, and `recognize_commands.h` files in the [aiml-extension examples](https://github.com/SiliconLabsSoftware/aiml-extension/tree/v2.0.0/examples/ml_voice_control_light) for guidance on implementing this logic, including LED control and command recognition. You will need to add components for the microphone, audio processing, and LED control to your project.

### Voice-Control Light Demo - Quick Start Guide

This guide provides instructions for quickly demonstrating the Voice-Control Light application using pre-built binaries. This demo allows you to control an LED on an EFR32xG24 Dev Kit (BRD2601B Rev A01) by speaking "on" or "off" into a microphone.

- **Hardware**: EFR32xG24 Dev Kit Board (BRD2601B Rev A01)
- **Software**: Simplicity Studio (SiSDK 2024.12 or later)

#### Steps

1. **Open Simplicity Studio**: Launch Simplicity Studio (using the rocket button in the top right corner).
2. **Connect your Device**: Connect your EFR32xG24 Dev Kit to your computer. Wait 5-10 seconds for the device to be recognized by Simplicity Studio.  
   - **Troubleshooting**: If your device isn't recognized, click the "refresh" button in the **Debug Adapters** sub-window (usually located at the bottom left).    
     ![Open the Component Configuration UI for the TensorFlow component](/aiml-getting-started/3.0.0/images/device-detection.png)
3. **Select your Device**: Choose your connected device from the **Connected Devices** dropdown and click **Start**.
4. **Navigate to the Demo**: Go to **Example Projects & Demos**. In the left-hand context menu, scroll down to **Capability** and select **Machine Learning**.
5. **Run the Demo**: Find the **Voice Control Light** demo and click **Run**. This will flash the pre-built binary onto your board.  
   ![Open the Component Configuration UI for the TensorFlow component](/aiml-getting-started/3.0.0/images/demo-sanpshot.png)

## Fundamentals

### Machine Learning Fundamentals

[TensorFlow Lite for Microcontrollers](https://ai.google.dev/edge/litert/microcontrollers/overview) is a framework that provides a set of tools for running neural network inference on microcontrollers. It contains a wide selection of kernel operators with good support for 8-bit integer quantized networks. The framework is limited to model inference and does not support training. For information about how to train a neural network, see the [Silicon Labs Machine Learning Toolkit](https://siliconlabs.github.io/mltk/) (MLTK).

Silicon Labs provides an integration of TensorFlow Lite for Microcontrollers with the Simplicity SDK. See the [Getting Started Guides](/machine-learning/3.0.0/aiml-getting-started) for step-by-step instructions on how to make use of Machine Learning in your project.

#### SDK Component Overview

The software components required to use TensorFlow Lite for Microcontrollers can be found under **Machine Learning > TensorFlow** in the software component browser UI in the Simplicity Studio project configurator.

##### TensorFlow Lite Micro

This component contains the full TensorFlow Lite for Microcontrollers framework, and automatically pulls in the most optimal implementation of kernels for the device selected for the project by default. To use TensorFlow Lite Micro, this component is the only one that needs to be explicitly installed. It is however possible to manually install different kernel implementations if so desired, for instance to compare inference performance or code size, and to manually install a different debug logging implementation. By default, the TensorFlow Lite Micro component makes use of the [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion) to convert a `.tflite` file into a C array and to initialize this neural network model automatically. See the section on [automatic initialization](#automatic-initialization-of-default-model) for more details.

##### Kernel Implementations

###### Reference Kernels

This component provides unoptimized software implementations of all kernels. This is a default implementation that is designed to be easy to read and can run on any platform. As a result, these kernels may run more slowly than an optimal implementation.

###### CMSIS-NN Optimized Kernels

Some kernels have implementations that have been optimized for certain CPU architectures using the CMSIS-NN library. Using these kernels when available can improve inference performance significantly. By enabling this component, the available optimized kernel implementations are added to the project, replacing the corresponding reference kernel implementations. The remaining kernels fall back to using the reference implementations by depending on the reference kernel component.

###### MVP Accelerated Kernels

Some kernels have implementations optimized for the MVP accelerator available on select Silicon Labs parts. Using these kernels will improve inference performance. By enabling this component, the available accelerated kernel implementations are added to the project, replacing the corresponding optimized or reference kernel implementations. The remaining kernels fall back to use the optimized or reference implementations by depending on the corresponding components. See [more details about the accelerator](./mvp-accelerator) to learn what kernels are supported, and what constraints apply.

##### Debug Logging using I/O Stream / Disabled

Debug logging is used in TensorFlow to display debug and error information. Additionally, it can be used to display inference results. Debug logging is enabled by default, with an implementation that uses [I/O Stream](https://docs.silabs.com/gecko-platform/latest/platform-service/iostream) to print over UART to the virtual COM port on development kits (VCOM). Logging can be disabled by ensuring that the component "Debug Logging Disabled" is included in the project.

##### TensorFlow Third Party Dependencies

A specific version of the CMSIS-NN library is used as with TensorFlow Lite for Microcontrollers to optimize certain kernels. This library is included in the project together with TensorFlow Lite for Microcontrollers. TensorFlow depends on a bleeding-edge version of CMSIS-NN, while the rest of the Simplicity SDK uses a stable CMSIS release. It is strongly recommended to avoid using functions from the Simplicity SDK version of CMSIS-DSP and CMSIS-NN elsewhere in the project and instead use the version bundled with TensorFlow Lite for Microcontrollers to avoid versioning conflicts between the two.

##### Audio Feature Generator

The [audio feature generator](/machine-learning/3.0.0/aiml-reference-guide/ml-audio-feature-generation) can be used to extract time-frequency features from an audio signal for use with machine learning (ML) audio classification applications. The generated feature array is a mel-scaled spectrogram, representing the frequency information of the signal of a given sample length of audio. The audio feature generator can be added as a component; it is found under **Machine Learning > Feature Generator** in the Simplicity Studio component browser.

When used with the **ML Model** (`ml_model`) component, the audio feature generator can consume configuration from parameters embedded in the `.tflite` flatbuffer. This helps to ensure that inference settings on the embedded device match training. If models without such metadata are used, configuration values can be set in the configuration header `sl_ml_audio_feature_generation_config.h`.

#### Automatic Initialization of Default Model

When the TensorFlow Lite Micro component is added to the project, it will by default attempt to automatically initialize a default model using the [TFLite Micro Init API](/machine-learning/3.0.0/aiml-reference-guide/tflite-micro-init). It performs initialization of TensorFlow Lite Micro by creating an opcode resolver and interpreter for the given flatbuffer. In addition, it creates the tensor arena buffer.

The model used by the automatic initialization code comes from the [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion). If the flatbuffer was produced using the [MLTK](https://siliconlabs.github.io/mltk/), it may contain metadata about the necessary tensor arena size. If such information is present, it will be automatically initialized to the correct size. If a non-MLTK flatbuffer is used, the tensor arena size must be configured manually using the configuration file for the TensorFlow Lite Micro component.

If automatic initialization at startup is not desired, this can be turned off using the **Automatically initialize model** (`SL_TFLITE_MICRO_INTERPRETER_INIT_ENABLE`) configuration option.

#### Version

The Silicon Labs AI/ML extension incorporates TensorFlow Lite for Microcontrollers version #[02414075e7f718a2d0412775fcadbf28fb4cc5aa](https://github.com/tensorflow/tflite-micro/commit/02414075e7f718a2d0412775fcadbf28fb4cc5aa) in `third_party/tflite-micro/`. The core TensorFlow Lite for Microcontrollers offering is unpatched, all additional content for Silicon Labs devices is delivered in the extension's root directory.

#### Third-party Tools and Partners

##### Tools

- [Netron](https://github.com/lutzroeder/netron) is a visualization tool for neural networks, compatible with `.tflite` model files. This is useful for viewing the operations used in a model, the sizes of tensors and kernels, etc.

##### AI/ML Partners

Silicon Labs AI/ML partners provide expertise and platforms for data collection, model development, and training. See the [technology partner pages](https://www.silabs.com/partner-network/technology-partners) to learn more.

### MVP Accelerator

The MVP accelerator is a co-processor designed to perform matrix and vector
operations. Using hardware accelerated kernel implementations will reduce neural
network inference time, as well as off-load the main processor to allow it to
perform other tasks or go to sleep.

Silicon Labs has implemented common neural network operators as programs to be
executed on the MVP and integrated these with TensorFlow Lite for
Microcontrollers. The MVP has 5 array controllers, each of which can support
iterating in 3 independent dimensions. Each dimension is limited to 1024
elements, with a stride between each element of 2047. The limiting factor for
most neural network operations is therefore the product of the width and depth
dimensions, since this becomes the stride in the height dimension.

All MVP-accelerated operations take signed 8-bit integers as input and output.
If the inner dimension of the tensor has even size, each element can contain two
int8 values, interpreted as a single complex int8 value by the accelerator. The
accelerator can then effectively support 2048 int8 values. If the inner
dimension is odd, the accelerator must perform one computation at a time, which
reduces performance and limits the dimension size to 1024 int8 values.

The operators listed  below will be accelerated using the MVP if tensor sizes
allow. If a specific tensor cannot be accelerated, the implementation will
automatically fall back to using optimized (CMSIS-NN) or reference kernel
implementations at runtime. To maximize the likelihood that an operator is
supported by the accelerator, use even-valued numbers of channels when designing
the model.

Internally, the MVP accelerator uses 16-bit floating point math, even when taking
8-bit integers as input. This means that there is a slight reduction in accuracy
of computations, which may be especially noticeable when performing operations
that accumulate many elements.

For more information about the MVP hardware accelerator, see the [reference manual for EFR32xG24](https://www.silabs.com/support/resources.ct-manuals_reference-manuals.p-wireless_zigbee-and-thread_efr32mg24-series-2-socs).

#### Accelerated TensorFlow operators

##### Add

TensorFlow operator name: `ADD`

Any tensor size is supported.

##### FullyConnected (Dense)

TensorFlow operator name: `FULLY_CONNECTED`, `FULLY_CONNECTED_INT8`

Supports tensors where all dimensions are within the 1024 element limit.
Also supports larger tensors where the size of the last dimension is
decomposable into two factors that are both within the 1024 element limit.

##### AveragePool2D

TensorFlow operator name: `AVERAGE_POOL_2D`

Supports tensors where `width*channels` is within the 2047 element stride limit
and all dimensions are within the 1024 element limit.

##### MaxPool2D

TensorFlow operator name: `MAX_POOL_2D`

Supports tensors where `width*channels` is within the 2047 element stride limit
and all dimensions are within the 1024 element limit.

##### Conv2D

TensorFlow operator name: `CONV_2D`

Supports tensors where `width*channels` is within the 2047 element stride limit
and all dimensions are within the 1024 element limit.

##### DepthwiseConv2D

TensorFlow operator name: `DEPTHWISE_CONV_2D`

Supports tensors where `width*channels` is within the 2047 element stride limit
and all dimensions are within the 1024 element limit.
Dilation is not supported.

##### TransposeConv2D

TensorFlow operator name: `TRANSPOSE_CONV_2D`

Supports tensors where `width*channels` is within the 2047 element stride limit
and all dimensions are within the 1024 element limit.
Dilation is not supported.

#### Suspending Execution While Waiting for Accelerator

The software API for the MVP accelerator is blocking, meaning that any call to the MVP driver will wait for completion before returning from the function call. To save energy, the driver can optionally suspend execution of the main processor while waiting for the accelerator to complete an operation. By default, the main processor busy-waits for the accelerator.

##### No sleep (0)

When the "No sleep" option is used, the MCU core will busy-wait for the MVP
to finish. This is the option which provides the fastest MVP execution
time. The "No sleep" option can be used in a bare metal application or
an application using a real-time operating system (RTOS).

##### Enter EM1 (1)

When the "Enter EM1" option is used, the MCU will be put into Energy Mode 1 whenever
the driver waits for an MVP program to complete. The "Enter EM1" option
is not safe to use in an application using RTOS because it will prevent proper RTOS scheduling.

##### Yield RTOS thread (2)

When the "Yield RTOS thread" option is used, the task waiting for the MVP
program to complete will yield, allowing other tasks in the system to
run or potentially let the scheduler put the system into a sleep mode.
The "Yield RTOS thread" requires that the application is using an RTOS.

The power mode of the MVP driver can be configured by setting the `SL_MVP_POWER_MODE` configuration option in the `sl_mvp_config.h` configuration header.

## Developers Guide

### Machine Learning Developers Guide

This Developer's Guide includes the following topics.

- [Add Machine Learning to a New or Existing Project](add-ml-to-new-or-existing-project): Describes how to add the ML Model (`ml_model`) component to a project and run inference.
- [Multiple-Model Support](multiple-model-support): Describes how to load and run several models in one Silicon Labs project (sequential or concurrent).
- [Feature Generators](feature-generators): Describes how to add and configure feature generators, including the audio frontend for microphone spectrogram models.
- [Update or Replace a .tflite File](guide-replace-model): Describes steps to update and replace a machine learning model in your project.
- [Developing a Model](developing-a-model): Explains the procedure to develop a machine learning model.
- [AI/ML Extension Setup](aiml-extension-setup): In-depth explanantion of adding AI/ML extension to the setup.
- [Flatbuffer Converter Tool](flatbuffer-conversion): Shows how a flatbuffer is converted to bytes for including into header file.
- [I2S Configuration for SiWx917](i2s-pin-configuration): Provides details on configuring I2S for AI/ML audio apps on SiWx917.
- [MVP Compiler](mvp-compiler): Describes about integration of the MVP Compiler in Simplicity Studio—components, pipeline stages, and troubleshooting.
- [MVP Compiler Configuration](mvp-compiler-configuration): Explains how to customize MVP Compiler settings.
- [Migrate from AI/ML SDK 2.2.2 to 3.0.0](aiml-3-migration): Details how to upgrade existing projects to AI/ML 3.0.0.

### Add Machine Learning to a New or Existing Project

This guide shows how to add a machine learning model to a Simplicity Studio project using the **ML Model** (`ml_model`) component. You will enable the AI/ML SDK extension, install the component, point it at a `.tflite` file in an `.mlconf` file, and confirm the generated headers.

The steps below use an **Empty C++** project as the starting point. To add a model to an existing project, skip [Step 1](#step-1-create-an-empty-c-project) and open your project's `.slcp` file instead.

Application code that calls the model APIs must be written in C++. If you are starting with a predominantly C application, see [Interfacing with C Code](#addendum-interfacing-with-c-code).

For inference code after the model is in the project, see [Machine Learning on Silicon Labs Devices from Scratch](/machine-learning/3.0.0/aiml-getting-started/guide-ml-from-scratch). For more than one model, see [Multiple-Model Support](multiple-model-support).

#### Prerequisites

- Simplicity Studio installed (screenshots from Studio 2234)
- Simplicity SDK Suite installed (e.g., v2026.6.0)
- A target board or platform selected in your workspace
- A `.tflite` model file on your local machine
- The [AI/ML extension](./aiml-extension-setup) enabled in your workspace

#### Procedure

##### Step 1: Create an Empty C++ Project

1. Open Simplicity Studio and go to the **PROJECTS** view.
2. Open the **Example Projects & Demos** tab.
3. Search for `empty_cpp`.
4. Select **Platform - Empty C++ Example** and click **CREATE**.

The empty C++ template is a good starting point when you want to add components yourself.

![Empty C++ project creation](/aiml-developers-guide/3.0.0/images/empty-project-creation.png)

---

##### Step 2: Open the Software Components Tab

1. In Project Explorer, open your project (for example `empty_cpp`).
2. Open the project `.slcp` file.
3. Switch to the **SOFTWARE COMPONENTS** tab.

From here you can browse and install components, including the Silicon Labs AI/ML stack.

![Open Software Components tab](/aiml-developers-guide/3.0.0/images/go-to-software-components.png)

---

##### Step 3: Enable the AI/ML SDK Extension

1. Search for `ml_model`.
2. Click on **Silicon Labs AI/ML v3.x.x** and then click on **Enable Extension** to enable Silicon Labs AI/ML extension.

![Enable AI/ML SDK extension](/aiml-developers-guide/3.0.0/images/enable-extension.png)

---

##### Step 4: Install the ML Model Component

1. With `ml_model` still in the search bar, Expand **Silicon Labs AI/ML** → **Machine Learning** and select **ML Model**
2. Click on **Install** to install the **ML Model** component and **Create A Component Instance** dialog pops up.

![Install ML Model component](/aiml-developers-guide/3.0.0/images/ml-model-component-enable.png)

---

##### Step 5: Name the Component Instance

When you click **Install**, Studio prompts you to create an instance:

1. Enter a name in **INSTANCE NAME** (for example `keyword_spotting` or `blink`). Use only valid C/POSIX filename characters — this name ends up in generated `#define` macros and handle names such as `sl_ml_keyword_spotting_model_handle`.
2. Click **Done**. ML Model component is now installed and and a new instance is created.

![Create ML Model component instance](/aiml-developers-guide/3.0.0/images/ml-model-instance-creation-keyword-spotting.png)

> **NOTE:** Each `.tflite` model requires its own **ML Model** component instance. After the **ML Model** component is installed, add another instance with a different name (for example `kws` and `blink`) and repeat Steps 5–7 for each additional model. For initialization and runtime behavior with multiple models, see [Multiple-Model Support](multiple-model-support).

---

##### Step 6: Dismiss the Initial Generation Error

Studio should confirm the component was added. You may also see a generation error like this:

> **Failed to generate setup apack_aiml.mvp-compiler**
> 
> `ERROR:root:compile: pass a .tflite path as the model argument, or set "model" in your YAML/mlconf config.`

This error is expected because the project has not yet been configured with a `.tflite` file path. Dismiss the dialog and proceed to the next step.

![Ignore generation error and proceed](/aiml-developers-guide/3.0.0/images/ignore-generation-error.png)

---

##### Step 7: Configure the `.mlconf` File

1. In Project Explorer, open `config/tflite/` and double-click your `.mlconf` file (for example `keyword_spotting.mlconf`).
2. Set `model:` to the absolute path of your `.tflite` file:  
   ```yaml  
   model: C:\Users\<username>\Desktop\keyword_spotting_on_off_v2.tflite  
   ```
3. Save the file. Studio regenerates the project automatically.

![Configure mlconf file with tflite model path](/aiml-developers-guide/3.0.0/images/mlconf-file-configuration.png)

> **NOTE:** A project with more than one model has one `.mlconf` file per instance under `config/tflite/` (for example `keyword_spotting.mlconf` and `blink.mlconf`). Set `model:` in each file to the `.tflite` path for that instance.

---

##### Step 8: Verify Generated Files

After generation finishes:

1. Expand the `autogen/` folder in Project Explorer.
2. Check for new headers named after your model, for example:  
   - `keyword_spotting_on_off_v2_generated.hpp`  
   - `sl_ml_model_keyword_spotting_on_off_v2.h`
3. On the **SOFTWARE COMPONENTS** tab, confirm your **ML Model** instance shows a green checkmark.

![Generated files after mlconf configuration](/aiml-developers-guide/3.0.0/images/mlconf-generated-files.png)

At project generation, Simplicity Studio runs the MVP Compiler on each model and produces embedded artifacts in `autogen/`, including:

|File|Purpose|
|---|---|
|`sl_ml_model_<instance>.h`|Pre-built handle for the model (for example `sl_ml_blink_model_handle`)|
|`<instance>_generated.hpp`|Model flatbuffer, opcode resolver, and statically allocated tensor buffers|
|`<instance>_generated_parameters.h`|Model-specific parameters when enabled in `.mlconf` (used by audio models — see [Feature Generators](feature-generators))|

The ML Model component includes the TensorFlow Lite Micro runtime. No automatic model initialization runs at system startup — the application loads the model when it is ready to run inference.

For microphone-based models, also add the **Audio Feature Generator** (`fe_audio`) component. See [Feature Generators](feature-generators).

> **NOTE:** With multiple model instances, `autogen/` contains a separate generated header and handle for each instance (for example `sl_ml_model_kws.h` and `sl_ml_model_blink.h`).

---

#### Summary

|Step|Action|
|---|---|
|1|Create a **Platform - Empty C++ Example** project (skip for existing projects)|
|2|Open **SOFTWARE COMPONENTS** via the project `.slcp` file|
|3|Enable the **Silicon Labs AI/ML** SDK extension|
|4|Install the **ML Model** component|
|5|Name the component instance (for example `keyword_spotting`); repeat Steps 5–7 for each additional model|
|6|Dismiss the generation error (no `.tflite` yet)|
|7|Set `model:` in the `.mlconf` file under `config/tflite/`|
|8|Confirm generated headers in `autogen/`|

#### Additional Software Components and C++ Build Settings

> **Note**: Skip this section for Series 2 devices. It applies to SiWx917 projects only.

1. Ensure the following components are installed in your project.  
   - **WiseConnect SDK > Device > Si91X > MCU > Service > Power Manager > Sleep Timer for Si91x**  
   - **Platform > Peripheral > Common Headers**  
   ![Add Sleep Timer Component](/aiml-developers-guide/3.0.0/images/sleep-timer-component.png)  
   ![Add Common Headers Component](/aiml-developers-guide/3.0.0/images/common-headers-component.png)
2. Update your C++ build settings as follows:  
   - In the **C** preprocessor defines, add: `SUPPORT_CPLUSPLUS`.  
   - In **GNU ARM C++ Compiler** > **Miscellaneous** settings, add: `-mfp16-format=ieee`.  
   ![Update C++ Build Settings](/aiml-developers-guide/3.0.0/images/cpp-build-settings.png)  
   ![GNU ARM C++ Compiler Miscellaneous Settings](/aiml-developers-guide/3.0.0/images/cpp-build-settings1.png)  
   **Alternate method**:  
   You can also add these settings directly to your project's `.slcp` file:  
   - Open the `.slcp` file in a text editor.  
   - Add `SUPPORT_CPLUSPLUS` to the `define` section for C preprocessor defines. For example:    
     ```yaml    
     define:    
       - name: SUPPORT_CPLUSPLUS    
         value: 1    
     ```  
   - Add `-mfp16-format=ieee` to the `toolchain_settings` section for C++ compiler flags, for example:    
     ```yaml    
     toolchain_settings:    
       - option: gcc_compiler_option    
         value: -mfp16-format=ieee    
     ```  
   - Save the file and regenerate your project to apply the changes.

#### Troubleshooting

|Issue|What to try|
|---|---|
|`Failed to generate setup apack_aiml.mvp-compiler`|Set `model:` in `.mlconf` to a valid `.tflite` absolute path, then regenerate.|
|`ml_model` not found in search|Enable the AI/ML SDK extension (Step 3).|
|Invalid instance name|Use letters, numbers, and underscores only.|
|Nothing new in `autogen/`|Double-check the `.tflite` path is absolute and saved. Look at **Notifications** for errors.|

#### Next Steps

Include the generated headers in your application and follow [Machine Learning on Silicon Labs Devices from Scratch](/machine-learning/3.0.0/aiml-getting-started/guide-ml-from-scratch) to initialize the model and run inference.

#### Addendum: Interfacing with C Code

If your project is written in C rather than C++, place the code interfacing with the model APIs into a separate file that exports a C API through an interface header. For this example, a filename `app_ml.cpp` is assumed that implements the function `ml_process_action()` with the same content as in the [from-scratch guide](/machine-learning/3.0.0/aiml-getting-started/guide-ml-from-scratch).

##### `app_ml.h`

```c++
#ifdef __cplusplus
extern "C" {
#endif

void ml_process_action(void);

#ifdef __cplusplus
}
#endif
```

##### `app_ml.cpp`

```c++
#include "app_ml.h"
#include "sl_ml_model_blink.h"
#include "sl_ml_tflite_micro_model.h"

extern "C" void ml_process_action(void)
{
    /* Call sl_ml_model_run() as shown in the from-scratch guide.
       Call sl_ml_model_init() from app_init(). */
}
```

##### `app.c`

```c++
#include "app_ml.h"
// ...
void app_process_action(void)
{
    ml_process_action();
}
```

#### Addendum: Series 2 to SiWx917 (and vice versa) App Conversion

If you need to port an application between Series 2 and SiWx917, follow the [Additional Software Components and C++ Build Settings](#additional-software-components-and-c-build-settings) section for SiWx917 when required. The **ML Model** (`ml_model`) component and [sl_ml_model_init()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-init) / [sl_ml_model_run()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-run) workflow is the same on supported boards. Regenerate the project after changing the target device.

### Multiple-Model Support

This guide describes how to run more than one machine learning model in a single Silicon Labs project. For single-model inference steps, see [Machine Learning on Silicon Labs Devices from Scratch](/machine-learning/3.0.0/aiml-getting-started/guide-ml-from-scratch).

---

#### Setting up multiple models in Simplicity Studio

When you need more than one model, add one **ML Model** (`ml_model`) component instance per model. Each instance gets its own `.mlconf` file under `config/tflite/` and its own generated headers under `autogen/ml/`.

> **IMPORTANT:** Follow the steps below in order. Finish Model A completely — instance, `.mlconf`, and generated sources — before you create Model B.

##### Step 1: Model A instance creation and `.mlconf` configuration

For Model A instance creation and `.mlconf` configuration, follow [Add Machine Learning to a New or Existing Project](add-ml-to-new-or-existing-project). Name the first instance (for example, `blink_model`), set the `model:` path in its `.mlconf` file, and confirm Model A sources appear under `autogen/ml/` — for example, `blink_generated.hpp` and `sl_ml_model_blink.h`. Do not add a second instance until these files are present.

##### Step 2: Model B instance creation

1. Open your project `.slcp` file and go to the **SOFTWARE COMPONENTS** tab.
2. Select **ML Model** under **Silicon Labs AI/ML** → **Machine Learning**.
3. Click **+ Add New Instances**, enter a name for Model B (for example, `keyword_spotting_model`), and confirm.

![Add a second ML Model instance](/aiml-developers-guide/3.0.0/images/add-ml-model-instance.png)

##### Step 3: Model B `.mlconf` configuration

1. Open the new `.mlconf` file in `config/tflite/` (for example, `keyword_spotting_model.mlconf`).
2. Set `model:` to the absolute path of Model B's `.tflite` file and save.
3. Wait for generation to finish. Confirm Model B sources appear under `autogen/ml/`, for example:  
   - `keyword_spotting_on_off_v2_generated.hpp`  
   - `sl_ml_model_keyword_spotting_on_off_v2.h`

##### Step 4: Verify both models

When both models are configured, Project Explorer and the **SOFTWARE COMPONENTS** tab should show:

- Two **ML Model** instances (for example, `blink_model` and `keyword_spotting_model`)
- One `.mlconf` file per instance under `config/tflite/`
- Generated source and header files for each model under `autogen/ml/`

![Multi-model instances, mlconf files, and generated sources](/aiml-developers-guide/3.0.0/images/multi-model-instance-creation.png)

#### Using multiple models in an application

Each model instance produces its own handle in `autogen/sl_ml_model_<instance>.h`. The handle variable name follows the instance name — for example, an instance named `kws` produces `sl_ml_kws_model_handle`, and an instance named `blink` produces `sl_ml_blink_model_handle`.

1. Call [sl_ml_model_init()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-init) during application startup in `app_init()`, and call [sl_ml_model_run()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-run) from `app_process_action()`.

Do not call [sl_ml_model_init()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-init) on every iteration of `app_process_action()` — as models stay initialized until [sl_ml_model_deinit()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-deinit) is called. Refer to the [ML TFLite Micro Model API reference](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model), for more information.

#### Choose how models share memory:

##### Concurrent Loading for Faster Model Switching

Initialize every required model once in `app_init()` and leave them loaded. Call [sl_ml_model_run()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-run) on each handle from `app_process_action()` as needed.

> **NOTE:**
> 
> - Use this when a second model must run without unloading the first (for example, keyword detection always active while a second model drives an LED animation).
> - Ensure that all the models can be loaded into the available RAM.
> - If [sl_ml_model_init()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-init) returns `SL_STATUS_FAIL`, try sequential loading instead.

```c
void app_init(void)
{
    sl_ml_model_init(&sl_ml_kws_model_handle);
    sl_ml_model_init(&sl_ml_blink_model_handle);
}

void app_process_action(void)
{
    sl_ml_model_run(&sl_ml_kws_model_handle);
    sl_ml_model_run(&sl_ml_blink_model_handle);
}
```

##### Sequential Loading for Lower RAM Usage

Load one model at a time. Call [sl_ml_model_init()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-init) before use and [sl_ml_model_deinit()](/machine-learning/3.0.0/aiml-reference-guide/ml-tflite-micro-model#sl-ml-model-deinit) before switching to another model. Use this pattern only when total RAM cannot hold every model's tensor arena at once.

```c
void app_process_action(void)
{
    sl_ml_model_init(&sl_ml_kws_model_handle);
    sl_ml_model_run(&sl_ml_kws_model_handle);
    sl_ml_model_deinit(&sl_ml_kws_model_handle);

    sl_ml_model_init(&sl_ml_blink_model_handle);
    sl_ml_model_run(&sl_ml_blink_model_handle);
    sl_ml_model_deinit(&sl_ml_blink_model_handle);
}
```

---

#### Reference

- For example projects with concurrent and sequential keyword spotting plus blink inference, refer to [Voice Control Light with Blink (multiple-model)](/machine-learning/3.0.0/aiml-sample-apps/#voice-control-light-with-blink-multiple-model)

---

### Feature Generators

This guide describes how to add and configure feature generator components in a machine learning project. Feature generators convert raw sensor data into the input format which a model expects. This document covers the Audio Feature Generator (`fe_audio`) for microphone-based classification models.

---

#### 1. Add the Audio Feature Generator Component

For microphone-based classification models, add the [Audio Feature Generator](/machine-learning/3.0.0/aiml-fundamentals/index#audio-feature-generator) component ( `fe_audio` ) to convert audio into spectrogram features for inference. Image, IMU, and other non-audio models do not require this component.

Add one `fe_audio` component instance per audio model. Each instance name must match the corresponding ML Model ( `ml_model` ) instance name.

##### In Simplicity Studio

Perform the following steps in Simplicity Studio.

1. Open the project `.slcp` file and select the **SOFTWARE COMPONENTS** tab.
2. Navigate to **Silicon Labs AI/ML** → **Machine Learning** → **Feature Generator**, select **Audio Feature Generator** ( `fe_audio` ), and then click **Install**.

![Install the Audio Feature Generator component](/aiml-developers-guide/3.0.0/images/fe-audio-component-install.png)

1. When prompted, enter an instance name that matches the corresponding `ml_model` instance (for example, `keyword_spotting`).

![Create an Audio Feature Generator component instance](/aiml-developers-guide/3.0.0/images/fe-audio-create-instance.png)

1. After installation, select the instance under **Audio Feature Generator** and click **Configure** to open its settings (see [Section 2](#2-configure-audio-frontend-parameters)).

![Open the installed Audio Feature Generator instance configuration](/aiml-developers-guide/3.0.0/images/fe-audio-instance-configure.png)

Repeat steps 2 to 4 for each audio model in the project.

When editing the `.slcp` file directly, the component entries look like this:

```yaml
component:
  - id: fe_audio
    instance:
      - keyword_spotting
```

---

#### 2. Configure Audio Frontend Parameters

The audio frontend converts microphone samples into the int8 features required by the model. Configure these settings to match the settings used during model training.

##### In Simplicity Studio

Perform the following steps in Simplicity Studio.

1. Open the **Audio Feature Generator** instance in **Software Components** to review frontend settings. The configuration UI has two groups, shown below for a `keyword_spotting` instance:![Audio Feature Generator configuration for keyword_spotting](/aiml-developers-guide/3.0.0/images/fe-audio-keyword-spotting-config.png)

- **Configurable parameters**: Instance options that you can change using the graphical user interface (GUI), such as **Audio Gain**. The values you set are written into the generated `sl_fe_audio_<instance>_config.h` and used during the build process.
- **Model defined parameters (read-only, from trained .tflite)**: Frontend settings from the matching audio model (sample rate, window timing, filterbank settings, and similar). When a value is not embedded in the model, the build uses built-in defaults. Keep the model-provided values unchanged so that inference remains aligned with trained values.

1. Enable parameter-header generation in the matching `ml_model` instance's `.mlconf` so that the MVP Compiler exports frontend metadata from the `.tflite`:  
   ```yaml  
   model: tflite/keyword_spotting.tflite  
   codegen:  
     model_parameters_header:  
       enabled: true  
   ```  
   The `fe_audio` instance name must match the `ml_model` instance name (for example, both `keyword_spotting`). After project generation, the audio frontend uses the model-specific values from `<instance>_generated_parameters.h` (for example, `keyword_spotting_generated_parameters.h`).

---

#### 3. Audio Feature Generation API

For initialization, feature updates, filling input tensors, and platform-specific behavior, see the [ML Audio Feature Generation API reference](/machine-learning/3.0.0/aiml-reference-guide/ml-audio-feature-generation).

---

#### 4. Multiple Audio Configurations

A project with more than one audio model needs a separate `fe_audio` instance (and matching `ml_model` instance) for each model.

##### Declare Instances in the Project

Add one `fe_audio` instance per audio model in Simplicity Studio or `.slcp` (see [Section 1](#1-add-the-audio-feature-generator-component)). Simplicity Studio generates a matching `sl_fe_audio_<instance>_cfg` for each instance in `autogen/sl_fe_audio_instances.h` and `autogen/sl_fe_audio_instances.c`.

##### Switch Between Configurations at Runtime

Only one audio frontend is active at a time. To move from one model's configuration to another:

1. Call `sl_ml_audio_feature_generation_deinit()` to stop the current frontend.
2. Call `sl_ml_audio_feature_generation_init(&sl_fe_audio_<instance>_cfg)` with the next instance's config struct.

Example:

```c
sl_ml_audio_feature_generation_init(&sl_fe_audio_first_model_cfg);
/* ... run inference with the first audio model ... */
sl_ml_audio_feature_generation_deinit();
sl_ml_audio_feature_generation_init(&sl_fe_audio_second_model_cfg);
/* ... run inference with the second audio model ... */
```

See the [ML Audio Feature Generation API reference](/machine-learning/3.0.0/aiml-reference-guide/ml-audio-feature-generation) for function details.

---

#### 5. Example Applications

|Application|Boards|Models|
|---|---|---|
|Voice control (keyword spotting)|Silicon Labs boards|One audio model|

See the [AI/ML Sample Applications](/machine-learning/3.0.0/aiml-sample-apps) documentation for voice-control example projects you can create in Simplicity Studio.

---

### Updating or Replacing the .tflite File in a Project

This guide describes how to swap out the model in an existing project. It assumes that the project uses the [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion).

#### Replace the Model

To replace the model in an existing project, drag-and-drop the new model file into the `config/tflite/` directory of the project. If the new model has the same file name as the previous model, accept the prompt to overwrite the file. If the new model has a different name, delete or rename the old `.tflite` file such that it no longer has the `.tflite` extension. The [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion) will automatically execute when the directory watcher notices that a different `.tflite` file is present.

> **Note**: If you have multiple `.tflite` files in the `config/tflite/` directory, the converter tool will pick the first file in alphabetical order. Hence the recommendation to rename or delete any old models to ensure that the tool uses the correct file.

#### Inspect the Model

You can take steps to ensure that the automatic regeneration of the C arrays and headers from the `.tflite` file executed as expected. Any of the below steps can be taken if you are ever unsure of what model is part of your application binary.

##### Check the Model Size

The generated file `autogen/sl_tflite_micro_model.c` defines a size variable `sl_tflite_model_len`. This number can be compared to the file size of the `.tflite` file in bytes, for example, by right-clicking the `.tflite` file and looking at the value of Properties > Resource > Size.

##### Check the Operators Used by the Model

The generated file `autogen/sl_tflite_micro_opcode_resolver.h` contains multiple calls to `tflite::MicroMutableOpResolver::AddXXX`, where `XXX` is the name of operators used by the model. This can be compared to the operators you know the model _should_ use.

##### Check the Model Parameters

If the `.tflite` file was compiled using the [MVP Compiler Configuration](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#codegen), it can include model metadata that can be generated through the `codegen.model_parameters_header` configuration in the `.mlconf` file:

```yaml
codegen: 
    model_parameters_header: 
        enabled: true
```

By default, `enabled` is set to false. When set to  `true`, the compiler generates model parameter metadata in the following file:

```c
 autogen/sl_tflite_micro_model_parameters.h
```

These parameters can be compared to the expected parameters.

#### Force Generation of C files

If anything happens that makes the generated `.c` and `.h` get out of sync with the `.tflite` file, the project can be forcefully regenerated by pressing the **Force Generation** button on the **Project Details** pane of the Project Configurator.

### Developing a Machine Learning Model

#### Developing a Model Manually using TensorFlow and Keras

![Block Diagram of TensorFlow Lite Micro Workflow](/aiml-developers-guide/3.0.0/images/tflite-and-keras-model-conversion.png)

When developing and training neural networks for use in embedded systems, it is important to note the limitations on TFLM that apply to [model architecture and training](https://ai.google.dev/edge/litert/microcontrollers/build_convert#operation_support). Embedded platforms also have significant [performance constraints](https://ai.google.dev/edge/litert/models/best_practices) that must be considered when designing and evaluating a model. The embedded TLFM documentation links describe these limitations and considerations in detail.

Additionally, the [TensorFlow Software Components](/machine-learning/3.0.0/aiml-fundamentals) in Simplicity Studio require a quantized `*.tflite` representation of the trained model. As a result, [TensorFlow](https://www.tensorflow.org/guide/basics) and [Keras](https://www.tensorflow.org/guide/keras/sequential_model) are the recommended platforms for model development and training because both platforms are supported by the TensorFlow Lite Converter that generates `.tflite` model representations.

Both TensorFlow and Keras provide guides on model development and training:

- [TensorFlow Basic Training Loops](https://www.tensorflow.org/guide/basic_training_loops)
- [Keras Training and Evaluation](https://www.tensorflow.org/guide/keras/training_with_built_in_methods)

After a model has been created and trained in TensorFlow or Keras, it needs to be converted and serialized into a `*.tflite` file. During model conversion, it is important to optimize the memory usage of the model by quantizing it. It is highly recommended to use [integer quantization](https://ai.google.dev/edge/litert/models/post_training_integer_quant) on Silicon Labs devices.

- [TensorFlow Lite Converter](https://ai.google.dev/edge/litert/models/convert)
- [Quantization Overview](https://ai.google.dev/edge/litert/models/post_training_quantization)

A complete example demonstrating the training, conversion, and quantization of a simple TFLM compatible neural network is available from TensorFlow:

- [TensorFlow Hello World Training Example](https://github.com/tensorflow/tflite-micro/blob/3e190e5389be49c94475e509452bdae245bd4fa6/tensorflow/lite/micro/examples/hello_world/README.md)
- [Trained Hello World Model](https://storage.googleapis.com/download.tensorflow.org/models/tflite/micro/hello_world_2020_12_28.zip) (Downloads a .zip file containing the model)

#### Developing a Model using Silicon Labs AI/ML Partners

See the **AI/ML Partners** section on the [Silicon Labs Machine Learning in IoT](https://www.silabs.com/applications/artificial-intelligence-machine-learning) page for more information about Silicon Labs AI/ML partners. These partners can help you develop a model that is compatible with Silicon Labs devices.

#### Developing a Model using the MLTK

> **Note**: MLTK is experimental and official support is unavailable. It is expected that the MLTK is used by an ML Expert with deep knowledge of TensorFlow and Python, or by a developer willing to learn.

The [Silicon Labs Machine Learning Toolkit](https://siliconlabs.github.io/mltk/) (MLTK) is a Python package that implements a layer above TensorFlow to help the TensorFlow developer build models that can be successfully deployed on Silicon Labs chips. These scripts are a reference implementation for the audio use case, which includes the use of the [Audio Feature Generator](/machine-learning/3.0.0/aiml-fundamentals/index#audio-feature-generator) on both the training and inference side. This is modified version of the TensorFlow "microfrontend" audio front end.

The MLTK is offered as a self-serve, self-support, fully documented, Python reference package published through GitHub. We are delivering this as an Experimental package, which means it’s available “as-is”, un-tested, and without support.

See the [MLTK](https://siliconlabs.github.io/mltk/) documentation for more information.

### Installing the AI/ML Extension for Silicon Labs Simplicity Studio

This guide details the installation process for the AI/ML extension within Silicon Labs Simplicity Studio. This extension empowers developers to integrate machine learning capabilities into their Silicon Labs-based projects.

#### Prerequisites

Before proceeding with the installation, ensure you have the following:

- **Silicon Labs Simplicity Studio**: The latest version of Simplicity Studio is essential. Download it from the official Silicon Labs website.
- **Supported Hardware**: Verify that your target Silicon Labs hardware is compatible with the AI/ML extension. Consult the extension's release notes or documentation for a list of supported devices.
- **Python Environment (Potentially)**: Some AI/ML functionalities might rely on a Python environment. It is recommended to have Python 3.7 or higher installed. A virtual environment is strongly advised to manage dependencies effectively.
- **Git (Potentially)**: Git might be required for certain installation methods or for accessing specific resources. Ensure Git is installed on your system.

#### Installation Methods

The AI/ML extension can be installed via the following methods:

**1. Simplicity Installer (Recommended)**

This is the most straightforward and recommended approach.

1. Download Simplicity Installer using [this link](https://www.silabs.com/software-and-tools/simplicity-studio?tab=getting-started) for your OS.
2. Open Simplicity Installer.
3. Click on **Installation Wizard**.
4. Click **Technology Install**.
5. Select the **AI/ML** from the list of available extensions under **Optional Packages**.
6. Click **NEXT**. On the next page, accept the Terms of Use and License Agreement, and then click **INSTALL** to begin the installation.

**2. Silicon Labs Tool (command line)**

1. Download Silicon Labs Tool (SLT) using [this link](https://www.silabs.com/software-and-tools/simplicity-studio/configurator-command-line-development?tab=getting-started) for your OS.
2. Unzip the downloaded zip file to your preferred location. Add this location to your PATH environment variable so that `slt` command is available globally.
3. Install Simplicity SDK by invoking `slt install simplicity-sdk` on the command line.

#### Post-Installation Steps

After successful installation:

1. **Start Simplicity Studio**: Restart Simplicity Studio to ensure the changes take effect.
2. **Verify Installation**: Check the Simplicity Studio preferences or installed software list to confirm that the AI/ML extension is listed and installed.
3. **Explore Documentation and Examples**: The AI/ML extension should include documentation and example projects. These resources are crucial for getting started and understanding how to use the extension's features and APIs.

#### Troubleshooting

If you encounter any issues during installation:

1. **Check Simplicity Studio Logs**: Examine the Simplicity Studio logs for any error messages. These logs can provide valuable clues for troubleshooting.
2. **Review Documentation**: Refer to the AI/ML extension's documentation and release notes for troubleshooting tips and known issues.
3. **Silicon Labs Community Forum**: The Silicon Labs community forum is an excellent resource for finding solutions to common problems or asking for help from other users and Silicon Labs experts.

#### Updating the Extension

To update the AI/ML extension, follow the same installation steps as described above. Simplicity Studio will typically detect the newer version and guide you through the update process.

#### Uninstallation

To uninstall the AI/ML extension:

1. Open Simplicity Installer.
2. Click **Package Manager**.
3. Search for **Simplicity SDKs**.
4. Click the SDK from which you want to uninstall the AI/ML Extension and click the Trash Bin icon beside it.

### Flatbuffer Converter Tool

The Flatbuffer Converter Tool helps to convert a `.tflite` file into a C array that can be compiled into a binary for an embedded system. This array can be used with the TensorFlow Lite for Microcontrollers API, which takes a void pointer to a buffer containing the model as an argument to its `tflite::GetModel()` init function.

In addition to converting the flatbuffer into a C array, the tool supports emitting model parameters embedded as metadata in the `.tflite` file as C preprocessor macros.

#### Input

The tool takes a directory containing one or more `.tflite` files as input. If the directory consists of multiple files, only the first file in alphabetical order is converted.

> **Tip**: If you have multiple files in the directory, but the one you want to convert isn't the first file in alphabetical order, you can rename the other files to add a `.bak` extension or rename the target file accordingly.

#### Output

The tool writes its output into multiple files in a single output directory.

##### Model Array

The tool always emits a pair of files `sl_tflite_micro_model.c`/`.h`, which declares the variables as follows.

- `const uint8_t sl_tflite_model_array[]` containing the full contents of the `.tflite` file
- `const uint32_t sl_tflite_model_len` containing the length of the model array

##### Opcode Resolver

A header file `sl_tflite_micro_opcode_resolver.h` is also emitted. This file declares a C preprocessor macro `SL_TFLITE_MICRO_OPCODE_RESOLVER(opcode_resolver, error_reporter)` that instantiates a `tflite::MicroMutableOpResolver` object and automatically registers the set of operators required to parse the model.

This macro can be used as part of an initialization sequence to automatically initializing the optimal opcode resolver.

##### Model Parameters

If the `.tflite` file contains model parameters in its metadata section, a third header file `sl_tflite_micro_model_parameters.h` is emitted.

For every model parameter key-value pair, a C preprocessor macro `SL_TFLITE_MODEL_<key>` is created with the relevant value.

See the [MLTK documentation](https://siliconlabs.github.io/mltk/docs/guides/model_parameters.html) to learn more about embedding model parameters in the `.tflite` file.

#### SLC Project Configuration Integration

The Flatbuffer Converter Tool integrates with the SLC project configuration tools in Simplicity Studio and on the command line using SLC-CLI. When using these tools, the Flatbuffer Converter is automatically run with the `config/tflite/` directory of the project as input, and the `autogen/` directory as output.

In other words, any file with the `.tflite` extension in the `config/tflite/` directory in the project will be automatically converted when the project is generated. If using Simplicity Studio, a directory watcher ensures that the project is automatically generated if a `.tflite` file is added or removed. This means that it is sufficient to drag-and-drop a `.tflite` file into the project, and it is automatically converted into C code.

#### Manual Usage

If conversion is desired outside of a full SLC project generation cycle, the flatbuffer converter can be invoked manually. This is generally not necessary, but is an option for advanced users. This can only be done using the SLC-CLI, users of Simplicity Studio are recommended to regenerate the full project.

##### As Standalone Conversion Command

The Flatbuffer Converter Tool runs as a standalone Python script outside of a project generation flow. Execute the following command using absolute paths for both input and output directories.

- NumPy must be installed. If not install it using:

```bash
pip install numpy
```

- The output directory must already exist before running the tool.  
  Create one in any location you prefer:

```bash
mkdir -p /path/to/output/folder
```

- Identify your TFLite model folder where `.tflite` model files are stored. You may also use your own custom `.tflite` model files by supplying their absolute path to `-i`.
- Run `slt where aiml` to locate the AIML package installation path, and then go to the `tool/tflite` directory where `tflite.py` is located.
- Navigate to the folder containing flatbuffer_converter.py:

```bash
cd "$(slt where aiml)/tool/flatbuffer-converter/flatbuffer_converter.py"
```

- Run the Flatbuffer Converter Tool using:

```bash
python flatbuffer_converter.py generate </path/to/tflite/model/folder> </path/to/output/folder> <part_number>
```

##### Tool Help

You can run the help command at any time to view the latest usage instructions for this tool:

```bash
python flatbuffer_converter.py generate --help
```

```bash
usage: flatbuffer_converter.py generate [-h] input_dir output_dir part_number

Runs when project is generated using SLC-CLI or Studio.

positional arguments:
  input_dir    Input directory containing .tflite files
  output_dir   Output directory to populate with serialized content.
  part_number  Part Number

options:
  -h, --help   show this help message and exit
```

### I2S Pin Configuration for ML Audio Applications on SiWx917 platform

The default configuration of I2S pins on SiWx917 does not provide the expected output for classification results on hardware for all AI/ML audio applications. **You MUST manually configure the I2S pins using the `.slcp` as described below.**

To configure the I2S pins for your board, follow these steps using Simplicity Studio:

#### 1. Enable I2S Peripheral via Software Components

Once the .pintool file has been generated in your project folder, open the .slcp file in Simplicity Studio. After that, navigate to the **Software Components** tab. Search for and enable the **I2S** peripheral (e.g., `I2S0`). Navigate to WiSeConnect 3 SDK v3.5.0 > Device > Si91x > MCU > Peripheral > I2S > i2s0 > Configure.

#### 2. Configure I2S Pins

In the Software Components configuration, click the **Configure** button next to the enabled I2S peripheral.

![I2S Peripheral Configuration Example](/aiml-developers-guide/3.0.0/images/i2sconfig.png)

Assign the required I2S signals (`DIN0`, `SCLK`, and `WSCLK`) to the appropriate GPIO pins as shown in the image below. The configuration tool displays available pins. Ensure you select only those indicated in the image.

![I2S Pin Configuration Example](/aiml-developers-guide/3.0.0/images/i2spinconfig.png)

#### 3. Save and Generate Code

The tool automatically generates the necessary pin configuration code for your project.

#### 4. Rebuild the Project

Build your project to ensure the new pin configuration is included.

For more details, refer to the [Simplicity Studio Software Components documentation](https://docs.silabs.com/simplicity-studio-5-users-guide/ss-5-using/using-software-components).

### MVP Compiler

This guide describes MVP compiler integration in Simplicity Studio that includes components, pipeline stages, and troubleshooting. For setup steps and a Project Configurator information, refer to [Add Machine Learning to a New or Existing Project](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/add-ml-to-new-or-existing-project). For `*.mlconf` keys, see [MVP Compiler Configuration](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration).

The `ml_model` component is required for machine learning applications.

The compiler transforms a quantized TensorFlow Lite (`.tflite`) model into firmware-ready artifacts:

- Optimized flatbuffer (`_generated.h`)
- Generated C/C++ sources, headers
- Memory layout metadata in the flatbuffer

To change compiler behavior, edit the project `*.mlconf` bound to each `ml_model` instance and regenerate the project.

#### Overview

During project generation, Studio invokes the compiler for each ml_model instance. To learn more about how settings combine, what runs by default, and how your board maps to a platform id, refer to [MVP Compiler Configuration](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#default-behavior).

![MVP compiler end-to-end flow](/aiml-developers-guide/3.0.0/images/mvp-compiler-api-overview.png)

##### Components

Add an `ml_model` instance for each model in your project. For multiple models or board-specific flatbuffers, see [Multi-Model Support](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/multi-model-support).

|Component|Role|
|---|---|
|`ml_model`|Registers the model, also owns `*.mlconf` and `.tflite` config slots under `directory: tflite`.|
|`ml_compiler`|Runs the compiler during project generation.|

Each instance reserves `config/compiler/<instance>.mlconf`, ships a default template with `model: null` until you set `model:` in your project `*.mlconf`, and publishes compiled artifacts under `autogen/` named from the `.tflite` stem.

#### Compiler Pipeline Stages

The compiler executes an ordered pipeline. Extension defaults apply where your `*.mlconf` is silent; project overrides merge for configurable sections such as `graph_optimizer`, `memory_optimizer`, `memory_specification`, and `codegen`. See [MVP Compiler Configuration](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration) for key details.

![Compiler pipeline stages](/aiml-developers-guide/3.0.0/images/mvp-compiler-core-engine.png)

The compiler runs optimization passes in sequence. Each pass transforms the model and prepares it for the next stage.

**Register compression**: Records MVP accelerator register programs during compilation, and then compresses them by removing redundant writes and applying delta encoding. The compressed programs are stored in the compiled model metadata, so runtime kernels load smaller and more efficient programs. This stage always runs, and it is not configurable in `*.mlconf`.

![Register compression](/aiml-developers-guide/3.0.0/images/mvp-compiler-register-compression.png)

**Memory planning**: Builds an offline memory allocation plan for tensors and buffers so the firmware knows where data stored before inference runs. This reduces runtime planning overhead and produces a deterministic memory layout. The planner pass uses extension defaults, so you generally do not need to change [`memory_planner`](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#memory_planner) in a project `*.mlconf`. To tune region sizes or linker sections without disabling the planner, use the [`memory_specification`](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#memory_specification) section; memory planning reads those definitions when building the plan. That lets you cap SRAM usage, or assign weights to flash.

**Graph optimizer**: Configurable in [`graph_optimizer`](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#graph_optimizer). Simplifies the TensorFlow Lite graph before other passes run (for example, by merging or removing layers), and when enabled, precomputes constant subgraphs. This can reduce latency, RAM, and flash use on Silicon Labs targets. Enable it for production builds unless you are isolating a graph-related issue.

![Graph optimization](/aiml-developers-guide/3.0.0/images/mvp-compiler-graph-optimization.png)

**Memory optimizer**: Configurable in [`memory_optimizer`](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#memory_optimizer). It uses the memory plan to apply weights paging, and when enabled, reuses safe buffer between layers. This helps large models fit within available SRAM, or flash. Enable it when the model is memory-constrained or when you want dual weights paging on platforms that support it.

![Memory optimization](/aiml-developers-guide/3.0.0/images/mvp-compiler-memory-optimization.png)

**Code generation**: Configurable in [`codegen`](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#codegen). Produces C/C++ headers, sources for embedded integration, model data, operation resolver for the kernels for your graph, and symbol names your application links against. You can adjust symbols, linker sections, and `runtime_memory_size`. This stage is required for normal Studio builds that publish artifacts under `autogen/`.

Override memory regions in `memory_specification` rather than trying to disable automatic memory planning. Set [`codegen.model_header.runtime_memory_size`](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#codegenmodel_header) only when you have a validated size from profiling or documentation—not to replace the memory planner in normal builds.

#### Output Layout

During project generation, Simplicity Studio scans the staged `tflite/` directory for bound `*.mlconf` files and runs the compiler once per file. Generated code is published to the project autogen tree. Your application links against the autogen copy; compiler workspace folders are not retained in the project source tree.

|Output|Behavior|
|---|---|
|Autogen directory|Generated files placed under the configured `output` path (often `autogen/` with model artifacts under `autogen/ml/`)|
|Build log|Project generation console; `sml.log` written under the autogen output directory|

When code generation is enabled, compiled TFLM sources and generated symbols are published to autogen.

#### Best Practices

The following recommendations apply to production firmware:

- **Register compression**: Leave enabled (default SLC behavior). It is required for normal compilation and code generation and cannot be controlled from `*.mlconf`.
- **Memory planning**: Keep `memory_planner.enabled: true`. Disabling the planner is appropriate only for controlled experiments. When disabled, set `codegen.model_header.runtime_memory_size` explicitly:  
  ```yaml  
  memory_planner:  
    enabled: false   # not recommended for production  
    
  codegen:  
    model_header:  
      runtime_memory_size: <tensor arena size>  
  ```
- **Graph and memory optimization**: `graph_optimizer` and `memory_optimizer` are configurable in project `*.mlconf`. You may disable either stage temporarily for comparison. For release builds, leave both enabled to avoid reduced performance and increased RAM usage.

#### Troubleshooting

If compilation or autogen output does not match expectations, check the following issues.

|Issue|Possible Cause and Solution|
|---|---|
|Model not optimized beyond basics|Confirm an `ml_model` instance and bound `*.mlconf` are present, `model:` is set, and the project was regenerated. Enable stages explicitly in `*.mlconf` if you need more than the [default behavior](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#default-behavior).|
|`ml_model` present but compile did not run|Bind a project `*.mlconf` in `config_file:` with `override:` (`file_id: ml_compiler_config`) and set `model:`.|
|Wrong model or “model not found”|Check `model:` points at the correct `.tflite` (full path, relative path, or filename when the flatbuffer is in `*.slcp`); if the flatbuffer is in the project, verify it is registered with `directory: tflite`; confirm `override.instance` matches the `ml_model` instance name ([Model path and project wiring](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#model-path-and-project-wiring)).|
|Compiled output missing after generation|Regenerate the project, and verify that `model:` points to the correct `.tflite` and compilation is succeeded in `sml.log`.|
|Failure after board or SDK change|Regenerate the project, and verify that OPN or board support ([Supported Platforms](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#supported-platforms)); review the build log and `sml.log`.|
|Out of memory or linker errors|Adjust [`memory_specification`](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration#memory_specification). Avoid `memory_planner.enabled: false` unless `runtime_memory_size` is validated for the target.|

#### See Also

- [Add Machine Learning to a New or Existing Project](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/add-ml-to-new-or-existing-project)
- [MVP Compiler Configuration](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler-configuration)
- [Machine Learning Fundamentals](/machine-learning/3.0.0/aiml-fundamentals)
- [Simplicity Machine Learning](https://docs.silabs.com/simplicity-machine-learning/latest/simplicity-machine-learning-start/)

### MVP Compiler Configuration

This page describes `*.mlconf` keys and merge order. For project setup, see [Add Machine Learning to a New or Existing Project](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/add-ml-to-new-or-existing-project). For components, pipeline stages, and troubleshooting, see [MVP Compiler](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler).

#### Default Behavior

A machine learning application compiles its model through an `ml_model` instance with a bound project `*.mlconf`. Set `model:` to the input `.tflite` path and regenerate the project. For more information, refer to [Model path and project wiring](#model-path-and-project-wiring) and [Add Machine Learning to a New or Existing Project](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/add-ml-to-new-or-existing-project).

With the default `*.mlconf` shipped for a new `ml_model` instance, the compiler applies memory planning, graph optimization, and memory optimization. The shipped component template enables graph and memory optimization on top of compiler built-in defaults. Custom memory regions and other advanced options are configurable form `*.mlconf` file in project.

Register compression always runs and cannot be turned off in `*.mlconf`. Memory planning uses extension defaults (see [memory_planner](#memory_planner)). Studio supplies the target platform ID from your board or OPN during generation ([Supported Platforms](#supported-platforms)).

#### How Settings Combine

When you regenerate a project, effective compiler settings are applied in layers. Each higher layer overrides the previous.

![Configuration merge order](/aiml-developers-guide/3.0.0/images/mvp-compiler-config-overlay.png)

1. **Compiler built-in defaults**: Baseline values shipped with the compiler engine.
2. **Component default template**: `inst.mlconf` from the `ml_model` component merges on top of built-in defaults.
3. **Your project `*.mlconf`**: The file you edit under `config/compiler/`, bound to an `ml_model` instance in `*.slcp` (see [Model path and project wiring](#model-path-and-project-wiring)).
4. **Project generation**: Simplicity Studio supplies the target OPN or board (resolved to a platform ID. For more information, refer to [Supported Platforms](#supported-platforms)) when the compiler runs. You normally do not set `platform:` in `*.mlconf`.

Nested sections in `*.mlconf` merge recursively. Unknown top-level keys are ignored. Regenerate the project after every change to a `*.mlconf` file so Studio applies the new settings.

Omit a key in your `*.mlconf` to keep the merged default from lower layers.

#### Supported Platforms

SLC passes the target orderable part number (OPN) or board ID from your project configuration. The compiler sanitizes that value and converts it to a canonical platform ID used for the rest of the compile:

1. If the value already matches a known platform ID (case-insensitive), that ID is used.
2. Otherwise, the compiler infers a platform from the OPN or board pattern (for example, MG24-style parts → `efr32xg24`, `brd4187` → `efr32xg24`, Si91x OPNs → `siwg917`).
3. If no rule matches, the sanitized value is passed through. If the driver does not recognize it, compilation fails.

You do not require to set platform: manually. The conversion happens automatically during generation. Unrecognized targets appear in the build log.

##### Compiler Platform IDs

|Platform ID|Typical Targets|
|---|---|
|`brd2601`|BRD2601 (EFR32)|
|`brd2605`|BRD2605 (SiWG917)|
|`brd2608`|BRD2608 (EFR32)|
|`brd2719`|BRD2719 (EFR32)|
|`efr32`|Generic EFR32 family|
|`efr32xg24`|EFR32xG24 (MG24 / xG24 class parts)|
|`efr32xg26`|EFR32xG26 (MG26 / xG26 class parts)|
|`simg301`|SiMG301|
|`siwg917`|SiWG917 / Si91x SoC|

You can set `accelerator:` in `*.mlconf` to override the default for a platform. Typical accelerator IDs: `auto` (default), `cmsis`, `mvpv1`, `sw_ref`.

#### Configuration Format

Project `*.mlconf` files use YAML with nested sections. The following is a quick overview of all settings with detailed descriptions in [Configuration keys](#configuration-keys). Set `model:` and include only the sections you want to change.

```yaml
model: my_model.tflite                     # input .tflite flatbuffer to compile
output: null                               # output path; SLC uses autogen
accelerator: auto                          # kernel backend for target platform
verbose: false                             # enable verbose compiler logging
log_level: INFO                            # compiler log level threshold
enable_debugging: false                    # enable compiler debug behavior
platform: auto                             # platform ID; SLC supplies target

disabled_layers: []                        # layer names excluded from compile
disabled_kernels: []                       # kernel names excluded from compile

graph_optimizer:
  enabled: true                            # enable graph optimization stage
  remove_constant_layers: true             # remove constant-only subgraphs

memory_optimizer:
  enabled: true                            # enable memory optimization stage
  weights_paging: single                   # weights paging mode
  buffer_reuse: false                      # reuse activation buffers when safe
  debugging_forced_buffer_sizes: null      # debug buffer size overrides

memory_planner:
  enabled: true                            # automatic tensor memory planning
  strategy: greedy                         # placement strategy for tensors
  plan_activations: false                  # include activations in planning
  plan_persistent_data: null               # plan persistent data placement

memory_specification:
  - type: PagingBuffer                     # memory region type name
    size: 32768                            # region size in bytes
    section: ".bss"                        # linker section for region
  - type: WeightsAndBiases2                # second weights and biases region
    size: 0                                # zero removes region from layout

codegen:
  enabled: true                            # enable firmware code generation
  shorten_paths: true                      # shorten paths in generated code
  output_format: source                    # header, source, or both
  include_paths: []                        # extra include paths for codegen
  linker_sections: {}                      # memory type to linker section map
  strip_strings: true                      # strip strings from model output
  generate_op_resolver: true               # emit model-specific op resolver
  prefix: model-stem                       # symbol prefix; uses .tflite stem
  logger_enabled: false                    # logger hooks in generated code
  model_header:
    filename: "{prefix}_generated.hpp"     # generated model header filename
    runtime_memory_size: null              # primary tensor arena size bytes
    model_memory_section: null             # linker section for model memory
    add_header_includes: true              # add standard includes to header
    generate_model_load_function: true     # emit model load helper function
    generate_op_resolver_instance: true    # emit op resolver in header
  model_parameters_header:
    enabled: false                         # emit parameters header file
    prefix: "SL_TFLITE_MODEL_{prefix}_"    # macro prefix for parameters
    filename: "{prefix}_generated_parameters.h"
```

When `codegen.prefix` is `model-stem` (the default), it is replaced by the `.tflite` basename and sanitized for C identifiers. `{prefix}` in generated filenames and macro templates expands accordingly (for example, `SL_TFLITE_MODEL_{prefix}_` in `model_parameters_header`).

The template above describes every supported key. The `ml_model` component ships `inst.mlconf` with `model: null` until you set the `.tflite` path in your project `*.mlconf`—see [Default behavior](#default-behavior).

#### Configuration Keys

This section describes all supported configuration keys. Keys with nested sections are annotated with angled brackets where helpful (for example, `codegen.model_header`).

Many `enabled` fields accept `true`, `false`, or `"auto"` (the stage runs only when the selected accelerator supports it).

##### model

- **Type:** `string` or `null`
- **Default:** `null` in the component template; **required** in project configuration files
- **Description:** Path to the input `.tflite` flatbuffer. Set a full host path to compile a flatbuffer outside the project, or register the file in `*.slcp` and use the filename (for example, `my_model.tflite`). See [Model path and project wiring](#model-path-and-project-wiring).

##### output

- **Type:** `string` or `null`
- **Default:** `null`
- **Description:** Compiler output directory. No need to pass from `.mlconf`, SLC uses the autogen path.

##### platform

- **Type:** `string`
- **Default:** `auto`
- **Description:** Compiler platform ID (see [Supported Platforms](#supported-platforms)). Normally supplied by SLC from the target OPN or board.

##### accelerator

- **Type:** `string`
- **Default:** `auto`
- **Description:** Kernel backend for the target. Typical values: `auto`, `cmsis`, `mvpv1`, `sw_ref`, or other IDs supported for the platform.

##### verbose

- **Type:** `boolean`
- **Default:** `false`
- **Description:** Enables verbose compiler logging.

##### log_level

- **Type:** `string` or `integer`
- **Default:** `INFO`
- **Description:** `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`, or a numeric logging level.

##### enable_debugging

- **Type:** `boolean`
- **Default:** `false`
- **Description:** Enables compiler debug behavior.

##### disabled_layers

- **Type:** `list` of `strings`
- **Default:** `[]`
- **Description:** Layer names to exclude from compilation.

##### disabled_kernels

- **Type:** `list` of `strings`
- **Default:** `[]`
- **Description:** Kernel names to exclude from compilation.

##### graph_optimizer

- **Type:** `mapping`
- **Default:** see [Configuration format](#configuration-format)

|Parameter|Type|Default|Description|
|---|---|---|---|
|`enabled`|`boolean` or `"auto"`|`true`|Enable/disable the graph optimizer stage.|
|`remove_constant_layers`|`boolean`|`true`|Remove constant-only subgraphs when the stage runs.|

##### memory_planner

- **Type:** `mapping`
- **Default:** see [Configuration format](#configuration-format)

Silicon Labs recommends leaving `memory_planner.enabled` at `true` for production firmware. Setting it to `false` disables automatic tensor placement. You must then provide a valid `codegen.model_header.runtime_memory_size` for your model and target.
To change region sizes or linker sections without disabling the planner, use the [memory_specification](#memory_specification) section.

|Parameter|Type|Default|Description|
|---|---|---|---|
|`enabled`|`boolean` or `"auto"`|`true`|Enable/disable memory planning.<br/><br/>Not recommended to set `false` in production configuration files.|
|`strategy`|`string`|`greedy`|Placement strategy (for example, `greedy`).|
|`plan_activations`|`boolean` or `null`|`false`|Plan activation tensors.|
|`plan_persistent_data`|`boolean` or `null`|`null`|Plan persistent data placement.|

##### memory_optimizer

- **Type:** `mapping`
- **Default:** see [Configuration format](#configuration-format)

|Parameter|Type|Default|Description|
|---|---|---|---|
|`enabled`|`boolean` or `"auto"`|`true`|Enable/disable the memory optimizer stage.|
|`weights_paging`|`string`|`single`|One of `single`, `dual`, or `auto`.|
|`buffer_reuse`|`boolean`|`false`|Enable activation and buffer reuse when safe.|
|`debugging_forced_buffer_sizes`|`mapping` or `null`|`null`|Debug overrides for buffer sizes (kernel name → size).|

##### memory_specification

`memory_specification` is a top-level section in `*.mlconf`, separate from `memory_planner`. Memory planning consumes these region definitions when building the allocation plan.

- **Type:** `list` or `null`
- **Default:** platform-dependent regions [Configuration format](#configuration-format)
- **Description:** List of memory region overrides merged with platform defaults. Use `size: 0` to remove a region.

Each list entry is a mapping with the following keys:

|Parameter|Type|Default|Description|
|---|---|---|---|
|`type`|`string`|—|**Required.** One of:<br/><br/>`PrimaryTensorArena`, `SecondaryTensorArena`,<br/><br/>`PagingBuffer`, `ActivationsCache`,<br/><br/>`WeightsAndBiases`, `WeightsAndBiases2`.|
|`size`|`integer` or `null`|—|Region size in bytes.|
|`section`|`string` or `null`|—|Linker section (for example, `".bss"`).|
|`bank_size`, `bank_count`, `bank_offset`|`integer` or `null`|—|Optional bank geometry.|

Example:

```yaml
memory_specification:
  - type: PagingBuffer
    size: 32768
    section: ".bss"
  - type: WeightsAndBiases2
    size: 0
```

##### codegen

- **Type:** `mapping`
- **Default:** see [Configuration format](#configuration-format)

|Parameter|Type|Default|Description|
|---|---|---|---|
|`enabled`|`boolean` or `"auto"`|`true`|Enable/disable the code generation stage.|
|`shorten_paths`|`boolean`|`true`|Shorten paths in generated code.|
|`output_format`|`string`|`source`|One of `header`, `source`, or `both`.|
|`include_paths`|`list` of `strings`|`[]`|Extra include paths for generated code.|
|`linker_sections`|`mapping`|`{}`|Memory type name → linker section string.<br/><br/>Same type names as `memory_specification.type`.|
|`strip_strings`|`boolean`|`true`|Strip strings from the model in output artifacts.|
|`generate_op_resolver`|`boolean`|`true`|Generate a model-specific op resolver.|
|`prefix`|`string`|`model-stem`|Symbol and file prefix.<br/><br/>Default expands to the sanitized `.tflite` basename.|
|`logger_enabled`|`boolean`|`false`|Enable logger hooks in generated code.|
|`model_header`|`mapping`|—|See [codegen.model_header](#codegenmodel_header).|
|`model_parameters_header`|`mapping`|—|See [codegen.model_parameters_header](#codegenmodel_parameters_header).|

###### codegen.model_header

|Parameter|Type|Default|Description|
|---|---|---|---|
|`filename`|`string`|`{prefix}_generated.hpp`|Generated model header filename.|
|`runtime_memory_size`|`integer` or `null`|`null`|Primary tensor arena size in bytes.<br/><br/>Set only when you have a validated size from profiling or documentation—not to replace the memory planner in normal builds.|
|`model_memory_section`|`string` or `null`|`null`|Linker section for model memory.|
|`add_header_includes`|`boolean`|`true`|Add standard includes to the header.|
|`generate_model_load_function`|`boolean`|`true`|Emit model load helper function.|
|`generate_op_resolver_instance`|`boolean`|`true`|Emit op resolver instance in the header.|

###### codegen.model_parameters_header

|Parameter|Type|Default|Description|
|---|---|---|---|
|`enabled`|`boolean`|`false`|Enable/disable emission of `{prefix}_generated_parameters.h`.|
|`prefix`|`string`|`SL_TFLITE_MODEL_{prefix}_`|Macro prefix for parameters.|
|`filename`|`string` or `null`|`{prefix}_generated_parameters.h`|Output filename.|

#### Model Path and Project Wiring

The `model` key identifies which `.tflite` flatbuffer an `ml_model` instance compiles. You can point at a flatbuffer outside the project or include it in the project source tree.

**Full host path** — Set `model:` to an absolute path (for example, `C:/models/my_model.tflite`). The flatbuffer does not need to be listed in `*.slcp`.

**Filename in `tflite/`** — To make the flatbuffer part of the project, register it in `config_file:` with `directory: tflite`, then set `model:` to the filename (for example, `my_model.tflite`). During generation, SLC stages the flatbuffer beside the `*.mlconf` under the virtual `tflite/` directory.

**Relative path** — Resolved relative to the directory that contains the `*.mlconf` in the generated project tree (for example, `../tflite/my_model.tflite`).

##### Wiring `ml_model` in `*.slcp`

The following registers one model. For multiple models, see [Multi-Model Support](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/multi-model-support).

Register and **override** the component's config slots:

```yaml
### my_project.slcp (excerpt)
component:
  - id: ml_model
    instance:
      - my_model
config_file:
  - path: config/compiler/my_model.mlconf
    directory: tflite
    override:
      component: ml_model
      file_id: ml_compiler_config
      instance: my_model
  - path: config/tflite/my_model.tflite
    directory: tflite
```

The `directory: tflite` entries expose both files under the virtual `tflite/` tree used during generation. The `override:` block binds the project `*.mlconf` to the `ml_model` instance's `ml_compiler_config` slot. The `.tflite` entry is optional when `model:` uses a full host path; register it in `config_file:` with `directory: tflite` when you want the flatbuffer in the project (no `override` required for the flatbuffer unless your template specifies one).

Align the instance name and `*.mlconf` basename for clarity (for example, instance `my_model` → `my_model.mlconf`). Compiled output filenames use the `.tflite` filename stem from `model:`, regardless of the instance name.

If you change which flatbuffer a configuration file applies to, update `model:` and the matching `config_file:` `.tflite` registration, then regenerate the project. Output filenames change with the new flatbuffer stem.

#### Minimal Project Configuration

See [Model path and project wiring](#model-path-and-project-wiring) for `*.slcp` registration. The shipped component template already enables graph and memory optimization.

```yaml
model: my_model.tflite

graph_optimizer:
  enabled: true
memory_optimizer:
  enabled: true
```

#### See Also

- [Add Machine Learning to a New or Existing Project](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/add-ml-to-new-or-existing-project) for *.slcp and *.mlconf setup steps.
- [MVP Compiler](https://docs.silabs.com/machine-learning/latest/aiml-developers-guide/mvp-compiler) for integration overview and troubleshooting.

### Migrate from AI/ML SDK 2.2.2 to 3.0.0

This guide explains how to upgrade an existing Simplicity Studio project from AI/ML SDK 2.2.2 to AI/ML SDK 3.0.0.

AI/ML 3.0.0 introduces breaking changes: EFR32 projects move from the flatbuffer converter to the MVP compiler. The SiWx917 projects already used the MVP compiler (`mvp_compiler`) in 2.2.2 but without the `ml_model` component. On both platforms, application code moves to the unified `sl_ml_model_*` runtime API. Register each model with the instantiable ML Model (`ml_model`) component and a project `*.mlconf`.

#### Scope

This guide covers projects that already use AI/ML 2.x — EFR32 / Series 2 (`tensorflow_lite_micro`, flatbuffer autogen, `sl_tflite_micro_*`) or SiWx917 (`mvp_compiler`, `slx_ml_*`, `tflite_micro_model.hpp`). For new projects on 3.0.0, see [Add Machine Learning to a New or Existing Project](add-ml-to-new-or-existing-project) and the [MVP Compiler](mvp-compiler).

---

#### Summary of Breaking Changes

In AI/ML 2.2.2, EFR32 and SiWx917 used different compilation and runtime APIs. In AI/ML 3.0.0, both platforms compile via the MVP compiler with ml_model and share a common runtime (sl_ml_model_init(), sl_ml_model_run(), and tensor accessors). Replace platform-specific 2.2.2 calls with this unified interface (`MODEL_STEM` is the `.tflite` filename without extension).

|Area|AI/ML 2.2.2 (EFR32 / Series 2)|AI/ML 2.2.2 (SiWx917)|AI/ML 3.0.0 (unified)|Example|
|---|---|---|---|---|
|Model compilation AC|Flatbuffer converter (`tensorflow_lite_micro`)|MVP compiler (`mvp_compiler`) — no `ml_model` component|MVP compiler via ML Model (`ml_model`) + `*.mlconf`|`config/tflite/inst0.mlconf`|
|Generated headers|`autogen/sl_tflite_micro_model.*`|`autogen/sl_ml_model_<model_name>.h`|`autogen/sl_ml_model_<MODEL_STEM>.h`|`autogen/sl_ml_model_keyword_spotting_on_off_v2.h`|
|Initialization|`sl_tflite_micro_init()`, `sl_tflite_micro_get_*()`|`slx_ml_<model_name>_model_init()`|`sl_ml_model_init(&sl_ml_<MODEL_STEM>_model_handle)`|`sl_ml_model_init(&sl_ml_keyword_spotting_on_off_v2_model_handle)`|
|Inference|`interpreter->Invoke()`|`slx_ml_<model_name>_model_run()`|`sl_ml_model_run(&sl_ml_<MODEL_STEM>_model_handle)`|`sl_ml_model_run(&sl_ml_keyword_spotting_on_off_v2_model_handle)`|
|Tensor access|`sl_tflite_micro_get_input_tensor()` / `sl_tflite_micro_get_output_tensor()`|`<model_name>_model.input(i)` / `.output(i)` via `tflite_micro_model.hpp`|`sl_ml_<MODEL_STEM>_model_handle.input_tensor(0)` / `.output_tensor(0)`|`sl_ml_keyword_spotting_on_off_v2_model_handle.input_tensor(0)`|

##### Audio Feature Generator API Changes

If your project uses the audio feature generator, after you reinstall the **Audio Feature Generator** (`fe_audio`) component ([step 2](#2-reinstall-the-audio-feature-generator-fe_audio-if-applicable)) update application code as follows.

|Area|AI/ML 2.2.2|AI/ML 3.0.0|Example (`aiml_soc_voice_control_light_efr32_micriumos`)|
|---|---|---|---|
|Header|`#include "sl_ml_audio_feature_generation.h"`|`#include "sl_fe_audio.h"` on EFR32, or `#include "sl_fe_audio_si91x.h"` on SiWx917|`#include "sl_fe_audio.h"`|
|Initialization (EFR32)|`sl_ml_audio_feature_generation_init()`|Same function; include `sl_fe_audio.h`|`sl_ml_audio_feature_generation_init()`|
|Initialization (SiWx917)|`sl_ml_audio_feature_generation_init()`|`sl_ml_audio_feature_generation_init(&sl_fe_audio_<instance>_cfg)` — pass `sl_fe_audio_<instance>_cfg` from `sl_fe_audio_instances.h`|—|
|Load model settings|Not used with flatbuffer autogen|`sl_ml_audio_feature_generation_load_model_settings(sl_ml_<instance>_model_handle.flatbuffer)` before `init`, when using the ML Model workflow|`sl_ml_audio_feature_generation_load_model_settings(sl_ml_inst0_model_handle.flatbuffer)`|
|Fill input tensor|`sl_ml_audio_feature_generation_fill_tensor(sl_tflite_micro_get_input_tensor())`|`sl_ml_audio_feature_generation_fill_tensor(sl_ml_<instance>_model_handle.input_tensor(0))`|`sl_ml_audio_feature_generation_fill_tensor(sl_ml_inst0_model_handle.input_tensor(0))`|

On EFR32, `sl_ml_audio_feature_generation_update_features()`, `sl_ml_audio_feature_generation_get_features_*()`, and related runtime functions keep the same names.

#### Upgrade Through Simplicity Studio

This process uses `aiml_soc_voice_control_light_efr32_micriumos` as the reference project. The Voice Control Light sample on BRD2601B, upgraded from AI/ML SDK 2.2.2.

##### Prerequisites

This guide assumes you already have a working project on AI/ML SDK 2.2.2. Before upgrading, install Simplicity SDK Suite v2026.6.0 (or newer 2026.x) with Silicon Labs AI/ML SDK 3.0.0 or later.

##### 1. Upgrade the SDK in the GUI

1. Open the project `.slcp` file in **Project Configurator**, click the **Change SDK version** on the **OVERVIEW** tab. Studio opens the **Select SDK** dialog.![Select the target SDK for upgrade](/aiml-developers-guide/3.0.0/images/aiml-migration-change-sdk.png)
2. Select **Simplicity SDK Suite v2026.6.0 (preferred)** or the latest 2026.x entry that includes AI/ML 3.0.0+.  
   ![Select SDK for upgrade](/aiml-developers-guide/3.0.0/images/aiml-migration-select-sdk.png)
3. Click **VERIFY** to open **Upgrade**:  
   ![Confirm upgrade and accept the risk](/aiml-developers-guide/3.0.0/images/aiml-migration-upgrade.png)
4. Review AUTOMATIC UPGRADE changes (for example, adding `ml_model`, renaming `ml_audio_feature_generation` to `fe_audio`, moving `nn_util` / `nn_mvp` to `aiml`).
5. Under **NO UPGRADE POSSIBLE**, Studio lists the manual steps (update to `sl_ml_model_*` APIs, regenerate, use Force Upgrade). Select **I understand the risk**, then click **UPGRADE**. Studio cannot rewrite your application source automatically — this is expected.
6. After a successful upgrade, the Project Explorer references `simplicity_sdk_2026.6.0` and `aiml_3.x.x` folders.
7. The first **Generate** may fail with an MVP compiler error until you fix `*.mlconf` ([step 3](#3-fix-the-mlconf-model-path-after-upgrade)) — this is expected.  
   ![MVP compiler error](/aiml-developers-guide/3.0.0/images/aiml-3-migration-mvp-compiler-error.png)

> _**NOTE:**_ The SDK upgrade is **partially** complete at this point. Generation will fail until you fix the model compiler configuration (.mlconf) and update application source code.

##### 2. Reinstall the Audio Feature Generator (`fe_audio`) (if applicable)

Skip this step if your project does not use the audio feature generator.

In AI/ML 2.2.2, `ml_audio_feature_generation` was a non-instantiable component. In 3.0.0, `fe_audio` is instantiable — add one `fe_audio` instance per model that uses the audio feature generator.

In testing with `aiml_soc_voice_control_light_efr32_micriumos_5`, the SDK upgrade removed the legacy `ml_audio_feature_generation` component and did not leave a working replacement in place. You must add the AI/ML 3.0 component manually:

1. Open the project `.slcp` file in Project Configurator.
2. Under **Software Components**, search for `audio feature`.
3. Expand **AI/ML → Machine Learning → Feature Generator** and install **Audio Feature Generator** (`fe_audio`).
4. Add a `fe_audio` instance in Studio. The instance name must match the corresponding ML Model (`ml_model`) instance name exactly.
5. **Generate** the project.
6. Confirm `sl_fe_audio.h`, `sl_fe_audio_instances.h` (SiWx917), and related `fe_audio` config files appear (for example `config/sl_ml_audio_feature_generation_config.h`).

Platform-specific setup after adding the instance:

###### SiWx917

Enable `model_parameters_header` in the model's `*.mlconf` so the compiler generates `<instance>_generated_parameters.h` for the frontend config:

```yaml
codegen:
  model_parameters_header:
    enabled: true
```

Then in application code:

```c
#include "sl_fe_audio_instances.h"
#include "sl_fe_audio_si91x.h"

sl_ml_audio_feature_generation_init(&sl_fe_audio_keyword_spotting_on_off_v3_cfg);
```

Replace `keyword_spotting_on_off_v3` with your shared `fe_audio` / `ml_model` instance name.

###### EFR32

Add the `fe_audio` instance in Studio as described above. Initialization stays parameterless — call `sl_ml_audio_feature_generation_load_model_settings()` with the model flatbuffer, then `sl_ml_audio_feature_generation_init()`:

```c
#include "sl_fe_audio.h"
#include "sl_ml_model_inst0.h"

sl_ml_audio_feature_generation_load_model_settings(sl_ml_inst0_model_handle.flatbuffer);
sl_ml_audio_feature_generation_init();
```

##### 3. Fix the `*.mlconf` Model Path After Upgrade

After upgrading the SDK, the first project generation often fails with the following error:
"Set `model:` to the absolute path to the `.tflite` file that you want to associate with this `.mlconf` file, or just the name of the `.tflite` file that will be copied into the `config/tflite` directory of your project."

1. In Project Explorer, open `config/tflite/` and identify every `*.mlconf` file (one per ML Model instance). In the reference project this is `config/tflite/inst0.mlconf`.
2. Find the matching `.tflite` model file (`keyword_spotting_on_off_v2.tflite` in the reference project). Edit the `*.mlconf` file and set `model:` to the absolute path to that file, or to its filename if the flatbuffer is registered under `config_file:` with `directory: tflite`.  
   For example:

```yaml
model: keyword_spotting_on_off_v2.tflite
```

1. Generate the project again.
2. Confirm `autogen/ml/` and `autogen/sl_ml_model_<instance>.h` appear. If generation still fails, open `autogen/sml.log` for details.
3. If your project uses the audio feature generator with Siwx917, enable`model_parameters_header` in that `*.mlconf`, so the compiler emits  
   `<instance>_generated_parameters.h` for `fe_audio`. Remove the legacy **Audio Feature  
   Generator** (`ml_audio_feature_generation`) component if it is still listed alongside  
   `fe_audio`.

> **NOTE:** If your `.slcp` still contains `SL_TFLITE_MICRO_ARENA_SIZE` from AI/ML 2.2.2, you can leave it. AI/ML 3.0.0 plans tensor memory at compile time through the ML Model component, so this setting is not used on the new inference path.

##### 4. Update Application Source Code

Update your application `.c` / `.cc` / `.cpp` files (not the files under `autogen/`), or use the [AI-assisted migration prompt](#ai-assisted-migration-prompt) after completing the Steps 1 to 3.
If your project uses the audio feature generator, apply [Audio feature generator API changes](#audio-feature-generator-api-changes) after completion of upgrade in Step 1.

###### API Replacement Table

|Legacy (2.x)|AI/ML 3.0.0|
|---|---|
|`#include "sl_tflite_micro_init.h"`|`#include "sl_ml_model_<instance>.h"`|
|`#include "sl_tflite_micro_model.h"`|`#include "sl_ml_model_<instance>.h"`|
|`sl_tflite_micro_init()`|`sl_ml_model_init(&sl_ml_<instance>_model_handle)`|
|`slx_ml_<instance>_model_init()`|`sl_ml_model_init(&sl_ml_<instance>_model_handle)`|
|`sl_ml_<instance>_model_init()`|`sl_ml_model_init(&sl_ml_<instance>_model_handle)`|
|`interpreter->Invoke()`|`sl_ml_model_run(&sl_ml_<instance>_model_handle)`|
|`slx_ml_<instance>_model_run()`|`sl_ml_model_run(&sl_ml_<instance>_model_handle)`|
|`sl_tflite_micro_get_input_tensor()`|`sl_ml_<instance>_model_handle.input_tensor(0)`|
|`sl_tflite_micro_get_output_tensor()`|`sl_ml_<instance>_model_handle.output_tensor(0)`|
|`sl_tflite_micro_get_interpreter()`|Not used — call `sl_ml_model_run()` on the handle|
|`TF_LITE_REPORT_ERROR(sl_tflite_micro_get_error_reporter(), …)`|Check `SL_STATUS_OK` return from `sl_ml_model_init` / `sl_ml_model_run`|
|`kTfLiteOk` on invoke|`SL_STATUS_OK` on `sl_ml_model_run`|
|Automatic init at startup|Explicit `sl_ml_model_init(&sl_ml_<instance>_model_handle)` in your app|
|`sl_ml_audio_feature_generation_fill_tensor(sl_tflite_micro_get_input_tensor())`|`sl_ml_audio_feature_generation_fill_tensor(sl_ml_<instance>_model_handle.input_tensor(0))`|

###### Before (2.2.2)

```cpp
#include "sl_tflite_micro_init.h"

void app_process_action(void) {
  TfLiteTensor* input = sl_tflite_micro_get_input_tensor();
  input->data.int8[0] = sample;

  TfLiteStatus status = sl_tflite_micro_get_interpreter()->Invoke();
  if (status != kTfLiteOk) {
    return;
  }

  TfLiteTensor* output = sl_tflite_micro_get_output_tensor();
  int8_t result = output->data.int8[0];
}
```

###### After (3.0.0)

```cpp
#include "sl_ml_model_keyword_spotting_on_off_v2.h"

void app_process_action(void) {
  if (sl_ml_model_init(&sl_ml_keyword_spotting_on_off_v2_model_handle) != SL_STATUS_OK) {
    return;
  }

  TfLiteTensor* input = sl_ml_keyword_spotting_on_off_v2_model_handle.input_tensor(0);
  input->data.int8[0] = sample;

  if (sl_ml_model_run(&sl_ml_keyword_spotting_on_off_v2_model_handle) != SL_STATUS_OK) {
    return;
  }

  TfLiteTensor* output = sl_ml_keyword_spotting_on_off_v2_model_handle.output_tensor(0);
  int8_t result = output->data.int8[0];
}
```

> **Tip:** Call `sl_ml_model_init` once (for example in `app_init` or task startup), then call `sl_ml_model_run` in your inference loop. Use `sl_ml_model_deinit` only when unloading the model.

##### AI-assisted Migration Prompt

1. Complete SDK upgrade in Simplicity Studio.
2. Verify the Studio checklist, the [AI-assisted migration prompt](#copy-paste-prompt) repairs common `.slcp` issues that Studio often cannot fix (ghost legacy components, missing `*.mlconf` bindings), and migrates application source.

> **Note**: Close Studio before the AI session. If Project Configurator is open, it can overwrite `.slcp` edits when you save.
> After the AI finishes, reopen Studio → Generate → Build. Do not open Software Components or save from Configurator unless you intend to change components.

###### Studio Checklist (complete before pasting the prompt)

Do these in **Project Configurator → Software Components** :

|Action|Component|
|---|---|
|Install / keep|ML Model (`ml_model`) — one instance per model (for example `inst0`)|
|Install / keep|Audio Feature Generator (`fe_audio`) — same instance name as `ml_model` (audio projects only)|
|Install / keep|TensorFlow Lite Micro (`tensorflow_lite_micro`) — required by `ml_model`|
|Remove if present|`ml_audio_feature_generation` (legacy 2.x ghost — Studio often cannot show it; the [AI migration prompt](#copy-paste-prompt) removes it)|
|Remove if present|MVPv1 Accelerated Kernels (`tensorflow_lite_micro_accelerated_kernels`), CMSIS-NN Optimized Kernels (`tensorflow_lite_micro_optimized_kernels`), MVP NN (`nn_mvp`), NN Utilities (`nn_util`)|
|Remove if present|Debug Logging using IO Stream (`tensorflow_debug_log_iostream`) (legacy debug log — breaks build with missing `tensorflow/lite/micro/debug_log.h`)|

Make sure to complete the [Step 3](#3-fix-the-mlconf-model-path-after-upgrade) and then perform the AI prompt.

###### Copy-paste Prompt

Replace `PROJECT_ROOT` in the block below, then copy the entire fenced block into your AI coding session.

```c
You are migrating a Silicon Labs Simplicity Studio project from AI/ML SDK 2.2.2 to AI/ML 3.0.0.

Project root: PLACE YOUR PROJECT PATH HERE

The user should have completed the SDK upgrade in Studio and closed Simplicity Studio (so `.slcp` edits are not reverted on Save).
Your job is to repair common `.slcp` issues Studio cannot fix, migrate application source, fix `config/**/*.mlconf`, add the EFR32 FP16 toolchain flag when missing, and apply the VS Code (GCC) CMake fallback when needed. The user will **Generate** and **Build** in Studio after you finish — do not run `slc generate`.

#### Hard rules

1. **Never edit** `autogen/`, autogenerated `cmake_gcc/*.cmake` (for example `aiml_soc_voice_control_light_efr32_micriumos_8.cmake`), `simplicity_sdk_*`, `aiml_*`, or `wiseconnect*_sdk_*`. **Exception:** Phase 0.6 may edit only `cmake_gcc/CMakeLists.txt` (user extension point).
2. **Only edit** application source (`.c`, `.cc`, `.cpp`, `.h`, `.hpp`), `config/**/*.mlconf`, limited `*.slcp` keys in Phase 0.5, and `cmake_gcc/CMakeLists.txt` in Phase 0.6 (EFR32 only). Never change SDK version, `sdk_extension`, or unrelated `.slcp` keys.
3. Discover all symbols from the project — do not guess model names or instance names.
4. Apply every replacement consistently across all application files before finishing.
5. Do not change application logic, timing, or recognition thresholds — only migrate APIs and headers.
6. **Hard stop only** for blockers you cannot fix: missing `ml_model`, `fe_audio` (audio projects), or `tensorflow_lite_micro`; missing `config/tflite/MODEL_FILE` on disk; or legacy kernel components (`tensorflow_lite_micro_accelerated_kernels`, `tensorflow_lite_micro_optimized_kernels`, `nn_mvp`, `nn_util`, `tensorflow_debug_log_iostream`) still listed under `component:`. For those, print the blocker list and stop — do not edit source. Ghost `ml_audio_feature_generation`, missing `*.mlconf` in `config_file:`, and missing `-mfp16-format=ieee` (`.slcp` and/or `cmake_gcc/CMakeLists.txt`) are **not** hard stops — fix in Phase 0.5 and 0.6.
7. **Do not** use `slc generate --with` / `--without` or patch autogenerated `cmake_gcc/*.cmake` files.
8. **Do not delete** `sl_ml_audio_feature_generation_config.*` or other SDK `sl_ml_audio_feature_generation_*` files — in 3.x they belong to `fe_audio`.
9. After edits, print the verification checklist (Phase 4) with pass/fail for each item.
10. **Studio v6 / VS Code (GCC):** There is no GNU ARM C++ Compiler GUI. If `.slcp` has `-mfp16-format=ieee` but `cmake_gcc/aiml_soc_voice_control_light_efr32_micriumos_8.cmake` lacks it in `target_compile_options(slc ...)`, apply Phase 0.6. MVP `mvpv1/*.cc` files compile into **`slc`**, not the executable.

#### Phase 0 — Discovery (read only)

1. Read the `.slcp` file in PROJECT_ROOT.
2. Determine platform:
   - **SiWx917** if `.slcp` lists `wiseconnect3_sdk` or source uses `slx_ml_*`,
     `sl_ml_audio_feature_generation_si91x.h`, or `tflite_micro_model.hpp`.
   - **EFR32 / Series 2** otherwise (typical: `sl_tflite_micro_*` in app source).
3. Record from `.slcp` and `config/tflite/`:
   - `MODEL_STEM` = `.tflite` filename without extension (for example `keyword_spotting_on_off_v2`).
   - `MODEL_FILE` = basename (for example `keyword_spotting_on_off_v2.tflite`).
   - `ML_INSTANCE` = `ml_model` instance name (for example `inst0`).
   If multiple models exist, migrate each; one `ml_model` instance per model.
4. Check prerequisites (read `.slcp`):
   - **Hard blockers** (stop if any fail): `ml_model` with instance; `fe_audio` matching `ml_model` (audio); `tensorflow_lite_micro`; no legacy kernels under `component:`; `config/tflite/MODEL_FILE` on disk.
   - **Auto-repair in Phase 0.5** (do not stop): ghost `ml_audio_feature_generation` when `fe_audio` is present; missing `config_file:` entry for `config/tflite/ML_INSTANCE.mlconf`; missing `-mfp16-format=ieee` in `.slcp` (EFR32).
   - **Auto-repair in Phase 0.6** (do not stop, EFR32 only): if `cmake_gcc/CMakeLists.txt` lacks `-mfp16-format=ieee` on the `slc` target, or generated `cmake_gcc/*_*.cmake` (project name cmake) has no `-mfp16-format=ieee` under `target_compile_options(slc` — add Phase 0.6 block (Studio Save often reverts `.slcp` before Generate propagates flags).
5. Detect project generator: if `.slps` contains `visual-studio-code` or OVERVIEW would show **VS Code (GCC)**, plan Phase 0.6 for EFR32 MVP builds.
6. Read `autogen/sml.log` if present — note if it contains `no mlconf files found` (Phase 0.5 should fix the binding).
7. Grep PROJECT_ROOT application source for legacy APIs:
   - `sl_tflite_micro_`, `slx_ml_`
   - `sl_tflite_micro_model.h`, `sl_tflite_micro_init.h`
   - `tensorflow/lite/c/common.h`, `tensorflow/lite/micro/`
   - `sl_ml_audio_feature_generation.h` (include path — replace with `sl_fe_audio.h`)
   - `tflite_micro_model.hpp`, `keyword_spotting_*_model.`, `register_tflite_micro_accelerator`
8. Generated symbols use **MODEL_STEM**, not ML_INSTANCE (unless they match):
   - Header: `sl_ml_model_MODEL_STEM.h` (under `autogen/` after Generate)
   - Handle: `sl_ml_MODEL_STEM_model_handle`

#### Phase 0.5 — Safe `.slcp` repairs (editable)

Apply when Phase 0 found auto-repair items. Edit only `component:` (ghost removal) and `config_file:` / `toolchain_settings` in `PROJECT_ROOT/*.slcp`. Do not change SDK version or other keys.

1. **Remove ghost `ml_audio_feature_generation`** when `fe_audio` is already installed: delete only this block from `component:`:

       - package: aiml
         vendor: silabs
         id: ml_audio_feature_generation

   Do not remove `fe_audio` or `ml_model`.

2. **Add missing `*.mlconf` binding** when `config/tflite/ML_INSTANCE.mlconf` exists on disk but `config_file:` lacks it. Insert before the `.tflite` entry:

       - path: config/tflite/ML_INSTANCE.mlconf
         directory: tflite
         override:
           component: ml_model
           file_id: ml_compiler_config
           instance: ML_INSTANCE

3. **EFR32 FP16 flag** — if no `toolchain_settings` entry has `option: gcc_compiler_option` and `value:` containing `-mfp16-format=ieee`, append:

       - value: -mfp16-format=ieee
         option: gcc_compiler_option

   Skip on SiWx917. Without this flag, MVP kernels fail with `float16_t has not been declared`.

#### Phase 0.6 — EFR32 FP16 in `cmake_gcc/CMakeLists.txt` (VS Code / GCC fallback)

Apply on **EFR32** when `autogen/ml/accelerator/mvpv1/` exists or MVP compilation is enabled, and **either**:

- `cmake_gcc/CMakeLists.txt` does not already pass `-mfp16-format=ieee` to `slc`, or
- the autogenerated project cmake (for example `cmake_gcc/aiml_soc_voice_control_light_efr32_micriumos_8.cmake`) lacks `-mfp16-format=ieee` in `target_compile_options(slc` (common when Studio reverted `.slcp` before Generate).

Edit **only** `PROJECT_ROOT/cmake_gcc/CMakeLists.txt`. Immediately after the line `include(...cmake)` that pulls in the autogenerated `slc` target, ensure this block exists (add if missing; do not duplicate):

    # MVP-compiled kernels in autogen/ml/accelerator/mvpv1/ require IEEE FP16 on EFR32.
    target_compile_options(slc PUBLIC
        $<$<COMPILE_LANGUAGE:C>:-mfp16-format=ieee>
        $<$<COMPILE_LANGUAGE:CXX>:-mfp16-format=ieee>
    )

Skip on SiWx917. Still apply Phase 0.5 `.slcp` `toolchain_settings` when possible — Phase 0.6 is the reliable build fix for Studio v6 + VS Code (GCC) when Generate does not propagate the flag.

#### Phase 1 — `*.mlconf` and model files (editable)

1. Ensure `config/tflite/ML_INSTANCE.mlconf` exists. Create from the project template if missing.
2. Set `model: MODEL_FILE` (not `null`).
3. Ensure `config/tflite/MODEL_FILE` exists on disk. If referenced but missing, tell the user where
   to copy it from — do not invent model binaries.
4. Platform-specific `codegen` in mlconf:
   - **SiWx917** + audio FE: `model_parameters_header: enabled: true`
   - **EFR32** + audio FE: `model_parameters_header` may stay `false`

#### Phase 2 — Application source migration

Migrate every application file with legacy ML APIs. Typical files: `audio_classifier.cc`,
`recognize_commands.h`, `recognize_commands.cc`, `*_config.h`, `*_config.cc`, `app.c`.

##### 2a. Headers

| Remove / replace | With |
| ---------------- | ---- |
| `#include "sl_tflite_micro_model.h"` | `#include "sl_ml_model_MODEL_STEM.h"` |
| `#include "sl_tflite_micro_init.h"` | (remove) |
| `#include "sl_ml_audio_feature_generation.h"` | `#include "sl_fe_audio.h"` (EFR32) |
| `#include "sl_ml_audio_feature_generation_si91x.h"` | `#include "sl_fe_audio_si91x.h"` |
| `#include "sl_ml_audio_feature_generation_config_si91x.h"` | `#include "sl_fe_audio_instances.h"` (SiWx917) |
| `#include "tensorflow/lite/c/common.h"` | `#include "ml/third_party/tflm/common.h"` |
| `#include "tensorflow/lite/micro/tflite_bridge/micro_error_reporter.h"` | (remove — see 2e) |
| `#include "tensorflow/lite/micro/micro_error_reporter.h"` | (remove — see 2e) |
| `#include "tflite_micro_model.hpp"` | (remove unless still required) |
| `#include "slx_ml_MODEL_STEM_model.h"` | `#include "sl_ml_model_MODEL_STEM.h"` |
| `#if __has_include("sl_tflite_micro_model_parameters.h")` | Optional: `MODEL_STEM_generated_parameters.h` if enabled in mlconf |

Also add `#include "sl_ml_audio_feature_generation_config.h"` where the audio FE config is needed (EFR32).

##### 2b. Model init / run / tensors

| Legacy (2.x) | AI/ML 3.0.0 |
| ------------ | ----------- |
| `sl_tflite_micro_init()` | `sl_ml_model_init(&sl_ml_MODEL_STEM_model_handle)` |
| `slx_ml_MODEL_STEM_model_init()` | `sl_ml_model_init(&sl_ml_MODEL_STEM_model_handle)` |
| `sl_tflite_micro_get_interpreter()->Invoke()` | `sl_ml_model_run(&sl_ml_MODEL_STEM_model_handle)` |
| `slx_ml_MODEL_STEM_model_run()` | `sl_ml_model_run(&sl_ml_MODEL_STEM_model_handle)` |
| `sl_tflite_micro_get_input_tensor()` | `sl_ml_MODEL_STEM_model_handle.input_tensor(0)` |
| `sl_tflite_micro_get_output_tensor()` | `sl_ml_MODEL_STEM_model_handle.output_tensor(0)` |
| `keyword_spotting_*_model.input()` | `sl_ml_MODEL_STEM_model_handle.input_tensor(0)` |
| `keyword_spotting_*_model.output()` | `sl_ml_MODEL_STEM_model_handle.output_tensor(0)` |
| `*_model_flatbuffer` | `sl_ml_MODEL_STEM_model_handle.flatbuffer` |
| `register_tflite_micro_accelerator()` | Remove — handled inside `sl_ml_model_init()` |

Call `sl_ml_model_init()` once at startup. Call `sl_ml_model_run()` in the inference loop.
Check `SL_STATUS_OK` for init/run (not `kTfLiteOk` on invoke).

##### 2c. Audio feature generator (EFR32)

After `#include "sl_fe_audio.h"` and model init:

    if (!sl_ml_audio_feature_generation_load_model_settings(sl_ml_MODEL_STEM_model_handle.flatbuffer)) { ... }
    if (sl_ml_audio_feature_generation_init() != SL_STATUS_OK) { ... }
    sl_ml_audio_feature_generation_fill_tensor(sl_ml_MODEL_STEM_model_handle.input_tensor(0));

##### 2d. Audio feature generator (SiWx917)

    sl_ml_model_init(&sl_ml_MODEL_STEM_model_handle);
    sl_ml_audio_feature_generation_init(&sl_fe_audio_ML_INSTANCE_cfg);
    sl_ml_audio_feature_generation_fill_tensor(sl_ml_MODEL_STEM_model_handle.input_tensor(0));

Omit `load_model_settings()` when `model_parameters_header` is enabled in mlconf.

##### 2e. `recognize_commands.h` / `recognize_commands.cc` (AI/ML 3.0 pattern)

- Use `ml/third_party/tflm/common.h` and `ml/third_party/tflm/micro_log.h` (not `tensorflow/lite/*`).
- `PreviousResultsQueue` has a default constructor (no `ErrorReporter` parameter).
- `RecognizeCommands` constructor has **no** `tflite::ErrorReporter*` argument.
- Replace `TF_LITE_REPORT_ERROR(...)` with `MicroPrintf(...)` or `printf(...)` in app code.
- Remove `error_reporter_` member variables.

##### 2f. Error handling

    if (sl_ml_model_run(&sl_ml_MODEL_STEM_model_handle) != SL_STATUS_OK) { ... }

#### Phase 3 — Post-migration grep

Re-grep application source (exclude `autogen/`, SDK copies). **Zero hits** required for:

- `sl_tflite_micro_get_`, `sl_tflite_micro_init`, `slx_ml_`
- `sl_tflite_micro_model.h`, `sl_tflite_micro_init.h`
- `tensorflow/lite/c/common.h`, `tensorflow/lite/micro/`
- `sl_ml_audio_feature_generation.h` (use `sl_fe_audio.h` instead)
- `sl_ml_audio_feature_generation_si91x.h`
- `tflite_micro_model.hpp` (unless required by non-ML code)
- `keyword_spotting_*_model.` (C++ wrapper object API)
- `sl_tflite_micro_get_error_reporter`

#### Phase 4 — Verification checklist (print to user)

| Check | Expected |
| ----- | -------- |
| Studio: `ml_model` + instance | Present (user verified in Studio) |
| Studio: `fe_audio` (if audio) | Instance matches `ml_model` |
| Studio: `tensorflow_lite_micro` | Present |
| Studio: legacy components removed | No `ml_audio_feature_generation`, no accelerated/optimized TFLM kernels, no `nn_mvp`/`nn_util`, no `tensorflow_debug_log_iostream` |
| Studio: mlconf in `.slcp` `config_file` | `config/tflite/ML_INSTANCE.mlconf` with matching `instance` |
| `-mfp16-format=ieee` in `.slcp` `toolchain_settings` (EFR32) | Present (AI Phase 0.5 added, or was already set) |
| `-mfp16-format=ieee` on `slc` in `cmake_gcc/CMakeLists.txt` (EFR32, VS Code/GCC) | Present (AI Phase 0.6 added if needed) |
| After Generate: `-mfp16-format=ieee` in compile flags for `mvpv1/*.cc` | Present in `.rsp` or generated cmake (user verifies after Build if needed) |
| `config/tflite/*.mlconf` `model:` | `MODEL_FILE`, not `null` |
| `config/tflite/MODEL_FILE` on disk | Present |
| Legacy API grep (app source) | Zero hits |
| User: **Generate** in Studio | Required (after AI edits) |
| After Generate: `autogen/sl_ml_model_MODEL_STEM.h` | Exists |
| After Generate: `autogen/ml/` | Exists |
| After Generate: `autogen/sml.log` | No `no mlconf files found` |
| User: **Build** in Studio | Succeeds |
| User: flash and test | Hardware OK |

#### Output format

1. Discovery summary: platform, MODEL_STEM, ML_INSTANCE, generator (VS Code/GCC or other), hard blockers (if any), and Phase 0.5 / 0.6 repairs applied.
2. If hard blockers exist, **only** print section 1, the Studio fix list, and stop — no file edits.
3. Every file edited and why.
4. Phase 4 checklist with pass/fail.
5. Remind user: reopen Studio (if closed) → **Generate** → **Build** → flash. Do not Save from Project Configurator unless changing components (may revert `.slcp`). On VS Code (GCC) projects, keep the Phase 0.6 `CMakeLists.txt` edit even if `.slcp` was reverted.
```

> **Note:** Generated model symbols use the `.tflite` filename stem (`MODEL_STEM`), not necessarily the `ml_model` instance name. For example, instance `inst0` with `keyword_spotting_on_off_v2.tflite` produces `sl_ml_model_keyword_spotting_on_off_v2.h` and `sl_ml_keyword_spotting_on_off_v2_model_handle`, not `sl_ml_inst0_model_handle`.

##### 5. Build and Test on Hardware

1. Build the project in Studio.
2. Flash and run on your board.
3. Verify that inference behavior matches the pre-migration application.

#### Upgrade Through CLI

It uses `aiml_soc_voice_control_light_efr32_micriumos` as the reference project — the Voice Control Light sample on BRD2601B, upgraded from AI/ML SDK 2.2.2. Use [SLT](https://docs.silabs.com/command-line-development/latest/ssv6-slt-cli/) and [SLC](https://docs.silabs.com/command-line-development/latest/slc-cli/) instead of Simplicity Studio.

##### Prerequisites

```bash
slt install aiml/2.2.2@silabs   # pulls simplicity-sdk/2025.12.3@silabs
slt install aiml/3.0.0@silabs   # pulls simplicity-sdk/2026.6.0@silabs
```

##### 1. Open the Reference Project

Open a terminal and change to your existing AI/ML 2.2.2 project directory, or use the bundled example:

```bash
cd "$(slt where aiml/2.2.2)/examples/aiml_soc_voice_control_light_efr32_micriumos"
```

If you copied the example from the SDK, generate once with the 2.2.2 stack first:

```bash
slc generate -cp -p aiml_soc_voice_control_light_efr32_micriumos.slcp \
  -d target/brd2601b --with brd2601b \
  --sdk-package-path "$(slt where simplicity-sdk/2025.12.3),$(slt where aiml/2.2.2)"
```

##### 2. Upgrade the `.slcp`

`slc upgrade` updates project metadata only — it does not regenerate upgraded source code in the autogen/ directory.

```bash
slc upgrade -p aiml_soc_voice_control_light_efr32_micriumos.slcp \
  --sdk-package-path "$(slt where simplicity-sdk/2026.6.0),$(slt where aiml/3.0.0)" \
  --source-sdk-version 2025.12.3 --force-upgrade
```

Without `--force-upgrade`, SLC cancels when upgrade rules list manual steps (for example migrating to `sl_ml_model_*` APIs) and the upgrade does not complete. You must pass `--force-upgrade` to make the upgrade from AI/ML 2.2.2 to 3.0.0+.

Example terminal output:

```c
PS C:\Users\<username>\.silabs\slt\installs\conan\p\aiml220b56d6ae053\p\examples\aiml_soc_voice_control_light_efr32_micriumos> slc upgrade -p aiml_soc_voice_control_light_efr32_micriumos.slcp --sdk-package-path "$(slt where simplicity-sdk/2026.6.0-latest),$(slt where aiml/3.0.0)" --source-sdk-version 2025.12.3
3. Regenerate the project.
4. For this upgrade to go through, please use the "Force Upgrade" option.
Problem detected, no action performed: Some component references are not explicit. Some upgrades may not trigger correctly if the components cannot be found. Implicit components: ml_audio_feature_generation
Automatic upgrade: SDK silabs.simplicity_sdk:2025.12.3 upgraded to silabs.simplicity_sdk:2026.6.0
Automatic upgrade: Extension silabs.aiml:2.2.2 upgraded to silabs.aiml:3.0.0
Automatic upgrade: Adds ml_model component for sml MVP compilation of .tflite models.
Automatic upgrade: Adds aiml nn_util and nn_mvp required by MVP-accelerated kernels.
upgrade was cancelled because of invalid statuses.

PS C:\Users\<username>\.silabs\slt\installs\conan\p\aiml220b56d6ae053\p\examples\aiml_soc_voice_control_light_efr32_micriumos> slc upgrade -p aiml_soc_voice_control_light_efr32_micriumos.slcp --sdk-package-path "$(slt where simplicity-sdk/2026.6.0-latest),$(slt where aiml/3.0.0)" --source-sdk-version 2025.12.3 --force-upgrade
Problem detected, no action performed: .
1. Use sl_ml_model_init, sl_ml_model_run, and sl_ml_model_deinit on sl_ml_<model>_model_handle from sl_ml_model_<model>.h.
2. Replace slx_ml_<model>_model_init/run or sl_tflite_micro_init / sl_tflite_micro_get_input_tensor as needed.
3. Regenerate the project.
4. For this upgrade to go through, please use the "Force Upgrade" option.
Problem detected, no action performed: Some component references are not explicit. Some upgrades may not trigger correctly if the components cannot be found. Implicit components: ml_audio_feature_generation
Automatic upgrade: SDK silabs.simplicity_sdk:2025.12.3 upgraded to silabs.simplicity_sdk:2026.6.0
Automatic upgrade: Extension silabs.aiml:2.2.2 upgraded to silabs.aiml:3.0.0
Automatic upgrade: Adds ml_model component for sml MVP compilation of .tflite models.
Automatic upgrade: Adds aiml nn_util and nn_mvp required by MVP-accelerated kernels.
Despite issues, the project was requested to be upgraded.
A full generation should be run to sync the generated content with the new SDK.
```

##### 3. Fix the `.slcp` and `*.mlconf`

`slc upgrade` updates SDK metadata but does not add every component or fix compiler config. Edit project files directly using text editor. See [steps  2-3](#2-reinstall-the-audio-feature-generator-fe_audio-if-applicable) for the same changes that has been done using Project Configurator.

**Edit `aiml_soc_voice_control_light_efr32_micriumos.slcp`**

In `component:`:

- Add `fe_audio` with the same instance name as `ml_model` (for example, `inst0`) when the project uses the audio feature generator.
- Remove legacy entries if still listed after upgrade:  
  - `ml_audio_feature_generation`  
  - `tensorflow_lite_micro_accelerated_kernels`, `tensorflow_lite_micro_optimized_kernels`, `nn_mvp`, `nn_util`, `tensorflow_debug_log_iostream`

In `config_file:`, bind each `*.mlconf` to its `ml_model` instance when missing:

```yaml
### excerpt — aiml_soc_voice_control_light_efr32_micriumos.slcp
component:
  - package: aiml
    vendor: silabs
    id: ml_model
    instance:
      - name: inst0
  - package: aiml
    vendor: silabs
    id: fe_audio
    instance:
      - name: inst0
config_file:
  - path: config/tflite/inst0.mlconf
    directory: tflite
    override:
      component: ml_model
      file_id: ml_compiler_config
      instance: inst0
```

On EFR32, append under `toolchain_settings` if `-mfp16-format=ieee` is missing:

```yaml
  - value: -mfp16-format=ieee
    option: gcc_compiler_option
```

**Edit `config/tflite/inst0.mlconf`**

Set `model:` to the `.tflite` filename (for example, `keyword_spotting_on_off_v2.tflite`). See [step 3](#3-fix-the-mlconf-model-path-after-upgrade) for details.

##### 4. Regenerate with the New SDK

```bash
slc generate -cp -p aiml_soc_voice_control_light_efr32_micriumos.slcp \
  -d target/brd2601b --with brd2601b \
  --sdk-package-path "$(slt where simplicity-sdk/2026.6.0),$(slt where aiml/3.0.0)" 
```

Confirm `autogen/ml/` and `autogen/sl_ml_model_<MODEL_STEM>.h` appear. If generation fails, open `autogen/sml.log` — `no mlconf files found` usually means the `*.mlconf` binding or `model:` path is still wrong.

##### 5. Update Application Source and Build

Migrate application `.c` / `.cc` / `.cpp` files to `sl_ml_model_*` APIs ([step 5](#5-update-application-source-code)), then build and flash ([step 6](#6-build-and-test-on-hardware)).

---

## Simplicity Machine Learning Tools

### Simplicity Machine Learning Guide

This guide includes the following Simplicity Machine Learning tools.

- [Profiler](profiler): Profiles `.tflite` model execution on Silicon Labs embedded devices.
- [Converter](converter): Converts PyTorch and ONNX models to `.tflite`.
- [Model Graph Viewer](model-graph-viewer): Presents Model graph to understand its structure.

### Simplicity Machine Learning Profiler

#### Overview

The Profiler is part of the Simplicity Machine Learning suite of tools. It helps you to understand how TensorFlow Lite for Microcontrollers (.tflite) models run on Silicon Labs embedded devices and optimize them before deployment.

The tool enables users to:

- Correlate layer execution with clock rate, and memory pressure.
- Build intuition for optimizing models to reduce stalls and improve inference latency
- Identify performance bottlenecks during inference
- Understand trade-offs between execution on the ARM Cortex-M CPU and the Matrix Vector Processor (MVP).
- View and analyze your model layer by layer.
- Convert PyTorch (`.pt`, `.pth`) and ONNX (`.onnx`) to `.tflite` models. The process is detailed in the [Silicon Labs sml Converter](converter) page.

The tool is available as:

- A graphical interface - Simplicity Machine Learning (GUI) or `sml`
- A command-line interface - Simplicity Machine Learning (CLI) or `sml-cli`

It can also be launched directly from **Simplicity Studio v6**.

#### Who This Tool Is For

This documentation is written primarily for embedded and ML engineers.<br />Product managers, data scientists, and sales engineers are expected to be sufficiently familiar with machine learning concepts to interpret the results.

The profiler focuses exclusively on execution performance, not model accuracy or output quality.

#### Key Concepts and Terminology

|Term|Meaning|
|---|---|
|Inference|One complete execution of a model|
|Layer|A neural network layer|
|Operator|A logical operation within a layer|
|Kernel|The concrete implementation that executes an operator|
|CPU|ARM Cortex-M core|
|MVP|Matrix Vector Processor hardware accelerator|
|Stall / Wait|Time spent idle due to memory or resource contention|
|Tensor Arena|Memory allocated for TFLM state|
|Quantization|Optimization technique to reduce model size|
|Perfetto|The trace visualization tool used|

#### Running a Profiling Session from the GUI

1. Launch the Simplicity Machine Learning tool from **Simplicity Studio v6**  
   1. Open Simplicity Studio and navigate to the **Tools** tab on the left panel.  
   2. Either click on the **Simplicity Machine Learning(GUI)** button to check the overview and launch the tool or point to **Simplicity Machine Learning(GUI)** and click the play icon.

![Simplicity Machine Learning launch](/simplicity-machine-learning-guide/1.1.0/images/sml-launch.png)

1. Or, Launch the Simplicity Machine Learning from the command line:  
   ```bash  
   slt launch sml  
   ```
2. Step 1 or 2 should launch the Simplicity Machine Learning. It is recommended to keep the window of Simplicity Machine Learning maximized or in full-screen for the best user experience.

![Simplicity Machine Learning GUI Landing Page](/simplicity-machine-learning-guide/1.1.0/images/sml-gui-landing-page.png)

1. Connect the board you on which you want to profile your model. The board will be detected automatically.
2. Click the **Browse** button, navigate to the folder that contains the model file, and then select the .tflite model to profile.
3. Optional. If your model is not available in the right format, you can convert PyTorch (`.pt`, `.pth`) and ONNX (`.onnx`) to `.tflite` models. The process is detailed in the [Silicon Labs sml Converter](converter) page.
4. Optional. After you select the model, click **View Model** to view and analyze the model in detail.  
   ![Model Graph view](/simplicity-machine-learning-guide/1.1.0/images/model-graph-view.png)
5. Optional. Select the kernel implementation that you want to run. By default, the HW Accelerated kernels are selected.
6. Click the **Profile** Button.  
   ![Profiling Session Setup and Run](/simplicity-machine-learning-guide/1.1.0/images/sml-profiling-setup-and-run.png)  
   > **NOTE:**  
   > See [Troubleshooting](#troubleshooting) section for handling any errors.

##### Outputs

- **Summary tab** includes:  
  - Flash and RAM usage, CPU usage metrics, basic identification of the device  
  - CPU and MVP accelerated cycle count, stalls, layer definitions  
  - a way to export the data in either `.json` or `.txt` format.  
  ![Profiling Summary Tab 1](/simplicity-machine-learning-guide/1.1.0/images/sml-profiling-summary-tab-1.png)  
  ![Profiling Summary Tab 2](/simplicity-machine-learning-guide/1.1.0/images/sml-profiling-summary-tab-2.png)
- **Perfetto trace tab**: time-based execution and resource traces  
  ![Profiling Perfetto Trace Tab](/simplicity-machine-learning-guide/1.1.0/images/sml-perfetto-trace-tab.png)  
  > **NOTE:**  
  > The profiler currently tracks only the ARM Cortex‑M CPU processor timeline.  
  > Usage and cycle information for the Matrix Vector Processor (MVP) is instead provided in the summary tab.

#### Running a Profiling Session from the CLI

1. Connect the board on which you want to profile your model. The board will be detected automatically, once connected.
2. Find the "device ID" of the connected board.  
   This is optional if only one device is connected. The SDM will detect the connected device.  
   1. Linux/macOS    
      ```bash    
      $ ~/.silabs/slt/installs/archive/sdm-darwin-arm64/sdm adapter list    
      👉 Total adapter count: 1    
      ↳ xxxxx [ usb wstk 440339411 xxxxx 127.0.0.1 ]    
      ```  
   2. Windows  
   ```powershell  
   PS> $HOME\.silabs\slt\installs\archive\sdm-windows-amd64\sdm.exe adapter list  
   👉 Total adapter count: 1  
     ↳ xxxxx [ usb wstk 440339411 xxxxx 127.0.0.1 ]  
   ```  
   The device ID is "440339411".
3. Run Profiling  
   ```bash  
   sml profile /path/to/model_name.tflite 440339411  
   ```  
   > **NOTE:**  
   > See [Usage](#usage) for more command line arguments.  
   > See [Troubleshooting](#troubleshooting) section for handling any errors.

##### Output

The following is an example of the output you can expect to see on the command line terminal. Usernames and other sensitive information has been stubbed.

The log below includes:

- Inference time
- CPU vs MVP cycle breakdown

You can access:

- text summary
- detailed JSON report

```c
🚀 Running profiling workflow...
   Device: 440333937 (BRD2601B)
   Model:  keyword_spotting_on_off_v2

📡 Step 1: Connecting to debug channel...

⚡ Step 2: Combining model with firmware and flashing......

📦 Step 3: Capturing packets and generating trace...

╔══════════════════════════════════════════════════════════╗
║           ML PROFILER - PROFILING SUMMARY                ║
╚══════════════════════════════════════════════════════════╝

SESSION SUMMARY
────────────────────────────────────────────────────────────
  Model Name                               keyword_spotting_on_off_v2
  Arena size                               88.0 KB
  Total Flash usage                        391.0 KB
  Total RAM usage                          96.0 KB
  Board                                    BRD2601B
  Order-able Part Number                   EFR32MG24B310F1536IM48
  Part Family                              xG24
  Flash                                    1,536 KB
  RAM                                      256 KB
  CPU                                      ARM Cortex-M33
  Accelerator                              MVP
  Total number of CPU cycles               284,142
  Number of Layers executed on CPU         2
  Layers executed on CPU                   RESHAPE, SOFTMAX
  CPU Utilization                          4.2 %
  Clock Rate                               78.0 MHz
  Total number of Accelerator cycles       6,491,814
  Total number of Accelerator stalls       2,000,816
  Total Accelerator MAC/cycle              0.55
  Number of Layers executed on Accelerator 11
  Layers executed on Accelerator           MAX_POOL_2D, FULLY_CONNECTED, CONV_2D
  Total inference time                     85.144 ms
  Inferences per second                    11.74
  Total number of operations               16,678,338
  Total number of MACs                     8,097,720

PER-LAYER SUMMARY
────────────────────────────────────────────────────────────────────────────────────────────────────────
                 |                  |                  |            |           Acc           |
     Layer       |   Input Shape    |   Output Shape   | CPU Cycles | ----------------------- | Time(ms)
                 |                  |                  |            | Cycles     | Stalls     |
-----------------+------------------+------------------+------------+------------+------------+---------
CONV_2D          | 1 x 99 x 68 x 1  | 1 x 99 x 68 x 10 | 29,860     | 965,680    | 228,087    | 12.763
MAX_POOL_2D      | 1 x 99 x 68 x 10 | 1 x 49 x 34 x 10 | 10,381     | 50,073     | 18         | 0.775
CONV_2D          | 1 x 49 x 34 x 10 | 1 x 49 x 34 x 20 | 31,113     | 2,299,263  | 740,554    | 29.877
MAX_POOL_2D      | 1 x 49 x 34 x 20 | 1 x 24 x 17 x 20 | 18,922     | 24,620     | 0          | 0.558
CONV_2D          | 1 x 24 x 17 x 20 | 1 x 24 x 17 x 40 | 31,701     | 2,117,241  | 691,564    | 27.551
MAX_POOL_2D      | 1 x 24 x 17 x 40 | 1 x 12 x 8 x 40  | 35,665     | 11,800     | 0          | 0.609
CONV_2D          | 1 x 12 x 8 x 40  | 1 x 12 x 8 x 40  | 32,258     | 917,766    | 305,283    | 12.18
MAX_POOL_2D      | 1 x 12 x 8 x 40  | 1 x 6 x 4 x 40   | 35,731     | 3,160      | 0          | 0.499
CONV_2D          | 1 x 6 x 4 x 40   | 1 x 6 x 4 x 20   | 32,867     | 101,265    | 34,916     | 1.72
MAX_POOL_2D      | 1 x 6 x 4 x 20   | 1 x 1 x 4 x 20   | 18,713     | 546        | 66         | 0.247
RESHAPE          | 1 x 1 x 4 x 20   | 1 x 80           | 1,188      | 0          | 66         | 0.015
FULLY_CONNECTED  | 1 x 80           | 1 x 3            | 2,514      | 400        | 131        | 0.037
SOFTMAX          | 1 x 3            | 1 x 3            | 3,229      | 0          | 131        | 0.041
────────────────────────────────────────────────────────────────────────────────────────────────────────

────────────────────────────────────────────────────────────
Generated: DATE/TIMER

📁 Profile data saved to:
   /$HOME/.silabs/sml/profiles/keyword_spotting_on_off_v2-2026-06-12T17-47-45Z

   Includes:
   • keyword_spotting_on_off_v2.pftrace (Perfetto trace)
   • captured-packets.json (decoded packets)
   • report.json (profiling data)
   • summary.txt (readable summary)

   📄 See summary.txt for the complete profiling summary.

✅ Profiling completed successfully!

📊 To view the trace, open the following file in https://ui.perfetto.dev/ , or re-run with --gui to open it automatically.
   Trace file: /$HOME/.silabs/sml/profiles/keyword_spotting_on_off_v2-2026-06-12T17-47-45Z/keyword_spotting_on_off_v2.pftrace
```

> **NOTE:**
> If the --gui flag is provided the Perfetto trace will open in a window.

##### Usage

```bash
sml --help
```

```console
  Usage: sml [OPTIONS] COMMAND [ARGS]...

 Silicon Labs ML tooling.

╭─ Options ─────────────────────────────────────────────────────────────────────╮
│ --gui                      Open GUI after command completes (if supported).   │
│ --dry-run                  Validate and print the effective configuration,    │
│                            but do not execute the command.                    │
│ --log-level          TEXT  Logging verbosity. One of: error, warning, info,   │
│                            debug.                                             │
│                            [default: info]                                    │
│ --version    -v            Show version and exit.                             │
│ --help                     Show this message and exit.                        │
╰───────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ────────────────────────────────────────────────────────────────────╮
│ profile  Profile a machine learning model on a Silicon Labs device. Emits a   │
│          Perfetto-compatible trace (.pftrace) or JSON summary (.json).        │
│ convert  Convert a PyTorch (.pt / .pth) or ONNX (.onnx) model to TFLite.      │
│ version  Show the version number.                                             │
╰───────────────────────────────────────────────────────────────────────────────╯
```

```bash
sml profile --help
```

```c
 Usage: sml profile [OPTIONS] MODEL [DEVICE]

 Profile a machine learning model on a Silicon Labs device. Emits a
 Perfetto-compatible trace (.pftrace) or JSON summary (.json).

╭─ Arguments ──────────────────────────────────────────────────────────────────╮
│ *    model       TEXT      Path to model file (e.g. .tflite). Use '-' to     │
│                            read from stdin.                                  │
│                            [required]                                        │
│      device      [DEVICE]  Device identifier: Device ID, serial number,      │
│                            nickname, or IP address (on-device profiling). If │
│                            omitted, the only supported connected device is   │
│                            used.                                             │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --output  -o      TEXT  Output directory for all profiling results files. If │
│                         omitted, outputs to                                  │
│                         ~/.silabs/sml/profiles/<model>-<timestamp>/.         │
│ --kernel          TEXT  Kernel implementation to use. Accelerated kernels    │
│                         are chosen based on the value of device.             │
│                         [default: accelerated]                               │
│ --help                  Show this message and exit.                          │
╰──────────────────────────────────────────────────────────────────────────────╯
```

#### Understanding Performance

The profiler presents a hierarchical execution view:

Inference → Layer → Operator → Kernel

Time-aligned tracks allow correlation between:

- CPU vs MVP execution
- memory usage
- clock rate

Idle time per kernel helps identify when:

- accelerator overhead dominates
- memory stalls occur
- CPU execution may be more efficient

#### Limitations

- Requires real Silicon Labs hardware, currently only supports xG24, xG26, and xG28 devices, specifically BRD2601B, BRD2608A, and BRD2705A dev kits and BRD2505A, BRD2506A, BRD4186C and BRD4187C boards.
- Simulator support is in development
- Does not auto-compare CPU vs MVP
- Does not measure model accuracy. This is not a target of this tool. It is geared exclusively towards execution performance analysis.

#### Summary

The Simplicity Machine Learning Profiler helps you analyze embedded ML performance by making execution behavior visible, comparable, and intuitive.

#### Troubleshooting

##### "SDM Service is not available" warning

![SDM Service is not available warning](/simplicity-machine-learning-guide/1.1.0/images/ml-profiler-sdm-unavailable-warning.png)

###### Solution

1. Verify if Simplicity Device Manager (SDM) is installed using, `slt locate sdm`.
2. If you see no output on the console, install SDM using:  
   1. `slt install sdm` through the CLI, or  
   2. Simplicity Installer by following the steps mentioned in the [Install using Simplicity Installer](#using-simplicity-installer) section. Search for "Simplicity Device Manager" instead of "Simplicity Machine Learning".
3. Start SDM server.  
   1. Linux/macOS    
      ```bash    
      ~/.silabs/slt/installs/archive/sdm-darwin-arm64/sdm server start    
      ```  
   2. Windows  
   ```powershell  
   PS> $HOME\.silabs\slt\installs\archive\sdm-windows-amd64\sdm.exe server start  
   ```

##### "No devices connected" message in the "Select Device" field

![No Device Connected](/simplicity-machine-learning-guide/1.1.0/images/ml-profiler-no-device-connected.png)

###### Solution

Connect the desired board on which you want to profile your models.

##### Any type of "Firmware preparation/flashing failed: Failed to combine model with firmware" error

Examples of this type of error:

1. Firmware preparation/flashing failed: Failed to combine model with firmware: 404 Not Found: Not Found
2. Firmware preparation/flashing failed: Failed to combine model with firmware: Combine binary job failed: Error: Could not find function simpleCombineConvertBinaries. It is either typed wrong, you miss an adapter pack, or you need to upgrade one.

###### Solution

1. This issue is most commonly caused due to an older version of either Simplicity Device Manager or Simplicity Commander.
2. Update Simplicity Commander to v1.22+. Install using `slt install commander`. Verify using `slt locate commander`.
3. Update Simplicity Device Manager to v0.101.4+. Install using `slt install sdm`. Verify using `slt locate sdm`.

##### No Profiling Output

**GUI**

![no-profiling-summary-output](/simplicity-machine-learning-guide/1.1.0/images/ml-profiler-no-profiling-summary-output.png)
![no-profiling-trace-output](/simplicity-machine-learning-guide/1.1.0/images/ml-profiler-no-profiling-trace-output.png)

**CLI**

```console
📦 Step 3: Capturing packets and generating trace...
   Captured 43 packets, building trace...
   Decoded 0 packets, generated 0 trace events

╔══════════════════════════════════════════════════════════╗
║           Simplicity Machine Learning - PROFILING SUMMARY                ║
╚══════════════════════════════════════════════════════════╝

────────────────────────────────────────────────────────────
```

###### Solution

1. Verify Simplicity Device Manager Service is up: `sdm server status`. If not, invoke `sdm server start`.
2. Find the device ID, see [Running a Profiling Session From the CLI](#running-a-profiling-session-from-the-cli) section.
3. Jump into admin console of your device: `sdm terminal -a <device_id> -c admin`.
4. Verify the debug message version: `dch message version`, If the output is `Message protocol version : 3`, use Step 5 below.
5. Invoke `dch message version 2`. The output must show `Current version = 2`.
6. Execute a Profiling session again.

### Simplicity Machine Learning Converter

#### Overview

The Converter is part of the Simplicity Machine Learning suite of tools. It converts PyTorch and ONNX models into TensorFlow Lite (`.tflite`) format for deployment on Silicon Labs embedded devices. The Silicon Labs ML toolchain currently consumes `.tflite` models; this tool bridges common training workflows (PyTorch, ONNX) without requiring a separate runtime.

The converter enables you to:

- Convert PyTorch models (`.pt`, `.pth`) to `.tflite` using [litert-torch](https://github.com/google-ai-edge/litert-torch)
- Convert ONNX models (`.onnx`) to `.tflite` using [onnx2tf](https://github.com/PINTO0309/onnx2tf)
- Optionally generate conversion metadata (`manifest.json`) and a diagnostic log (`conversion.log` when `--log-level debug`)
- Use the same conversion engine from the **Simplicity Machine Learning GUI** and **CLI** (`sml convert`)

The tool is available as:

- A graphical interface (GUI) — the Converter is integrated into the **Simplicity Machine Learning** application GUI.
- A command-line interface (CLI) called `sml convert`.

> **NOTE:**
> The Converter (`sml convert`) is only available in Simplicity Machine Learning (or `sml` on the CLI) version 1.1.0-beta or later. If you installed an older Simplicity Machine Learning (GUI) or (CLI) package before this release, upgrade through Simplicity Installer or SLT so the Converter functionality on the GUI and `sml convert` command on the CLI are available.

#### Scope of This Tool

This documentation is written primarily for embedded and ML engineers who have trained or exported a model in PyTorch or ONNX and need a `.tflite` file for Silicon Labs projects.

To work with trained models, you must have familiarity with ML concepts to run conversion and interpret validation results.

> **NOTE:**
> The converter focuses on model format conversion to float32 `.tflite`. It does not train models, apply INT8/FP16 quantization, or measure on-device execution performance.

> **NOTE:**
> PyTorch conversion requires Linux, WSL2 (on Windows), or MacOS and Python 3.12. See [Limitations](#limitations) for platform and environment constraints.

#### Key Concepts and Terminology

|Term|Description|
|---|---|
|LiteRT|Google's edge inference stack (formerly TensorFlow Lite)|
|TFLite / `.tflite`|Serialized LiteRT model format used by Silicon Labs tooling|
|PyTorch model|A trained model saved as `.pt` or `.pth`|
|ONNX model|Framework-agnostic model in `.onnx` format|
|Representative dataset|Sample inputs used to calibrate quantization (not used by this converter; output is float32)|
|input_shape|Fixed dimensions for the model input tensor (required for PyTorch conversion)|
|manifest.json|Optional metadata file describing the conversion run|

#### Supported Input and Output

##### Input Models

|Format|Extension|Note|
|---|---|---|
|PyTorch|`.pt`, `.pth`|Must contain a full `nn.Module` (not state-dict-only). `--input-shape` required|
|ONNX|`.onnx`|Self-contained file (no external weight files). `--input-shape` required only if inputs have dynamic dimensions|

Format detection uses file extensions (`.pt`, `.pth`, `.onnx`). Invalid content is reported when the model is loaded.

##### **Output artifacts**

|Artifact|Required|Description|
|---|---|---|
|`model.tflite`|Yes|Primary output; path defaults from the source filename in the current working directory unless `--output` is set (CLI)|
|`manifest.json`|No|Conversion metadata when `--save-manifest` (CLI)|
|`conversion.log`|No|Diagnostic trace when `--log-level debug` (CLI)|

##### Usage

```bash
sml convert --help
```

```console
Usage: sml convert <input_model> [options]

Convert PyTorch or ONNX model to TFLite format.

Arguments:
  input_model                 Input model file path (.pt, .pth, .onnx)

Options:
  -o, --output PATH           Output .tflite path (auto-generated if omitted)
  --input-shape SHAPE         Input shape for PyTorch (e.g. 1,3,224,224); required for .pt/.pth
  --save-manifest             Generate manifest.json
  --log-level <level>         Logging verbosity: error|warning|info|debug
                              (default: error; debug writes conversion.log)
  -v, --verbose               Verbose output
  -h, --help                  Show help
```

**Examples:**

```bash
### PyTorch — input shape required
sml convert model.pt --input-shape 1,3,224,224

### ONNX — custom output path
sml convert model.onnx --output output/model.tflite

### With optional artifacts
sml convert model.pt --input-shape 1,3,224,224 --save-manifest --log-level info
```

> **NOTE:**
> 
> Each conversion produces one **float32** `.tflite` file. INT8/FP16 quantization is not applied by this tool.

#### **Converting a Model from the GUI**

Install **Simplicity Machine Learning (GUI)** version **1.1.0-beta** or later (see [Installation](#installation)).

##### Launch Simplicity Machine Learning

1. Launch from **Simplicity Studio v6**:  
   1. Open Simplicity Studio and navigate to the **Tools** tab on the left panel.  
   2. Hover on **Simplicity Machine Learning** and click the Play icon that appears on the right side.
2. Or, launch from the command line:  
   ```bash  
   slt launch sml  
   ```
3. Open the **Convert** tab in the application.

##### Convert a PyTorch Model (`.pt` / `.pth`)

1. Click **Browse** and select your PyTorch model file (`.pt` or `.pth`). A file-selection dialog opens for supported model types.  
   ![Browse for PyTorch model](/simplicity-machine-learning-guide/1.1.0/images/select-pytorch-model.png)
2. The tool detects the PyTorch format from the file extension. Enter **input shape** (for example, `1,3,224,224`) — this field is **required** for PyTorch models.  
   ![PyTorch model with input shape](/simplicity-machine-learning-guide/1.1.0/images/pytorch-input-shape.png)
3. Optionally set the output `.tflite` path and enable **manifest.json** or debug logging.
4. Click **Convert** and wait while conversion runs. Progress and status updates appear in the UI.  
   ![PyTorch conversion in progress](/simplicity-machine-learning-guide/1.1.0/images/model-converted-pytorch.png)
5. When conversion completes, download or save the generated `.tflite` file.

##### Convert an ONNX Model (`.onnx`)

1. Click **Browse** and select your ONNX model file (`.onnx`).  
   ![Browse for ONNX model](/simplicity-machine-learning-guide/1.1.0/images/onnx-model-choose.png)
2. For ONNX models with **fixed** input shapes, **input shape** is not required. The Convert control is available once the model file is selected.  
   ![ONNX model ready to convert](/simplicity-machine-learning-guide/1.1.0/images/onnx-without-user-shape.png)
3. Click **Convert** and wait for conversion to finish.
4. Download or save the generated `.tflite` file.

#### Optional Artifacts

##### manifest.json

When you pass `--save-manifest` on the CLI , the converter writes a `manifest.json` file next to the output `.tflite`. Use this optional file to audit a conversion in development or CI: it records what was converted, how long it took, and whether any warnings or errors occurred.

The file includes:

- **conversion** — source and output paths, detected format, converter version, and duration
- **model_info** — input and output tensor shapes
- **file_info** — source and output file sizes and compression ratio
- **warnings** and **errors** — messages collected during the run (empty when none)

Example structure:

```json
{
  "version": "1.0",
  "conversion": {
    "source_model": "/path/to/model.onnx",
    "source_format": "onnx",
    "output_model": "/path/to/model.tflite",
    "converter_version": "1.0.0",
    "duration_seconds": 12.5
  },
  "model_info": {
    "input_shapes": { "input": [1, 224, 224, 3] },
    "output_shapes": { "output": [1, 1000] }
  },
  "file_info": {
    "source_size_bytes": 5242880,
    "output_size_bytes": 2621440,
    "compression_ratio": 2.0
  },
  "warnings": [],
  "errors": []
}
```

#### Validating Converted Models

A conversion is valid when the `.tflite` model produces functionally equivalent outputs to the source model for representative inputs.

**Validation criteria:**

- **Output similarity** — converted outputs match source outputs within tolerance (for example, cosine similarity ≥ 0.99, numerical error < 5%)
- **Structural integrity** — the `.tflite` file loads successfully and tensor shapes match expectations

Compare source and converted models using the same test inputs before deploying to hardware. Numerical parity is not bit-exact; small drift (for example, relative tolerance `rtol≈1e-3`) is normal.

#### Limitations

##### Environment and Platform

- **Python 3.12 only** (`>=3.12,<3.13`); Python 3.11 and 3.13+ are not supported.
- **Linux, WSL2 or MacOS** is required for PyTorch conversion (`litert_torch`).
- **CPU-only** conversion; GPU conversion is not supported.
- Native **Windows** PyTorch conversion is generally not supported for this stack. Prefer Linux ,WSL2 or MacOS. See [litert-torch#968](https://github.com/google-ai-edge/litert-torch/issues/968).

##### **Input formats and models**

- Supported inputs are **PyTorch** (`.pt`, `.pth`) and **ONNX** (`.onnx`) only.
- PyTorch files must contain a **full `nn.Module`** (`torch.save(model)` or a dict with a `"model"` key). **State-dict-only** files are rejected.
- **`input_shape` is required** for PyTorch conversion (for example, `1,3,224,224`).
- The PyTorch path supports a **single input tensor** only.
- ONNX models must be **self-contained** (no external weight files).
- For ONNX models with dynamic input dimensions, provide `input_shape` (multi-input: `name1:d1,d2;name2:...`).

##### Conversion Behavior

- Output is **float32 `.tflite` only**; INT8/FP16 quantization is not applied by this tool.
- Not all PyTorch or ONNX operators are supported; unsupported ops fail with diagnostic messages.
- **Ultralytics YOLO** and similar detection checkpoints are not reliably convertible on the PyTorch path. Export to ONNX with Ultralytics and use the ONNX path as a workaround.
- Models with data-dependent control flow, `.item()` / `.tolist()` in the forward path, or multiple non-tensor inputs may fail during `torch.export`.
- ONNX output file size may differ from the source ONNX file due to graph layout changes (NCHW → NHWC) and FlatBuffer encoding.

#### Summary

The Silicon Labs sml converter produces float32 `.tflite` models from PyTorch and ONNX sources through a single `sml` engine, available from the **Simplicity Machine Learning** GUI and CLI today, with a Python API planned for the future. Provide `input_shape` for PyTorch models, validate outputs against the source model, and use optional `manifest.json` to audit conversions in development and CI.

#### Troubleshooting

**`sml convert` not found or Convert tab missing**

You may have an older **Simplicity Machine Learning** package installed. The converter requires **version 1.1.0-beta** or later. Check your version with `sml --version`, then upgrade **Simplicity Machine Learning (GUI)** and/or **(CLI)** through Simplicity Installer or by re-running `slt install sml` / `slt install sml-cli`.

**Input file not found**

Verify the path to `.pt`, `.pth`, or `.onnx` is correct and readable.

**Unsupported file extension**

Only `.pt`, `.pth`, and `.onnx` are accepted. Rename or re-export the model in a supported format.

**PyTorch: missing or invalid input shape**

Provide `--input-shape` on the CLI with batch, channels, height, and width (for example, `1,3,224,224`). The tool may infer shape from the saved model in some cases; if inference fails, set it explicitly.

**PyTorch: state-dict-only file**

Instantiate the model architecture, load the state dict, and save the full `nn.Module` before converting.

**PyTorch conversion fails during tracing**

Ensure the model is in evaluation mode, uses float32 weights, and avoids data-dependent control flow. See [LiteRT PyTorch conversion](https://ai.google.dev/edge/litert/conversion/pytorch/overview). For YOLO and similar models, export to ONNX first.

**ONNX conversion fails operator validation**

Check operator support and model structure. Ensure the ONNX file is self-contained.

**Outputs differ significantly from the source model**

Re-run validation with representative inputs. A small numerical drift is expected.

**Platform or Python version errors**

Use Python 3.12 on Linux, WSL2 or MacOS for PyTorch conversion. Do not rely on native Windows for the PyTorch path.

#### References

- [Profiler](profiler) — on-device profiling after you have a `.tflite` model
- [LiteRT PyTorch conversion overview](https://ai.google.dev/edge/litert/conversion/pytorch/overview)
- [LiteRT TensorFlow conversion overview](https://ai.google.dev/edge/litert/conversion/tensorflow/overview)

### Simplicity Machine Learning Model Graph Viewer

#### Overview

The Model Graph Viewer is part of the Simplicity Machine Learning suite of tools. It is based on Google's [Model Explorer](https://developers.google.com/edge/model-explorer). It helps you to view the structure of a machine learning model.

The tool is only available in the GUI version of Simplicity Machine Learning tool.

#### Scope

You can use this tool to view the machine learning models. The only prerequisite is knowledge of machine learning models and how to view them.

#### Viewing a Machine Learning Model

You can launch the Model Graph Viewer using the following ways.

- From **Simplicity Studio v6**:  
  1. Open Simplicity Studio and navigate to the **Tools** tab on the left panel.  
  2. Hover on **Simplicity Machine Learning** and click the Play icon that appears on the right side.
- From the command line:  
  ```bash  
  slt launch sml  
  ```  
  Simplicity Machine Learning model is launched and displayed on the screen. It is recommended to keep the Simplicity Machine Learning window maximized for the best user experience.

![Simplicity Machine Learning GUI Landing Page](/simplicity-machine-learning-guide/1.1.0/images/sml-gui-landing-page.png)

1. Click the **Browse** button, navigate to the folder that contains the model file, and then select the .tflite model to profile.
2. Optional. If your model is not available in the right format, you can convert PyTorch (.pt, .pth) and ONNX (.onnx) to .tflite models. The process is detailed in the Silicon Labs sml Converter page.
3. Click **View Model** to view and analyze the model in detail.  
   ![View Model Link on GUI](/simplicity-machine-learning-guide/1.1.0/images/sml-profiling-setup-and-run.png)  
   ![Model Graph View](/simplicity-machine-learning-guide/1.1.0/images/model-graph-view.png)

## Machine Learning API Reference

### Microphone I2S Driver for Machine Learning

Microphone driver API for I2S interface on SI91x. 

Microphone driver API for I2S interface on Si91x. 

#### Typedefs

##### sl_mic_buffer_ready_callback_t

`typedef void(* sl_mic_buffer_ready_callback_t) (const void *buffer, uint32_t n_frames)`

**Description:**

Callback function indicating that the sample buffer is ready.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
||[in]|buffer|Pointer to the sample buffer.|
||[in]|n_frames|Number of audio frames in the sample buffer.|

**Details:**

**Returns**

- None.

#### Functions

##### sl_ml_mic_init

`sl_status_t sl_ml_mic_init(uint32_t sample_rate, uint8_t channels)`

**Description:** Initialize the microphone.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint32_t|[in]|sample_rate|The desired sample rate in Hz|
|uint8_t|[in]|channels|Number of audio channels (1 or 2)|

**Returns**

- Returns SL_STATUS_OK on success, non-zero otherwise

##### sl_ml_mic_deinit

`sl_status_t sl_ml_mic_deinit(void)`

**Description:** De-initialize the microphone.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

##### sl_ml_mic_start_streaming

`sl_status_t sl_ml_mic_start_streaming(void *buffer, uint32_t n_frames, sl_mic_buffer_ready_callback_t callback)`

**Description:** Read samples from the microphone into a sample buffer continuously.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void *|[in]|buffer|Pointer to the sample buffer to store the data. 16-bit channel data is stored consecutively, starting with ch0. This buffer shall be big enough to hold twice the n_frames because of the ping-pong operation.|
|uint32_t|[in]|n_frames|The number of audio frames to receive before the callback is called. Maximum value limited by DMADRV_MAX_XFER_COUNT.|
|[sl_mic_buffer_ready_callback_t](mic#sl-mic-buffer-ready-callback-t)|[in]|callback|Callback is called when n_frames in the sample buffer is ready.|

This function starts the microphone sampling and stops only upon calling [sl_ml_mic_stop](sl-ml-mic-i2s-si91x#sl-ml-mic-stop) or [sl_ml_mic_deinit](sl-ml-mic-i2s-si91x#sl-ml-mic-deinit). The buffer is used in a "ping-pong" manner meaning that one half of the buffer is used for sampling while the other half is being processed.

##### sl_ml_mic_stop

`sl_status_t sl_ml_mic_stop(void)`

**Description:** Stop the microphone.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

##### sl_ml_mic_process_action

`sl_status_t sl_ml_mic_process_action(void)`

**Description:** Process the microphone state machine for continuous transfers.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

This function should be called in the main application loop to handle the state machine for continuous DMA transfers. It manages the RECEIVE_DATA and WAIT_STATE transitions to ensure continuous streaming.

### Microphone

Sound level driver for PDM and I2S microphones. 

Sound level driver for PDM and I2S microphones.

<br />

#### Microphone example code

Basic example for looping measurement of sound level: <br /><br />

```c
#include "sl_mic.h"

#define MIC_SAMPLE_RATE            44100
#define MIC_SAMPLE_BUFFER_SIZE     1024
#define MIC_N_CHANNELS             2

  static int16_t buffer[MIC_SAMPLE_BUFFER_SIZE * MIC_N_CHANNELS];

  int main( void )
  {

   ...
   float sound_level_0;
   float sound_level_1;
   uint32_t n_samples = 1024;

   // Initialize microphone with sample rate and number of channels
   sl_mic_init(MIC_SAMPLE_RATE, MIC_N_CHANNELS);

   while(true){

     // Read samples from the microphone
     sl_mic_get_n_samples(buffer, n_samples);

     while (!sl_mic_sample_buffer_ready()) {
       // Wait until sample buffer ready
     }

     // Calculate sound level
     sl_mic_calculate_sound_level(&sound_level_0, buffer, n_samples, 0);
     sl_mic_calculate_sound_level(&sound_level_1, buffer, n_samples, 1);

   }

   ...

  } 
```

#### Typedefs

##### sl_mic_buffer_ready_callback_t

`typedef void(* sl_mic_buffer_ready_callback_t) (const void *buffer, uint32_t n_frames)`

**Description:**

Callback function indicating that the sample buffer is ready.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
||[in]|buffer|Pointer to the sample buffer.|
||[in]|n_frames|Number of audio frames in the sample buffer.|

**Details:**

**Returns**

- None.

#### Functions

##### sl_mic_init

`sl_status_t sl_mic_init(uint32_t sample_rate, uint8_t channels)`

**Description:** Initialize the microphone.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint32_t|[in]|sample_rate|The desired sample rate in Hz|
|uint8_t|[in]|channels|Number of audio channels (1 or 2)|

**Returns**

- Returns SL_STATUS_OK on success, non-zero otherwise

##### sl_mic_deinit

`sl_status_t sl_mic_deinit(void)`

**Description:** De-initialize the microphone.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

##### sl_mic_get_n_samples

`sl_status_t sl_mic_get_n_samples(void *buffer, uint32_t n_frames)`

**Description:** Read samples from the microphone into a sample buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void *|[in]|buffer|Pointer to the sample buffer to store the data. 16-bit channel data is stored consecutively, starting with ch0|
|uint32_t|[in]|n_frames|The number of the audio frames to get|

This function starts the microphone sampling and stops the sampling after reading the desired number of samples. Call [sl_mic_sample_buffer_ready](mic#sl-mic-sample-buffer-ready) to check when the samples are ready in the buffer.

##### sl_mic_start_streaming

`sl_status_t sl_mic_start_streaming(void *buffer, uint32_t n_frames, sl_mic_buffer_ready_callback_t callback)`

**Description:** Read samples from the microphone into a sample buffer continuously.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void *|[in]|buffer|Pointer to the sample buffer to store the data. 16-bit channel data is stored consecutively, starting with ch0. This buffer shall be big enough to hold twice the n_frames because of the ping-pong operation.|
|uint32_t|[in]|n_frames|The number of audio frames to receive before the callback is called. Maximum value limited by DMADRV_MAX_XFER_COUNT.|
|[sl_mic_buffer_ready_callback_t](mic#sl-mic-buffer-ready-callback-t)|[in]|callback|Callback is called when n_frames in the sample buffer is ready.|

This function starts the microphone sampling and stops only upon calling [sl_mic_stop](mic#sl-mic-stop) or [sl_mic_deinit](mic#sl-mic-deinit). The buffer is used in a "ping-pong" manner meaning that one half of the buffer is used for sampling while the other half is being processed.

##### sl_mic_start

`sl_status_t sl_mic_start(void)`

**Description:** Start the microphone.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

##### sl_mic_stop

`sl_status_t sl_mic_stop(void)`

**Description:** Stop the microphone.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

##### sl_mic_sample_buffer_ready

`bool sl_mic_sample_buffer_ready(void)`

**Description:** Check whether the sample buffer is ready.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

##### sl_mic_calculate_sound_level

`sl_status_t sl_mic_calculate_sound_level(float *sound_level, const int16_t *buffer, uint32_t n_frames, uint8_t channel)`

**Description:** Calculate the dBSPL value for a channel from a sample buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float *|[out]|sound_level|The calculated sound level|
|const int16_t *|[in]|buffer|Buffer to calculate sound level from. Must contain 16-bit samples, starting with channel 0|
|uint32_t|[in]|n_frames|Number of audio frames to use when calculating sound level|
|uint8_t|[in]|channel|The channel to get the sound level for|

### Image Feature Generator

Processes camera images and extracts features for machine learning image classification applications.

The image feature generator process input image captured from camera and extracts required features to use with machine learning image classification applications using a camera as an image source.

##### Feature Generation

The captured image pre-processed using crop and mean-std normalization based on model configuration used from application. 

```c
            Image
              │
      ┌───────▼───────┐
      │      Crop     │
      └───────┬───────┘
              │
      ┌───────▼───────┐
      │  Check mean   │
      └───────┬───────┘
              │
      ┌───────▼───────┐
      │ Normalization │
      └───────┬───────┘
              │
              ▼
            Model

```

##### Usage

[sl_ml_image_feature_generation_init()](ml-image-feature-generation#sl-ml-image-feature-generation-init) initializes the feature generation based on the configuration in sl_ml_image_feature_generation_config.h. It also initializes and starts the camera in streaming mode, which places the image samples into a ping-pong-buffer.

The image is pre-processed and filled in input tensor when [sl_ml_image_feature_generation_fill_tensor()](ml-image-feature-generation#sl-ml-image-feature-generation-fill-tensor) is called.

To retrieve the generated features [sl_ml_image_feature_generation_fill_tensor()](ml-image-feature-generation#sl-ml-image-feature-generation-fill-tensor) must be called.

###### Example

When used with TensorFlow Lite Micro, the image feature generator can be used to fill a tensor directly by using [sl_ml_image_feature_generation_fill_tensor()](ml-image-feature-generation#sl-ml-image-feature-generation-fill-tensor). However, the model has to be trained using the same feature generator configurations as used for inference, configured in sl_ml_image_feature_generation_config.h.

```c
#include "sl_tflite_micro_init.h"
#include "sl_ml_image_feature_generation.h"

void main(void)
{
  sl_ml_image_feature_generation_init();

  while(1){ *
    if(do_inference){
      sl_ml_image_feature_generation_fill_tensor(sl_tflite_micro_get_input_tensor());
      sl_tflite_micro_get_interpreter()->Invoke();
    }

    ...

  }
}

```

#### Functions

##### sl_ml_image_feature_generation_init

`sl_status_t sl_ml_image_feature_generation_init()`

**Description:** Set up the camera as an image source for feature generation.

**Returns**

- SL_STATUS_OK if [sl_ml_initialize_arducam_camera](ml-image-feature-generation#sl-ml-initialize-arducam-camera) succeeded. JLink "image" stream registration is optional: on failure, a warning is printed to the log and the function still returns SL_STATUS_OK; [sl_ml_dump_image](ml-image-feature-generation#sl-ml-dump-image) and PC-side visualization are inactive until a future successful registration. If camera init failed, same status as [sl_ml_initialize_arducam_camera](ml-image-feature-generation#sl-ml-initialize-arducam-camera) (e.g. SL_STATUS_BUS_ERROR); [sl_ml_image_feature_generation_reset](ml-image-feature-generation#sl-ml-image-feature-generation-reset) was run before return.

##### sl_ml_image_feature_generation_fill_tensor

`sl_status_t sl_ml_image_feature_generation_fill_tensor(TfLiteTensor *input_tensor)`

**Description:** Fill a TensorFlow tensor with feature data. Data type of input image for model will be selected based on model configuration.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|TfLiteTensor *|[in]|input_tensor|The input tensor to fill with features.|

**Note**

- This function overwrites the entire input tensor.

**Returns**

- SL_STATUS_OK for success SL_STATUS_INVALID_PARAMETER Tensor type or size does not correspond with configuration

##### sl_ml_initialize_arducam_camera

`sl_status_t sl_ml_initialize_arducam_camera()`

**Description:** Set up the aurducam as an image source for feature generation and initialize the camera with configuration.

**Returns**

- SL_STATUS_OK for success SL_STATUS_FAIL

##### sl_ml_dump_image

`void sl_ml_dump_image(const uint8_t *image_data, uint32_t image_length)`

**Description:** Set up the JLink stream as output node. Image data streamed over JLink to python interface.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const uint8_t *|N/A|image_data||
|uint32_t|N/A|image_length||

**Returns**

- SL_STATUS_OK for success SL_STATUS_FAIL

##### sl_ml_retrieve_next_camera_image

`void sl_ml_retrieve_next_camera_image(uint8_t **image_data, uint32_t *image_size)`

**Description:** Retrieve image from ping-pog buffer captured from aurducam. Store image data to destination pointer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint8_t **|N/A|image_data||
|uint32_t *|N/A|image_size||

##### sl_ml_image_crop_lut_init

`void sl_ml_image_crop_lut_init()`

**Description:** Initializes Look up table for croping image.

##### sl_ml_image_feature_generation_get_image_scaled

`sl_status_t sl_ml_image_feature_generation_get_image_scaled(uint8_t *image_data, float *buffer, size_t num_elements, float scaler)`

**Description:** Retrieve the features, scales them by the given scaler, and fills float buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint8_t *|[out]|image_data|Pointer to the buffer to store the scaled feature data|
|float *|[in]|buffer|The number of elements corresponding to the size of the buffer; If this is not large enough to store the entire feature buffer the function will return with an error.|
|size_t|[in]|num_elements|The scaling factor to apply to each feature value.|
|float|N/A|scaler||

buffer = (float)image_data * scaler

**Note**

- This function overwrites the entire buffer.

**Returns**

- SL_STATUS_OK for success SL_STATUS_INVALID_PARAMETER num_elements too small

##### sl_ml_get_image_mean

`sl_status_t sl_ml_get_image_mean(uint8_t *in_cam_image, float *mean, float *mean2, size_t num_elements)`

**Description:** Computes mean and mean square of input image.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint8_t *|[out]|in_cam_image|Pointer to the running mean; reset to 0 at entry, then set to the sample mean.|
|float *|[out]|mean|Pointer to the Welford M2 accumulator; reset to 0 at entry, then set so that population variance is mean2 / num_elements.|
|float *|[in]|mean2|The number of elements corresponding to the size of the buffer; If this is not large enough to store the entire feature buffer the function will return with an error.|
|size_t|N/A|num_elements||

mean = ((float)image_data / (width*length)

**Returns**

- SL_STATUS_OK for success SL_STATUS_INVALID_PARAMETER num_elements too small

##### sl_ml_image_feature_generation_get_image_mean_std_normalized

`sl_status_t sl_ml_image_feature_generation_get_image_mean_std_normalized(uint8_t *image_data, float *buffer, float mean, float mean2, size_t num_elements)`

**Description:** Retrieve the features, normalizes them by centering about their mean and standard deviation and fills float buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint8_t *|[out]|image_data|Pointer to the buffer to store the normalized feature data|
|float *|[in]|buffer|float mean, mean value of image.|
|float|[in]|mean|Welford M2 from [sl_ml_get_image_mean](ml-image-feature-generation#sl-ml-get-image-mean); population variance is mean2 / num_elements.|
|float|[in]|mean2|The number of elements corresponding to the size of the buffer; If this is not large enough to store the entire feature buffer the function will return with an error.|
|size_t|N/A|num_elements||

buffer = ((float)image_data - mean(image_data)) / std(image_data)

**Note**

- This function overwrites the entire buffer. std uses population variance: sqrtf(mean2 / num_elements). A small floor is applied to the divisor so uniform or near-uniform crops (std ~ 0) do not produce Inf/NaN; negative variance from float error is clamped to zero before sqrtf.

**Returns**

- SL_STATUS_OK for success SL_STATUS_INVALID_PARAMETER num_elements too small

##### sl_ml_image_feature_generation_get_image_raw_float32

`sl_status_t sl_ml_image_feature_generation_get_image_raw_float32(uint8_t *image_data, float *buffer, size_t num_elements)`

**Description:** Retrieve the features as type float32 and copy them to the provided buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint8_t *|[out]|image_data|Pointer to the buffer to store the feature data|
|float *|[in]|buffer|The number of elements corresponding to the size of the buffer; If this is not large enough to store the entire feature buffer the function will return with an error.|
|size_t|N/A|num_elements||

**Note**

- This function overwrites the entire buffer.

**Returns**

- SL_STATUS_OK for success SL_STATUS_INVALID_PARAMETER num_elements too small

##### sl_ml_image_feature_generation_reset

`void sl_ml_image_feature_generation_reset()`

**Description:** Reset the state of the image feature generator.

##### sl_ml_convert_rgb565_to_gray

`void sl_ml_convert_rgb565_to_gray(uint8_t *img)`

**Description:** Function to convert image color space to gray.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint8_t *|[out]|img|Pointer holding reference to image data.|

### Overview

|List of modules|Description|
|---|---|
|[Machine Learning model APIs and structures](ml-tflite-micro-model)|Model handle structure and init/run/deinit functions for embedded TensorFlow Lite Micro models.|
|[Audio Feature Generator](fe-audio)|Extracts mel-filterbank features from an audio signal to use with machine learning audio classification applications.|
|[Microphone I2S Driver for Machine Learning](sl-ml-mic-i2s-si91x)|Microphone driver API for I2S interface on Si91x.|
|[Microphone](mic)|Sound level driver for PDM and I2S microphones.|
|[IMU - Inertial Measurement Unit](imu)|Inertial Measurement Unit driver.|
|[Image Feature Generator](ml-image-feature-generation)|Processes camera images and extracts features for machine learning image classification applications.|

### Machine Learning model APIs and structures

Model handle structure and init/run/deinit functions for embedded TensorFlow Lite Micro models. 

#### Modules

[sl_ml_model_handle_t](sl-ml-model-handle-t)

#### Functions

##### sl_ml_model_init

`sl_status_t sl_ml_model_init(sl_ml_model_handle_t *handle)`

**Description:** Load the model flatbuffer and initialize the interpreter for inference.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_ml_model_handle_t](sl-ml-model-handle-t) *|[in]|handle|Pointer to an initialized handle structure; must not be NULL. `flatbuffer`, `opcode_resolver`, `buffers`, and `buffer_sizes` must also be set.|

If the model is already loaded, returns SL_STATUS_OK without reloading the flatbuffer.

To reload the same `handle`, call [sl_ml_model_deinit](ml-tflite-micro-model#sl-ml-model-deinit) first, then [sl_ml_model_init](ml-tflite-micro-model#sl-ml-model-init).

**Returns**

- `sl_status_t` indicating whether the model loaded successfully.

**Return values**

- SL_STATUS_OK: The model loaded successfully, or was already loaded.
- SL_STATUS_INVALID_PARAMETER: `handle`, `flatbuffer`, `opcode_resolver`, `buffers`, or `buffer_sizes` is NULL, or `flatbuffer_length` or `buffer_count` is not positive.
- SL_STATUS_FAIL: Interpreter setup or tensor allocation failed.

##### sl_ml_model_run

`sl_status_t sl_ml_model_run(sl_ml_model_handle_t *handle)`

**Description:** Run one inference pass on a loaded model.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_ml_model_handle_t](sl-ml-model-handle-t) *|[in]|handle|Pointer to a loaded model handle; must not be NULL.|

**Returns**

- `sl_status_t` indicating whether inference completed successfully.

**Return values**

- SL_STATUS_OK: Inference completed successfully.
- SL_STATUS_INVALID_PARAMETER: `handle` is NULL.
- SL_STATUS_NOT_INITIALIZED: [sl_ml_model_init](ml-tflite-micro-model#sl-ml-model-init) did not complete successfully, or [sl_ml_model_deinit](ml-tflite-micro-model#sl-ml-model-deinit) has already been called.
- SL_STATUS_FAIL: The TFLM `invoke()` call failed.

##### sl_ml_model_deinit

`sl_status_t sl_ml_model_deinit(sl_ml_model_handle_t *handle)`

**Description:** Unload the model and release interpreter resources held by `handle`.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_ml_model_handle_t](sl-ml-model-handle-t) *|[in]|handle|Pointer to the model handle to unload; must not be NULL.|

**Returns**

- `sl_status_t` indicating whether the model was unloaded successfully.

**Return values**

- SL_STATUS_OK: The model was loaded and has been unloaded.
- SL_STATUS_NOT_INITIALIZED: The model was not loaded; `unload()` is not invoked.
- SL_STATUS_INVALID_PARAMETER: `handle` is NULL.

###### Model Handle Structure (heading level 7)

Runtime context for one TensorFlow Lite Micro model on an embedded target. Instantiate one handle per deployed model.

The handle holds the serialized model flatbuffer (`flatbuffer`), operator resolver (`opcode_resolver`), and tensor arena memory (`buffers` and `buffer_sizes`). The embedded interpreter wrapper (`TfliteMicroModel`, or `SLTfliteMicroModel` when profiling is enabled) is default-constructed at creation; call [sl_ml_model_init](ml-tflite-micro-model#sl-ml-model-init) before running inference. 

##### Public Attributes

###### model

```
npu_toolkit::TfliteMicroModel sl_ml_model_handle_t::model
```

**Details:** Embedded TFLM interpreter; default-constructed until [sl_ml_model_init](ml-tflite-micro-model#sl-ml-model-init) succeeds.

###### flatbuffer

```
const uint8_t* sl_ml_model_handle_t::flatbuffer
```

**Details:** Pointer to the serialized model flatbuffer.

###### flatbuffer_length

```
int sl_ml_model_handle_t::flatbuffer_length
```

**Details:** Length of `flatbuffer` in bytes.

###### opcode_resolver

```
const tflite::MicroOpResolver* sl_ml_model_handle_t::opcode_resolver
```

**Details:** Operator resolver that registers kernels required by the model.

###### buffers

```
uint8_t** sl_ml_model_handle_t::buffers
```

**Details:** Pointers to tensor arena buffers; parallel to `buffer_sizes`.

###### buffer_sizes

```
const int32_t* sl_ml_model_handle_t::buffer_sizes
```

**Details:** Size in bytes of each buffer in `buffers`.

###### buffer_count

```
int32_t sl_ml_model_handle_t::buffer_count
```

**Details:** Number of entries in `buffers` and `buffer_sizes`.

###### model_buffer_alignment

```
int32_t sl_ml_model_handle_t::model_buffer_alignment
```

**Details:** Byte alignment required for each tensor arena buffer (typically 4).

###### model_buffer_sections

```
const char** sl_ml_model_handle_t::model_buffer_sections
```

**Details:** Linker section name for each buffer slot; parallel to `buffers`. May be NULL.

##### Public Functions

###### input_tensor

`TfLiteTensor * sl_ml_model_handle_t::input_tensor(size_t index) const`

**Description:** Return the input tensor at `index`.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|size_t|[in]|index|Zero-based input tensor index (0 to `num_inputs` - 1).|

The model must be loaded successfully ([sl_ml_model_init](ml-tflite-micro-model#sl-ml-model-init)).

**Returns**

- Pointer to the input `TfLiteTensor`, or NULL if the model is not loaded, `index` is invalid, or the interpreter is unavailable.

###### output_tensor

`TfLiteTensor * sl_ml_model_handle_t::output_tensor(size_t index) const`

**Description:** Return the output tensor at `index`.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|size_t|[in]|index|Zero-based output tensor index (0 to `num_outputs` - 1).|

The model must be loaded successfully ([sl_ml_model_init](ml-tflite-micro-model#sl-ml-model-init)).

**Returns**

- Pointer to the output `TfLiteTensor`, or NULL if the model is not loaded, `index` is invalid, or the interpreter is unavailable.

###### sl_ml_model_handle_t

`sl_ml_model_handle_t::sl_ml_model_handle_t(const uint8_t *flatbuffer_in, int flatbuffer_length_in, const tflite::MicroOpResolver *opcode_resolver_in, uint8_t **buffers_in, const int32_t *buffer_sizes_in, int32_t buffer_count_in, int32_t model_buffer_alignment_in, const char **model_buffer_sections_in)`

**Description:** Initialize a model handle with flatbuffer, resolver, and tensor-buffer metadata.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const uint8_t *|[in]|flatbuffer_in|Pointer to the serialized model flatbuffer; must not be NULL.|
|int|[in]|flatbuffer_length_in|Length of `flatbuffer_in` in bytes; must be greater than zero.|
|const tflite::MicroOpResolver *|[in]|opcode_resolver_in|Operator resolver for kernels used by the model; must not be NULL.|
|uint8_t **|[in]|buffers_in|Array of tensor arena buffers; must not be NULL.|
|const int32_t *|[in]|buffer_sizes_in|Size in bytes of each buffer in `buffers_in`; must not be NULL.|
|int32_t|[in]|buffer_count_in|Number of elements in `buffers_in` and `buffer_sizes_in`; must be greater than zero.|
|int32_t|[in]|model_buffer_alignment_in|Required byte alignment for each tensor arena buffer (typically 4).|
|const char **|[in]|model_buffer_sections_in|Linker section name for each buffer slot; parallel to `buffers_in`. May be NULL.|

Default-constructs the embedded interpreter wrapper (and profiler when enabled). Call [sl_ml_model_init](ml-tflite-micro-model#sl-ml-model-init) before [sl_ml_model_run](ml-tflite-micro-model#sl-ml-model-run).

### Audio Feature Generator

Extracts mel-filterbank features from an audio signal for use with machine learning audio classification applications. 

#### Modules

[Audio feature generator (EFR series)](ml-audio-feature-generation-efr)

[Audio feature generator (Si91x)](ml-audio-feature-generation-si91x)

#### Audio feature generator (EFR series)

The audio feature generator extracts mel-filterbank features from an audio signal to use with machine learning audio classification applications using a microphone as an audio source.

###### Feature Generation

The Mel scale replicates the behavior of the human ear, which has a higher resolution for lower frequencies and is less discriminative of the higher frequencies. To create a mel filterbank, a number of filters are applied to the signal, where the pass-band of the lower channel filters is narrow and increases towards higher frequencies.

The audio signal is split into short overlapping segments using a window function (Hamming). The Fast Fourier Transform (FFT) is applied to each segment to retrieve the frequency spectrum and then the power spectrum of the segment. The filterbank is created by applying a series of mel-scaled filters to the output. Finally, the log is applied to the output to increase the sensitivity between the lower channels. 

```c
         Audio Signal
              │
      ┌───────▼───────┐
      │   Windowing   │
      └───────┬───────┘
              │
      ┌───────▼───────┐
      │      FFT      │
      └───────┬───────┘
              │
      ┌───────▼───────┐
      │  Mel Filters  │
      └───────┬───────┘
              │
      ┌───────▼───────┐
      │      Log      │
      └───────┬───────┘
              │
              ▼
   Log-scaled Mel Filterbank

```

The feature array is generated by stacking filterbanks of sequential segments together to form a spectrogram. The array is sorted such that the first element is the first channel of the oldest filterbank.

###### Usage

[sl_ml_audio_feature_generation_init()](ml-audio-feature-generation-efr#sl-ml-audio-feature-generation-init) initializes the frontend for feature generation based on the configuration in sl_ml_audio_feature_generation_config.h. It also initializes and starts the microphone in streaming mode, which places the audio samples into a ring-buffer.

If used together with the Flatbuffer Converter Tool and a compatible TensorFlow Lite model, the configuration is pulled from the TensorFlow Lite model by default. In that mode you must call sl_ml_audio_feature_generation_load_model_settings() with the model flatbuffer before [sl_ml_audio_feature_generation_init()](ml-audio-feature-generation-efr#sl-ml-audio-feature-generation-init) so sample rate and window timing are valid. Set the configuration option `SL_ML_AUDIO_FEATURE_GENERATION_MANUAL_CONFIG_ENABLE` to override this behavior and use manually-configured options from the configuration header.

The features are generated when [sl_ml_audio_feature_generation_update_features()](ml-audio-feature-generation-efr#sl-ml-audio-feature-generation-update-features) is called. The feature generator then updates the features for as many new segments of audio as possible, starting from the last time the function was called up until the current time. The new features are appended to the feature buffer, replacing the oldest features such that the feature array always contains the most up to date features.

Note that if the audio buffer is not large enough to hold all audio samples required to generate features between calls to [sl_ml_audio_feature_generation_update_features()](ml-audio-feature-generation-efr#sl-ml-audio-feature-generation-update-features), audio data will simply be overwritten. The generator will not return an error. The audio buffer must therefore be configured to be large enough to store all new sampled data between updating features.

To retrieve the generated features, either [sl_ml_audio_feature_generation_get_features_raw()](ml-audio-feature-generation-efr#sl-ml-audio-feature-generation-get-features-raw), sl_ml_audio_feature_generation_get_features_quantized(), or [sl_ml_audio_feature_generation_fill_tensor()](ml-audio-feature-generation-efr#sl-ml-audio-feature-generation-fill-tensor) must be called.

###### Example (heading level 7)

When used with TensorFlow Lite Micro, the audio feature generator can be used to fill a tensor directly by using [sl_ml_audio_feature_generation_fill_tensor()](ml-audio-feature-generation-efr#sl-ml-audio-feature-generation-fill-tensor). However, the model has to be trained using the same feature generator configurations as used for inference, configured in sl_ml_audio_feature_generation_config.h.

```c
#include "sl_tflite_micro_init.h"
#include "sl_fe_audio.h"

void main(void)
{
  sl_ml_audio_feature_generation_init();

  while(1){
    sl_ml_audio_feature_generation_update_features();

    if(do_inference){
      sl_ml_audio_feature_generation_fill_tensor(sl_tflite_micro_get_input_tensor());
      sl_tflite_micro_get_interpreter()->Invoke();
    }

    ...

  }
}

```

Note that updating features and retrieving them can be performed independently. Updating features should be done often enough to avoid overwriting the audio buffer while retrieving them only needs to be done prior to inference. 

##### Functions

###### sl_ml_audio_feature_generation_init

`sl_status_t sl_ml_audio_feature_generation_init()`

**Description:** Set up the microphone as an audio source for feature generation and initialize the frontend for feature generation.

**Returns**

- SL_STATUS_OK for success SL_STATUS_FAIL

###### sl_ml_audio_feature_generation_frontend_init

`sl_status_t sl_ml_audio_feature_generation_frontend_init()`

**Description:** Initialize microfrontend according to the configuration in sl_ml_audio_feature_generation_config.h.

**Returns**

- SL_STATUS_OK for success SL_STATUS_FAIL

###### sl_ml_audio_feature_generation_update_features

`sl_status_t sl_ml_audio_feature_generation_update_features()`

**Description:** Update the feature buffer with the missing feature slices since the last call to this function.

To retrieve the features, call sl_ml_audio_feature_generation_get_features_raw or sl_ml_audio_feature_generation_fill_tensor.

**Note**

- This function needs to be called often enough to ensure that the audio buffer isn't overwritten.

**Returns**

- SL_STATUS_OK for success SL_STATUS_EMPTY No new slices were calculated

###### sl_ml_audio_feature_generation_get_features_raw

`sl_status_t sl_ml_audio_feature_generation_get_features_raw(uint16_t *buffer, size_t num_elements)`

**Description:** Retrieve the features as type uint16 and copy them to the provided buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint16_t *|[out]|buffer|Pointer to the buffer to store the feature data|
|size_t|[in]|num_elements|The number of elements corresponding to the size of the buffer; If this is not large enough to store the entire feature buffer the function will return with an error.|

**Note**

- This function overwrites the entire buffer.

**Returns**

- SL_STATUS_OK for success SL_STATUS_INVALID_PARAMETER num_elements too small

###### sl_ml_audio_feature_generation_fill_tensor

`sl_status_t sl_ml_audio_feature_generation_fill_tensor(TfLiteTensor *input_tensor)`

**Description:** Fill a TensorFlow tensor with feature data of type int8.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|TfLiteTensor *|[in]|input_tensor|The input tensor to fill with features.|

The int8 values are derived by quantizing the microfrontend output, expected to be in the range 0 to 670, to signed integer numbers in -128 to 127 range.

**Note**

- This function overwrites the entire input tensor.
- Supports tensors of type kTfLiteInt8.

**Returns**

- SL_STATUS_OK for success SL_STATUS_INVALID_PARAMETER Tensor type or size does not correspond with configuration

###### sl_ml_audio_feature_generation_get_new_feature_slice_count

`int sl_ml_audio_feature_generation_get_new_feature_slice_count()`

**Description:** Return the number of new or unfetched feature slices that have been updated since the last call to sl_ml_audio_feature_generation_get_features_raw or sl_ml_audio_feature_generation_fill_tensor.

**Returns**

- The number of unfetched feature slices

###### sl_ml_audio_feature_generation_get_feature_buffer_size

`int sl_ml_audio_feature_generation_get_feature_buffer_size()`

**Description:** Return the feature buffer size.

**Returns**

- Size of the feature buffer

###### sl_ml_audio_feature_generation_reset

`void sl_ml_audio_feature_generation_reset()`

**Description:** Reset the state of the audio feature generator.

#### Audio feature generator (Si91x)

The audio feature generator extracts mel-filterbank features from an audio signal to use with machine learning audio classification applications using a microphone as an audio source.

###### Feature Generation

The Mel scale replicates the behavior of the human ear, which has a higher resolution for lower frequencies and is less discriminative of the higher frequencies. To create a mel filterbank, a number of filters are applied to the signal, where the pass-band of the lower channel filters is narrow and increases towards higher frequencies.

The audio signal is split into short overlapping segments using a window function (Hamming). The Fast Fourier Transform (FFT) is applied to each segment to retrieve the frequency spectrum and then the power spectrum of the segment. The filterbank is created by applying a series of mel-scaled filters to the output. Finally, the log is applied to the output to increase the sensitivity between the lower channels. 

```c
         Audio Signal
              │
      ┌───────▼───────┐
      │   Windowing   │
      └───────┬───────┘
              │
      ┌───────▼───────┐
      │      FFT      │
      └───────┬───────┘
              │
      ┌───────▼───────┐
      │  Mel Filters  │
      └───────┬───────┘
              │
      ┌───────▼───────┐
      │      Log      │
      └───────┬───────┘
              │
              ▼
   Log-scaled Mel Filterbank

```

The feature array is generated by stacking filterbanks of sequential segments together to form a spectrogram. The array is sorted such that the first element is the first channel of the oldest filterbank.

###### Usage

[sl_ml_audio_feature_generation_init()](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-init) initializes the frontend from a per-model [sl_fe_audio_config_t](ml-audio-feature-generation-si91x#sl-fe-audio-config-t) (typically `sl_fe_audio_<instance>_cfg` from the fe_audio component). It also starts the microphone in streaming mode into a heap-allocated ring buffer sized from `config->audio_buffer_size`.

###### Si91x single pipeline (multi-instance configs) (heading level 7)

The fe_audio component may define several `sl_fe_audio_<instance>_cfg` symbols (one per model). The Si91x implementation still uses one set of global buffers and one `FrontendState` at a time. Only one pipeline may be active. After validating the new parameters, [sl_ml_audio_feature_generation_init](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-init) and [sl_ml_audio_feature_generation_init_with_buffer](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-init-with-buffer) tear down an existing pipeline (same as [sl_ml_audio_feature_generation_deinit](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-deinit)) and then bring up the new config, so callers can switch models with a single `init` call.

###### Instance configuration (fe_audio) (heading level 7)

Frontend parameters for inference come from the per-model `sl_fe_audio_config_t` that the fe_audio component exports (typically `sl_fe_audio_<instance>_cfg` in `sl_fe_audio_instances.h`, autogenerated from the same TensorFlow Lite flatbuffer metadata produced by the Silicon Labs converter toolchain). Pass `&sl_fe_audio_<instance>_cfg` to [sl_ml_audio_feature_generation_init](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-init) so the microfrontend, sample rate, ring buffer sizing, and quantization options match that model.

The features are generated when [sl_ml_audio_feature_generation_update_features()](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-update-features) is called. The feature generator then updates the features for as many new segments of audio as possible, starting from the last time the function was called up until the current time. The new features are appended to the feature buffer, replacing the oldest features such that the feature array always contains the most up to date features.

Note that if the audio buffer is not large enough to hold all audio samples required to generate features between calls to [sl_ml_audio_feature_generation_update_features()](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-update-features), audio data will simply be overwritten. The generator will not return an error. The audio buffer must therefore be configured to be large enough to store all new sampled data between updating features.

To retrieve the generated features, either [sl_ml_audio_feature_generation_get_features_raw()](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-get-features-raw), sl_ml_audio_feature_generation_get_features_quantized(), or [sl_ml_audio_feature_generation_fill_tensor()](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-fill-tensor) must be called.

###### Example (heading level 7)

When used with TensorFlow Lite Micro, the audio feature generator can fill the network input tensor via [sl_ml_audio_feature_generation_fill_tensor()](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-fill-tensor). Training and inference must use the same frontend pipeline; with instance-based integration that means initializing with the `sl_fe_audio_config_t` generated for the deployed ``.tflite (same embedded FE metadata the converter wrote into the model).

```c
#include "sl_tflite_micro_init.h"
#include "sl_fe_audio_instances.h"
#include "sl_fe_audio_si91x.h"

void main(void)
{
  sl_ml_audio_feature_generation_init(&sl_fe_audio_my_model_cfg);

  while(1){
    sl_ml_audio_feature_generation_update_features();

    if(do_inference){
      sl_ml_audio_feature_generation_fill_tensor(sl_tflite_micro_get_input_tensor());
      sl_tflite_micro_get_interpreter()->Invoke();
    }

    ...

  }
}

```

Note that updating features and retrieving them can be performed independently. Updating features should be done often enough to avoid overwriting the audio buffer while retrieving them only needs to be done prior to inference. 

##### Modules

[sl_fe_audio_config](sl-fe-audio-config)

##### Typedefs

###### sl_fe_audio_config_t

`typedef struct sl_fe_audio_config sl_fe_audio_config_t`

**Details:**

Per-model frontend + buffer/quantization parameters (fe_audio component instance).

###### sl_ml_audio_feature_generation_mic_callback_t

`typedef void(* sl_ml_audio_feature_generation_mic_callback_t) (void *arg, const int16_t *data, uint32_t n_frames)`

**Description:**

Microphone callback function type for audio feature generation.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
||[in]|arg|User-defined argument passed to the callback.|
||[in]|data|Pointer to the audio data buffer.|
||[in]|n_frames|Number of audio frames in the buffer.|

**Details:**

##### Variables

###### sl_ml_audio_feature_generation_audio_buffer

```
int16_t* sl_ml_audio_feature_generation_audio_buffer
```

**Description:** External audio buffer for audio feature generation (mic / DMA ring backing store).

##### Functions

###### sl_ml_audio_feature_generation_init

`sl_status_t sl_ml_audio_feature_generation_init(const sl_fe_audio_config_t *config)`

**Description:** Set up the microphone as an audio source for feature generation and initialize the frontend from `config` (allocates the audio ring buffer).

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_fe_audio_config_t](ml-audio-feature-generation-si91x#sl-fe-audio-config-t) *|[in]|config|Per-model frontend and buffer parameters; must not be NULL.|

If a pipeline is already active, it is torn down first (same as [sl_ml_audio_feature_generation_deinit](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-deinit)). A non-OK status from that step is the return value from `sl_ml_mic_deinit()` during deinit.

After the frontend is initialized, failures from `sl_ml_mic_init`, `sl_ml_mic_start_streaming`, or `sl_ml_mic_process_action` return that driver `sl_status_t` after cleaning up allocated resources.

**Returns**

- Other non-OK `sl_status_t` values may be returned from the microphone / I2S driver during teardown or bring-up.

**Return values**

- SL_STATUS_OK: Success.
- SL_STATUS_INVALID_PARAMETER: `config` is NULL, `audio_buffer_size` is less than 2, or invalid parameters from [sl_ml_audio_feature_generation_init_with_buffer](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-init-with-buffer) or the frontend layer.
- SL_STATUS_FAIL: Coarse validation failed (sample rate, window step/size, segment length), or microfrontend state cannot be populated ([sl_ml_audio_feature_generation_frontend_init](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-frontend-init)).
- SL_STATUS_ALLOCATION_FAILED: The heap audio ring or feature ring could not be allocated.

###### sl_ml_audio_feature_generation_init_with_buffer

`sl_status_t sl_ml_audio_feature_generation_init_with_buffer(int16_t *buffer, int n_frames, const sl_fe_audio_config_t *config)`

**Description:** Initialize audio feature generation with a user-provided buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|int16_t *|[in]|buffer|Pointer to the audio buffer to use for feature generation.|
|int|[in]|n_frames|Number of int16 audio samples in the buffer; must equal `config->audio_buffer_size`.|
|const [sl_fe_audio_config_t](ml-audio-feature-generation-si91x#sl-fe-audio-config-t) *|[in]|config|Per-model frontend and buffer parameters; must not be NULL.|

If a pipeline is already active, it is torn down first (same as [sl_ml_audio_feature_generation_deinit](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-deinit)). A non-OK status from that step is the return value from `sl_ml_mic_deinit()` during deinit.

After the frontend is initialized, failures from `sl_ml_mic_init`, `sl_ml_mic_start_streaming`, or `sl_ml_mic_process_action` return that driver `sl_status_t` after cleaning up allocated resources.

**Returns**

- Other non-OK `sl_status_t` values may be returned from the microphone / I2S driver during teardown or bring-up.

**Return values**

- SL_STATUS_OK: Success.
- SL_STATUS_INVALID_PARAMETER: `config` or `buffer` is NULL, `n_frames` is less than 2, `n_frames` does not equal `config->audio_buffer_size`, or invalid frontend parameters from [sl_ml_audio_feature_generation_frontend_init](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-frontend-init).
- SL_STATUS_FAIL: Coarse validation failed (sample rate, window step/size, segment length), or microfrontend state cannot be populated.
- SL_STATUS_ALLOCATION_FAILED: The feature ring buffer could not be allocated.

###### sl_ml_audio_feature_generation_deinit

`sl_status_t sl_ml_audio_feature_generation_deinit(void)`

**Description:** Tear down the Si91x audio feature pipeline (mic, internal feature buffer, frontend state).

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

Idempotent: returns `SL_STATUS_OK` if the pipeline was already inactive. After [sl_ml_audio_feature_generation_init](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-init), frees the heap audio buffer owned by that API. Buffers passed to [sl_ml_audio_feature_generation_init_with_buffer](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-init-with-buffer) are never freed here (caller retains ownership).

Teardown is best-effort: the internal feature buffer and frontend state are always released after `sl_ml_mic_deinit()` is attempted. If the microphone returns a non-OK status, the pipeline is still marked inactive and FE memory is freed; the caller may need to handle or log the mic status separately.

**Returns**

- If the pipeline was active and `sl_ml_mic_deinit()` returns a value other than `SL_STATUS_OK`, that status is returned (feature-buffer and frontend teardown may still have completed).

**Return values**

- SL_STATUS_OK: The microphone deinitialized cleanly, or the pipeline was already inactive.

###### sl_ml_audio_feature_generation_frontend_init

`sl_status_t sl_ml_audio_feature_generation_frontend_init(const sl_fe_audio_config_t *config)`

**Description:** Initialize the microfrontend and feature buffers from `config`.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_fe_audio_config_t](ml-audio-feature-generation-si91x#sl-fe-audio-config-t) *|[in]|config|Per-model frontend and buffer parameters; must not be NULL.|

###### sl_ml_audio_feature_generation_update_features

`sl_status_t sl_ml_audio_feature_generation_update_features()`

**Description:** Update the feature buffer with feature slices computed since the last call.

To retrieve features, call [sl_ml_audio_feature_generation_get_features_raw](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-get-features-raw) or [sl_ml_audio_feature_generation_fill_tensor](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-fill-tensor).

**Note**

- Call often enough that the audio ring is not overwritten.

###### sl_ml_audio_feature_generation_get_features_raw

`sl_status_t sl_ml_audio_feature_generation_get_features_raw(uint16_t *buffer, size_t num_elements)`

**Description:** Copy the active spectrogram ring to a `uint16` buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|uint16_t *|[out]|buffer|Pointer to the buffer to store the feature data.|
|size_t|[in]|num_elements|Must equal the active feature element count ([sl_ml_audio_feature_generation_get_feature_buffer_size](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-get-feature-buffer-size)).|

**Note**

- Overwrites the entire `buffer`.

###### sl_ml_audio_feature_generation_get_features_raw_float32

`sl_status_t sl_ml_audio_feature_generation_get_features_raw_float32(float *buffer, size_t num_elements)`

**Description:** Copy the active spectrogram ring to a `float32` buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float *|[out]|buffer|Pointer to the buffer to store the feature data.|
|size_t|[in]|num_elements|Must equal the active feature element count ([sl_ml_audio_feature_generation_get_feature_buffer_size](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-get-feature-buffer-size)).|

**Note**

- Overwrites the entire `buffer`.

###### sl_ml_audio_feature_generation_get_features_scaled

`sl_status_t sl_ml_audio_feature_generation_get_features_scaled(float *buffer, size_t num_elements, float scaler)`

**Description:** Copy the active spectrogram to `buffer` with each sample multiplied by `scaler`.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float *|[out]|buffer|Pointer to the buffer to store the scaled feature data.|
|size_t|[in]|num_elements|Must equal the active feature element count ([sl_ml_audio_feature_generation_get_feature_buffer_size](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-get-feature-buffer-size)).|
|float|[in]|scaler|Scaling factor applied to each feature value (must be non-zero).|

Computes `buffer`[i] = (float)feature[i] * `scaler` for each element in the ring.

**Note**

- Overwrites the entire `buffer`.

###### sl_ml_audio_feature_generation_get_features_mean_std_normalized

`sl_status_t sl_ml_audio_feature_generation_get_features_mean_std_normalized(float *buffer, size_t num_elements)`

**Description:** Mean- and standard-deviation-normalized copy of the active spectrogram into `buffer`.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float *|[out]|buffer|Pointer to the buffer to store the normalized feature data.|
|size_t|[in]|num_elements|Must equal the active feature element count ([sl_ml_audio_feature_generation_get_feature_buffer_size](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-get-feature-buffer-size)).|

For each element: ``(float(value) - mean) / std. Near-constant input yields zeros in `buffer`.

**Note**

- Overwrites the entire `buffer`.

###### sl_ml_audio_feature_generation_fill_tensor

`sl_status_t sl_ml_audio_feature_generation_fill_tensor(TfLiteTensor *input_tensor)`

**Description:** Fill a TensorFlow Lite input tensor from the active feature buffer.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|TfLiteTensor *|[in]|input_tensor|The input tensor to fill with features.|

Writes packed tensor data according to `input_tensor->type:`

- `kTfLiteInt8:` static or dynamically quantized int8 (per active `sl_fe_audio_config_t`).
- `kTfLiteUInt16:` raw uint16 spectrogram.
- `kTfLiteFloat32:` raw float, scaled float, or mean/std-normalized float (per active config).

**Note**

- Overwrites the entire input tensor payload.

###### sl_ml_audio_feature_generation_get_new_feature_slice_count

`int sl_ml_audio_feature_generation_get_new_feature_slice_count()`

**Description:** Return the number of new or unfetched feature slices that have been updated since the last call to sl_ml_audio_feature_generation_get_features_raw or sl_ml_audio_feature_generation_fill_tensor.

**Returns**

- Number of unfetched feature slices (non-negative). Zero if none pending or if the pipeline is not initialized.

###### sl_ml_audio_feature_generation_get_feature_buffer_size

`int sl_ml_audio_feature_generation_get_feature_buffer_size()`

**Description:** Return the feature buffer size.

**Returns**

- Number of uint16 feature elements in the active spectrogram ring, or `0` if the pipeline / feature buffer is not initialized.

###### sl_ml_audio_feature_generation_reset

`void sl_ml_audio_feature_generation_reset()`

**Description:** Reset the state of the audio feature generator.

###### sl_ml_audio_feature_generation_activity_detected

`sl_status_t sl_ml_audio_feature_generation_activity_detected()`

**Description:** Query whether the activity-detection block has tripped since the last successful read.

Call [sl_ml_audio_feature_generation_update_features](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-update-features) periodically so the detector advances on new audio.

**Note**

- Activity detection must be enabled in the active `sl_fe_audio_config_t` (see [sl_ml_audio_feature_generation_is_activity_detection_enabled](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-is-activity-detection-enabled)).
- Internal trip state is cleared when this returns `SL_STATUS_OK`; a subsequent call returns `SL_STATUS_IN_PROGRESS` until new activity is detected.

###### sl_ml_audio_feature_generation_is_activity_detection_enabled

`bool sl_ml_audio_feature_generation_is_activity_detection_enabled(void)`

**Description:** Return whether the runtime frontend config has activity detection enabled.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

After [sl_ml_audio_feature_generation_init](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-init), reflects the active `sl_fe_audio_config_t`. 

###### sl_ml_audio_feature_generation_set_mic_callback

`sl_status_t sl_ml_audio_feature_generation_set_mic_callback(sl_ml_audio_feature_generation_mic_callback_t callback, void *arg)`

**Description:** Register the optional microphone PCM callback (or clear it).

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_ml_audio_feature_generation_mic_callback_t](ml-audio-feature-generation-si91x#sl-ml-audio-feature-generation-mic-callback-t)|[in]|callback|Function pointer (may be NULL to clear).|
|void *|[in]|arg|User argument passed to `callback`.|

Per-model frontend + buffer/quantization parameters (fe_audio component instance). 

###### Public Attributes

###### frontend_config (heading level 7)

```
struct FrontendConfig sl_fe_audio_config::frontend_config
```

###### sample_rate_hz (heading level 7)

```
int sl_fe_audio_config::sample_rate_hz
```

###### fft_length (heading level 7)

```
unsigned sl_fe_audio_config::fft_length
```

###### sample_length_ms (heading level 7)

```
unsigned sl_fe_audio_config::sample_length_ms
```

###### audio_buffer_size (heading level 7)

```
size_t sl_fe_audio_config::audio_buffer_size
```

###### audio_buffer_chunk_size (heading level 7)

```
size_t sl_fe_audio_config::audio_buffer_chunk_size
```

###### audio_gain (heading level 7)

```
int sl_fe_audio_config::audio_gain
```

###### quantize_dynamic_scale_enable (heading level 7)

```
int sl_fe_audio_config::quantize_dynamic_scale_enable
```

###### quantize_dynamic_scale_range_db (heading level 7)

```
float sl_fe_audio_config::quantize_dynamic_scale_range_db
```

###### quantize_feature_range_min (heading level 7)

```
uint16_t sl_fe_audio_config::quantize_feature_range_min
```

###### quantize_feature_range_max (heading level 7)

```
uint16_t sl_fe_audio_config::quantize_feature_range_max
```

###### samplewise_norm_rescale (heading level 7)

```
float sl_fe_audio_config::samplewise_norm_rescale
```

**Details:** Float tensor path: multiply uint16 features by this factor (0 = off).

###### samplewise_norm_mean_and_std (heading level 7)

```
int sl_fe_audio_config::samplewise_norm_mean_and_std
```

**Details:** Float tensor path: per-buffer mean/std normalization.

### IMU - Inertial Measurement Unit

Inertial Measurement Unit driver. 

Inertial Measurement Unit driver.

<br />

#### IMU example code

Basic example for looping measurement of orientation data: <br /><br />

```c
#include "sl_imu.h"

int main( void )
{

  ...

  int16_t o_vec[3];

  sl_imu_init();

  // Configure sample rate
  sl_imu_configure(10);

  // Recalibrate gyro
  sl_imu_calibrate_gyro();

  while (true) {

    sl_imu_update();

    while (!sl_imu_is_data_ready()) {
      // wait
    }

    sl_imu_get_orientation(o_vec);

    ...

  }
} 
```

#### Modules

[IMU Fusion](imu-fusion)

[Vector and Matrix Math](vector-matrix-math)

[Direction Cosine Matrix](direction-cosine-matrix)

#### State Definitions

`#define IMU_STATE_DISABLED 0x00`

**Description**: The IMU is disabled <br />

`#define IMU_STATE_READY 0x01`

**Description**: The IMU is fully configured and ready to take measurements <br />

`#define IMU_STATE_INITIALIZING 0x02`

**Description**: The IMU is being initialized <br />

`#define IMU_STATE_CALIBRATING 0x03`

**Description**: The IMU is being calibrated <br />

#### Functions

##### sl_imu_init

`sl_status_t sl_imu_init(sl_ssi_handle_t ssi_driver_handle)`

**Description:** Initialize and calibrate the IMU chip.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|sl_ssi_handle_t|N/A|ssi_driver_handle||

**Returns**

- Returns zero on OK, non-zero otherwise

##### sl_imu_deinit

`sl_status_t sl_imu_deinit(void)`

**Description:** De-initialize the IMU chip.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

**Returns**

- Returns zero on OK, non-zero otherwise

##### sl_imu_get_state

`uint8_t sl_imu_get_state(void)`

**Description:** Return IMU state.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

**Returns**

- IMU state

##### sl_imu_update

`void sl_imu_update(void)`

**Description:** Get a new set of data from the accel and gyro sensor and updates the fusion calculation.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

##### sl_imu_reset

`void sl_imu_reset(void)`

**Description:** Reset the fusion calculation.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

##### sl_imu_get_acceleration

`void sl_imu_get_acceleration(int16_t avec[3])`

**Description:** Retrieve the processed acceleration data.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|int16_t|[out]|avec|Three dimensional acceleration vector|

##### sl_imu_get_orientation

`void sl_imu_get_orientation(int16_t ovec[3])`

**Description:** Retrieve the processed orientation data.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|int16_t|[out]|ovec|Three dimensional orientation vector|

##### sl_imu_get_gyro

`void sl_imu_get_gyro(int16_t gvec[3])`

**Description:** Retrieve the processed gyroscope data.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|int16_t|[out]|gvec|Three dimensional gyro vector|

##### sl_imu_calibrate_gyro

`sl_status_t sl_imu_calibrate_gyro(sl_ssi_handle_t ssi_driver_handle)`

**Description:** Perform gyroscope calibration to cancel gyro bias.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|sl_ssi_handle_t|N/A|ssi_driver_handle||

##### sl_imu_get_gyro_correction_angles

`void sl_imu_get_gyro_correction_angles(float acorr[3])`

**Description:** Retrieve the processed gyroscope correction angles.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[out]|acorr|Three dimensional gyro correction angle vector|

##### sl_imu_configure

`void sl_imu_configure(float sampleRate, sl_ssi_handle_t ssi_driver_handle)`

**Description:** Configure the IMU.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[in]|sampleRate|The desired sample rate of the acceleration and gyro sensor|
|sl_ssi_handle_t|N/A|ssi_driver_handle||

##### sl_imu_is_data_ready

`bool sl_imu_is_data_ready(sl_ssi_handle_t ssi_driver_handle)`

**Description:** Check if new accel/gyro data is available for read.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|sl_ssi_handle_t|N/A|ssi_driver_handle||

**Returns**

- True if the measurement data is ready, false otherwise

##### sl_imu_get_acceleration_raw_data

`void sl_imu_get_acceleration_raw_data(float avec[3])`

**Description:** Retrieve the raw acceleration data from the IMU.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[out]|avec|Three dimensional raw acceleration vector|

##### sl_imu_get_gyro_raw_data

`void sl_imu_get_gyro_raw_data(float gvec[3])`

**Description:** Retrieve the raw gyroscope data from the IMU.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[out]|gvec|Three dimensional raw gyro vector|

#### Vector and Matrix Math

Inertial measurement unit fusion driver math routines. 

##### Functions

###### sl_imu_normalize_angle

`void sl_imu_normalize_angle(float *a)`

**Description:** Normalize the angle ( -PI < angle <= PI )

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float *|N/A|a|The angle to be normalized|

###### sl_imu_matrix_multiply

`void sl_imu_matrix_multiply(float c[3][3], float a[3][3], float b[3][3])`

**Description:** Multiply two 3x3 matrices.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[out]|c|The multiplication result, AB|
|float|[in]|a|Input vector A|
|float|[in]|b|Input vector B|

###### sl_imu_vector_normalize_angle

`void sl_imu_vector_normalize_angle(float v[3])`

**Description:** Normalize the angle of a vector.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|N/A|v|The vector, which contains angles to be normalized|

###### sl_imu_vector_zero

`void sl_imu_vector_zero(float v[3])`

**Description:** Set all elements of a vector to 0.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|N/A|v|The vector to be cleared|

###### sl_imu_vector_scale

`void sl_imu_vector_scale(float v[3], float scale)`

**Description:** Scale a vector by a factor.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|N/A|v|The vector to be scaled|
|float|[in]|scale|The scale factor|

###### sl_imu_vector_scalar_multiplication

`void sl_imu_vector_scalar_multiplication(float r[3], float v[3], float scale)`

**Description:** Multiply a vector by a scalar.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[out]|r|The multiplied vector|
|float|[in]|v|The vector to be multiplied|
|float|[in]|scale|The scalar multiplicator value|

###### sl_imu_vector_add

`void sl_imu_vector_add(float r[3], float a[3], float b[3])`

**Description:** Add two vectors.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[out]|r|The vectorial sum of the vectors, a+b|
|float|[in]|a|The first vector|
|float|[in]|b|The second vector|

###### sl_imu_vector_subtract

`void sl_imu_vector_subtract(float r[3], float a[3], float b[3])`

**Description:** Subtract vector b from vector a.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[out]|r|The vectorial difference, a-b|
|float|[in]|a|Vector a|
|float|[in]|b|Vector b|

###### sl_imu_vector_dot_product

`float sl_imu_vector_dot_product(float a[3], float b[3])`

**Description:** Calculate the dot product of two vectors.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[in]|a|The first vector|
|float|[in]|b|The second vector|

**Returns**

- The dot product

###### sl_imu_vector_cross_product

`void sl_imu_vector_cross_product(float r[3], float a[3], float b[3])`

**Description:** Calculate the cross product of two vectors.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[out]|r|The cross product|
|float|[in]|a|The first vector|
|float|[in]|b|The second vector|

#### Direction Cosine Matrix

Unit DCM matrix related routines. 

##### Functions

###### sl_imu_dcm_reset

`void sl_imu_dcm_reset(float dcm[3][3])`

**Description:** Set the elements of the DCM matrix to the corresponding elements of the identity matrix.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|N/A|dcm|DCM matrix|

###### sl_imu_dcm_reset_z

`void sl_imu_dcm_reset_z(float dcm[3][3])`

**Description:** DCM reset, Z direction.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|N/A|dcm|DCM matrix|

###### sl_imu_dcm_normalize

`void sl_imu_dcm_normalize(float dcm[3][3])`

**Description:** Normalize the DCM matrix.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|N/A|dcm|DCM matrix|

###### sl_imu_dcm_rotate

`void sl_imu_dcm_rotate(float dcm[3][3], float ang[3])`

**Description:** Rotate the DCM matrix by a given angle.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[inout]|dcm|DCM matrix|
|float|[in]|ang|Rotation angle|

###### sl_imu_dcm_get_angles

`void sl_imu_dcm_get_angles(float dcm[3][3], float ang[3])`

**Description:** Calculate the Euler angles (roll, pitch, yaw) from the DCM matrix.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float|[in]|dcm|DCM matrix|
|float|[out]|ang|An array containing the Euler angles|

#### IMU Fusion

IMU fusion driver. 

##### Modules

[sl_imu_sensor_fusion](sl-imu-sensor-fusion)

##### Typedefs

###### sl_imu_sensor_fusion_t

`typedef struct sl_imu_sensor_fusion sl_imu_sensor_fusion_t`

**Description:**

Structure to store the sensor fusion data.

##### Functions

###### sl_imu_fuse_accelerometer_set_sample_rate

`void sl_imu_fuse_accelerometer_set_sample_rate(sl_imu_sensor_fusion_t *f, float rate)`

**Description:** Set the accelerometer sample rate in the sl_imu_sensor_fusion_t structure.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_imu_sensor_fusion_t](imu-fusion#sl-imu-sensor-fusion-t) *|[inout]|f|Pointer to the sl_imu_sensor_fusion_t object|
|float|[in]|rate|Sample rate of the accelerometer|

###### sl_imu_fuse_accelerometer_update_filter

`void sl_imu_fuse_accelerometer_update_filter(sl_imu_sensor_fusion_t *f, float avec[3])`

**Description:** Add the current accelerometer data to the accumulator.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_imu_sensor_fusion_t](imu-fusion#sl-imu-sensor-fusion-t) *|[inout]|f|Pointer to the sl_imu_sensor_fusion_t object|
|float|[in]|avec|Accelerometer vector|

###### sl_imu_fuse_gyro_set_sample_rate

`void sl_imu_fuse_gyro_set_sample_rate(sl_imu_sensor_fusion_t *f, float rate)`

**Description:** Set the gyro sample rate and related values in the sl_imu_sensor_fusion_t structure.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_imu_sensor_fusion_t](imu-fusion#sl-imu-sensor-fusion-t) *|[inout]|f|Pointer to the sl_imu_sensor_fusion_t object|
|float|[in]|rate|Sample rate of the gyroscope|

###### sl_imu_fuse_gyro_update

`void sl_imu_fuse_gyro_update(sl_imu_sensor_fusion_t *f, float gvec[3])`

**Description:** Update the fusion calculation with a new gyro data.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_imu_sensor_fusion_t](imu-fusion#sl-imu-sensor-fusion-t) *|[inout]|f|Pointer to the sl_imu_sensor_fusion_t object|
|float|[in]|gvec|Gyroscope vector|

###### sl_imu_fuse_gyro_clear_correction_vector

`void sl_imu_fuse_gyro_clear_correction_vector(sl_imu_sensor_fusion_t *f)`

**Description:** Clear the gyro correction vector.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_imu_sensor_fusion_t](imu-fusion#sl-imu-sensor-fusion-t) *|[inout]|f|Pointer to the sl_imu_sensor_fusion_t object|

###### sl_imu_fuse_gyro_calculate_correction_vector

`void sl_imu_fuse_gyro_calculate_correction_vector(sl_imu_sensor_fusion_t *f, bool accValid, bool dirValid, float dirZ)`

**Description:** Calculate the gyro correction vector.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_imu_sensor_fusion_t](imu-fusion#sl-imu-sensor-fusion-t) *|[inout]|f|Pointer to the sl_imu_sensor_fusion_t object|
|bool|[in]|accValid|True if the acceleration value is within limits|
|bool|[in]|dirValid|True if the direction value is valid|
|float|[in]|dirZ|The direction of the Z axis|

###### sl_imu_fuse_new

`void sl_imu_fuse_new(sl_imu_sensor_fusion_t *f)`

**Description:** Initialize a new sl_imu_sensor_fusion_t structure.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_imu_sensor_fusion_t](imu-fusion#sl-imu-sensor-fusion-t) *|[inout]|f|Pointer to the sl_imu_sensor_fusion_t object to be initialized|

###### sl_imu_fuse_reset

`void sl_imu_fuse_reset(sl_imu_sensor_fusion_t *f)`

**Description:** Clear the values of the sensor fusion object.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_imu_sensor_fusion_t](imu-fusion#sl-imu-sensor-fusion-t) *|[inout]|f|Pointer to the sl_imu_sensor_fusion_t object|

###### sl_imu_fuse_update

`void sl_imu_fuse_update(sl_imu_sensor_fusion_t *f)`

**Description:** Update the fusion calculation.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_imu_sensor_fusion_t](imu-fusion#sl-imu-sensor-fusion-t) *|[inout]|f|Pointer to the sl_imu_sensor_fusion_t object|

Structure to store the sensor fusion data. 

###### Public Attributes

###### dcm (heading level 7)

```
float sl_imu_sensor_fusion::dcm[3][3]
```

**Details:** Direction Cosine Matrix <br />

###### aVector (heading level 7)

```
float sl_imu_sensor_fusion::aVector[3]
```

**Details:** Acceleration vector <br />

###### aAccumulator (heading level 7)

```
float sl_imu_sensor_fusion::aAccumulator[3]
```

**Details:** Accumulator for acceleration vector <br />

###### aAccumulatorCount (heading level 7)

```
uint32_t sl_imu_sensor_fusion::aAccumulatorCount
```

**Details:** Number of vectors stored in the accumulator <br />

###### aSampleRate (heading level 7)

```
float sl_imu_sensor_fusion::aSampleRate
```

**Details:** Acceleration measurement sample rate <br />

###### gVector (heading level 7)

```
float sl_imu_sensor_fusion::gVector[3]
```

**Details:** Gyro vector <br />

###### gSampleRate (heading level 7)

```
float sl_imu_sensor_fusion::gSampleRate
```

**Details:** Gyroscope measurement sample rate <br />

###### gDeltaTime (heading level 7)

```
float sl_imu_sensor_fusion::gDeltaTime
```

**Details:** Time between gyro samples <br />

###### gDeltaTimeScale (heading level 7)

```
float sl_imu_sensor_fusion::gDeltaTimeScale
```

**Details:** Rotation between gyro samples <br />

###### angleCorrection (heading level 7)

```
float sl_imu_sensor_fusion::angleCorrection[3]
```

**Details:** Angle correction vector <br />

###### orientation (heading level 7)

```
float sl_imu_sensor_fusion::orientation[3]
```

**Details:** Orientation vector <br />

## Math Library API Reference

### Vector functions

#### Functions

##### sl_math_mvp_complex_vector_conjugate_f16

`sl_status_t sl_math_mvp_complex_vector_conjugate_f16(float16_t *input, float16_t *output, size_t num_elements)`

**Description:** Conjugates the elements of a complex data vector.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float16_t *|[in]|input|Input vector.|
|float16_t *|[in]|output|Output Vector.|
|size_t|[in]|num_elements|The number of complex elements in the vectors.|

Maximum vector length is 1M (2^20), and all vectors must be 4-byte aligned.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_complex_vector_dot_product_f16

`sl_status_t sl_math_mvp_complex_vector_dot_product_f16(float16_t *input_a, float16_t *input_b, size_t num_elements, float16_t *output)`

**Description:** Computes the dot product of two complex vectors. The vectors are multiplied element-by-element and then summed.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float16_t *|[in]|input_a|Input vector a.|
|float16_t *|[in]|input_b|Input vector b.|
|size_t|[in]|num_elements|The number of complex elements in the input vectors.|
|float16_t *|[out]|output|Dot product result.|

Maximum vector length is 1M (2^20), and all vectors must be 4-byte aligned.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_complex_vector_magnitude_squared_f16

`sl_status_t sl_math_mvp_complex_vector_magnitude_squared_f16(const float16_t *input, float16_t *output, size_t num_elements)`

**Description:** Computes the magnitude squared of the elements of a complex data vector.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input|Input vector.|
|float16_t *|[in]|output|Output Vector.|
|size_t|[in]|num_elements|The number of complex elements in the input vector and the number of scalar elements in the output vector.|

The input vector shall point to the source that is a vector of complex numbers and the output vector shall point to a vector where the result will be written.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_complex_vector_mult_real_f16

`sl_status_t sl_math_mvp_complex_vector_mult_real_f16(const float16_t *input_a, const float16_t *input_b, float16_t *output, size_t num_elements)`

**Description:** Multiply a vector of complex f16 by a vector of real f16.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input_a|The complex vector, input A.|
|const float16_t *|[in]|input_b|The real vector, input B.|
|float16_t *|[out]|output|The complex output vector, output Z.|
|size_t|[in]|num_elements|The number of elements in the input and output vectors.|

This function will perform the following operation: Z = A * B. Both vectors must be of same length. If both vector buffers are 4-byte aligned, the function will operate twice as fast using MVP complex processing. Maximum vector length is 1M (2^20) elements in the 4-byte aligned case, and 512K when oen or more of the complex vectors are 2-byte aligned.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_complex_vector_mult_f16

`sl_status_t sl_math_mvp_complex_vector_mult_f16(const float16_t *input_a, const float16_t *input_b, float16_t *output, size_t num_elements)`

**Description:** Multiply complex f16 vectors.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input_a|Complex input vector A.|
|const float16_t *|[in]|input_b|Complex input vector B.|
|float16_t *|[out]|output|Complex output vector.|
|size_t|[in]|num_elements|The number of complex elements in the input and output vectors.|

This function will multiply two complex vectors. It is assumed that both input vectors, and the output vector have same length. All input and output buffers must be 4-byte aligned. Maximum vector length is 1M (2^20) elements.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_abs_f16

`sl_status_t sl_math_mvp_vector_abs_f16(float16_t *input, float16_t *output, size_t num_elements)`

**Description:** Computes the absolute value of a vector on an element-by-element basis.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float16_t *|[in]|input|Input vector.|
|float16_t *|[in]|output|Output Vector.|
|size_t|[in]|num_elements|The number of elements in the vectors.|

The output vector can be the same as or differnt to the input vector. Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_add_f16

`sl_status_t sl_math_mvp_vector_add_f16(const float16_t *input_a, const float16_t *input_b, float16_t *output, size_t num_elements)`

**Description:** Add two vectors of 16 bit floats.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input_a|First input vector, input A.|
|const float16_t *|[in]|input_b|Second input vector, input B.|
|float16_t *|[out]|output|Output vector, output Z.|
|size_t|[in]|num_elements|The number of elements in the vectors.|

This function will perform the following operation: Z = A + B. All vectors must be of equal length. If all vector buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_add_i8

`sl_status_t sl_math_mvp_vector_add_i8(const int8_t *input_a, const int8_t *input_b, int8_t *output, size_t num_elements)`

**Description:** Add two vectors of signed 8 bit integers.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const int8_t *|[in]|input_a|First input vector, input A.|
|const int8_t *|[in]|input_b|Second input vector, input B.|
|int8_t *|[out]|output|Output vector, output Z.|
|size_t|[in]|num_elements|The number of elements in the vectors.|

All vectors must be of the same length. This function will perform the following operation: Z = A + B. The add operation is performing a saturation add, which means that the operation will never overflow or underflow. When adding two elements would overflow (>127) then the result will be 127. When adding two elements would underflow (<-128) then the result will be -128.

**Returns**

- SL_STATUS_OK.

##### sl_math_mvp_clamp_i8

`sl_status_t sl_math_mvp_clamp_i8(int8_t *data, size_t num_elements, int8_t min, int8_t max)`

**Description:** Clamp all signed 8 bit integers in a vector to a certain range.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|int8_t *|[inout]|data|Vector with data values.|
|size_t|[in]|num_elements|The number of elements in the vector.|
|int8_t|[in]|min|Minimum value, after operation no elements will be < min.|
|int8_t|[in]|max|Maximum value, after operation no elements will be > max.|

Given a min/max value, this function will make sure that none of the element in the input vector will be < min or > max. If any elements are < min then the value will be modified to min. If any elements are > max then value will be modified to max.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_clip_f16

`sl_status_t sl_math_mvp_vector_clip_f16(const float16_t *input, float16_t *output, float16_t low, float16_t high, size_t num_elements)`

**Description:** Element-by-element clipping of a value.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input|Input vector, input A.|
|float16_t *|[out]|output|Output vector, output Z.|
|float16_t|[in]|low|Lower bound.|
|float16_t|[in]|high|Higher bound.|
|size_t|[in]|num_elements|Length of input and output vectors.|

This function will do an element-by-element clipping of a value. The value is constrained between 2 bounds. Both vectors must be of equal length. If all vector buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_copy_f16

`sl_status_t sl_math_mvp_vector_copy_f16(const float16_t *input, float16_t *output, size_t num_elements)`

**Description:** Copy one 16 bit float vector into another.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input|Input vector, input A.|
|float16_t *|[out]|output|Output vector, output Z.|
|size_t|[in]|num_elements|Length of input and output vectors.|

This function will perform the following operation: Z = A. All vectors must be of equal length. If all vector buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_dot_product_f16

`sl_status_t sl_math_mvp_vector_dot_product_f16(const float16_t *input_a, const float16_t *input_b, size_t num_elements, float16_t *output)`

**Description:** Computes the dot product of two vectors. The vectors are multiplied element-by-element and then summed.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input_a|Input vector a.|
|const float16_t *|[in]|input_b|Input vector b.|
|size_t|[in]|num_elements|The number of elements in the input vectors.|
|float16_t *|[out]|output|The result.|

All vectors must be of equal length. If all vector buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Note**

- Depending on the function arguments, the MVP implementation can calculate the dot product in different ways that may effect the rounding errors. If the same input vectors are calculated with different memory alignmen, the results may not be identical.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_fill_f16

`sl_status_t sl_math_mvp_vector_fill_f16(float16_t *output, const float16_t value, size_t num_elements)`

**Description:** Fills a constant value into a floating-point vector.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|float16_t *|[in]|output|Vector to fill.|
|const float16_t|[in]|value|Fill value.|
|size_t|[in]|num_elements|Length of the output vector.|

Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_mult_f16

`sl_status_t sl_math_mvp_vector_mult_f16(const float16_t *input_a, const float16_t *input_b, float16_t *output, size_t num_elements)`

**Description:** Elementwise multiply two vectors of 16 bit floats.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input_a|First input vector, input A.|
|const float16_t *|[in]|input_b|Second input vector, input B.|
|float16_t *|[out]|output|Output vector, output Z.|
|size_t|[in]|num_elements|Length of all input and output vectors.|

This function will perform the following operation: Z[i] = A[i] * B[i]. All vectors must be of equal length. If all vector buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_negate_f16

`sl_status_t sl_math_mvp_vector_negate_f16(const float16_t *input, float16_t *output, size_t num_elements)`

**Description:** Negate a vector of 16 bit floats.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input|Input vector.|
|float16_t *|[out]|output|Output vector.|
|size_t|[in]|num_elements|Length of input and output vectors.|

This function will perform the following operation: Z = - A. Vectors must be of equal length. If both vector buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case. In-place negation is supported (input and output reference same buffer).

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_offset_f16

`sl_status_t sl_math_mvp_vector_offset_f16(const float16_t *input, const float16_t offset, float16_t *output, size_t num_elements)`

**Description:** Adds a constant offset to each element of a vector.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input|Input vector.|
|const float16_t|[in]|offset|Offset value.|
|float16_t *|[in]|output|Output vector.|
|size_t|[in]|num_elements|The number of elements in the input and output vectors.|

Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_scale_f16

`sl_status_t sl_math_mvp_vector_scale_f16(const float16_t *input, float16_t scale, float16_t *output, size_t num_elements)`

**Description:** Scale a vector of 16-bits floats with a float16 scale.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input|The input vector.|
|float16_t|[in]|scale|The value by which to scale the vector.|
|float16_t *|[out]|output|Output vector, output Z.|
|size_t|[in]|num_elements|Length of input and output vectors.|

This function will perform the following operation: Z[i] = A[i] * scale. All vectors must be of equal length. If all vector buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_vector_sub_f16

`sl_status_t sl_math_mvp_vector_sub_f16(const float16_t *input_a, const float16_t *input_b, float16_t *output, size_t num_elements)`

**Description:** Subtract two vectors of 16 bit floats.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const float16_t *|[in]|input_a|First input vector, input A.|
|const float16_t *|[in]|input_b|Second input vector, input B.|
|float16_t *|[out]|output|Output vector, output Z.|
|size_t|[in]|num_elements|Length of all input and output vectors.|

This function will perform the following operation: Z = A - B. All vectors must be of equal length. If all vector buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum vector length is 1M (2^20), and 2M in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

### Matrix functions

#### Functions

##### sl_math_matrix_init_f16

`void sl_math_matrix_init_f16(sl_math_matrix_f16_t *matrix, size_t num_rows, size_t num_cols, float16_t *data)`

**Description:** Matrix initialization.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|[sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|matrix|Pointer to a matrix.|
|size_t|[in]|num_rows|The number of rows in the matrix.|
|size_t|[in]|num_cols|The number of cols in the matrix.|
|float16_t *|[in]|data|A pointer to the matrix data.|

##### sl_math_mvp_complex_matrix_mult_f16

`sl_status_t sl_math_mvp_complex_matrix_mult_f16(const sl_math_matrix_f16_t *input_a, const sl_math_matrix_f16_t *input_b, sl_math_matrix_f16_t *output)`

**Description:** Multiply two matrices of complex 16 bit floats.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input_a|First input matrix, input A.|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input_b|Second input matrix, input B.|
|[sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[out]|output|Output matrix, output Z.|

The number of columns of the first matrix must be equal to the number of rows of the second matrix. Also the output matrix row count must match matrix A row count and output matrix column count must match matrix B column count. All input and output matrix data buffers must be 4-byte aligned (a complex f16 element occupies 4 bytes of storage). Maximum matrix size is 1024 x 1024 which is 1M (2^20) complex f16 elements. Maximum column and row size is 1024 elements.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_matrix_add_f16

`sl_status_t sl_math_mvp_matrix_add_f16(const sl_math_matrix_f16_t *input_a, const sl_math_matrix_f16_t *input_b, sl_math_matrix_f16_t *output)`

**Description:** Add two matrices of 16 bit floats.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input_a|First input matrix, input A.|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input_b|Second input matrix, input B.|
|[sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[out]|output|Output matrix, output Z.|

This function will perform the following operation: Z = A + B. All matrices must have equal dimensions. If all matrice buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum matrices size is 1M (2^20) elements, and 2M elements in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_matrix_mult_f16

`sl_status_t sl_math_mvp_matrix_mult_f16(const sl_math_matrix_f16_t *input_a, const sl_math_matrix_f16_t *input_b, sl_math_matrix_f16_t *output)`

**Description:** Multiply two matrices of 16 bit floats.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input_a|First input matrix, input A.|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input_b|Second input matrix, input B.|
|[sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[out]|output|Output matrix, output Z.|

This function will perform the following operation: Z = A * B (matrix multiplication). The number of columns of the first matrix must be equal to the number of rows of the second matrix. If the input is 4 bytes aligned, and the number of columns in matrix B is divisible by 2, it will be 2x faster.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_matrix_scale_f16

`sl_status_t sl_math_mvp_matrix_scale_f16(const sl_math_matrix_f16_t *input, float16_t scale, sl_math_matrix_f16_t *output)`

**Description:** Scale each element in a float16 matrix by a float16 scale.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input|Input matrix.|
|float16_t|[in]|scale|Scale value.|
|[sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[out]|output|Output matrix.|

This function will multiply each element in the input matrix by a scale, and write the result to the output matrix. The input and output matrices must be the same size. **Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_matrix_sub_f16

`sl_status_t sl_math_mvp_matrix_sub_f16(const sl_math_matrix_f16_t *input_a, const sl_math_matrix_f16_t *input_b, sl_math_matrix_f16_t *output)`

**Description:** Subtract two matrices of 16 bit floats.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input_a|First input matrix, input A.|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input_b|Second input matrix, input B.|
|[sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[out]|output|Output matrix, output Z.|

This function will perform the following operation: Z = A - B. All matrices must have equal dimensions. If all matrice buffers are 4-byte aligned, the function will operate twice as fast using MVP parallel processing. Maximum matrices size is 1M (2^20) elements, and 2M elements in the 4-byte aligned case.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_matrix_transpose_f16

`sl_status_t sl_math_mvp_matrix_transpose_f16(const sl_math_matrix_f16_t *input, sl_math_matrix_f16_t *output)`

**Description:** Transpose a matrix.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input|Input matrix.|
|[sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[out]|output|output matrix.|

This function will fill the output matrix with the transposed version of the input matrix. The maximum value for the rows and cols argument is 1024.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_complex_matrix_transpose_f16

`sl_status_t sl_math_mvp_complex_matrix_transpose_f16(const sl_math_matrix_f16_t *input, sl_math_matrix_f16_t *output)`

**Description:** Transpose a complex f16 matrix.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input|Input matrix.|
|[sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[out]|output|output matrix.|

This function will fill the output matrix with the transposed version of the input matrix. The maximum value for the rows and cols argument is 1024. Matrix input and output data buffers must be 4-byte aligned.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

##### sl_math_mvp_matrix_vector_mult_f16

`sl_status_t sl_math_mvp_matrix_vector_mult_f16(const sl_math_matrix_f16_t *input_a, const float16_t *input_b, float16_t *output)`

**Description:** Multiply a matrix with a vector, both of 16 bit floats.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|const [sl_math_matrix_f16_t](sl-math-matrix-f16-t) *|[in]|input_a|The input matrix.|
|const float16_t *|[in]|input_b|The input vector.|
|float16_t *|[out]|output|The output vector.|

This function will perform the following operation: Z = A * b (matrix vector multiplication). The vector must be equal in length to the number of columns in matrix A. The output vector will be equal in length to the number of rows in matrix A.

**Returns**

- SL_STATUS_OK on success. On failure, an appropriate sl_status_t errorcode is returned.

### Utility functions

#### Functions

##### sl_math_mvp_clear_errors

`void sl_math_mvp_clear_errors(void)`

**Description:** Clear all Math exception and fault flags.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|void|N/A|undefined||

##### sl_math_mvp_get_error

`sl_status_t sl_math_mvp_get_error(sl_status_t *error_code, char *error_message, uint32_t buffer_length)`

**Description:** Get a Math exception or fault errorcode and optional descriptive error message.

**Parameters:**

|Type|Direction|Argument Name|Description|
|----|---------|-------------|-----------|
|sl_status_t *|[out]|error_code|The assigned sl_status_t errorcode.|
|char *|[inout]|error_message|A descriptive error message string. Input a NULL pointer to skip the error message.|
|uint32_t|[in]|buffer_length|The size of the error_message buffer.|

Intended use of this function is to call it repeatedly to iterate over existing errors and get errorcodes and optional error message strings.

**Returns**

- Return SL_STATUS_OK when an error is present, this indicates that error_code and optionally error_message output parameters are valid. Return SL_STATUS_NOT_FOUND when no error to report.

### MVP Math Library API

#### Introduction

Some of the Silicon Labs parts have included what is called the **Matrix Vector Processor (MVP)**. The MVP is a hardware accelerator designed to execute certain operations faster than the CPU. In particular, vector and matrix operatons are usually good candidates for acceleration. The purpose with this math library is to offer functions that utilize the MVP to speed up the operations.

The MVP supports 8 bit integers and 16 bit floating point numbers, and this library contains only functions that can be accelerated on the MVP.

Similar or identical functions can be found in the [ARM CMSIS-DSP](https://www.keil.com/pack/doc/CMSIS/DSP/html/index.html) library.

For more information on the MVP hardware, please refer to the reference manual for the actual part.

#### Memory alignment

The MVP will read and write to the system memory without using the CPU. When using 16-bit floating point variables, there are certain rules to follow:

- Scalar variables (single 16-bit values) must be aligned to an even address; 0, 2, 4, etc.
- Complex variables (double 16-bit values) must be aligned to a 4-byte word address; 0, 4, 8, etc.

---

**NOTE:**

If functions that are working on scalar values get 4-byte word addresses for all of the function arguments, it will in many cases be able to process two values per cycle. That will nearly double the speed of the operation, and is highly recommended.

---

#### Using the library

The library is delivered as source code. It can easily be used by including the `math_mvp` component to the project and just calling the functions.

The library requires that the MVP driver has been initialized by calling the `sli_mvp_init()` function. If the project has included the `sl_system`, this function will be called automatically, else it is to be called by the user application before any of the other mvp math functions are used.

The library is divided into a number of functions in one of the categories:

- Matrix functions
- Vector functions

Each of the library functions has a separate header file, but for convenience, the `sl_math_mvp.h` file contains everything the application needs to use the library.

```c
#include "sl_math_mvp.h"

static float16_t input_a[256] SL_ATTRIBUTE_ALIGN(4);
static float16_t input_b[256] SL_ATTRIBUTE_ALIGN(4);
static float16_t output[256] SL_ATTRIBUTE_ALIGN(4);

void example()
{
  sl_status_t status;
  status = sl_math_mvp_vector_fill_f16(input_a, 1.0f, 6);
  ...
  status = sl_math_mvp_vector_add_f16(input_a, input_b, output, 6);
  ...
  sl_math_matrix_init_f16(&matrix_a, 3, 4, input_a);
  sl_math_matrix_init_f16(&matrix_b, 4, 3, input_b);
  sl_math_matrix_init_f16(&matrix_z, 3, 3, output);
  status = sl_math_mvp_matrix_mult_f16(&matrix_a, &matrix_b, &matrix_z);
  ...
}

```

Please take a look at the `math_mvp_demo` example in the Simplicity SDK. It shows various examples of how to use the functions.

#### Error handling

In general all math functions in the library will return one of these codes defined in `sl_status.h`:

```c
#define SL_STATUS_OK                 ((sl_status_t)0x0000)  // No error.
#define SL_STATUS_FAIL               ((sl_status_t)0x0001)  // Generic error.
#define SL_STATUS_INVALID_PARAMETER  ((sl_status_t)0x0021)  // Generic invalid argument or consequence of invalid argument.

```

`SL_STATUS_INVALID_PARAMETER` is returned when the call was made with invalid input parameters.

`SL_STATUS_FAIL`is returned when execution on the MVP processor led to unrecoverable errors.

`SL_STATUS_OK` is returned when MVP program execution succeeded. In this case execution may have generated math exceptions such as overflow, underflow or inifinty etc.

An MVP program can produce these errors/exceptions:

```c
#define SL_STATUS_COMPUTE_MATH_FAULT       ((sl_status_t)0x1511)   // MATH Critical fault
#define SL_STATUS_COMPUTE_MATH_NAN         ((sl_status_t)0x1512)   // MATH NaN encountered
#define SL_STATUS_COMPUTE_MATH_INFINITY    ((sl_status_t)0x1513)   // MATH Infinity encountered
#define SL_STATUS_COMPUTE_MATH_OVERFLOW    ((sl_status_t)0x1514)   // MATH numeric overflow
#define SL_STATUS_COMPUTE_MATH_UNDERFLOW   ((sl_status_t)0x1515)   // MATH numeric underflow

```

To investigate which (if any) math exceptions occured use:

```c
sl_status_t sl_math_mvp_get_error(sl_status_t *error_code, char *error_message, uint32_t buffer_length);

```

As several exception may be present, you can call this function repeatedly to retrieve error codes. The function will return `SL_STATUS_OK` when a valid error code is returned via `*error_code`, until `SL_STATUS_NOT_FOUND` is returned.

```c
void example()
{
  sl_status_t error_code;

  while (sl_math_mvp_get_error(&error_code, NULL, 0) == SL_STATUS_OK) {
    printf("Error code is: %X\n", error_code);
  }
}

```

If you add the `status_string` component to your application, the error function will also return descriptive error strings for the different exceptions. This might be handy for debugging.

```c
void example()
{
  char error_string[100];
  sl_status_t error_code;

  while (sl_math_mvp_get_error(&error_code, error_string, sizeof(error_string)) == SL_STATUS_OK) {
    printf("Error code / message is: %X / %s\n", error_code, error_string);
  }
}

```

---

**NOTE:**

Errors and exceptions will accumulate across calls of MVP Math functions. This means that in many cases it will be sufficient to check for errors/exceptions after a sequence of MVP Math functions have been executed. The following function is handy to make sure all errors/exceptions are cleared before commencing on a long sequence of MVP Math function calls:

```c
void sl_math_mvp_clear_errors(void);

```

---

## Additional Topics

### Third Party Tooling and Partner Solutions

#### Tooling

##### TensorFlow

The SiSDK supports TensorFlow Lite for Microcontrollers (TFLM) [natively](/machine-learning/3.0.0/aiml-fundamentals). The developer can create a quantized
`.tflite` model file using the TensorFlow environment directly and integrate it into the GDSK.

###### Getting Started

- [Developing a Model Using TensorFlow and Keras](/machine-learning/3.0.0/aiml-developers-guide/developing-a-model#developing-a-model-manually-using-tensor-flow-and-keras)

##### Silicon Labs Machine Learning Toolkit (MLTK) (Deprecated)

The Machine Learning Toolkit ([MLTK](https://siliconlabs.github.io/mltk)) was created for these [reasons](https://siliconlabs.github.io/mltk/docs/why_mltk.html) to help the Tensorflow developer. It is a set of python scripts designed to follow the typical machine learning workflow for Silicon Labs embedded devices.

> **Note**:
> 
> - This package is made available as an open source, self-serve, community supported, reference package with a comprehensive set of online documentation. There are no Silicon Labs support services for this software at this time.
> - These scripts are a reference implementations for the use case covered by the documented [tutorials](https://siliconlabs.github.io/mltk/docs/tutorials.html). Support for other use cases is the responsibility of the developer.

###### Getting Started

- [Create a Keyword Spotting Model](https://siliconlabs.github.io/mltk/mltk/tutorials/keyword_spotting_on_off.html) for an SiSDK example. (GitHub.io) - MLTK Tutorial

##### Integrating the Model

The trained model, whether using TensorFlow directly or the MLTK, is represented in a `.tflite` file. To add the `.tflite` file to your embedded application, see [developing an inference application](/machine-learning/3.0.0/aiml-getting-started/index#developing-an-inference-application-using-simplicity-studio-si-sdk-and-aiml-extension).

There are several SiSDK examples that include machine learning and show how to run inference using pre-trained models. The pre-trained models can be replaced with a model trained from one of the methods above.

###### Getting Started

- Start with any one of these [Sample Applications](/machine-learning/3.0.0/aiml-sample-apps) that are provided with the SiSDK.

#### Partner Toolchains

These tools curate the end-to-end workflow for creating a machine learning application specific model and accompanying embedded software to include in your application.

They offer:

- An end-to-end coverage of the machine learning workflow
- An easy-to-follow developer experience
- Extra value added features like AutoML, or object detection

Requires:

- Understanding of machine learning concepts (date collection, training, verification, inference, confusion matrix, etc.).
- Ability to collect data that represents the real world scenarios for your product deployment.

The following tools fit well with developing ML as a feature for a Silicon Labs-based embedded application.

##### Edge Impulse

[Edge Impulse](https://www.silabs.com/partner-network/technology-partners/partner.edge-impulse) is ushering in the future of embedded machine learning by empowering developers to create and optimize solutions with real-world data. They are making the process of building, deploying, and scaling embedded ML applications easier and faster than ever, unlocking massive value across every industry, with millions of developers making billions of devices smarter.

###### Getting Started

[Using Edge Impulse Studio with the xG24 Dev Kit](https://docs.edgeimpulse.com/docs/development-boards/silabs-xg24-devkit)

##### SensiML

[SensiML](https://www.silabs.com/partner-network/technology-partners/partner.sensiml) offers cutting edge AutoML embedded code generation software for implementing AI at the IoT edge. With SensiML Analytics Toolkit, developers have an AI development tool which supports rapid data collection, labeling, feature extraction, ML classification and optimized firmware code generation. Automation built into the tool drastically reduces development time and cost, allowing projects ranging from single users to large teams to generate optimized edge AI sensor algorithms in a fraction of the time that would have otherwise been required with hand coding.

###### Getting Started

[Using SensiML Analytics Toolkit with the xG24 Dev Kit](https://sensiml.com/documentation/firmware/silicon-labs-xg24/silicon-labs-xg24.html)

##### Micro.AI

[MicroAI](https://www.silabs.com/partner-network/technology-partners/partner.microai)'s AtomML is an Edge-native, self-correcting, semi-supervised learning engine that aggregates data from internal device sensors, to tune itself to create a behavioral profile of the asset, which then detects and acts upon abnormal behavior. AtomML brings big infrastructure intelligence into a single piece of equipment or device. Unlike traditional AI-driven asset management solutions that rely on the cloud, AtomML is deployed directly to smart devices and sensors. AtomML operates within the small environment of the device itself, providing a more efficient method for asset analytics and generating real-time alerts. AtomML brings an intimate, local approach to asset management for producing a host of operational efficiencies.

###### Getting Started

[Using MicroAI AtomML with the xG24 Dev Kit](https://www.micro.ai/silabs/)

#### Partner Solutions

These tools do not require any knowledge of machine learning to take full advantage of their features. They are designed for specific use cases.

##### Wake-word/Voice Commands

[Sensory](https://www.silabs.com/partner-network/technology-partners/partner.sensory) creates a safer and superior UX through vision and voice technologies. Sensory technologies are widely deployed in consumer electronics applications including mobile phones, automotive, wearables, toys, IoT, PCs, medical products, and various home electronics. Sensory’s product line includes TrulyHandsfree voice control, TrulySecure biometric authentication, and TrulyNatural large vocabulary natural language embedded speech recognition. Sensory’s technologies have shipped in over three billion units of leading consumer products.

###### Getting Started

[Using Sensory Truly Hands Free with the xG24 Dev Kit](https://github.com/SiliconLabs/machine_learning_applications/tree/main/application/voice/sensory_wakeupword)

#### Choosing a Machine Learning Tool Based on Use Case

This section provides getting started links for tools available or suggested, based on use case. The links provided include examples, demos, and tutorials.

##### Sensor Signal Processing

Sensor signal processing is the use of low data rate sensors, like accelerometers, gyroscopes, air quality sensors, temperature sensors, pressure sensors, and so on.
These use cases can be found in many types of markets, such as preventive maintenance, medical devices, or smoke detectors.

- [TensorFlow Magic Wand Example](/machine-learning/3.0.0/aiml-additional-topics/sample-apps#tensor-flow-lite-micro-magic-wand): SiSDK Platform Example
- [Predictive Maintenance Tutorial (PDF)](https://www.silabs.com/documents/public/training/works-with/eml-301-lab-procedure-maunal.pdf)
- [Air Quality Anomaly Detection Demo](https://www.youtube.com/watch?v=3KDq0Oi3nk8&t=4s): Micro.ai Demo (video 1.5 min)
- [BLE PowerPoint Gesture Controller Demo](https://www.youtube.com/watch?v=l1DmYCVpGHk): Neuton Demo (video 3 min)
- [Smartwatch Touch Free Control](https://www.youtube.com/watch?v=JS4gJ9JtxO8): Neuton Demo (video 1 min)
- [Package Condition Monitoring](https://www.youtube.com/watch?v=GaoBkeb2y48): Neuton Demo (video 2.5 min)

##### Audio Pattern Matching

Audio pattern matching uses a microphone to detect different sounds. The types of sounds detected can be a wide range of non-speech related sounds, such as squeaky bearings, jingling keys, breaking glass, water running, animal sounds, and so on.

- [Creating an Acoustic Smart Home Door Lock Demo](https://sensiml.com/blog/creating-an-acoustic-smarthome-sensor-with-silabs-xg24-platform/): SensiML Tutorial (5 part blog)
- [Introduction to Building an Audio Classifier Demo](https://youtu.be/ssGfdiam9BY): Edge Impulse Tutorial Introduction (video 10 min)
- [Industrial Predictive Maintenance](https://youtu.be/hhJN1r-sAgg): Edge Impulse Tutorial (video 70 min), with [pre-work instructions (PDF), start on page 12](https://www.silabs.com/documents/public/training/works-with/works-with-2021-pre-work-and-installation-instructions.pdf)
- [Audio classifier Example](https://siliconlabs.github.io/mltk/docs/cpp_development/examples/audio_classifier.html): MLTK Example

##### Voice Command

Voice commands is a specific subset of audio patterns that are the recognition of a small set of spoken words. This is also referred to as keyword spotting. It can be used in a variety of use cases, such as waking up a voice service (i.e., Alexa), or using voice activation for smart home devices or appliances.

- [Zigbee Voice Controlled Light Switch Example](/machine-learning/3.0.0/aiml-additional-topics/sample-apps#z3-switch-with-voice): SiSDK Zigbee Example
- [Voice Controlled LED Example](/machine-learning/3.0.0/aiml-additional-topics/sample-apps#voice-control-light): SiSDK Platform Example
- [Create a Voice Command Model for a SiSDK Example](https://siliconlabs.github.io/mltk/mltk/tutorials/keyword_spotting_on_off.html): MLTK Tutorial  
  - This tutorial can be used for either example above to create a model (i.e., `.tflite` file).
- [Building a Voice Recognition Demo](https://www.silabs.com/support/training/intro-machine-learning-with-edge-impulse/intro-machine-learning-with-edge-impulse-presentation): Edge Impulse Tutorial (video 90 min)
- [Voice Command/Wake-word Example](https://github.com/SiliconLabs/machine_learning_applications/tree/main/application/voice/sensory_wakeupword): Sensory Truly Hands Free Example

##### Low-Resolution Vision

Low resolution vision uses a camera with resolution around 100x100 to detect objects for presence detection, people counting, video wake-up or more.

- [People Flow and Counting Example](https://github.com/SiliconLabs/machine_learning_applications/tree/main/application/vision/people_flow_counter_mlx90640): SiSDK Platform Example
- [People Counting Demo](https://docs.edgeimpulse.com/docs/tutorials/hardware-specific-tutorials/object-detection-xg24-devkit): Edge Impulse Example
- [Build a Rock, Paper, Scissors Detector Demo](https://siliconlabs.github.io/mltk/mltk/tutorials/image_classification.html): MLTK Tutorial
- [Build a Fingerprint Authenticator Demo](https://siliconlabs.github.io/mltk/mltk/tutorials/fingerprint_authentication.html): MLTK Tutorial

#### Summary of Machine Learning Tools

Below is a table that summarizes our different tool options organized by developer skills and target use cases.

![ML Tools by skill and use case](/aiml-additional-topics/3.0.0/images/ml-tool-table.png)

### Sample Applications

#### Sample Applications Overview

The following applications demonstrate the use of the TensorFlow Lite for Microcontrollers framework
with the Simplicity SDK.

##### Voice Control Light

This application demonstrates a neural network with TensorFlow Lite for Microcontrollers to
detect the spoken words "on" and "off" from audio data recorded on the microphone in
a Micrium OS kernel task.

The detected keywords are used to control an LED on the board. The audio data is sampled
continuously and preprocessed using the Audio Feature Generator component. Inference is
run every 200 ms on the past ~1 s of audio data.

This sample application uses the [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion)
to add the .tflite file to the application binary.

##### Z3SwitchWithVoice

This application combines voice detection with Zigbee 3.0 to create a voice-controlled
switch node that can be used to toggle a light node. The application uses the same
model as Voice Control Light to detect the spoken keywords "on" and "off". Upon detection,
the switch node sends On/Off commands over the Zigbee network.

This sample application uses the [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion)
to add the .tflite file to the application binary.

##### TensorFlow Lite Micro - Hello World

This application demonstrates a model trained to replicate a sine function and
use the inference results to fade an LED. The application is originally written
by TensorFlow, but has been ported to the Simplicity SDK.

The model is approximately 2.5 KB. The entire application takes around
157 KB flash and 15 KB RAM. This application uses large amounts of flash memory
because it does not manually specify which operations are used in the model and,
as a result, compiles all kernel implementations.

The application illustrates a minimal inference application and serves as a good
starting point for understanding the TensorFlow Lite for Microcontrollers
model interpretation flow.

This sample application uses a fixed model contained in `hello_world_model_data.cc`.

##### TensorFlow Lite Micro - Micro Speech

This application demonstrates a 20 KB model trained to detect simple words from
speech data recorded from a microphone. The application is originally written by
TensorFlow, but has been ported to the Simplicity SDK.

This application uses around 100 KB flash and 37 KB of RAM. Around 10 KB of the RAM
usage is related to FFT frontend and to store audio data.
With a clock speed of 38.4 MHz and using the optimized kernel implementations, the
inference time on ~1 s of audio data is approximately 111 ms.

This application illustrates the process of generating features from audio data
and doing detections in real time. It also demonstrates how to manually specify
which operations are used in the network, which saves a significant amount of flash.

This sample application uses a fixed model contained in `micro_speech_model_data.cc`.

##### TensorFlow Lite Micro - Magic Wand

This application demonstrates a 10 KB model trained to recognize various hand gestures
using an accelerometer to detect the motion. The detected gestures are printed to
the serial port. The application is originally written by
TensorFlow, but has been ported to the Simplicity SDK.

This application uses around 104 KB flash and 25 KB of RAM. This application demonstrates
how to use accelerometer data as inference input and also shows how to manually specify
which operations are used in the network, which saves a significant amount of flash.

This sample application uses the [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion)
to add the .tflite file to the application binary.

##### TensorFlow Model Profiler

This application is designed to profile a TensorFlow Lite Micro model on Silicon
Labs hardware. The model used by the application is provided by a TensorFlow
Lite flatbuffer file called model.tflite in the config/tflite subdirectory. The
profiler will measure the number of CPU clock cycles and elapsed time in each
layer of the model when performing an inference. It will also produce a summary
when inference is done. The input layer of the model is filled with all zeroes
before performing a single inference. Profiling results are transmitted over
VCOM.

To run the application with a different .tflite model, you can
replace the file called model.tflite with a new TensorFlow Lite Micro flatbuffer
file. This new file must also be called "model.tflite" and be placed inside the
config/tflite subdirectory to be picked up by the sample application.
After the model has been replaced, regenerate the project.

To load and perform inference on a TensorFlow Lite Micro model,
allocate a number of bytes to a "tensor arena" to hold state needed
by the TensorFlow Lite Micro. The size of this tensor arena depends on the size of
the model and the number of operators. The TensorFlow Model Profiler
application can be used to measure the amount of RAM needed by the tensor arena
to load the specific TensorFlow Lite Micro model. This is measured by
dynamically allocating RAM for the tensor arena and reporting the number of
bytes needed on VCOM. The number of bytes needed for the tensor arena can later
be used to statically allocate memory when the model is used in a different
application.

This sample application uses the [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion)
to add the .tflite file to the application binary.

##### Rock-Paper-Scissors (Image Classification)

Image classification is one of the most important applications of deep learning and
Artificial Intelligence. Image classification refers to assigning labels to images
based on certain characteristics or features present in them. The algorithm identifies
these features and uses them to differentiate between different images and assign labels to them.

This application uses TensorFlow Lite for Microcontrollers to run image
classification machine learning models to classify hand gestures from image data
captured from [ArduCAM](https://www.arducam.com/product/arducam-2mp-spi-camera-b0067-arduino/) camera. The detection is visualized using the LED's on the
board and the classification results are written to the VCOM serial port.

For more information, refer to the [Image Classifier documentation](image-classifier).

##### Wi-Fi Voice Control Light

This FreeRTOS example on SiWG917 runs TensorFlow Lite for Microcontrollers keyword spotting for on and off, drives a local LED, logs to VCOM, and sends UDP notifications on the WLAN. The SoC runs as a Wi-Fi access point.

For more information, refer to the [Wi-Fi Voice Control Light documentation](wifi-voice-control).

A second board on the same network can listen for those UDP packets (no ML on the receiver) and map ON / OFF to a status LED—for example blue when on and off when off.
This board acts as a station (STA) which connects to the access point created by the [Wi-Fi Voice Control Light documentation](wifi-voice-control).
This acts as a companion app to the above [Wi-Fi Voice Control Light documentation](wifi-voice-control).

For more information, refer to the [Wi-Fi UDP LED receiver documentation](wifi-udp-led-receiver).

##### Voice Control Light with Blink (multiple-model)

Concurrent and sequential sample applications are available for EFR32 and SiWG917. Each combines keyword spotting (`kws`) for voice commands with a model to blink an LED in a sine wave pattern (`blink`). When **"on"** is detected, the blink model drives the LED; when **"off"** is detected, the LED turns off.

- **Concurrent:** Both models are initialized at startup and remain loaded in RAM. The application runs keyword spotting and blink inference as needed without unloading either model.
- **Sequential:** Only one model is loaded at a time. The application swaps between keyword spotting and the blink model to reduce RAM usage.

#### Image Classifier

Image classification is one of the most important applications of deep learning and
Artificial Intelligence. Image classification refers to assigning labels to images
based on certain characteristics or features present in them. The algorithm identifies
these features and uses them to differentiate between different images and assign labels to them.

This application uses TensorFlow Lite for Microcontrollers to run image
classification machine learning models to classify hand gestures from image data
captured from [ArduCAM](https://www.arducam.com/product/arducam-2mp-spi-camera-b0067-arduino/) camera. The detection is visualized using the LED's on the
board and the classification results are written to the VCOM serial port.

This sample application uses the [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion)
to add the .tflite file to the application binary.

##### Class Labels

- rock: Images of a person’s hand making a “rock” gesture
- paper: Images of a person’s hand making a “paper” gesture
- scissors: Images of a person’s hand making a “scissors” gesture
- unknown: Random images not containing any of the above

Following figure describes class labels with respect to hand pose.

![HandImage](/aiml-sample-apps/3.0.0/images/rock-paper-scissor-overview.png)

##### Required Hardware and Setup

- Silicon Labs EFR series boards BRD2601B or BRD2608A.
- Berg Strip Connectors with Jumper wires ( minimum 8 count) any one of following combination.  
  - Male-Berg strip with female to female jumper wires.  
  - Female-Berg strip with male to female jumper wires.
- [ArduCAM](https://www.arducam.com/product/arducam-2mp-spi-camera-b0067-arduino/) camera module.

###### Pin Configuration

Following table shows pin connections between [ArduCAM](https://www.arducam.com/product/arducam-2mp-spi-camera-b0067-arduino/) and Development kit.

|ArduCAM Pin|Board Expansion Header Pin|
|---|---|
|GND|1|
|VCC|18|
|CS|10|
|MOSI|4|
|MISO|6|
|SCK|8|
|SDA|16|
|SCL|15|

##### Required Software

- Simplicity studio v5 with  
  - simplicity_sdk  
  - aiml-extension

##### Dumping Images to PC

This application uses JLink to stream image data to a Python script located at aiml-extension/tools/image-visualization. To get started, refer to the instructions provided in the readme.md file. Once the application binary is flashed onto the development board, you can launch the visualization tool to view incoming image streams and optionally save them to your local PC.

##### Application Notes

- Camera Input: This application utilizes images captured using an [ArduCAM](https://www.arducam.com/product/arducam-2mp-spi-camera-b0067-arduino/) camera.
- Lighting Conditions: The model was trained on well-lit images. To achieve optimal results, conduct experiments in good lighting. Adjust the SL_ML_IMAGE_MEAN_THRESHOLD parameter in the .slcp configuration file to set the minimum mean intensity required for image processing.
- Recommended Distance: Maintain approximately 0.5 meters between the camera and the subject’s hand during experimentation.
- Background Setup: Use a plain background (preferably white or black) to improve detection accuracy and consistency.

##### Convolutional Neural Networks

The type of machine learning model used in this application is Convolutional Neural Network (CNN).

A Convolutional Neural Network (ConvNet/CNN) is a Deep Learning algorithm which can take in an
input image, assign importance (learnable weights and biases) to various aspects/objects in the
image and be able to differentiate one from the other.

A typical CNN can be visualized as follows:

![Convolution Neural Networks](/aiml-sample-apps/3.0.0/images/cnn.png)

A typical CNN is comprised of multiple layers. A given layer is basically a mathematical operation
that operates on multi-dimensional arrays (a.k.a tensors). The layers of a CNN can be split into two core phases:

- Feature Learning: This uses Convolutional layers to extract “features” from the input image
- Classification: This takes the flatten “feature vector” from the feature learning layers and uses “fully connected” layer(s) to make a prediction on which class the input image belongs

##### Deep Learning Pipeline

A deep learning pipeline typically consists of three primary stages: dataset collection, model training, and inference as follows.

![Machine learning](/aiml-sample-apps/3.0.0/images/aiml-pipeline.png)

Some sample data used for training the model in this application is illustrated in the figure below.

![Machine learning](/aiml-sample-apps/3.0.0/images/rock-paper-scissor-dataset.png)

##### Data Preprocessing

The preprocessing stage involves specific data normalization settings, managed by the ml_image_feature_generation component.

samplewise_center = True
samplewise_std_normalization = True

norm_img = (img - mean(img)) / std(img)

These settings normalize each input image individually using the formula. This helps to ensure the model is not as dependent on camera and lighting variations.

##### Model Details

The model summary presents detailed information about each layer along with the number of parameters involved. This breakdown outlines the architecture used to perform image classification task.

![Machine learning](/aiml-sample-apps/3.0.0/images/rock-paper-scissor-model-summary.png)

##### Model Evaluation

The fundamental approach to model evaluation involves feeding test samples—new, unseen data not used during training—into the model and comparing its predictions against the actual expected values. If every prediction is correct, the model achieves 100% accuracy; each incorrect prediction lowers the overall accuracy.

The figure below illustrates key performance indicators (KPIs) achieved using the Rock-Paper-Scissors dataset, including:

Accuracy: Proportion of correct predictions over total predictions
ROC Curve: Graphical representation of true positive rate vs. false positive rate
Recall: Measure of the model’s ability to identify all relevant instances
Precision: Proportion of true positives among all predicted positives

![Machine learning](/aiml-sample-apps/3.0.0/images/rock-paper-scissor-evaluation.png)

Overall accuracy: 95.037%
Class accuracies:

- paper = 98.394%
- scissor = 97.500%
- rock = 92.476%
- unknown = 92.083%  
  Average ROC AUC: 98.664%  
  Class ROC AUC:
- paper = 99.461%
- unknown = 99.042%
- scissor = 98.554%
- rock = 97.600%

#### Wi-Fi Voice Control Light (SiWG917, FreeRTOS)

This application uses TensorFlow Lite for Microcontrollers on SiWG917 under FreeRTOS with the WiseConnect Wi-Fi stack. It detects the spoken words on and off from microphone audio—the same Voice Control Light style pipeline as the bare-metal SiWG917 example—and uses detections to drive LED0, print on VCOM, and send UDP notifications to a host on the WLAN. The SoC boots as a Wi-Fi access point on 2.4 GHz with an on-device DHCPv4 server. Clients join using the AP SSID and passphrase defined in the project `.slcp` file. At least one client must associate before the ML loop starts.

This sample application uses the [Flatbuffer Converter Tool](/machine-learning/3.0.0/aiml-developers-guide/flatbuffer-conversion)
to add the `.tflite` file to the application binary.

##### Command labels

- on: Spoken command to turn the indication LED on (and notify over UDP).
- off: Spoken command to turn the indication LED off (and notify over UDP).
- Other labels (background / non-command) are handled in firmware so spurious speech does not constantly toggle the LED; see the example `readme.md` for behavior aligned with the Voice Control Light family.

![Wi-Fi voice control overview](/aiml-sample-apps/3.0.0/images/wifi-voice-control-overview.png)

##### References

The AI/ML Sample Apps package readme summarizes all examples and where to read more. In short:

- Per-application behavior, model file location, and Wi-Fi vs bare-metal differences: see `readme.md` inside the example folder `aiml_wifi_soc_voice_control_light_siwg917_rtos/`.
- Sample applications list on the web: [Silicon Labs Sample Applications](https://docs.silabs.com/machine-learning/latest/aiml-sample-apps/).
- Developing ML applications: see `aiml/README.md` in the AI/ML extension tree (sibling of the `aiml_app` sources in the packaged extension) and [Machine Learning developer documentation](https://docs.silabs.com/machine-learning/latest).

This Wi-Fi example is grouped under Wireless Integration in that readme: FreeRTOS application with WiseConnect Wi-Fi plus TFL-M voice control for an LED; platform SiWG917 (FreeRTOS), for example BRD2605A.

Install Simplicity Studio 6 with Simplicity SDK, the Silicon Labs Machine Learning (aiml) extension, and WiseConnect. Use versions compatible with the AI/ML extension release you are using.

##### Important steps

1. In Simplicity Studio, create a project from the example AI/ML - SoC Wi-Fi Voice Control Light for SiWG917 (FreeRTOS) (`aiml_wifi_soc_voice_control_light_siwg917_rtos`) and select a supported board (for example BRD2605A).
2. Configure the Wi-Fi access point using the AP SSID, passphrase, channel, and region in the project `.slcp` file and related project settings. Adjust values as needed, per [WiseConnect documentation](https://docs.silabs.com/wiseconnect/latest/).
3. Set `SERVER_IP` and `SERVER_PORT` in `app.c` to match whichever associated device will run `udp_listener.py` on the AP subnet (defaults are in the example `readme.md` and in the Network defaults table below), then flash the firmware.
4. Connect VCOM with a serial terminal to watch AP bring-up, waiting for client, association, and detections.
5. Join the SoC access point from a Wi-Fi client; after association and DHCP, the keyword loop runs—speak on and off toward the microphone and confirm LED0, VCOM, and UDP output.
6. For memory configuration (`si91x_mem_config_3`), NWP firmware load, and differences from the bare-metal Voice Control Light example, follow the Differences from the Baremetal Voice Control Light Example section in the example `readme.md`.

##### Required Hardware and Setup

- Silicon Labs SiWG917 development kit, for example BRD2605A (see the AI/ML extension template board list for other supported boards).
- USB cable for flash / debug and VCOM serial log output.
- At least one Wi-Fi capable device to join the SoC access point (required: inference starts only after a client connects). Use the AP SSID and passphrase from the project `.slcp` file when associating.
- Any associated device on the AP that can run `udp_listener.py` (for example a laptop, single-board computer, or another host with Python 3), if you want to see UDP payloads. It does not have to be a PC, and it can be the same device that joined the AP or a different one on the same subnet.

###### Network defaults (firmware)

|Setting|Default (in `app.c`)|Notes|
|---|---|---|
|`SERVER_IP`|`192.168.10.11`|Use this (or your chosen value) on the machine running `udp_listener.py` on the AP subnet.|
|`SERVER_PORT`|`5000`|Must match `udp_listener.py`. Do not wrap with `htons()` unless you align the full Si91x BSD socket usage.|
|AP SSID / passphrase|From the project `.slcp` file|Use these values when associating your Wi-Fi client unless you change them and reflash the firmware.|

##### Required Software

- Python 3 (standard library only) for `udp_listener.py`

##### Receiving keyword events over UDP

After flashing, open a serial terminal on the board VCOM port to see AP bring-up, the printed AP IPv4 address, waiting for client, association events, and detections.

Join the SoC access point from a Wi-Fi client using the SSID and passphrase from the project `.slcp` file. On whichever device on the AP should receive UDP messages (not necessarily a PC), set a static IPv4 address consistent with your AP subnet and matching `SERVER_IP` (or change `SERVER_IP` and reflash). From a copy of the example sources on that device, run:

```c
python3 udp_listener.py
```

The script listens on UDP port 5000 and prints each payload.

##### Application Notes

- Wi-Fi gating: The application waits for a Wi-Fi client connected event, then a short delay for DHCP, before `ml_init` and the `voice_task` keyword loop. If no client joins, VCOM repeats waiting for client and ML does not start.
- Acoustic environment: Voice commands work best in a quiet room with an unobstructed microphone path.
- Firmware details: NWP load, memory split, and model file handling are described in the example `readme.md`; defer to that file rather than duplicating model internals here.

![Wi-Fi plus keyword spotting runtime](/aiml-sample-apps/3.0.0/images/wifi-voice-ml-wifi-runtime.png)

#### Wi-Fi UDP LED Receiver (companion to Wi-Fi Voice Control Light)

This application runs on a second development board on the same Wi-Fi network as the [Wi-Fi Voice Control Light (SiWG917, FreeRTOS)](wifi-voice-control) example. It receives UDP packets that the voice application sends after keyword detections and drives a status LED from the payload:

- ON → the board turns the LED on (for example solid blue).
- OFF → the LED is turned off.

##### References

The AI/ML Sample Apps package readme summarizes all examples and where to read more. In short:

- Per-application behavior, model file location, and Wi-Fi vs bare-metal differences: see `readme.md` inside the example folder `aiml_wifi_soc_voice_control_light_siwg917_rtos/`.
- Sample applications list on the web: [Silicon Labs Sample Applications](https://docs.silabs.com/machine-learning/latest/aiml-sample-apps/).
- Developing ML applications: see `aiml/README.md` in the AI/ML extension tree (sibling of the `aiml_app` sources in the packaged extension) and [Machine Learning developer documentation](https://docs.silabs.com/machine-learning/latest).

This Wi-Fi example is grouped under Wireless Integration in that readme: FreeRTOS application with WiseConnect Wi-Fi plus TFL-M voice control for an LED; platform SiWG917 (FreeRTOS), for example BRD2605A.

Install Simplicity Studio 6 with Simplicity SDK, the Silicon Labs Machine Learning (aiml) extension, and WiseConnect. Use versions compatible with the AI/ML extension release you are using.

##### Important steps

1. First board: Create a project from AI/ML - SoC Wi-Fi Voice Control Light for SiWG917 (FreeRTOS) (`aiml_wifi_soc_voice_control_light_siwg917_rtos`), configure the AP as in the Wi-Fi Voice doc, and set `SERVER_IP` / `SERVER_PORT` to the second board’s IPv4 and the same UDP port the receiver uses (default 5000 unless you change both sides).
2. Second board: Create a project from the UDP LED receiver example in the AI/ML extension (name shown in Studio), assign a static IPv4 on the AP subnet that matches `SERVER_IP` on the first board, and flash the firmware.
3. Connect VCOM on both boards to verify association, UDP activity, and LED behavior.
4. Associate a client to the SoC access point if required for the voice app’s ML loop; speak on / off and confirm LED behavior on the receiver board and logs on both devices as described in each example’s `readme.md`.

##### Required hardware and setup

- Two supported SiWG917 kits (or one voice board plus a second board as supported by the receiver example—confirm in the template).
- USB for flash / debug and VCOM on each board.
- Wi-Fi topology: the voice board is the AP in the reference design; the receiver joins that AP (or follows the topology described in your example `readme.md`) so it can receive datagrams sent to its station address.

##### Application notes

- Addressing: The sender must target the receiver’s IPv4 (`SERVER_IP`). Use a static address on the receiver if DHCP would make the address unstable between runs.
- Port: UDP port must match on both projects (same value as `SERVER_PORT` and the receiver bind).
- Payload format: Treat the exact ON/OFF strings (or binary format) as defined in firmware; parse in the receiver task and map to GPIO/LED timing (including blink if implemented on this board only).

##### Troubleshooting

- No LED changes: confirm routing—voice app has a client associated if required, `SERVER_IP` equals the receiver, firewall off on test hosts, and port unchanged on both sides.
- Wrong state: verify payload parsing against the sender’s `readme.md` and serial logs on VCOM.