Skip to content

Epic: C-side training support (zero-Python/zero-torch enablement) #25

Closed

Description

@w4ffl35

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_batch runs cross_entropy + AmpController.backward (spikeforge/training/scaleup_mixin.py:86-101) through snnTorch neurons whose spike_grad surrogate 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; its Threshold is 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_loader is 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) use torch.rand/Bernoulli sampling; seeding is torch.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.save pickles (.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-74 exposes 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_summary is the tensor-free JSON the C loader consumes (exporter.py:86-99); save_graph writes the version-stamped spikeforge-nir-graph envelope 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 from to_nir + NirInterpreter (inference golden only).
  • graph_summary JSON 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

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-graph v1 envelope.

Activity

  1. w4ffl35 commented on Oct 14, 2026

    @w4ffl35
    MemberAuthor

    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.

  2. w4ffl35 commented on Oct 14, 2026

    @w4ffl35
    MemberAuthor

    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.

  3. w4ffl35 commented on Oct 14, 2026

    @w4ffl35
    MemberAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions