Repository navigation
interop foldins plan
Focused design for workstream F of the
professional_roadmap.md. Read the roadmap first for the vision, cross-workstream interfaces, and packaging rules.
Design/spec only. Every claim about the current code is grounded in a file/line reference so a Code-mode agent can execute this file-by-file.
Objective. Close the remaining gaps folded in from the earlier list:
train on event datasets, bridge to/from ONNX, ingest third-party
PyTorch modules via nirtorch, apply target quantization constraints, and
fix the small gaps — non-square sensor geometry and per-step hidden-layer
animation in the client. Each is a small, independently verifiable phase.
| Gap | Current reality | Anchor |
|---|---|---|
| Event-dataset training |
build_dataset refuses event specs (spec.cls is None) |
datasets.py |
| Event loading |
EventSampleSource, bridge, frames exist |
event_source.py, event_bridge.py
|
| ONNX | Absent | setup.py |
nirtorch extraction |
Probe exists, extraction deferred | api.py |
| Quantization | Declared in constraints only | target_spec.py |
| Geometry | 28x28 / square conv math hardcoded |
presets.py, datasets.py
|
| Hidden-layer animation | Raster snapshots only | INTEGRATION_PLAN.md |
- The image training path is unchanged; event training is additive behind the
eventsextra (datasets.py). - ONNX and extraction are opt-in extras; their absence is reported, never raised
at import (
probe.pypattern). - Quantization is only applied where the target declares support; otherwise it is reported as unapplied.
- Existing presets remain exactly 28x28 by default; geometry changes are opt-in via an explicit shape parameter.
- Existing WebSocket payload keys stay additive.
Gap. build_dataset refuses an event spec because it has no torchvision
class (datasets.py), so training never
reaches the event modality even though inference does.
Design. A thin event training engine that composes the existing pieces:
spikeforge/training/event_engine.py EventTrainingEngine: steps over EventSampleSource
spikeforge/training/event_batches.py batch an event stream into [T,B,...] via the bridge
-
event_batchesusesEventSpikeBridgeto produce the same[T, B, F]/[T, B, C, H, W]contract the simulator already consumes, so the loss/optimizer loop reusestraining_engine.pyunchanged. -
TrainingEnginelearns a modality-aware dataset step: image modality usesbuild_loader, event modality usesevent_batches; the rest of the loop, metrics, and checkpointing are shared. - Honesty: when
tonicis absent the engine raises the typedEventsExtraMissingError(event_errors.py), and a synthetic event stream is never presented as a recording (see theoriginconvention inevent_source.py).
Acceptance: a tiny event fixture trains for one epoch end to end and records
modality: event in checkpoint meta; the image path is unchanged.
Design. An isolated onnx_bridge/ package, the only module that imports
onnx/onnxruntime, behind the onnx extra:
spikeforge/onnx_bridge/
__init__.py
api.py isolated onnx/onnxruntime probe + import helpers
export.py export the built module's forward graph to ONNX
import_onnx.py import an ONNX graph and map it to a topology spec
errors.py typed unsupported-op errors
-
Export takes the built
StageModuleand traces a single step to ONNX, emitting metadata that names the topology and the temporal contract (the ONNX graph is one step; the loop stays in the simulator). This mirrors the "declarative-first" philosophy: the module is one rendering, ONNX is another. -
Import maps ONNX ops (
Gemm,Conv,MatMul,Relu, ...) to stage kinds where a faithful mapping exists and raises a typed error naming any op it cannot map — never a silent partial. - Honesty: an op with no SNN-equivalent is reported; an ONNX model with dynamic temporal behavior is explicitly out of scope and noted.
Acceptance: conv_net exports and re-imports to a graph whose summary
matches; an unsupported op raises a typed error naming it.
Gap. api.py probes nirtorch but
no extraction path is wired.
Design. nir_bridge/extract.py exposes
extract(module) -> NIRGraph | UnsupportedNodeError:
- Uses
nirtorch.extract_nir_graph(isolated inapi.py) to lift an arbitrarytorch.nn.Moduleinto NIR. - Any node
nirtorchcannot map raises the existing typedUnsupportedNodeErrorinerrors.py, consistent with the ingest path (ingest.py). - The extracted graph is then runnable by the reference interpreter and classifyable by the capability matrix, so a third-party PyTorch model can be inspected and deployed like any other.
Acceptance: a small hand-built nn.Sequential extracts to NIR and
interprets; an unsupported node raises the typed error naming it.
Gap. Targets declare quantization in constraints
(catalog.py) but nothing applies it.
Design. targets/quantize.py applies a target's declared quantization to a
built module's weights:
- Supported schemes (seed):
none(no-op),weight_int8,weight_uint8(per-tensor symmetric/asymmetric, matching the declared constraint strings incatalog.py). - Applied only where the target declares support; a target that declares
nonegets a no-op report; an unknown scheme is reported unapplied, never guessed. - A quantization report lists per-layer before/after ranges and the drift this
induces, reusing the drift machinery
(
drift.py). - The rewrite/backend pipeline (WS-B) can call
quantizeafter substitution and before compile, so a deployment is quantized exactly when its target requires it.
Acceptance: quantizing conv_net for lava_loihi2 clamps weights to int8
and reports the induced drift; a none-quantization target reports a no-op; an
unknown scheme is reported unapplied.
The transform hardcodes 28x28 (datasets.py)
and conv_net derives its feature size from a square side
(presets.py).
Design: allow an explicit (height, width) shape:
-
datasets.transform(size=(28, 28))takes a shape; the default is unchanged. - Presets accept
input_sizeasint(square, unchanged) or(h, w); the feature-size math becomeschannels * (h/4) * (w/4). -
input_shape(input_shape.py) and theSampleSourcesize accessor propagate the tuple. - Defaults keep every shipped preset byte-identical.
Acceptance: a (32, 28) input builds and runs through conv_net; the
default path is unchanged.
Gap. INTEGRATION_PLAN.md deliberately deferred per-step hidden-layer
animation (INTEGRATION_PLAN.md); only rasters are
streamed.
Design: extend the existing spike_frame stream
(messages.py) to optionally emit a hidden/output
frame per step during run, gated by an additive EncodeConfig.animate_hidden
flag. The client
(NetworkActivity.tsx) already
renders activity frames; it gains a per-step playback mode driven by the stream.
Default stays off, so existing payloads and the run cost are unchanged.
Acceptance: with animate_hidden set, hidden frames stream per step and the
client animates them; with it unset, the payload stream is identical to today.
| Phase | Deliverables | Acceptance |
|---|---|---|
| F1 Event training |
training/event_engine.py, training/event_batches.py, modality routing in training_engine.py
|
one-epoch event fixture trains; meta.modality == "event"; image path unchanged |
| F2 ONNX bridge |
onnx_bridge/{__init__,api,export,import_onnx,errors}.py; onnx extra |
conv_net exports and re-imports; unsupported op raises typed error |
F3 nirtorch extraction |
nir_bridge/extract.py |
nn.Sequential extracts + interprets; unsupported node raises typed error |
| F4 Quantization | targets/quantize.py |
int8 applied with drift report; none is a no-op; unknown scheme reported |
| F5 Geometry + animation |
datasets.py, presets.py, input_shape.py, messages.py, EncodeConfig, NetworkActivity.tsx
|
non-square runs; default unchanged; animation opt-in streams frames |
- ONNX temporal semantics: ONNX has no native SNN time loop; the bridge is explicitly one-step + external loop, and mismatches are reported.
-
nirtorchcoverage: arbitrary modules may contain unmappable nodes; the typed error names them rather than silently truncating the graph. - Quantization fidelity: applied quantization changes numerics; the report quantifies the drift so it is never mistaken for free.
- Deferred: event-driven training (WS-D is inference-only), ONNX training graphs, multi-precision quantization (int4), and non-uniform sensor downsampling.
- Home
- Architecture
- Backend Execution
- Benchmarks
- Dashboard
- Development
- Event Datasets
- Event Runtime And Energy
- Features
- Implications And Boundaries
- Interop Foldins
- Interpreter Spine
- Introspection
- Model Deployment
- Model Hub
- Notes
- Operational Maturity
- Production Workflows
- Project Layout
- Quickstart
- Requirements
- Sequence Primitives
- Streaming Timeseries
- Targets And Interop
- Usage
- Arch 0001 Adr Repo Topology
- Arch 0001 Core Boundary
- Arch 0001 Decision Metrics
- Arch 0001 Migration Plan
- Arch 0001 Packaging Versioning
- Arch 0001 Protocol Contract
- Arch 0001 Risk Register
- Arch 0001 Target Topology
- Backend Execution Plan
- Ecosystem Listings
- Ecosystem Roadmap
- Event Runtime Plan
- Hub Expansion Plan
- Plans
- Interop Foldins Plan
- Interpreter Spine Plan
- Memory System Research
- Model Hub Plan
- Operations Plan
- Production Toolkit Plan
- Production Use Cases
- Professional Roadmap
- Repo Topology Plan
- Sequence Primitives Plan
- Use Case Audio Keyword Spotting
- Use Case Biosignal Medical Monitoring
- Use Case Computational Neuroscience
- Use Case Edge Power Budgets
- Use Case Event Camera Vision
- Use Case Intrusion Anomaly Detection
- Use Case Low Latency Sensor Stream
- Use Case Rl Control Robotics
- Use Case Spiking Transformers
- Use Case Streaming Timeseries