Native layer suite (Lucy menu [14])
Run: Lucy Bloom Rivers → [14] (or [0] for all layer types).
Code: Lucy examples/seven_layer/native_menu.go
Runtime log: lucy_testing_output/native_layers.txt (reset each session)
This suite exercises native-exact training (UseExactDType = true): forward and backward in storage dtype via *_native.go, plus 30-epoch CPU training per dtype. When Plan 9 SIMD is linked, each row also reports native-exact SIMD fwd/bwd timing vs scalar native.
Contrast with menu [7] (seven-layer suite): default QAT-like path (GetActive FP32 dequant), SC/MC/SIMD parity, save/reload. See training.md — Training paradigms.
Harness shape
| Setting | Value |
|---|---|
| Grid | 1³ (one cell) |
| Layers per cell | 7 (same stack shape as other native suites; primary layer type under test) |
| Dtypes | 21 (IsLayerNativeExactDType) |
| Train epochs | 30 |
| SIMD | SetSimdForward(true) for timing columns; *_native_simd.go when linked |
Layer types (menu [1]–[10]): Dense, SwiGLU, MHA, CNN1, CNN2, CNN3, RNN, LSTM, Embedding, Residual.
Per-row gates: Path (native routing) · Fwd · Bwd · Train (loss finite + harness trainingOK) · optional SIMD fwd/bwd speedup.
Full-run results (Jul 2026)
Captured logs:
| Platform | Log file |
|---|---|
| amd64 | native_layers_amd.txt (user archive; same format as native_layers.txt) |
| arm64 | native_layers_arm.txt |
Pass summary (21 dtypes × layer)
| Layer | amd64 | arm64 | Notes |
|---|---|---|---|
| Dense | 21/21 | 21/21 | |
| SwiGLU | 21/21 | 21/21 | Int8 learns on both (e.g. amd64 0.22→0.06) |
| MHA | 21/21 | 21/21 | |
| CNN1 | 21/21 | 21/21 | |
| CNN2 | 21/21 | 21/21 | Many dtypes flat loss (stable, not diverging) |
| CNN3 | 21/21 | 20/21 | arm64 Int32 train: loss 0.29→0.36 |
| RNN | 20/21 | 19/21 | amd64 Int2 train fail; arm64 Int4, Int2 train fail |
| LSTM | 21/21 | 21/21 | |
| Embedding | 21/21 | 21/21 | |
| Residual | 21/21 | 21/21 | No skip wire in 1³ forward chain; loss flat by design |
| Total | 209/210 | 207/210 | Fwd/bwd pass on all rows; train fails listed above |
Train failures are loss-criteria only (forward/backward still PASS). Low-bit RNN at 30 epochs on a tiny 1³ stack is the flaky zone; wide unsigned integers (Uint64/Uint32) often start from huge loss then recover within 30 epochs.
Native-exact SIMD speedup (Float32, 1³)
Speedup = scalar native time ÷ native SIMD time (>1 = SIMD faster). Representative Float32 rows from the archived logs:
Forward (SIMD vs scalar native)
| Layer | amd64 | arm64 |
|---|---|---|
| Dense | 1.6× | 1.6× |
| SwiGLU | 2.4× | 3.8× |
| MHA | 1.3× | 1.5× |
| CNN1 | 19.7× | 13.5× |
| CNN2 | 56.2× | 65.5× |
| CNN3 | 33.0× | 41.9× |
| RNN | 17.1× | 14.1× |
| LSTM | 28.3× | 17.9× |
| Embedding | 1.5× | 2.2× |
| Residual | ≈1× | n/a (sub-µs; skip not exercised) |
MAC dtypes (Float16, FP8, Int32, …) often see 8–11× forward wins on amd64 where scalar native still does per-dot GetNative work and SIMD materializes f32 tiles once.
Backward (SIMD vs scalar native)
| Layer | amd64 | arm64 |
|---|---|---|
| Dense | 8.5× | 7.7× |
| SwiGLU | 6.3× | 3.7× |
| MHA | 2.9× | 2.6× |
| CNN1 | 8.0× | 6.1× |
| CNN2 | 21.2× | 26.0× |
| CNN3 | 17.3× | 16.9× |
| RNN | 9.0× | 5.8× |
| LSTM | 12.3× | 11.8× |
| Embedding | 7.4× | 3.0× |
True integer dtypes (Int8) — CNN backward
Int8 native backward uses SaxpyI8*; speedups vs scalar int8 backward are extreme on conv layers:
| Layer | amd64 bwd | arm64 bwd |
|---|---|---|
| CNN1 Int8 | 35× | n/a (timer resolution) |
| CNN2 Int8 | 99.8× | 210.6× |
| CNN3 Int8 | 154.3× | 209.9× |
Int8 forward on CNN is only ~1.3–1.5× (already fast scalar loops; SIMD setup dominates).
Where SIMD does not help
- Residual on 1³: forward chain has no skip tensor (
skip=nil); residual is effectively identity. Timings are sub-microsecond — SIMD parallel add is pure overhead (amd64 Float64 fwd 4× slower with SIMD). - RNN/LSTM Int8 bwd: often ≈1× (scalar int8 backward already tight; BPTT serial).
- Uint2 Dense fwd (amd64): occasional slower SIMD (~1.0×).
Reading a log line
Example (Dense Float32, amd64):
· Float32 PASS fwd 78.7µs bwd 1.57ms simd fwd 49.4µs (37% faster (1.6×)) bwd 186.0µs (88% faster (8.5×)) loss 0.3312→0.3135 train 51.2ms
| Field | Meaning |
|---|---|
Path / first PASS columns |
LayerUsesNativeExact and fwd/bwd/train gates |
fwd / bwd |
Scalar native-exact micro-benchmark |
simd fwd / simd bwd |
Same with SetSimdForward(true) → *_native_simd.go |
loss₀→lossₙ |
First vs last of 30 training epochs |
train |
Wall time for full 30-epoch train on that dtype |
Table footer per layer: Dense native: 21 passed · 0 failed (of 21 dtypes).
Relationship to other docs
| Topic | Doc |
|---|---|
| QAT-like vs native exact | training.md, quantization.md |
| Plan 9 SIMD kernels | simd.md |
| Menu [7] SC/MC/SIMD parity + save/reload | bedrock_validation.md |
| Parity symbols / log layout | testing_and_validation.md |
Reproduce
cd lucy_bloom_rivers && go run .
# [14] → pick layer [1]–[10] or [0] for full matrix
Requires GOARCH=amd64 or arm64 with AVX2/NEON linked (poly/simd) for SIMD columns. On other arches, native scalar paths still run; SIMD timing columns are omitted when Plan9SimdForwardForLayer is false.