Reference simulator API

Understanding how the reference simulator works is important for debugging problems, and implementing your own simulator.

In general, there are two steps to the reference simulator. The first is a build step, in which a Network is converted into a Model which consists of Signals (values that can be manipulated) and Operators (operations to be done on those values). The second is the simulator, which runs Operator functions and collects probed data. The simulator API is described in the user API.

Bekolay et al., 2014 provides a high-level description and detailed picture of the build process, which may helpful.

Build step

class nengo.builder.Model(dt=0.001, label=None, decoder_cache=<nengo.cache.NoDecoderCache object>)[source]

Output of the Builder, used by the Simulator.

Attributes

config (Config instance or None) Build functions can set a config object here to affect sub-builders.
decoder_cache (DecoderCache instance) An object that will be used to cache decoders for faster builds.
dt (float) The length of each timestep, in seconds.
label (str or None) A name or description to differentiate different models.
operators (list of Operator instances) List of all operators created in the build process. All operators must be added to this list, as it is used by Simulator.
params (dict (NengoObject -> namedtuple)) Mapping from objects to namedtuples containing parameters generated in the build process.
probes (list of Probe) List of all probes. Probes must be added to this list in the build process, as this list is used by Simulator.
seeded (dict (NengoObject -> bool)) All objects are assigned a seed, whether the user defined the seed or it was automatically generated. ‘seeded’ keeps track of whether the seed is user-defined. We consider the seed to be user-defined if it was set directly on the object, or if a seed was set on the network in which the object resides, or if a seed was set on any ancestor network of the network in which the object resides.
seeds (dict (NengoObject -> int)) Mapping from objects to the integer seed assigned to that object.
sig (dict (str -> dict (object -> Signal))) A dictionary of dictionaries that organizes all of the signals created in the build process, as build functions often need to access signals created by other build functions.
step (Signal(dtype=int64)) The current step (i.e., how many timesteps have occurred thus far).
time (Signal(dtype=float64)) The current point in time.
toplevel (Network instance) The top-level network being built. This is sometimes useful for accessing network elements after build, or for the network builder to determine if it is the top-level network.
has_built(obj)[source]

Returns true if obj has built parameters.

Some objects (e.g. synapses) do not add params and can be built more than once (i.e. this function returns false), allowing re-use.

class nengo.builder.Builder[source]

Signals

class nengo.builder.signal.Signal(initial_value, name=None, base=None, readonly=False)[source]

Represents data or views onto data within Nengo

elemoffset

Offset of data from base in elements

elemstrides

Strides of data in elements

offset

Offset of data from base in bytes.

strides

Strides of data in bytes

column()[source]

Reshape into a column vector.

row()[source]

Reshape into a row vector.

Operators

class nengo.builder.operator.Operator(tag=None)[source]

Base class for operator instances understood by nengo.Simulator.

The lifetime of a Signal during one simulator timestep:

  1. at most one set operator (optional)
  2. any number of increments
  3. any number of reads
  4. at most one update

A signal that is only read can be considered a “constant”.

A signal that is both set and updated can be a problem: since reads must come after the set, and the set will destroy whatever were the contents of the update, it can be the case that the update is completely hidden and rendered irrelevant. There are however at least two reasons to use both a set and an update:

  • to use a signal as scratch space (updating means destroying it)
  • to use sets and updates on partly overlapping views of the same memory.

N.B.: It is done on purpose that there are no default values for reads, sets, incs, and updates.

Each operator should explicitly set each of these properties.

reads

Signals that are read and not modified

sets

Signals assigned by this operator

A signal that is set here cannot be set or updated by any other operator.

incs

Signals incremented by this operator

Increments will be applied after this signal has been set (if it is set), and before reads.

updates

Signals assigned their value for time t + 1

This operator will be scheduled so that updates appear after all sets, increments and reads of this signal.

init_signals(signals)[source]

Initialize simulator.signals

Install any buffers into the signals view that this operator will need. Classes for neurons that use extra buffers should create them here.

class nengo.builder.operator.Reset(dst, value=0, tag=None)[source]

Assign a constant value to a Signal.

class nengo.builder.operator.Copy(dst, src, tag=None)[source]

Assign the value of one signal to another.

class nengo.builder.operator.DotInc(A, X, Y, tag=None)[source]

Increment signal Y by dot(A, X)

Currently, this only supports matrix-vector multiplies for compatibility with NengoOCL.

class nengo.builder.node.SimPyFunc(output, fn, t, x, tag=None)[source]

Set signal output by some Python function of x, possibly t.

class nengo.builder.neurons.SimNeurons(neurons, J, output, states=[], tag=None)[source]

Set output to neuron model output for the given input current.

class nengo.builder.learning_rules.SimOja(pre_filtered, post_filtered, weights, delta, learning_rate, beta, tag=None)[source]

Calculate delta omega according to the Oja rule.

class nengo.builder.learning_rules.SimBCM(pre_filtered, post_filtered, theta, delta, learning_rate, tag=None)[source]

Calculate delta omega according to the BCM rule.

Build functions

Nengo Objects

nengo.builder.build_network(model, network)[source]

Takes a Network object and returns a Model.

This determines the signals and operators necessary to simulate that model.

Builder does this by mapping each high-level object to its associated signals and operators one-by-one, in the following order:

  1. Ensembles, Nodes, Neurons
  2. Subnetworks (recursively)
  3. Connections
  4. Learning Rules
  5. Probes
nengo.builder.build_ensemble(model, ens)[source]
nengo.builder.build_node(model, node)[source]
nengo.builder.build_probe(model, probe)[source]
nengo.builder.build_connection(model, conn)[source]

Neurons

nengo.builder.build_lifrate(model, lifrate, neurons)[source]
nengo.builder.build_lif(model, lif, neurons)[source]
nengo.builder.build_alifrate(model, alifrate, neurons)[source]
nengo.builder.build_alif(model, alif, neurons)[source]

Learning rules

nengo.builder.build_pes(model, pes, rule)[source]
nengo.builder.build_bcm(model, bcm, rule)[source]
nengo.builder.build_oja(model, oja, rule)[source]

Synapses

nengo.builder.build_synapse(model, synapse, sig_in, sig_out=None)[source]