-
Notifications
You must be signed in to change notification settings - Fork 0
event runtime plan
Focused design for workstream D 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. Add a sparse/event-driven execution path beside the existing dense unroll — event queues and spike-propagated synaptic operations rather than dense tensor MACs — and an energy/latency accounting model that counts synaptic operations, MACs vs. ACs, and timesteps, then maps those counts to a declared per-target cost table. Surface both in the benchmark harness, a new report, the CLI, and the dashboard. The dense path stays the untouched default.
Honesty headline. Energy numbers are estimates from declared cost tables,
never presented as measured, unless a real device is present and reports its own
timing. Every EnergyReport carries an explicit estimate: true field and a
basis describing where the numbers come from.
| Capability | Current reality | Anchor |
|---|---|---|
| Execution loop | One dense temporal loop | execution.py |
| Runner entry |
run(...) with modes |
runner.py |
| Trajectory capture |
S[t]/U[t]/I[t]
|
trajectory.py |
| Stage step | Stateless per-step (input, state)
|
stage_module.py |
| Benchmark harness | Time/memory only | harness.py |
| Op counting | None | n/a |
| Energy model | None | n/a |
| Target cost data | Constraints only (dtype, quantization) | target_spec.py |
| Sparse input | Input is already binary spikes | input_shape.py |
- The dense path (
execute,run) is the default and is unchanged; existing trajectories and tests stay byte-identical. - The sparse path returns a
Trajectorywith the same shape contract, so it is a drop-in for readout comparison. -
ExecutionMode.PRODUCTION/EDUCATIONALsemantics are unchanged (execution_mode.py). - Existing benchmark payload keys stay additive
(
server_message.py). -
referencetarget remains available; energy cost tables are declared, so an absent target still yields an estimate with a note.
The simulator already treats each stage as a pure (input, state) -> (output, state) function driven by binary spike frames
(execution.py). Dense execution
multiplies full spike tensors by weight matrices, paying for zeros. The sparse
path instead propagates events: for each step, only indices where
spike == 1 contribute, and synaptic operations are applied to those indices
only.
This is an inference path (and training-free): it has no surrogate gradients, which is fine because its purpose is honest op-counting and fast sparse inference. Training continues to use the dense path.
spikeforge_targets/event_runtime/
__init__.py
spike_view.py SparseSpikes: indices/values per frame; density helpers
ops.py event-driven linear/conv/pool applied to sparse spikes
counters.py SynapticCounter: SOP, MAC, AC, timestep tallies
sparse_runner.py sparse_run(module, spikes, counters=True) -> SparseResult
dense_compare.py compare a SparseResult to a dense Trajectory
errors.py typed sparse errors (unsupported stage kind)
| Symbol | Meaning | Rule |
|---|---|---|
| AC | accumulate operation | 1 per output element per step |
| SOP | synaptic operation | 1 per active (spike ==1) input-output pair |
| MAC | multiply-accumulate | dense baseline: 1 per input-output pair per step |
| timesteps | T |
number of temporal steps |
For a dense layer, SOP == MAC. For a sparse spike input, SOP counts only the
active pairs, so SOP/MAC is the sparse efficiency ratio the acceptance test
measures.
-
Parity:
dense_compareasserts the sparse readout equals the dense readout within tolerance on a seeded fixture. -
Reduction: on a sparse fixture (low spike density), measured
SOP < MACby the expected ratio; the test asserts a strict reduction.
Each target gains a declared cost table: energy per SOP/MAC/AC and latency per
timestep. Stored as bundled JSON next to the catalog and surfaced through the
same TargetSpec shape, so a target's costs travel with its capability matrix.
spikeforge_targets/energy/costs/
reference.json in-process estimates
norse.json simulator estimates
lava_loihi2.json declared device estimates
spinnaker2.json
speck.json
xylo.json
| Field | Meaning |
|---|---|
sop_pj |
energy per synaptic operation, picojoules |
mac_pj |
energy per dense MAC |
ac_pj |
energy per accumulate |
step_ns |
nominal latency per timestep |
source |
citation/notes for the numbers |
measured |
false for every bundled table |
A target with no bundled table still produces a report with basis: "unavailable" and a note, never a fabricated number.
spikeforge_targets/energy/
__init__.py
cost_table.py load/validate a target's declared costs
target_costs.py bundled per-target table lookup
accounting.py account(run_or_spec, target) -> EnergyReport
report.py JSON-able report assembly
probe.py isolated device probe (measured energy when present)
cli.py spikeforge-energy entry point
errors.py typed energy errors
{
"target": "reference",
"estimate": true,
"basis": "declared cost table",
"timesteps": 25,
"ops": {"sop": 120000, "mac": 400000, "ac": 80000},
"efficiency": {"sop_over_mac": 0.30},
"energy": {"sop_pj": 1200000.0, "mac_pj": 4000000.0, "total_pj": 1600000.0},
"latency": {"step_ns": 1.0, "total_ns": 25.0},
"notes": ["estimate only; no device measured"]
}estimate is true unless probe.py finds a device that reports its own
timing, in which case measured fields are added and the note changes.
benchmark/harness.py gains an opt-in
--energy path that runs the sparse runner and attaches an energy block to
each topology/mode record. Because the harness already reports unavailable
metrics as null, an unavailable cost table is null with a note, consistent
with harness.py.
| Action | Request | Reply | Payload |
|---|---|---|---|
energy_report |
{train, name: target, sparse?} |
energy_report |
EnergyReport + optional dense/sparse comparison |
Routed via protocol_handlers.py to a new
server/energy_handlers.py and server/energy_payloads.py.
New console script spikeforge-energy (energy/cli.py):
spikeforge-energy account --topology conv_net --target reference [--sparse]
spikeforge-energy report --topology conv_net --target lava_loihi2 --out energy.json
JSON output; report writes to --out when given, mirroring
_run_export.
EnergyPanel.tsx renders the report:
a dense-vs-sparse SOP/MAC bar, energy totals with a prominent "estimate" badge, a
per-stage breakdown, and the target cost source note. Types in
client/src/energyTypes.ts; hook client/src/hooks/useEnergy.ts.
-
Deliverables:
event_runtime/{__init__,spike_view,ops,counters, sparse_runner,dense_compare,errors}.py. -
Acceptance:
sparse_runonconv_netmatches the dense readout within tolerance on a seeded fixture; on a low-density fixtureSOP < MACby the expected ratio; an unsupported stage kind raises a typed error, never a silent dense fallback.
-
Deliverables:
energy/{__init__,cost_table,target_costs,accounting, report,probe,errors}.py,energy/costs/*.json. -
Acceptance:
accountmaps op counts to energy/latency for a target with a table and reportsestimate: true; a target without a table reportsbasis: "unavailable", never a number; the report is JSON-able.
-
Deliverables:
energy/cli.py, harness--energy,server/energy_handlers.py,server/energy_payloads.py, schema additions,EnergyPanel.tsx. -
Acceptance:
spikeforge-energy accountruns headless;energy_reportround-trips over a live connection; the benchmark record carries theenergyblock; the client builds and renders; existing benchmark payload keys are unchanged.
- Fidelity of sparse ops: conv/pool sparse implementations must reproduce the dense numerics exactly; the parity test is the safety net.
-
Energy credibility: numbers are inherently estimates; the design makes
that loud (
estimate,basis,source) rather than hidden. - Training-free only: the sparse path does not backpropagate; training stays dense. Stated explicitly so no one expects surrogate gradients from it.
- Deferred: measured on-device energy for Lava/Loihi (only when a device reports its own timing), event-driven training, and per-layer energy calibration against real silicon.
- 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