Skip to content

A Loihi emulator based on Brian2

License

Notifications You must be signed in to change notification settings

sagacitysite/brian2_loihi

Repository files navigation

A Loihi emulator based on Brian2

The package extends Brian2 classes such that they match Loihi simulations. While the neuron and synapse model results in an exact match to Loihi, the pre- and post-synaptic traces have very small variations from the Loihi chip due to stochastic rounding.

Further details are explained in a paper coming soon.

Installation

pip install brian2-loihi

Requirements and dependencies

Python 3.6 or higher is required.

Dependencies are automatically installed by the pip package manager.

If the source code is used directly, the following packages need to be installed:

Usage

Five Brian2 classes are extended. Available parameters are reported below. Further down you find example code.

Note:

  • It is important to use a LoihiNetwork. The Brian2 magic network approach is not supported.
  • Don't change the defaultclock.dt value. It is set to match Loihi.
  • Don't reorder the network simulation schedule.

First import the package as:

from brian2_loihi import *

The following classes can be used:

LoihiNetwork

Extends the Network class from Brian2 and supports the same parameters.

LoihiNeuronGroup

Extends the NeuronGroup class from Brian2 and supports the following parameters:

  • N (int): Number of neurons in the group.
  • refractory (int, 1...64, optional): The refactory period of the neuron.
  • threshold_v_mant (int, 0...131071, optional): The mantissa of the membrane voltage threshold.
  • decay_v (int, 0...4096, optional): The membrane voltage decay (note that tau_v = 4096/decay_v)
  • decay_I (int, 0...4096, optional): The current decay (note that tau_I = 4096/decay_I)
  • name (str, optional): A unique name for the group, otherwise use loihi_neurongroup_0, etc.

LoihiSynapses

Extends the Synapses class from Brian2 and supports the following parameters:

  • source (SpikeSource): The source of spikes, e.g. a NeuronGroup.
  • target (Group, optional): The target of the spikes, typically a NeuronGroup. If none is given, the same as source().
  • delay (int, optional): The synaptic delay.
  • dw (str, optional): Learning rule, using the pre- and post-synaptic traces. Also constant values are allowed. Note that only *, - and + is allowed.
  • w_exp (int, optional): Weight exponent which scales the weights by 2^(6 + w_exp). The weight exponent can be between -8 and 7.
  • sign_mode (int, optional): Defines if the synapses are mixed (1), excitatory (2) or inhibitory (3). Excitatory synapses are default. synapse_sign_mode can be used for defining the sign mode.
  • num_weight_bits (int, optional): Defines the precision of the weight, default is 8 bits. num_weight_bits is in a range between 0 and 8.
  • imp_x1 (int, optional): The impulse of the first synaptic pre trace x1. The impulse is between 0 and 127.
  • tau_x1 (int, optional): The time constant of the first synaptic pre trace x1. Tau has to be greater or equal to 0.
  • imp_x2 (int, optional): The impulse of the first synaptic pre trace x2. The impulse is between 0 and 127.
  • tau_x2 (int, optional): The time constant of the first synaptic pre trace x2. Tau has to be greater or equal to 0.
  • imp_y1 (int, optional): The impulse of the first synaptic post trace y1. The impulse is between 0 and 127.
  • tau_y1 (int, optional): The time constant of the first synaptic pre trace y1. Tau has to be greater or equal to 0.
  • imp_y2 (int, optional): The impulse of the first synaptic post trace y2. The impulse is between 0 and 127.
  • tau_y2 (int, optional): The time constant of the first synaptic pre trace y2. Tau has to be greater or equal to 0.
  • imp_y3 (int, optional): The impulse of the first synaptic post trace y3. The impulse is between 0 and 127.
  • tau_y3 (int, optional): The time constant of the first synaptic pre trace y3. Tau has to be greater or equal to 0.
  • name (str, optional): The name for this object. If none is given, a unique name of the form. loihi_synapses, loihi_synapses_1, etc. will be automatically chosen.

LoihiStateMonitor

Extends the StateMonitor class from Brian2 and supports the following parameters:

  • source (Group): Which object to record values from.
  • variable (str): Which variables to record, check the state object for details.
  • record (bool, sequence of ints): Which indices to record, nothing is recorded for False, everything is recorded for True (warning: may use a great deal of memory), or a specified subset of indices.
  • order (int, optional): The priority of of this group for operations occurring at the same time step and in the same scheduling slot. Defaults to 0.
  • name (str, optional): A unique name for the object, otherwise will use source.name+'loihi_statemonitor_0', etc.

LoihiSpikeMonitor

Extends the SpikeMonitor class from Brian2 and supports the following parameters:

  • source (Group): Which object to record values from.
  • variable (str, optional): Which variables to record at the time of the spike (in addition to the index of the neuron). Can be the name of a variable or a list of names
  • record (bool, sequence of ints, optional): Which indices to record, nothing is recorded for False, everything is recorded for True (warning: may use a great deal of memory), or a specified subset of indices.
  • order (int, optional): The priority of of this group for operations occurring at the same time step and in the same scheduling slot. Defaults to 0.
  • name (str, optional): A unique name for the object, otherwise will use source.name+'_loihi_spikemonitor_0', etc.

LoihiSpikeGeneratorGroup

Extends the SpikeGeneratorGroup class from Brian2 and supports the following parameters:

  • N (int): The number of "neurons" in this group
  • indices (array of integers): The indices of the spiking cells
  • times (list (int)): The spike times for the cells given in indices. Has to have the same length as indices and has to be integer (without time units)
  • period (int, optional): If this is specified, it will repeat spikes with this period. A period of 0 means not repeating spikes.
  • order (int, optional): The priority of of this group for operations occurring at the same time step and in the same scheduling slot. Defaults to 0.
  • sorted (bool, optional): Whether the given indices and times are already sorted. Set to True if your events are already sorted (first by spike time, then by index), this can save significant time at construction if your arrays contain large numbers of spikes. Defaults to False.
  • name (str, optional): A unique name for the object, otherwise will use loihi_spikegeneratorgroup_0', etc.

Example

More examples and further details are provided in this repository:

https://github.com/sagacitysite/brian2_loihi_utils

Here we just provide a simple example.

Single neuron

import matplotlib.pyplot as plt
from brian2_loihi import *

# Define a single neuron
loihi_group = LoihiNeuronGroup(
    1,
    refractory=2,
    threshold_v_mant=400,
    decay_v=1024,
    decay_I=1024
)

# Excitatory input spikes
ex_neuron_indices = [0, 0, 0, 0]
ex_spike_times = [12, 14, 40, 80]

# Inhibitory input spikes
in_neuron_indices = [0, 0, 0]
in_spike_times = [50, 60, 90]

# Define spike generators
generator_ex = LoihiSpikeGeneratorGroup(1, ex_neuron_indices, ex_spike_times)
generator_in = LoihiSpikeGeneratorGroup(1, in_neuron_indices, in_spike_times)

# Connect excitatory generator with neuron
syn_ex = LoihiSynapses(generator_ex, loihi_group, sign_mode=synapse_sign_mode.EXCITATORY)
syn_ex.connect()
syn_ex.w = 124

# Connect inhibitory generator with neuron
syn_in = LoihiSynapses(generator_in, loihi_group, sign_mode=synapse_sign_mode.INHIBITORY)
syn_in.connect()
syn_in.w = -124

# Probe synaptic input using a state monitor
mon_I = LoihiStateMonitor(loihi_group, 'I')
# Probe voltage using a state monitor
mon_v = LoihiStateMonitor(loihi_group, 'v')

# NOTE: It is important to use the LoihiNetwork,
#       using Brian's magic network is not provided
net = LoihiNetwork(
    loihi_group,
    generator_in,
    generator_ex,
    syn_ex,
    syn_in,
    mon_I,
    mon_v
)

# Run the simulation
net.run(100, report='text')

# Plot synaptic input (current)
plt.plot(mon_I.I[0])
plt.title('Synaptic input / Current')
pl = plt.show()

# Plot voltage
plt.plot(mon_v.v[0])
plt.title('Voltage')
pl = plt.show()

References

Emulator

The emulator is described in

... coming soon ...

Loihi

The Loihi chip was developed by Intel and is introduced in

M. Davies et al., "Loihi: A Neuromorphic Manycore Processor with On-Chip Learning," in IEEE Micro, vol. 38, no. 1, pp. 82-99, January/February 2018, doi: 10.1109/MM.2018.112130359.

Some further details are given in

C. Lin et al., "Programming Spiking Neural Networks on Intel’s Loihi," in Computer, vol. 51, no. 3, pp. 52-61, March 2018, doi: 10.1109/MC.2018.157113521.