Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
c7f3676
chore(examples): remove rotted legacy example/MnistExperiment (#235)
LeoBuron Jun 25, 2026
233ee5e
feat(layer): parametrize factory weight/bias init, default to PyTorch…
LeoBuron Jun 25, 2026
5b996f4
refactor(examples): consolidate v1/v2 into one factory-API trainer pe…
LeoBuron Jun 25, 2026
ef3bc00
ci(examples): build the full 'all' target in the bit-parity job (rot …
LeoBuron Jun 26, 2026
7f29375
feat(examples/_shared): add shared MNIST torchvision loader
LeoBuron Jun 26, 2026
9981a3d
feat(examples/mnist_mlp): prepare_data writes train/val/test npy
LeoBuron Jun 26, 2026
20f8ce9
feat(examples/mnist_mlp): PyTorch reference MLP + weight export
LeoBuron Jun 26, 2026
df4a21f
feat(examples/mnist_mlp): factory-API C trainer + CMake wiring
LeoBuron Jun 26, 2026
fad2b57
feat(examples/mnist_mlp): informational compare.py + plots
LeoBuron Jun 26, 2026
2e04430
docs(examples/mnist_mlp): add README
LeoBuron Jun 26, 2026
bfe5262
ci(examples): wire mnist_mlp into the bit-parity job
LeoBuron Jun 26, 2026
92e1be8
chore(examples/_shared): annotate load_mnist root param, drop unused-…
LeoBuron Jun 26, 2026
cee7d63
feat(examples/mnist_cnn): prepare_data writes train/val/test npy
LeoBuron Jun 26, 2026
bd5902e
feat(examples/mnist_cnn): PyTorch reference 1D-CNN + weight export
LeoBuron Jun 26, 2026
86f9f53
feat(examples/mnist_cnn): factory-API 1D-CNN trainer + CMake wiring
LeoBuron Jun 26, 2026
862230f
feat(examples/mnist_cnn): informational compare.py + plots
LeoBuron Jun 26, 2026
96b7a0a
docs(examples/mnist_cnn): add README + update suite table
LeoBuron Jun 26, 2026
39a2bd0
ci(examples): wire mnist_cnn into the bit-parity job
LeoBuron Jun 26, 2026
0f416f6
feat(examples/_shared): add SpeechCommands loader + torchaudio dep
LeoBuron Jun 26, 2026
44f0f91
feat(examples/kws_mfcc): prepare_data writes MFCC train/val/test npy
LeoBuron Jun 26, 2026
d4d6008
fix(examples/_shared): decode wavs via stdlib wave; bound loader memory
LeoBuron Jun 26, 2026
edc4f16
feat(examples/kws_mfcc): PyTorch reference MFCC CNN + weight export
LeoBuron Jun 26, 2026
b967ecc
feat(examples/kws_mfcc): factory-API MFCC CNN trainer + CMake wiring
LeoBuron Jun 26, 2026
e044d08
feat(examples/kws_mfcc): informational compare.py + plots
LeoBuron Jun 26, 2026
3e62857
docs(examples/kws_mfcc): add README
LeoBuron Jun 26, 2026
4aa661d
ci(examples): wire kws_mfcc into the bit-parity job
LeoBuron Jun 26, 2026
0c51088
harden(examples/_shared): assert mono 16-bit PCM in wav reader
LeoBuron Jun 26, 2026
6a559c7
feat(examples/kws_raw): prepare_data writes raw waveform train/val/te…
LeoBuron Jun 26, 2026
16736b8
feat(examples/kws_raw): PyTorch reference raw-waveform CNN + weight e…
LeoBuron Jun 26, 2026
2518b79
feat(examples/kws_raw): factory-API raw-waveform CNN trainer + CMake …
LeoBuron Jun 26, 2026
f445276
feat(examples/kws_raw): add LayerNorm + tune lr for raw-model converg…
LeoBuron Jun 26, 2026
fc7043d
feat(examples/kws_raw): informational compare.py + plots
LeoBuron Jun 26, 2026
4e19a2f
docs(examples/kws_raw): add README + update suite table
LeoBuron Jun 26, 2026
14b5fb7
ci(examples): wire kws_raw into the bit-parity job
LeoBuron Jun 26, 2026
062e7a3
feat(examples/kws_raw): per-conv LayerNorm (10-seed-validated) replac…
LeoBuron Jun 28, 2026
d655b13
refactor(training_loop): extract calculateGradsImpl with optional tra…
LeoBuron Jun 29, 2026
fc73ca2
feat(training_loop): tracedGrads fires activation + act-grad sink per…
LeoBuron Jun 29, 2026
87b5cf4
feat(training_loop): traceModelWeights/Grads dump per-layer params + …
LeoBuron Jun 29, 2026
d422aea
style(training_loop): clang-format trace-primitives test
LeoBuron Jun 29, 2026
d7f7655
feat(examples/_shared): npyDumpSink trace sink writes FLOAT32 tensors…
LeoBuron Jun 29, 2026
177788d
feat(examples/kws_raw): trace_c controlled-step harness writes per-la…
LeoBuron Jun 29, 2026
a83ce86
feat(examples/kws_raw): trace_pytorch mirrors the controlled step via…
LeoBuron Jun 29, 2026
a991211
feat(examples/_shared): trace_compare localizes first C-vs-PyTorch drift
LeoBuron Jun 29, 2026
1476364
fix(training_loop): trace agrad = grad wrt layer OUTPUT (align with P…
LeoBuron Jun 29, 2026
7dc92be
feat(trace): abs-floor drift gate + compare_pairs refactor + trace_sw…
LeoBuron Jun 29, 2026
c85ca03
style(examples): clang-format trace harness + dump sink
LeoBuron Jun 29, 2026
65bf907
fix(trace): final-review polish — shape/drift/manifest asserts, sweep…
LeoBuron Jun 29, 2026
a3bf34c
docs: SYM_INT32 compute-vs-storage honesty + conventions -> path-scop…
LeoBuron Jul 1, 2026
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
113 changes: 101 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:

- name: Check format
run: |
find src test example \( -name '*.c' -o -name '*.h' \) -print0 | \
find src test examples \( -name '*.c' -o -name '*.h' \) -print0 | \
xargs -0 clang-format-21 --dry-run -Werror

c-build-and-test:
Expand Down Expand Up @@ -159,7 +159,15 @@ jobs:
path: |
examples/har_classifier/data/raw
examples/ecg_anomaly_ae/data/raw
key: datasets-raw-${{ hashFiles('examples/har_classifier/prepare_data.py', 'examples/ecg_anomaly_ae/prepare_data.py') }}
examples/mnist_mlp/data/raw
examples/mnist_cnn/data/raw
key: datasets-raw-${{ hashFiles('examples/har_classifier/prepare_data.py', 'examples/ecg_anomaly_ae/prepare_data.py', 'examples/mnist_mlp/prepare_data.py', 'examples/mnist_cnn/prepare_data.py') }}

- name: Cache SpeechCommands raw download (shared, ~2.3 GB)
uses: actions/cache@v4
with:
path: examples/_shared/data/speech_commands
key: speechcommands-raw-${{ hashFiles('examples/_shared/speechcommands_data.py') }}

- name: Prepare HAR data
run: uv run examples/har_classifier/prepare_data.py
Expand All @@ -173,36 +181,117 @@ jobs:
- name: Train PyTorch ECG (produces reference reconstructions + weights)
run: uv run examples/ecg_anomaly_ae/train_pytorch.py

- name: Prepare MNIST MLP data
run: uv run examples/mnist_mlp/prepare_data.py

- name: Train PyTorch MNIST MLP (produces reference predictions + weights)
run: uv run examples/mnist_mlp/train_pytorch.py

- name: Prepare MNIST CNN data
run: uv run examples/mnist_cnn/prepare_data.py

- name: Train PyTorch MNIST CNN (produces reference predictions + weights)
run: uv run examples/mnist_cnn/train_pytorch.py

- name: Cache kws_mfcc processed data (6-class)
id: kws-mfcc-cache
uses: actions/cache@v4
with:
path: examples/kws_mfcc/data/6class
key: kws-mfcc-6class-${{ hashFiles('examples/kws_mfcc/prepare_data.py', 'examples/_shared/speechcommands_data.py') }}

- name: Prepare kws_mfcc data (6-class; only on cache miss)
if: steps.kws-mfcc-cache.outputs.cache-hit != 'true'
run: uv run examples/kws_mfcc/prepare_data.py

- name: Train PyTorch kws_mfcc (produces reference predictions + weights)
run: uv run examples/kws_mfcc/train_pytorch.py

- name: Cache kws_raw processed data (6-class)
id: kws-raw-cache
uses: actions/cache@v4
with:
path: examples/kws_raw/data/6class
key: kws-raw-6class-${{ hashFiles('examples/kws_raw/prepare_data.py', 'examples/_shared/speechcommands_data.py') }}

- name: Prepare kws_raw data (6-class; only on cache miss)
if: steps.kws-raw-cache.outputs.cache-hit != 'true'
run: uv run examples/kws_raw/prepare_data.py

- name: Train PyTorch kws_raw (produces reference predictions + weights)
run: uv run examples/kws_raw/train_pytorch.py

- name: Configure
run: cmake --preset examples

- name: Build v2 binaries
run: |
cmake --build --preset examples --target train_c_har_classifier_v2
cmake --build --preset examples --target train_c_ecg_anomaly_ae_v2
- name: Build ALL example binaries (rot guard — any broken example fails CI)
# Builds the default `all` target so every example executable is compiled,
# not just the two run below. Closes the gap that let example/MnistExperiment
# (#235) and the legacy v1 trainers silently rot — nothing built them.
run: cmake --build --preset examples

- name: Run HAR v2 in BIT_PARITY mode
run: BIT_PARITY=1 build/examples/examples/har_classifier_v2/train_c_har_classifier_v2
- name: Run HAR in BIT_PARITY mode
run: BIT_PARITY=1 build/examples/examples/har_classifier/train_c_har_classifier

- name: Run ECG v2 in BIT_PARITY mode
run: BIT_PARITY=1 build/examples/examples/ecg_anomaly_ae_v2/train_c_ecg_anomaly_ae_v2
- name: Run ECG in BIT_PARITY mode
run: BIT_PARITY=1 build/examples/examples/ecg_anomaly_ae/train_c_ecg_anomaly_ae

- name: Diff HAR predictions (int32, exact match required)
run: |
uv run examples/_shared/compare_predictions.py \
--pytorch examples/har_classifier/outputs/pytorch_predictions.npy \
--c examples/har_classifier_v2/outputs/c_predictions.npy \
--c examples/har_classifier/outputs/c_predictions.npy \
--dtype int32

- name: Diff ECG reconstructions (float32, allclose)
run: |
uv run examples/_shared/compare_predictions.py \
--pytorch examples/ecg_anomaly_ae/outputs/pytorch_reconstructions.npy \
--c examples/ecg_anomaly_ae_v2/outputs/c_reconstructions.npy \
--c examples/ecg_anomaly_ae/outputs/c_reconstructions.npy \
--dtype float32 \
--rtol 1e-4 \
--atol 1e-5

- name: Run MNIST MLP in BIT_PARITY mode
run: BIT_PARITY=1 build/examples/examples/mnist_mlp/train_c_mnist_mlp

- name: Diff MNIST MLP predictions (int32, exact match required)
run: |
uv run examples/_shared/compare_predictions.py \
--pytorch examples/mnist_mlp/outputs/pytorch_predictions.npy \
--c examples/mnist_mlp/outputs/c_predictions.npy \
--dtype int32

- name: Run MNIST CNN in BIT_PARITY mode
run: BIT_PARITY=1 build/examples/examples/mnist_cnn/train_c_mnist_cnn

- name: Diff MNIST CNN predictions (int32, exact match required)
run: |
uv run examples/_shared/compare_predictions.py \
--pytorch examples/mnist_cnn/outputs/pytorch_predictions.npy \
--c examples/mnist_cnn/outputs/c_predictions.npy \
--dtype int32

- name: Run kws_mfcc in BIT_PARITY mode
run: BIT_PARITY=1 build/examples/examples/kws_mfcc/train_c_kws_mfcc

- name: Diff kws_mfcc predictions (int32, exact match required)
run: |
uv run examples/_shared/compare_predictions.py \
--pytorch examples/kws_mfcc/outputs/6class/pytorch_predictions.npy \
--c examples/kws_mfcc/outputs/6class/c_predictions.npy \
--dtype int32

- name: Run kws_raw in BIT_PARITY mode
run: BIT_PARITY=1 build/examples/examples/kws_raw/train_c_kws_raw

- name: Diff kws_raw predictions (int32, exact match required)
run: |
uv run examples/_shared/compare_predictions.py \
--pytorch examples/kws_raw/outputs/6class/pytorch_predictions.npy \
--c examples/kws_raw/outputs/6class/c_predictions.npy \
--dtype int32

python-test:
runs-on: ubuntu-latest

Expand Down
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ if(ODT_TOP_LEVEL_PROJECT)
add_ctest()

add_subdirectory(test/unit)
add_subdirectory(example)
if(BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
Expand Down
2 changes: 1 addition & 1 deletion devenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ in
echo "$matches"
exit 1
fi
find src test example \( -name '*.c' -o -name '*.h' \) -print0 \
find src test examples \( -name '*.c' -o -name '*.h' \) -print0 \
| xargs -0 clang-format --dry-run -Werror
CC=gcc cmake --preset unit_test
cmake --build --preset unit_test
Expand Down
Loading
Loading