Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
name: Continuous Integration for Machine Learning Applications
on:
push:
branches:
- main
- feature/*
tags:
- v*
pull_request:
branches:
- main
- feature/*
workflow_dispatch:

permissions:
id-token: write
contents: read

jobs:
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v5

- name: Generate dynamic matrix from templates.xml
id: set-matrix
run: |
matrix=$(python3 .github/workflows/scripts/generate_matrix.py | jq -c .)
echo "matrix=$matrix" >> $GITHUB_OUTPUT

get-sdk:
runs-on: ubuntu-latest
steps:
- name: Clone GSDK and ai-ml app
shell: bash
run: |
set -e
mkdir src
echo "==> Creating developer directories..."
cd src
echo "==> Cloning public GSDK"
git clone https://github.com/SiliconLabs/simplicity_sdk.git gsdk
cd gsdk
git checkout v2025.6.2
mkdir extension
cd extension
git clone --recurse-submodules https://github.com/SiliconLabsSoftware/aiml-extension.git aiml-extension
cd aiml-extension
git checkout v2.1.2
git submodule update --init --recursive
git lfs pull || true

- name: Checkout machine_learning_applications (this repo)
uses: actions/checkout@v5
with:
path: src/gsdk/extension/machine_learning_applications

- name: Upload SDK
uses: actions/upload-artifact@v5
with:
name: sisdk-and-extensions
path: .
include-hidden-files: true

get-tools:
runs-on: ubuntu-latest
steps:
- name: Download ARM-GNU and SLC toolchain
run: |
mkdir -p tools && cd tools
wget -q https://developer.arm.com/-/media/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz
tar -xf arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz
mv arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi armgnu
rm arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz
wget -q https://www.silabs.com/documents/public/software/slc_cli_linux.zip
unzip -q slc_cli_linux.zip -d slc_cli
rm slc_cli_linux.zip

- name: Upload Tools
uses: actions/upload-artifact@v5
with:
name: arm-gnu-toolchain-and-slc
path: .
include-hidden-files: true

build:
runs-on: ubuntu-latest
needs: [generate-matrix, get-sdk, get-tools]
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.generate-matrix.outputs.matrix) }}
steps:
- name: Download GSDK
uses: actions/download-artifact@v5
with:
name: sisdk-and-extensions
path: .

- name: Download ARM-GNU and SLC toolchain
uses: actions/download-artifact@v5
with:
name: arm-gnu-toolchain-and-slc
path: .

- name: Install Java 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
check-latest: true

- name: Configure SLC,ARM-GNU, JAVA paths
run: |
set -e
tree -L 3
chmod -R +x ${{ github.workspace }}/tools/armgnu
echo "ARM_GCC_DIR=${{ github.workspace }}/tools/armgnu" >> "$GITHUB_ENV"
echo "${{ github.workspace }}/tools/armgnu/bin/" >> "$GITHUB_PATH"

SLC_DIR="${{ github.workspace }}/tools/slc_cli/slc_cli/bin/slc-cli"
chmod +x "$SLC_DIR/slc-cli"
ln -sf "$SLC_DIR/slc-cli" "$SLC_DIR/slc"
echo "UC_CLI_DIR=$SLC_DIR" >> "$GITHUB_ENV"
echo "$SLC_DIR" >> "$GITHUB_PATH"

echo "SLC_JAVA_HOME=$JAVA_HOME" >> "$GITHUB_ENV"

- name: Trust sdk's
run: |
set -e
slc configuration --sdk "${{ github.workspace }}/src/gsdk"
slc signature trust --sdk "${{ github.workspace }}/src/gsdk"
slc signature trust --extension-path "${{ github.workspace }}/src/gsdk/extension/aiml-extension"
slc signature trust --extension-path "${{ github.workspace }}/src/gsdk/extension/machine_learning_applications"

- name: Generate + Build
working-directory: ${{ github.workspace }}/src/gsdk/extension/machine_learning_applications
env:
APP: ${{ matrix.app }}
BOARD: ${{ matrix.board }}
run: |
set -e
echo "App: $APP"
echo "BOARD: $BOARD"
slc generate -d target/$APP/$BOARD -p $APP.slcp --with $BOARD -s "${{ github.workspace }}/src/gsdk"
cmake --preset project -S target/$APP/$BOARD/${APP##*/}_cmake
cmake --build target/$APP/$BOARD/${APP##*/}_cmake/build --parallel
echo "==> Listing generated .s37 files"
find ./target -name "*.s37"

41 changes: 41 additions & 0 deletions .github/workflows/scripts/generate_matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env python3
import os, json
from pathlib import Path
import xml.etree.ElementTree as ET

ROOT = Path(__file__).resolve().parents[3]
TEMPLATES_XML = ROOT / "templates.xml"

def get_prop(desc, key):
# <properties key="boardCompatibility" value="...">
p = desc.find(f'properties[@key="{key}"]')
return (p.get("value") if p is not None else "").strip()

def split_ws(s):
# boardCompatibility is space-separated: "brd2601a brd2601b"
return [x for x in s.replace(",", " ").split() if x]

def main():
tree = ET.parse(TEMPLATES_XML)
root = tree.getroot()

rows = []
for desc in root.findall("descriptors"):
app = get_prop(desc, "projectFilePaths").split(".")[0] # e.g. application/voice/.../series_2.slcp -> application/voice/.../series_2
boards = split_ws(get_prop(desc, "boardCompatibility")) # e.g. ["brd2601a", "brd2601b"]

for board in boards:
rows.append({
"app": app,
"board": board
})

if not rows:
# Avoid empty matrix which makes Actions error out
rows = [{"app":"noop","board":"noop"}]

matrix = {"include": rows}
print(json.dumps(matrix, indent=2))

if __name__ == "__main__":
main()
14 changes: 0 additions & 14 deletions templates.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,6 @@
<properties key="stockConfigCompatibility" value="com.silabs.ss.framework.project.toolchain.core.default"/>
<properties key="filters" value="Capability|Machine\ Learning Device\ Type|SoC MCU|32-bit\ MCU Project\ Difficulty|Advanced"/>
</descriptors>
<descriptors name="sensory_wakeupword" label="Machine Learning - Sensory Wakeup Word" description="This example project demos wakeup word detection using Sensory's TrulyHandsFree (THF) solution for Series 1 boards. Several models implementing different wake word phrases are included in the provided example projects. You can also create you own wake word model on Sensory's VoiceHub and include it in this demo to try it out.&#xA;">
<properties key="namespace" value="template.uc"/>
<properties key="keywords" value="universal\ configurator"/>
<properties key="projectFilePaths" value="application/voice/sensory_wakeupword/app/sensory_wakeupword_series_1.slcp"/>
<properties key="readmeFiles" value="application/voice/sensory_wakeupword/README.md"/>
<properties key="boardCompatibility" value="brd4166a"/>
<properties key="partCompatibility" value=".*efr32mg12p.*"/>
<properties key="ideCompatibility" value="iar-embedded-workbench makefile-ide segger-embedded-studio simplicity-ide"/>
<properties key="toolchainCompatibility" value="gcc iar segger"/>
<properties key="category" value="Example|Machine Learning"/>
<properties key="quality" value="EXPERIMENTAL"/>
<properties key="stockConfigCompatibility" value="com.silabs.ss.framework.project.toolchain.core.default"/>
<properties key="filters" value="Capability|Machine\ Learning Device\ Type|SoC MCU|32-bit\ MCU Project\ Difficulty|Advanced"/>
</descriptors>
<descriptors name="people_flow_counter_mlx90640" label="Machine Learning - People Flow Counter" description="A demo displaying how xG24-DK2601B can be used to to gain information about people flow using an IR camera.&#xA;">
<properties key="namespace" value="template.uc"/>
<properties key="keywords" value="universal\ configurator"/>
Expand Down