Research-Stack/5-Applications/scripts/snn/README.md

60 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SNN / NII / RGFlow / FAMM Test Harness
Imported 2026-04-24 from external triage pack. Calibration fixes applied
on import — see "Calibration deltas" below.
## Layout
- [snn_nii_reference.py](snn_nii_reference.py) — deterministic Python reference. Pipeline:
`predict → nii_step (clamp + bounded Δw + decay) → msnn_step (LIF + FAMM-modulated drive) → rgflow_step (3-verdict) → famm_update (saturating + exp decay)`.
Writes per-record JSONL with SHA-tagged hash for golden-vector compare.
- [generate_snn_vectors.py](generate_snn_vectors.py) — 4-phase synthetic stream
(stable / drift / repeated bad / near-miss osc) OR pulls from a
`uc_records.jsonl` topology18 stream.
- [snn_test_config.json](snn_test_config.json) — Q8 fixed-point + thresholds.
- RTL siblings live at [4-Infrastructure/hardware/tangnano9k/rtl/](../../hardware/tangnano9k/rtl/) and must
bit-match this Python reference.
## Quick start
```bash
python generate_snn_vectors.py --out vectors.jsonl --n 256
python snn_nii_reference.py --vectors vectors.jsonl --config snn_test_config.json --out results.jsonl --summary summary.json
```
The reference prints a pass/fail JSON to stdout. All four flags must be
true for the run to count: `bounded_nii`, `all_verdicts_present`,
`famm_unsaturated`, and any custom hardware-equivalence check.
## Calibration deltas (vs upstream pack)
The upstream harness produced a misleading `pass_fail: famm_updated: True`
when FAMM was actually pegged at 255 across all three counters from i≈40
onward — half the run was testing a dead controller. Fixes applied on
import:
1. **Exponential FAMM decay** (`decay_q8 = 232 ≈ 9.4%/step`). Replaces
the upstream linear `-1/step` on lawful-only. Time constant ~10 steps,
so phase 2's 64 consecutive heavy rejects can saturate momentarily but
recover before phase 3.
2. **Reduced reject contribution** (`rp/8` and `rp/16` instead of `rp/4`
and `rp/8`). Even with decay, the upstream scaling drove phase 2 to
saturation in ~5 events.
3. **Widened near-miss band** (`32 → 48`). Upstream produced 0/256
near-miss events.
4. **Saturation surfaces as failure** (`famm_unsaturated`,
`famm_saturation_steps`, `final_famm` now in pass/fail JSON). Failure
contract: silent saturation is unacceptable, must be observable.
Verified end-to-end after fixes: 189 lawful / 1 near-miss / 66 reject,
no counter saturated >25% of the run, max abs surprise 359 ≤ NII clip 384.
## Known follow-ups
- Synthetic generator phase 3 produces only 1 near-miss event in 64
steps — the σ corridor `[262, 293]` is too narrow for the current
amplitude swings. Either re-tune phase 3 amplitudes or add a fifth
phase explicitly designed for the near-miss band.
- RTL `nii_core.v` uses a one-tap `obs - prev_obs` predictor; the Python
reference uses 4 weighted delay taps. They will not bit-match until
the RTL is upgraded.