snnlab 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- snnlab/__init__.py +6 -0
- snnlab/lang/README.md +385 -0
- snnlab/lang/__init__.py +99 -0
- snnlab/lang/_version.py +3 -0
- snnlab/lang/compiler.py +1289 -0
- snnlab/lang/components.py +153 -0
- snnlab/lang/core.py +458 -0
- snnlab/lang/diagram.py +371 -0
- snnlab/lang/examples/__init__.py +1 -0
- snnlab/lang/examples/build_examples.py +148 -0
- snnlab/lang/ops.py +64 -0
- snnlab/lang/readouts.py +128 -0
- snnlab/lang/schemas/snn-graph-v1.schema.json +25 -0
- snnlab/lang/schemas/snn-training-v1.schema.json +15 -0
- snnlab/lang/simulation.py +312 -0
- snnlab/lang/training.py +107 -0
- snnlab/sim/__init__.py +5 -0
- snnlab/sim/__main__.py +6 -0
- snnlab/sim/_version.py +3 -0
- snnlab/sim/accelerator_forward.py +283 -0
- snnlab/sim/bundle.py +757 -0
- snnlab/sim/config.py +844 -0
- snnlab/sim/conformance.py +215 -0
- snnlab/sim/datasets.py +211 -0
- snnlab/sim/encoders.py +59 -0
- snnlab/sim/execution.py +4036 -0
- snnlab/sim/infer.py +1336 -0
- snnlab/sim/inputs.py +128 -0
- snnlab/sim/metrics.py +298 -0
- snnlab/sim/models.py +1664 -0
- snnlab/sim/profiling.py +73 -0
- snnlab/sim/runlog.py +843 -0
- snnlab/sim/scan.py +83 -0
- snnlab/sim/simulation_inputs.py +265 -0
- snnlab/sim/timing.py +81 -0
- snnlab/sim/tool.py +2494 -0
- snnlab/sim/train.py +1338 -0
- snnlab/viz/README.md +287 -0
- snnlab/viz/__init__.py +21 -0
- snnlab/viz/_version.py +3 -0
- snnlab/viz/animation.py +68 -0
- snnlab/viz/contracts.py +58 -0
- snnlab/viz/diagrams.py +329 -0
- snnlab/viz/figure_grid.py +319 -0
- snnlab/viz/layouts.py +25 -0
- snnlab/viz/loaders.py +59 -0
- snnlab/viz/scene.py +65 -0
- snnlab/viz/styles.py +76 -0
- snnlab/viz/transforms.py +60 -0
- snnlab-0.1.1.dist-info/METADATA +76 -0
- snnlab-0.1.1.dist-info/RECORD +54 -0
- snnlab-0.1.1.dist-info/WHEEL +4 -0
- snnlab-0.1.1.dist-info/entry_points.txt +2 -0
- snnlab-0.1.1.dist-info/licenses/LICENSE +21 -0
snnlab/__init__.py
ADDED
snnlab/lang/README.md
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# snnlang
|
|
2
|
+
|
|
3
|
+
`snnlang` is a standalone Python authoring library for graph-shaped spiking
|
|
4
|
+
circuits. It validates a network and optional standard training recipe, then
|
|
5
|
+
writes a deterministic, data-only bundle. It does not simulate or train.
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
from snnlab import lang as snn
|
|
9
|
+
|
|
10
|
+
net = snn.Network("small_ping")
|
|
11
|
+
events = net.input(
|
|
12
|
+
"events", shape=("time", "batch", 128), signal_type="spikes", unit="spike"
|
|
13
|
+
)
|
|
14
|
+
cell = snn.components.ping(net, name="cell", n_e=256, n_i=64, source=events)
|
|
15
|
+
scores = snn.readouts.MeanVoltage(
|
|
16
|
+
source=cell.E.spikes, classes=10, name="classifier"
|
|
17
|
+
)
|
|
18
|
+
net.output("scores", scores)
|
|
19
|
+
|
|
20
|
+
bundle = snn.compile(net)
|
|
21
|
+
bundle.write("small_ping.bundle", visualise=True)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The bundle contains canonical `graph.json`, optional `training.json`, a
|
|
25
|
+
digest-bearing `manifest.json`, copied logical assets, a text summary, and
|
|
26
|
+
optional circuit/training/expanded SVG and PNG reports. Physical dataset and
|
|
27
|
+
checkpoint paths deliberately do not belong in the graph.
|
|
28
|
+
|
|
29
|
+
Projection weights use `uS` (microsiemens), matching the conductance convention
|
|
30
|
+
of the graph executor and its `leak_us` neuron parameters. SNNLang and the graph
|
|
31
|
+
executor both reject projection parameters labelled with another unit; values
|
|
32
|
+
are never silently rescaled. Bundles produced before SNNLang 0.2.0 may carry an
|
|
33
|
+
incorrect legacy `nS` label even though their values were executed as `uS`.
|
|
34
|
+
|
|
35
|
+
`snnlang` owns the semantic projection of a bundle through `snn.diagram(...)`;
|
|
36
|
+
the resulting renderer-neutral diagram is rendered by `tools.snnviz`. The
|
|
37
|
+
existing `Bundle.visualise(...)` convenience method delegates through this same
|
|
38
|
+
boundary.
|
|
39
|
+
|
|
40
|
+
Inputs are graph contracts, not stimulus recipes. A time-varying spike input
|
|
41
|
+
uses the canonical `(time, batch, channels)` axis order and declares its signal
|
|
42
|
+
type and unit. Dataset selection, Poisson rates, encoders, seeds, durations, and
|
|
43
|
+
realised spike tensors belong to the experiment protocol. `tools/snnsim` may
|
|
44
|
+
generate a standard stimulus from CLI parameters or consume an exact replay
|
|
45
|
+
with `--input-file` or `--event-file`; the replay is optional evidence, not part
|
|
46
|
+
of the graph.
|
|
47
|
+
|
|
48
|
+
Dense replay is resolved before graph execution. NPY files bind to the sole
|
|
49
|
+
graph input; NPZ arrays bind by input id. The resolver requires exact input
|
|
50
|
+
coverage, matching time and batch axes, declared feature shapes, finite values,
|
|
51
|
+
binary spikes, and boolean or zero/one masks. It records a versioned execution
|
|
52
|
+
protocol containing source-file digests, resolved shapes and dtypes, dataset
|
|
53
|
+
identity and split when supplied, sample cap, batch size, shuffle behavior,
|
|
54
|
+
duration, masks, and the execution seed.
|
|
55
|
+
|
|
56
|
+
Sparse event replay uses an NPZ coordinate contract. A single-input file stores
|
|
57
|
+
`steps`, `batches`, `channels`, `steps_count`, and `batch_size`; multi-input
|
|
58
|
+
files prefix each field with the graph input id. Coordinates are zero-based
|
|
59
|
+
integer simulation steps ordered by step, batch, and channel. Resolution rejects
|
|
60
|
+
duplicates and out-of-bounds coordinates, then materializes binary spikes for
|
|
61
|
+
the graph executor while retaining event counts and source identity in the
|
|
62
|
+
protocol. Typed requests may combine event-stream spike inputs with dense mask
|
|
63
|
+
or continuous inputs when every binding resolves to the same time and batch
|
|
64
|
+
axes.
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
uv run python -m snnlab.sim sim \
|
|
68
|
+
--executor graph \
|
|
69
|
+
--bundle small_ping.bundle \
|
|
70
|
+
--input-file replay.npz \
|
|
71
|
+
--input-dataset-id mnist-test-sha256-... \
|
|
72
|
+
--input-split test \
|
|
73
|
+
--no-input-shuffle \
|
|
74
|
+
--seed 17 \
|
|
75
|
+
--out-dir run/
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The resolved contract is written under `execution_protocol` in `metrics.json`.
|
|
79
|
+
Generated Poisson inputs are execution protocols rather than graph structure.
|
|
80
|
+
`PoissonInputBinding` supports a fixed rate or a rate sampled uniformly and
|
|
81
|
+
independently per presentation from a categorical set. The resolver owns an
|
|
82
|
+
explicit seed, records both configured and realized rates, and uses the graph
|
|
83
|
+
timestep to materialize Bernoulli-discretized homogeneous Poisson spikes.
|
|
84
|
+
|
|
85
|
+
Portable dataset snapshots use `DatasetSnapshotBinding` and remain external
|
|
86
|
+
immutable NPZ files. The binding authenticates the file, selects samples by a
|
|
87
|
+
seeded permutation and cap, binds integer labels to an optional training target,
|
|
88
|
+
and applies one standard `DatasetEncoder`:
|
|
89
|
+
|
|
90
|
+
- `rate_poisson`: finite normalized `(samples, channels)` features scaled by a
|
|
91
|
+
maximum rate and sampled for a physical duration;
|
|
92
|
+
- `prebinned_spikes`: exact binary `(time, samples, channels)` replay;
|
|
93
|
+
- `event_bin`: timestamped sample/channel events binned at graph `dt`, with
|
|
94
|
+
binary collision counts retained in provenance.
|
|
95
|
+
|
|
96
|
+
The `tools/snnsim.dataset-snapshot-binding/v1` protocol records the source digest,
|
|
97
|
+
dataset identity and split, selected indices, keys, sample cap, batch size,
|
|
98
|
+
shuffle policy, timing, encoder parameters, labels, and execution/order/encoder
|
|
99
|
+
seeds. No download or dataset registry is consulted.
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
uv run python -m snnlab.sim train \
|
|
103
|
+
--executor graph \
|
|
104
|
+
--bundle deep_network.bundle \
|
|
105
|
+
--dataset-file shd-train-recording.npz \
|
|
106
|
+
--dataset-encoder event-bin \
|
|
107
|
+
--dataset-target-id gesture \
|
|
108
|
+
--input-dataset-id shd-train-sha256-... \
|
|
109
|
+
--input-split train \
|
|
110
|
+
--t-ms 100 \
|
|
111
|
+
--max-samples 1000 \
|
|
112
|
+
--input-shuffle \
|
|
113
|
+
--seed 17 \
|
|
114
|
+
--out-dir train-run/
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
uv run python -m snnlab.sim sim \
|
|
119
|
+
--executor graph \
|
|
120
|
+
--bundle small_ping.bundle \
|
|
121
|
+
--poisson-protocol categorical-rate \
|
|
122
|
+
--input-rates 0.5 1 5 10 25 \
|
|
123
|
+
--n-batch 64 \
|
|
124
|
+
--t-ms 200 \
|
|
125
|
+
--seed 17 \
|
|
126
|
+
--out-dir run/
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Run all examples:
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
uv run python -m snnlab.lang.examples.build_examples
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The generated examples include a 784-channel, 10-class one-layer PING recipe
|
|
136
|
+
and a 700-channel, 20-class three-layer PING hierarchy. The deep example now
|
|
137
|
+
contains an executable training recipe with every feedforward, recurrent, and
|
|
138
|
+
readout parameter assigned to an explicit group plus a six-population spike
|
|
139
|
+
budget. Focused local acceptance cases use tiny synthetic batches to validate
|
|
140
|
+
their production-shaped public tensors, recurrent gradients, fine-timestep
|
|
141
|
+
recompilation, and categorical variable-rate protocol. They do not substitute
|
|
142
|
+
for dataset accuracy, accelerator parity, or the final campaign comparison.
|
|
143
|
+
|
|
144
|
+
Graph validity is checked independently of a simulator backend. Passing
|
|
145
|
+
`target="tools/snnsim"` adds capability diagnostics but never changes the graph.
|
|
146
|
+
The first additive `tools/snnsim` backend route accepts the deliberately narrow
|
|
147
|
+
single-layer MNIST PING subset:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
uv run python -m snnlab.sim sim \
|
|
151
|
+
--bundle small_ping.bundle \
|
|
152
|
+
--t-ms 200 \
|
|
153
|
+
--out-dir run/
|
|
154
|
+
|
|
155
|
+
uv run python -m snnlab.sim train \
|
|
156
|
+
--bundle tools/snnlang/examples/generated/ping_classifier.bundle \
|
|
157
|
+
--max-samples 1000 \
|
|
158
|
+
--batch-size 64 \
|
|
159
|
+
--out-dir train-run/
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Execution choices such as duration, seed, input mode, output directory, and
|
|
163
|
+
recordings remain CLI concerns. Structural flags cannot override the bundle.
|
|
164
|
+
For the first training subset, `training.json` owns cross-entropy, AdamW,
|
|
165
|
+
epochs, learning rate, and a trainable input/readout plus frozen recurrent
|
|
166
|
+
scope; dataset cap and batch size remain execution choices.
|
|
167
|
+
Parameter groups are exhaustive and non-overlapping. The compiled recipe also
|
|
168
|
+
contains resolved trainable/frozen parameter lists and a stable per-parameter
|
|
169
|
+
learning-rate map; frozen groups use zero and trainable groups require a
|
|
170
|
+
positive finite rate.
|
|
171
|
+
The standard backward contract uses an explicit fast-sigmoid surrogate and
|
|
172
|
+
positive per-population voltage-gradient dampening factors. Compilation records
|
|
173
|
+
both in `resolved_gradients`; the legacy adapter maps the supported shared
|
|
174
|
+
dampening case back to its established CLI settings.
|
|
175
|
+
Training recipes may declare a physical presentation duration independently of
|
|
176
|
+
graph `dt`, plus the collection's exact multi-layer spike-budget penalty. Its
|
|
177
|
+
stored aggregation contract is the mean over presentations and layers of each
|
|
178
|
+
population's mean-rate squared overshoot above a ceiling in Hz.
|
|
179
|
+
Before serialization, reverse reachability proves that every objective and
|
|
180
|
+
regularizer reaches at least one trainable parameter through enabled graph
|
|
181
|
+
elements. The check respects frozen groups and stop-gradient boundaries and
|
|
182
|
+
reports the exact reachable and trainable sets when a route is absent.
|
|
183
|
+
Unsupported graph structures fail with an element-level capability error;
|
|
184
|
+
legacy commands that omit `--bundle` retain their existing defaults and
|
|
185
|
+
behaviour.
|
|
186
|
+
|
|
187
|
+
## Graph-native forward execution
|
|
188
|
+
|
|
189
|
+
The opt-in graph backend is exposed through typed requests. Bundle loading is
|
|
190
|
+
still data-only and does not import this authoring package.
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
import torch
|
|
194
|
+
from snnlab.sim.execution import ExecutionSpec, simulate
|
|
195
|
+
|
|
196
|
+
result = simulate(ExecutionSpec(
|
|
197
|
+
kind="simulate",
|
|
198
|
+
executor="graph",
|
|
199
|
+
bundle="small_ping.bundle",
|
|
200
|
+
inputs={"events": torch.zeros(100, 1, 128)},
|
|
201
|
+
))
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
For explicit provenance, pass `DenseArrayBinding` objects through
|
|
205
|
+
`ExecutionSpec.input_bindings`; the original `inputs={...}` tensor mapping is a
|
|
206
|
+
compatible in-memory shorthand and is resolved through the same validator.
|
|
207
|
+
|
|
208
|
+
The planner lowers the complete dense topology before stepping. It supports
|
|
209
|
+
arbitrarily named COBA-LIF and leaky-integrator populations, independent spike
|
|
210
|
+
inputs, AMPA and GABA projections, feedforward/recurrent/feedback paths,
|
|
211
|
+
integral delay buffers, standard readout operations, and recordings from every
|
|
212
|
+
named population. Mean voltage, final voltage, spike count, spike rate, and
|
|
213
|
+
cumulative-potential readouts execute through the graph operation vocabulary.
|
|
214
|
+
Spike-rate readouts report spikes/s from either an explicit duration in seconds
|
|
215
|
+
or a `(time, batch)` valid-time mask whose duration is inferred from graph
|
|
216
|
+
`dt`. Zero-delay feedforward edges follow a deterministic topological order.
|
|
217
|
+
Recurrent and feedback spikes are causal, so zero additional delay means one
|
|
218
|
+
simulation step. Positive delays must be exact integer multiples of the declared
|
|
219
|
+
timestep. Zero-delay cycles, dimension errors, malformed masks, ambiguous
|
|
220
|
+
durations, polarity mismatches, and missing backend capabilities fail before
|
|
221
|
+
simulation.
|
|
222
|
+
|
|
223
|
+
Projections authored with `enabled=False` remain in the graph with the same
|
|
224
|
+
parameter shape, initializer, name, and construction position, but contribute
|
|
225
|
+
zero conductance at runtime. Controlled cells can therefore disable a recurrent
|
|
226
|
+
loop without shifting later tensor identities or random initialization draws.
|
|
227
|
+
|
|
228
|
+
Initializer specifications distinguish lower-clamped and signed normals,
|
|
229
|
+
uniform, constant, and zero distributions. Lower-clamped normals can apply
|
|
230
|
+
seeded Bernoulli or exact-fan-in initial zeroing. Build metrics expose stable
|
|
231
|
+
per-parameter realized statistics together with the constraint, unit, runtime
|
|
232
|
+
shape, and fan-in scaling convention.
|
|
233
|
+
|
|
234
|
+
The typed graph API supports deterministic single-batch AdamW updates for the
|
|
235
|
+
validated cross-entropy and spike-budget vocabulary. `ExecutionSpec` supplies
|
|
236
|
+
resolved inputs and external targets; a bundle may authenticate and supply its
|
|
237
|
+
training recipe. Results expose per-update loss components, named gradients,
|
|
238
|
+
parameters, and optimizer state.
|
|
239
|
+
|
|
240
|
+
Graph training accepts named integer target arrays from NPY/NPZ files through
|
|
241
|
+
the same provenance boundary as inputs. With a positive recipe epoch count it
|
|
242
|
+
iterates the input sample axis in deterministic mini-batches, optionally using
|
|
243
|
+
a seed-derived permutation per epoch. The execution protocol records target
|
|
244
|
+
digests, dataset identity and split, sample cap, batch size, shuffle policy,
|
|
245
|
+
epoch count, and order seed.
|
|
246
|
+
|
|
247
|
+
Graph training checkpoints use a versioned manifest plus a digest-verified
|
|
248
|
+
tensor payload. They key parameters and AdamW state by stable graph id and
|
|
249
|
+
record graph/training digests, completed updates, execution protocol,
|
|
250
|
+
initializer metadata, CPU random state, exact named accelerator random states,
|
|
251
|
+
and the exact next epoch/batch. Manifest version 2 records `cpu`, `cuda`, or
|
|
252
|
+
`mps` as the random backend. CUDA captures every contiguous device generator;
|
|
253
|
+
MPS captures its single generator. Resume requires the same backend and exact
|
|
254
|
+
device topology before changing any stream. CPU-only version 1 checkpoints
|
|
255
|
+
remain loadable. The
|
|
256
|
+
trainer can save final and invocation-selected checkpoints and resume exactly after rejecting recipe,
|
|
257
|
+
protocol, initializer, shape, dtype, or parameter-set mismatches. An explicit
|
|
258
|
+
one-layer legacy parameter map fails closed when any graph parameter is
|
|
259
|
+
unrepresentable. Mocked topology tests cover accelerator-state serialization
|
|
260
|
+
and fail-closed restore dispatch, but production accelerator trajectory parity
|
|
261
|
+
remains a hardware gate. The legacy CLI
|
|
262
|
+
and bundle adapter remain the default and retain their historical numerical
|
|
263
|
+
contract.
|
|
264
|
+
|
|
265
|
+
`tools/snnsim/conformance.py` provides the versioned, fail-closed comparison layer
|
|
266
|
+
for migration evidence. It compares complete named tensor layers under an
|
|
267
|
+
explicit exact or numerical policy, reports coverage, shape, dtype, and error
|
|
268
|
+
bounds, and writes `tools/snnsim.conformance-report/v1` JSON. Canonical JSON
|
|
269
|
+
encoding brings topology, initializer metadata, protocols, and checkpoint
|
|
270
|
+
coordinates into the same report as forward outputs, gradients, parameters,
|
|
271
|
+
and optimizer tensors. Declared tolerance rules that match no field are errors.
|
|
272
|
+
|
|
273
|
+
The first cross-backend CPU fixtures copy one complete one-layer parameter set
|
|
274
|
+
through the semantic legacy map and compare E/I spikes, membrane traces,
|
|
275
|
+
input/AMPA/GABA conductances, and mean-voltage logits with recurrence both
|
|
276
|
+
isolated and active. Dynamic state and parameters match exactly; logits use a
|
|
277
|
+
predeclared `1e-6` absolute/relative tolerance. The fixtures established that
|
|
278
|
+
legacy recurrent keys are one-based (`W_ee.1`,
|
|
279
|
+
`W_ei.1`, `W_ie.1`, and `W_ii.1`) and that the compatible mean-voltage readout
|
|
280
|
+
uses the legacy 2 ms output-membrane time constant.
|
|
281
|
+
|
|
282
|
+
The bounded forward accelerator check reuses the active-recurrence case. It
|
|
283
|
+
runs the graph executor twice on one accelerator, then compares graph and
|
|
284
|
+
legacy forward state on that same device under predeclared `1e-6` absolute and
|
|
285
|
+
relative tolerances. It deliberately excludes training, checkpoints, datasets,
|
|
286
|
+
and cross-device equality:
|
|
287
|
+
|
|
288
|
+
```sh
|
|
289
|
+
uv run python tools/snnsim/accelerator_forward.py --device mps
|
|
290
|
+
# or, on a CUDA host:
|
|
291
|
+
uv run python tools/snnsim/accelerator_forward.py --device cuda
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The corresponding four-update backward fixture trains all six mapped tensors
|
|
295
|
+
and compares the complete cross-entropy trajectory, final named surrogate
|
|
296
|
+
gradients, constrained parameters, and AdamW step/first-moment/second-moment
|
|
297
|
+
tensors under the same frozen CPU policy. A two-plus-two checkpoint resume is
|
|
298
|
+
bit-identical to the uninterrupted graph trajectory.
|
|
299
|
+
Both routes apply the non-negative parameter projection after the optimizer
|
|
300
|
+
step; optimizer state itself remains the unconstrained AdamW update record.
|
|
301
|
+
|
|
302
|
+
`import_legacy_parameters_v1` and `export_legacy_parameters_v1` provide
|
|
303
|
+
bidirectional parameter-only interchange for the supported one-layer legacy
|
|
304
|
+
state. They require exact keys, runtime shapes, floating dtypes, and complete
|
|
305
|
+
graph coverage, and return mapping-version/direction provenance. Legacy
|
|
306
|
+
optimizer objects are not presented as portable graph training checkpoints.
|
|
307
|
+
|
|
308
|
+
Graph simulation/inference can load a selected or final training-checkpoint
|
|
309
|
+
directory after authenticating its payload, graph digest, names, shapes, and
|
|
310
|
+
dtypes. Inference metrics retain checkpoint format/path, graph and training
|
|
311
|
+
digests, completed update, and selected loss; optimizer and iterator state are
|
|
312
|
+
not restored for inference. Non-directory checkpoints remain the explicit
|
|
313
|
+
legacy PyTorch state-file route.
|
|
314
|
+
|
|
315
|
+
Inference variations use the request-local `tools/snnsim.inference-overrides/v1`
|
|
316
|
+
contract. Generated Poisson inputs may override a positive, timestep-aligned
|
|
317
|
+
duration and a finite non-negative rate. Named graph projections may be scaled
|
|
318
|
+
by finite non-negative factors after checkpoint loading. The original graph and
|
|
319
|
+
checkpoint stay unchanged, and metrics record the requested and resolved
|
|
320
|
+
values. Unknown projection ids, mixed replay/Poisson duration requests, and
|
|
321
|
+
non-resampleable replay tensors fail closed. A `timestep_ms` override recompiles
|
|
322
|
+
an immutable graph copy, rebuilds physical decays and delays, and resamples only
|
|
323
|
+
generated Poisson bindings while preserving their physical duration. Runtime
|
|
324
|
+
state is not converted. Checkpoints authenticate against the source graph
|
|
325
|
+
before named, same-shaped parameters load into the effective graph.
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
result = simulate(ExecutionSpec(
|
|
329
|
+
kind="simulate",
|
|
330
|
+
executor="graph",
|
|
331
|
+
bundle="small_ping.bundle",
|
|
332
|
+
checkpoint="train-run/selected.checkpoint",
|
|
333
|
+
poisson_bindings=(binding,),
|
|
334
|
+
options={"inference_overrides": {
|
|
335
|
+
"duration_ms": 400.0,
|
|
336
|
+
"input_rate_hz": 25.0,
|
|
337
|
+
"projection_scales": {"cell_I_to_E": 0.5},
|
|
338
|
+
}},
|
|
339
|
+
))
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
The CLI accepts repeatable `--scale-projection ID=FACTOR`; generated Poisson
|
|
343
|
+
duration and rate continue to use `--t-ms` and `--input-rate`, and
|
|
344
|
+
`--inference-timestep-ms` requests the recompiled timebase.
|
|
345
|
+
|
|
346
|
+
Ordered hidden-spike interventions use
|
|
347
|
+
`tools/snnsim.inference-interventions/v1`. `drop_spikes` removes emitted spikes by
|
|
348
|
+
a finite probability in `[0, 1]`; `add_poisson_spikes` unions them with a
|
|
349
|
+
seeded homogeneous Poisson stream at a finite non-negative rate supported by
|
|
350
|
+
the graph timestep. Targets are exact ids of spiking populations. Modified
|
|
351
|
+
spikes flow through downstream zero-delay projections, delay histories,
|
|
352
|
+
recordings, and readouts. Seed streams are keyed by absolute execution step, so
|
|
353
|
+
runtime continuation matches an uninterrupted request exactly.
|
|
354
|
+
|
|
355
|
+
```sh
|
|
356
|
+
uv run python -m snnlab.sim sim \
|
|
357
|
+
--executor graph \
|
|
358
|
+
--bundle small_ping.bundle \
|
|
359
|
+
--input-file replay.npz \
|
|
360
|
+
--intervention drop:cell_E=0.25 \
|
|
361
|
+
--intervention add:cell_E=5 \
|
|
362
|
+
--seed 17 \
|
|
363
|
+
--out-dir intervention-run/
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Every graph CLI inference directory also contains
|
|
367
|
+
`inference-manifest.json` using `tools/snnsim.inference-artifacts/v1`. It records
|
|
368
|
+
the graph and request identity, request seed, and the names, shapes, dtypes, and
|
|
369
|
+
SHA-256 digest of each NPZ payload. The request digest binds the execution
|
|
370
|
+
protocol, checkpoint, overrides, interventions, recording profile, and device.
|
|
371
|
+
Use `validate_inference_artifacts(path, graph=graph, seed=seed)` before cache
|
|
372
|
+
reuse; it rejects manifest drift, a different graph or seed, missing files,
|
|
373
|
+
payload corruption, and array-inventory changes. Task-specific accuracy and
|
|
374
|
+
raster aggregation remain experiment-level operations over these stable named
|
|
375
|
+
tensors.
|
|
376
|
+
|
|
377
|
+
`derive_inference_products` provides the standard conversion layer for those
|
|
378
|
+
public tensors. Given an authenticated inference directory, an exact logits id,
|
|
379
|
+
integer labels, and exact population-spike recording ids, it writes versioned
|
|
380
|
+
labels, predictions, accuracy, per-presentation per-cell rates in Hz, and
|
|
381
|
+
sparse zero-based time/batch/cell rasters. The
|
|
382
|
+
`tools/snnsim.derived-inference/v1` manifest authenticates all derived payloads and
|
|
383
|
+
retains the source artifact digest. `validate_derived_inference_products`
|
|
384
|
+
rejects corruption or reuse against a different source cache. Scientific
|
|
385
|
+
acceptance thresholds remain campaign decisions rather than executor defaults.
|
snnlab/lang/__init__.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""snnlang: deterministic authoring and inspection of spiking network graphs."""
|
|
2
|
+
|
|
3
|
+
from . import components, ops, readouts, simulation, training
|
|
4
|
+
from ._version import __version__
|
|
5
|
+
from .compiler import Bundle, Diagnostic, compile, load_bundle, validate_graph
|
|
6
|
+
from .core import (
|
|
7
|
+
AMPA,
|
|
8
|
+
COBA_LIF,
|
|
9
|
+
GABA,
|
|
10
|
+
LIF,
|
|
11
|
+
Constant,
|
|
12
|
+
Hz,
|
|
13
|
+
LeakyIntegrator,
|
|
14
|
+
LowerClampedNormal,
|
|
15
|
+
Modulatory,
|
|
16
|
+
Network,
|
|
17
|
+
NonNegative,
|
|
18
|
+
Normal,
|
|
19
|
+
ParameterRef,
|
|
20
|
+
Population,
|
|
21
|
+
Projection,
|
|
22
|
+
Quantity,
|
|
23
|
+
Signal,
|
|
24
|
+
SignedNormal,
|
|
25
|
+
Uniform,
|
|
26
|
+
Zeros,
|
|
27
|
+
ms,
|
|
28
|
+
mV,
|
|
29
|
+
nS,
|
|
30
|
+
uS,
|
|
31
|
+
)
|
|
32
|
+
from .diagram import diagram
|
|
33
|
+
from .simulation import (
|
|
34
|
+
BackgroundChannel,
|
|
35
|
+
CellDistribution,
|
|
36
|
+
ConductanceBackground,
|
|
37
|
+
ConductanceSchedule,
|
|
38
|
+
CorrelatedPoissonAfferents,
|
|
39
|
+
GlobalShotNoise,
|
|
40
|
+
GroupedShotNoise,
|
|
41
|
+
ShotNoise,
|
|
42
|
+
SimulationSpec,
|
|
43
|
+
StationaryRateWeather,
|
|
44
|
+
StructuredPoisson,
|
|
45
|
+
TransientAfferentWave,
|
|
46
|
+
)
|
|
47
|
+
from .training import TrainSpec
|
|
48
|
+
|
|
49
|
+
__all__ = [
|
|
50
|
+
"AMPA",
|
|
51
|
+
"GABA",
|
|
52
|
+
"COBA_LIF",
|
|
53
|
+
"LIF",
|
|
54
|
+
"Constant",
|
|
55
|
+
"LeakyIntegrator",
|
|
56
|
+
"LowerClampedNormal",
|
|
57
|
+
"Modulatory",
|
|
58
|
+
"Network",
|
|
59
|
+
"NonNegative",
|
|
60
|
+
"Normal",
|
|
61
|
+
"ParameterRef",
|
|
62
|
+
"Population",
|
|
63
|
+
"Projection",
|
|
64
|
+
"Quantity",
|
|
65
|
+
"Signal",
|
|
66
|
+
"SignedNormal",
|
|
67
|
+
"Uniform",
|
|
68
|
+
"Zeros",
|
|
69
|
+
"TrainSpec",
|
|
70
|
+
"SimulationSpec",
|
|
71
|
+
"StructuredPoisson",
|
|
72
|
+
"CorrelatedPoissonAfferents",
|
|
73
|
+
"StationaryRateWeather",
|
|
74
|
+
"TransientAfferentWave",
|
|
75
|
+
"ConductanceBackground",
|
|
76
|
+
"BackgroundChannel",
|
|
77
|
+
"ShotNoise",
|
|
78
|
+
"GlobalShotNoise",
|
|
79
|
+
"GroupedShotNoise",
|
|
80
|
+
"CellDistribution",
|
|
81
|
+
"ConductanceSchedule",
|
|
82
|
+
"Bundle",
|
|
83
|
+
"Diagnostic",
|
|
84
|
+
"compile",
|
|
85
|
+
"diagram",
|
|
86
|
+
"load_bundle",
|
|
87
|
+
"validate_graph",
|
|
88
|
+
"components",
|
|
89
|
+
"ops",
|
|
90
|
+
"readouts",
|
|
91
|
+
"training",
|
|
92
|
+
"simulation",
|
|
93
|
+
"Hz",
|
|
94
|
+
"mV",
|
|
95
|
+
"ms",
|
|
96
|
+
"nS",
|
|
97
|
+
"uS",
|
|
98
|
+
"__version__",
|
|
99
|
+
]
|
snnlab/lang/_version.py
ADDED