Neuron models and their cost
Choosing a model
Every grown network runs with any registered model:
from neurogenesis.spiking.batch import simulate_counts
counts = simulate_counts(nets, currents, ticks=300, model="hh") # "lif_int" (default), "two_compartment", "hh"
All models share the same transmission layer: the same synapses, axonal delays (up to 255 ticks of 1 ms) and driver neurons. The Poisson drivers and intrinsic bursters fire at exactly the same ticks in every model (tested). Models differ in how a neuron integrates its inputs between spikes.
Model |
Level |
Integration |
Uses from the grown network |
Known properties tested |
|---|---|---|---|---|
|
point neuron, integer |
1 update per tick |
everything (leak and synaptic shifts, threshold, refractory period) |
identical spikes in Python, JAX and the browser |
|
soma + dendrite, intermediate |
Euler, 4 substeps per tick |
membrane time constant 2^shift_v ms, synaptic time constant 2^shift_s ms, threshold, refractory period |
same rheobase as |
|
Hodgkin–Huxley point neuron (Na, K, leak) |
exponential Euler for gates, 40 substeps of 0.025 ms |
synaptic time constant; threshold and refractoriness come from the channels |
rest near −65 mV; abrupt onset of repetitive firing (type II) near 6.3 µA/cm² from rest, at 50–60 Hz; about 65–70 Hz at 10 µA/cm² |
Units. External currents and synaptic weights keep the toolbox’s integer units.
Hodgkin–Huxley: 1 unit = 0.74 µA/cm², so its onset of repetitive firing falls at the integer neuron’s rheobase (8.5 units).
Two compartments: the conversion is set the same way.
Weights: a synaptic weight w delivers the charge of a w-unit current lasting 1 ms.
This makes the models comparable on the same network, not quantitatively equivalent.
Adding a model: neurogenesis.spiking.models.register_model(module). The module provides name, description,
substeps, state_bytes, flops, init_state(net, seed) and tick(net, state, ext), and uses
models.base.drivers and models.base.transmit, so that drivers and delays behave as in every other model. Then add it
to the parametrised tests in tests/test_models.py.
Knowing the cost before trying
python -m neurogenesis estimate --neurons 3e8 --synapses-per-neuron 5000 --seconds 1
For each model, the estimator gives:
memory, counted array by array: neuron parameters and state, synapse arrays and their per-tick buffers, recorded counts;
the memory available (free GPU memory if JAX runs on a GPU, else RAM);
the time per simulated second.
How the time is computed. It comes from a throughput measured once per model and device: three short benchmarks,
fitting a fixed cost per tick, a cost per neuron-substep and a cost per synapse. The result is cached in
~/.cache/neurogenesis/throughput.json. The tests check that the estimate stays within a factor of 4 of the measured
time on a 3000-neuron, 120 000-synapse network.
Guard rail. Every batched simulation calls cost.check first:
it refuses a network that does not fit in memory (
CostError, unlessforce=True);it warns when a calibrated estimate exceeds one hour.
Example on the development cluster CPU (2026-11-01; numbers depend on the machine):
Network |
lif_int |
two_compartment |
hh |
|---|---|---|---|
10⁴ neurons, 10⁷ synapses |
250 MB; ~25 min / simulated s |
250 MB; ~47 min / simulated s |
250 MB; ~26 min / simulated s |
3 × 10⁸ neurons, 5000 synapses each (an order of magnitude for a primate ventral visual stream, illustrative only) |
does not fit: 37.5 TB; ~7 years / simulated s |
does not fit; ~13 years / s |
does not fit; ~7 years / s |
On this CPU, synapses dominate both memory and time; the neuron model matters once neurons dominate. For 10⁶ neurons without synapses, Hodgkin–Huxley costs about 50 times more than the integer neuron (40 substeps of a heavier update). Large extrapolations are linear and ignore memory bandwidth and multi-device communication, so they are optimistic.