Repository navigation
Epic: C-side training support (zero-Python/zero-torch enablement) #25
Copy link
Copy link
Closed
Description
Epic: C-side training support (zero-Python/zero-torch enablement)
Current state
nir-c-runtime is inference-only by design (README.md:77-79: "Training. This is inference-only."). Every training capability lives in spikeforge's Python/torch stack, and every bridge between the two projects flows one way: Python → C.
What C-side training would need (survey)
Mirrored from spikeforge's actual training path (spikeforge/training/):
- Weight updates: spikeforge trains by surrogate-gradient BPTT —
ScaleUpMixin._train_batchrunscross_entropy+AmpController.backward(spikeforge/training/scaleup_mixin.py:86-101) through snnTorch neurons whosespike_gradsurrogate is resolved from dynamically-discovered snnTorch factories (spikeforge/neurons/spike_grad.py:20-25,spikeforge/introspection/surrogate.py:71-79). The C runtime has no backward pass, no gradient tape, no loss, and no optimizer; itsThresholdis a strict Heaviside with no surrogate hook (include/nir_c_runtime/ops.h:81-88,src/ops.c:435). The only torch-side local rule portable without autograd is pair-based STDP (spikeforge/memory/stdp_synapse.py:64-92). - Dataset loading without torch:
build_loaderis torchvision +snntorch.utils.data_subset+torch DataLoader(spikeforge/data/data_loader.py:7-19); the dataset registry is torchvision classes (spikeforge/data/datasets.py:11-12,22-46). C has no loader at all, and tensors are batch-1 float-only (include/nir_c_runtime/tensor.h:1-6). - RNG + spike encoding: rate/latency/delta/random codings in
SpikeEncoder(spikeforge/encoding/spike_encoder.py:9-12,96-101) usetorch.rand/Bernoulli sampling; seeding istorch.manual_seed/torch.Generator(spikeforge/tracking/seed.py:33-47,tools/export_fixture.py:49-52). C has no RNG and no encoder. - Checkpoint save/load: checkpoints are
torch.savepickles (.pt: state_dict + meta + history + manifest,spikeforge/network/model_store.py:34-54) with a manifest card (spikeforge/training/checkpoint_mixin.py:62-104). C cannot read or write this format, and its JSON module is parse-only —include/nir_c_runtime/json.h:43-74exposes no serializer. - NIR export of trained state:
to_nir(spec, module)copies learned tensors out of a built torch module (spikeforge/nir_bridge/exporter.py:24-34);graph_summaryis the tensor-free JSON the C loader consumes (exporter.py:86-99);save_graphwrites the version-stampedspikeforge-nir-graphenvelope v1 (spikeforge/nir_bridge/serialization.py:52-60). There is no reverse path: nothing loads C-produced weights back into a torch module or NIR graph.
Existing bridges (all Python → C)
tools/export_fixture.py— generates the C test fixtures fromto_nir+NirInterpreter(inference golden only).graph_summaryJSON shape →nir_graph_load(include/nir_c_runtime/graph.h:88-97).- Quantized-weight envelope (
data/dtype/scale/zero_point) → dequantized at load (src/graph.c:32-76).
Sub-issues
- C Threshold is a strict Heaviside with no surrogate-gradient hook; no backward pass, loss, or optimizer exists #26 weight-update ops (surrogate-gradient hooks or STDP)
- No torch-free dataset loader: training data path is torchvision + DataLoader #27 torch-free dataset loader
- No seeded RNG or spike encoder in C: rate/latency/delta codings are torch-only #28 seeded RNG + spike encoder
- No checkpoint save/load in C: checkpoints are torch pickles and C JSON is parse-only #29 checkpoint save/load + JSON writer
- Reverse bridge missing: C-trained weights cannot flow back into NIR graphs or torch modules #30 reverse bridge (C weights back into NIR/torch) Impact if done: on-target fine-tuning / federated-edge learning without shipping Python; honest scope if not: the README "inference-only" line stays accurate.
Acceptance criteria (epic-level)
- Each sub-issue below is either implemented with C tests + a Python cross-check, or explicitly closed as out-of-scope with the README updated to say so.
- Any new C↔Python format is version-stamped like the existing
spikeforge-nir-graphv1 envelope.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
w4ffl35 commentedon Oct 14, 2026
Training-model decision for #26 (work-list item 1): option (c) — both paths behind separate APIs. PR #35 implements the surrogate-gradient path (named fast_sigmoid/atan hook, Threshold/LI/Affine/Linear backward ops, softmax CE, SGD/Adam over raw weight buffers) and the local STDP port (decay-before-update, Song/Abbott ratio preserved). Explicit follow-ups: graph-level BPTT tape retaining per-step activations, and a committed tools/ torch fixture generator.
w4ffl35 commentedon Oct 14, 2026
Phase-2 training-IO progress: #27, #28, #29, #30 are implemented in PR #37 (branch p2/training-io, commit 31fc317), one PR for the tight cluster. All four were verified live against origin/master e1bb03d before coding (no dupes/stale). 34/34 ctest pass plus ASan/UBSan 34/34. Note: PR is blocked on #36 (master does not compile; another worker's file), and torch-parity cross-checks plus the spikeforge-side state_dict loader remain as follow-ups (no torch env here). #26 (weight-update ops) is untouched, owned by the other worker.
w4ffl35 commentedon Oct 14, 2026
Epic complete: all slices merged to master — #26 via #35 (surrogate hook, backward ops, CE loss, SGD/Adam, STDP), #27-#30 via #37 (torch-free dataset loader, seeded RNG + rate/latency/delta encoders, C checkpoint save/load, reverse weight bridge), #33 via #34 (loader I/O validation). 35/35 ctest green (Debug + Release + ASan/UBSan). Closing.