Skip to content
Merged
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
79 changes: 21 additions & 58 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ jobs:
build-linux:
runs-on: ubuntu-24.04
env:
MPY_DIR: ./micropython
MICROPYTHON_BIN: ./micropython/ports/unix/build-nomodules/micropython
MICROPYTHON_BIN: ./dependencies/micropython/ports/unix/build-nomodules/micropython
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -19,15 +18,10 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- uses: actions/checkout@v4
with:
repository: micropython/micropython
path: micropython
ref: v1.27.0
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Setup MicroPython X86
working-directory: micropython
working-directory: ./dependencies/micropython
run: |
source tools/ci.sh && ci_unix_32bit_setup && ci_unix_standard_build
mv ./ports/unix/build-standard/ ./ports/unix/build-nomodules/
Expand All @@ -47,8 +41,7 @@ jobs:
build-arm:
runs-on: ubuntu-24.04
env:
MPY_DIR: ./micropython
MICROPYTHON_BIN: ./micropython/ports/unix/build-nomodules/micropython
MICROPYTHON_BIN: ./dependencies/micropython/ports/unix/build-nomodules/micropython
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -58,20 +51,15 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- uses: actions/checkout@v4
with:
repository: micropython/micropython
path: micropython
ref: v1.27.0
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Setup MicroPython ARM
working-directory: micropython
working-directory: ./dependencies/micropython
run: |
source tools/ci.sh && ci_rp2_setup
make -C mpy-cross
- name: Setup MicroPython RP2 port
working-directory: micropython/ports/rp2
working-directory: ./dependencies/micropython/ports/rp2
run: |
make submodules
make clean
Expand All @@ -92,8 +80,7 @@ jobs:
build-esp32:
runs-on: ubuntu-24.04
env:
MPY_DIR: ./micropython
MICROPYTHON_BIN: ./micropython/ports/unix/build-nomodules/micropython
IDF_VER: v5.5.1
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -103,29 +90,24 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- uses: actions/checkout@v4
with:
repository: micropython/micropython
path: micropython
ref: v1.27.0
- name: Install Python dependencies
run: pip install -r requirements.txt

- name: Setup MicroPython ESP32
working-directory: micropython
working-directory: ./dependencies/micropython
run: |
source tools/ci.sh && ci_esp32_idf_setup
make -C mpy-cross
- name: Setup submodules esp32
working-directory: micropython/ports/esp32
working-directory: ./dependencies/micropython/ports/esp32
run: source ../../esp-idf/export.sh && make submodules
- name: Build custom firmware with extmod, ESP32
run: |
source micropython/esp-idf/export.sh && pip install -r requirements.txt
source ./dependencies/micropython/esp-idf/export.sh && pip install -r requirements.txt
make extmod PORT=esp32 BOARD=ESP32_GENERIC_S3
make extmod PORT=esp32 BOARD=ESP32_GENERIC
- name: Build module xtensawin
run: source micropython/esp-idf/export.sh && pip install -r requirements.txt && make dist ARCH=xtensawin V=1
run: source ./dependencies/micropython/esp-idf/export.sh && pip install -r requirements.txt && make dist ARCH=xtensawin V=1
- name: Archive dist artifacts
uses: actions/upload-artifact@v4
with:
Expand All @@ -136,8 +118,7 @@ jobs:
build-riscv:
runs-on: ubuntu-24.04
env:
MPY_DIR: ./micropython
MICROPYTHON_BIN: ./micropython/ports/unix/build-nomodules/micropython
IDF_VER: v5.5.1
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -147,28 +128,23 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- uses: actions/checkout@v4
with:
repository: micropython/micropython
path: micropython
ref: v1.27.0
- name: Install Python dependencies
run: pip install -r requirements.txt

- name: Setup MicroPython ESP32
working-directory: micropython
working-directory: ./dependencies/micropython
run: |
source tools/ci.sh && ci_esp32_idf_setup && ci_gcc_riscv_setup
make -C mpy-cross
- name: Setup submodules esp32
working-directory: micropython/ports/esp32
working-directory: ./dependencies/micropython/ports/esp32
run: source ../../esp-idf/export.sh && make submodules
- name: Build custom firmware with extmod, ESP32
run: |
source micropython/esp-idf/export.sh && pip install -r requirements.txt
source ./dependencies/micropython/esp-idf/export.sh && pip install -r requirements.txt
echo make extmod PORT=esp32 BOARD=ESP32_GENERIC_C6
- name: Build nadmod xtensawin
run: source micropython/esp-idf/export.sh && pip install -r requirements.txt && make dist ARCH=rv32imc V=1
run: source ./dependencies/micropython/esp-idf/export.sh && pip install -r requirements.txt && make dist ARCH=rv32imc V=1
- name: Archive dist artifacts
uses: actions/upload-artifact@v4
with:
Expand All @@ -179,9 +155,7 @@ jobs:
build-macos:
runs-on: macos-latest
env:
MPY_DIR: ./micropython
MICROPYTHON_BIN: ./micropython/ports/unix/build-nomodules/micropython

MICROPYTHON_BIN: ./dependencies/micropython/ports/unix/build-nomodules/micropython
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -195,15 +169,10 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- uses: actions/checkout@v4
with:
repository: micropython/micropython
path: micropython
ref: v1.27.0
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Setup MicroPython X86
working-directory: micropython
working-directory: ./dependencies/micropython
run: |
make -C mpy-cross CFLAGS_EXTRA=-Wno-error
make -C ports/unix submodules
Expand All @@ -226,8 +195,7 @@ jobs:
build-webassembly:
runs-on: ubuntu-latest
env:
MPY_DIR: ./micropython
MICROPYTHON_BIN: ./micropython/ports/unix/build-nomodules/micropython
MICROPYTHON_BIN: ./dependencies/micropython/ports/unix/build-nomodules/micropython
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -237,24 +205,19 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- uses: actions/checkout@v4
with:
repository: jonnor/micropython
path: micropython
ref: webassembly-extra-cflags
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Setup MicroPython
working-directory: micropython
working-directory: ./dependencies/micropython
run: |
npm install terser
git clone https://github.com/emscripten-core/emsdk.git
(cd emsdk && ./emsdk install 4.0.21 && ./emsdk activate 4.0.21)
make -C mpy-cross CFLAGS_EXTRA=-Wno-error
- name: Build Webassembly
run: |
source ${MPY_DIR}/emsdk/emsdk_env.sh
make -C ${MPY_DIR}/ports/webassembly submodules
source ./dependencies/micropython/emsdk/emsdk_env.sh
make -C ./dependencies/micropython/ports/webassembly submodules
make webassembly V=1
- name: Archive dist artifacts
uses: actions/upload-artifact@v4
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "dependencies/CMSIS-DSP"]
path = dependencies/CMSIS-DSP
url = https://github.com/ARM-software/CMSIS-DSP.git
[submodule "dependencies/micropython"]
path = dependencies/micropython
url = https://github.com/jonnor/micropython.git
11 changes: 8 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

ARCH ?= x64
MPY_ABI_VERSION ?= 6.3
MPY_DIR ?= ../micropython
MPY_DIR ?= ./dependencies/micropython
MICROPYTHON_BIN ?= micropython

# extmod settings
Expand All @@ -10,7 +10,7 @@ BOARD=ESP32_GENERIC_S3

VERSION := $(shell git describe --tags --always)

MPY_DIR_ABS = $(abspath $(MPY_DIR))
MPY_DIR_ABS = $(abspath $(MPY_DIR))

C_MODULES_SRC_PATH = $(abspath ./src)

Expand Down Expand Up @@ -39,6 +39,7 @@ MODULES = emlearn_trees \
emlearn_linreg \
emlearn_logreg \
emlearn_extratrees \
emlearn_plsr \
emlearn_cnn_int8 \
emlearn_cnn_fp32

Expand All @@ -62,6 +63,7 @@ emlearn_arrayutils_SRC = src/emlearn_arrayutils
emlearn_linreg_SRC = src/emlearn_linreg
emlearn_logreg_SRC = src/emlearn_logreg
emlearn_extratrees_SRC = src/emlearn_extratrees
emlearn_plsr_SRC = src/emlearn_plsr

# Dependencies for each .mpy file: .c, .h, .py files, and Makefile
$(foreach mod,$(MODULES),\
Expand Down Expand Up @@ -151,7 +153,10 @@ extmod: $(SRC_ALL) src/manifest_unix.py
cp -r $(PORT_BUILD_DIR)/micropython* $(PORT_DIST_DIR)


.PHONY: clean unix
.PHONY: clean unix codesize

codesize:
python3 tools/code_size.py $(MPY_DIR_ABS)/ports/unix/build-standard

clean:
make -C src/emlearn_trees/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean
Expand Down
1 change: 1 addition & 0 deletions dependencies/micropython
Submodule micropython added at 0da3f4
Binary file added examples/datasets/airquality/X_test.npy
Binary file not shown.
Binary file added examples/datasets/airquality/X_train.npy
Binary file not shown.
83 changes: 83 additions & 0 deletions examples/datasets/airquality/prepare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
"""Download and preprocess the Air Quality UCI dataset for PLS regression.

Also computes sklearn PLSR reference results for comparison.
Run with CPython: python3 examples/datasets/airquality/prepare.py
"""

from pathlib import Path
import os
import urllib.request
import zipfile

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.cross_decomposition import PLSRegression
from sklearn.metrics import r2_score, mean_squared_error


def main():

here = os.path.dirname(__file__)
OUTPUT_DIR = Path(here)
OUTPUT_DIR.mkdir(exist_ok=True)

# Download
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/00360/AirQualityUCI.zip"
zip_path = OUTPUT_DIR / "AirQualityUCI.zip"
if not zip_path.exists():
print("Downloading Air Quality UCI dataset...")
urllib.request.urlretrieve(url, zip_path)
with zipfile.ZipFile(zip_path, 'r') as zf:
zf.extractall(OUTPUT_DIR)

# Load and preprocess
csv_file = OUTPUT_DIR / "AirQualityUCI.csv"
df = pd.read_csv(csv_file, sep=';', decimal=',')
df = df.iloc[:, :-2] # drop last two empty columns
df.replace(-200, np.nan, inplace=True)
df.dropna(inplace=True)

X = df.iloc[:, 2:].values.astype(np.float32) # sensor columns
y = df["CO(GT)"].values.astype(np.float32)

scaler_X = StandardScaler()
X = scaler_X.fit_transform(X).astype(np.float32)

X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)

FILENAMES = {
'X_train': OUTPUT_DIR / 'X_train.npy',
'X_test': OUTPUT_DIR / 'X_test.npy',
'y_train': OUTPUT_DIR / 'y_train.npy',
'y_test': OUTPUT_DIR / 'y_test.npy',
}

np.save(FILENAMES['X_train'], X_train)
np.save(FILENAMES['X_test'], X_test)
np.save(FILENAMES['y_train'], y_train)
np.save(FILENAMES['y_test'], y_test)

print('Saved datasets:')
print(f" X_train: {X_train.shape} -> {FILENAMES['X_train']}")
print(f" X_test : {X_test.shape} -> {FILENAMES['X_test']}")
print(f" y_train: {y_train.shape} -> {FILENAMES['y_train']}")
print(f" y_test : {y_test.shape} -> {FILENAMES['y_test']}")

# Sklearn PLSR reference results
print('\nSklearn PLSR reference:')
for nc in [3, 5]:
pls = PLSRegression(n_components=nc)
pls.fit(X_train, y_train)
y_pred = pls.predict(X_test).ravel()
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f" n_components={nc}: MSE={mse:.5f}, R^2={r2:.5f}")


if __name__ == '__main__':
main()
Binary file added examples/datasets/airquality/y_test.npy
Binary file not shown.
Binary file added examples/datasets/airquality/y_train.npy
Binary file not shown.
Binary file added examples/datasets/spectrofood/X_test.npy
Binary file not shown.
Binary file added examples/datasets/spectrofood/X_train.npy
Binary file not shown.
Loading
Loading