Skip to content

Add C-side training math: surrogate hook, backward ops, loss, optimizers - #35

Merged
w4ffl35 merged 3 commits into
masterfrom
p2/train-math
Oct 14, 2026
Merged

w4ffl35 merged 3 commits into
masterfrom
p2/train-math

Conversation

@w4ffl35

@w4ffl35 w4ffl35 commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Closes #26. Training-model decision (work-list item 1): option (c), both paths behind separate APIs — a surrogate-gradient path (named surrogate + CE loss + SGD/Adam + layer backward ops) and a local STDP port. Recorded on the epic in #25.

What this adds:

  • Surrogate hook in ops.c/ops.h: Threshold/LI/Affine/Linear single-step backward ops; forward stays strict Heaviside. nir_surrogate_from_name (train.h) resolves only fast_sigmoid/atan and fails on anything else — no silent default, mirroring resolve_surrogate's KeyError.
  • train.h/train.c: softmax cross-entropy (single sample, torch semantics), SGD (momentum, L2) and Adam (bias correction) matching torch.optim update rules, STDP ported from STDPSynapse with decay-before-update ordering and [w_min, w_max] clamp.
  • test_train: every primitive plus one full Adam step on a two-layer Affine-Threshold-Affine topology checked against float64 closed-form references (tolerances 1e-5..1e-7), and a 300-step convergence run (loss 0.798 -> 0.00052, bound 0.01).
  • README scope section updated to state the supported training model.

Follow-ups (out of this worker's scope): graph-level backprop-through-time tape retaining per-step activations (runtime.c), and a committed tools/ torch fixture generator (tools owner) to replace the throwaway float64 reference script.

Note: includes the same two-line set_error arity fix as PR #34 (master does not compile without it); the hunks are identical so they merge cleanly.

Tests: ctest 31/31 green in Debug, Release, and the ASan/UBSan configure from ci.yml.

Forward spikes stay strict Heavisides; the backward pass substitutes a
named surrogate derivative (fast_sigmoid/atan, snnTorch formulas) with
no silent default. New train.h/train.c provide name resolution,
softmax cross-entropy, SGD/Adam over raw weight buffers, and a local
STDP rule ported from STDPSynapse with decay-before-update ordering.
Layer backward ops cover Threshold, LI, Affine, and Linear; test_train
checks each primitive plus one Adam step on a two-layer topology
against float64 closed-form references and a 300-step convergence run.

Also fix two Conv2d groups set_error call sites left with a stale
third argument after #24 (same fix as the loader PR; master did not
compile). A graph-level backprop-through-time tape and a committed
torch fixture generator remain follow-ups.

Fixes #26.
@w4ffl35
w4ffl35 merged commit 0b7e0f7 into master Oct 14, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C Threshold is a strict Heaviside with no surrogate-gradient hook; no backward pass, loss, or optimizer exists

1 participant