API reference¶
Simulator¶
This is the NengoOCL simulator.
It uses the Nengo builder to take a model
and turn it into signals and operators.
Then, we copy all the signals into OpenCL,
and create OpenCL versions of all the operators.
This is what the Simulator.plan_*
functions do;
each one of them is responsible for
creating an OpenCL kernel (or kernels)
to execute the corresponding operator.
-
class
nengo_ocl.
Simulator
(network, dt=0.001, seed=None, model=None, context=None, n_prealloc_probes=32, profiling=None, if_python_code='none', planner=<function greedy_planner>, progress_bar=True)[source]¶ Simulator for running Nengo models in OpenCL.
- Parameters
- network, dt, seed, model
These parameters are the same as in
nengo.Simulator
.- context
pyopencl.Context
(optional) OpenCL context specifying which device(s) to run on. By default, we will create a context by calling
pyopencl.create_some_context
and use this context as the default for all subsequent instances.- n_prealloc_probesint (optional)
Number of timesteps to buffer when probing. Larger numbers mean less data transfer with the device (faster), but use more device memory.
- profilingboolean (optional)
If
True
,print_profiling()
will show profiling information. By default, will check the environment variableNENGO_OCL_PROFILING
- if_python_code‘none’ | ‘warn’ | ‘error’
How the simulator should react if a Python function cannot be converted to OpenCL code.
- plannercallable
A function to plan operator order. See
nengo_ocl.planners
.
-
property
dt
¶ (float) The time step of the simulator.
-
property
n_steps
¶ (int) The current time step of the simulator.
-
property
time
¶ (float) The current time of the simulator.
-
property
signals
¶ Get/set [properly-shaped] signal value (either 0d, 1d, or 2d)
-
close
(self)[source]¶ Closes the simulator.
Any call to
Simulator.run
,Simulator.run_steps
,Simulator.step
, andSimulator.reset
on a closed simulator raises anengo.exceptions.SimulatorClosed
exception.
-
reset
(self, seed=None)[source]¶ Reset the simulator state.
- Parameters
- seedNone
Not implemented. Changing the simulator seed during reset is not supported by NengoOCL.
-
run
(self, time_in_seconds, progress_bar=None)[source]¶ Simulate for the given length of time.
If the given length of time is not a multiple of
dt
, it will be rounded to the nearestdt
. For example, ifdt
is 0.001 andrun
is called withtime_in_seconds=0.0006
, the simulator will advance one timestep, resulting in the actual simulator time being 0.001.The given length of time must be positive. The simulator cannot be run backwards.
- Parameters
- time_in_secondsfloat
Amount of time to run the simulation for. Must be positive.
- progress_barbool or
nengo.utils.progress.ProgressBar
, optional Progress bar for displaying the progress of the simulation run.
If True, the default progress bar will be used. If False, the progress bar will be disabled. For more control over the progress bar, pass in a
nengo.utils.progress.ProgressBar
instance.
-
run_steps
(self, steps, progress_bar=True)[source]¶ Simulate for the given number of
dt
steps.- Parameters
- stepsint
Number of steps to run the simulation for.
- progress_barbool or
nengo.utils.progress.ProgressBar
, optional Progress bar for displaying the progress of the simulation run.
If True, the default progress bar will be used. If False, the progress bar will be disabled. For more control over the progress bar, pass in a
nengo.utils.progress.ProgressBar
instance.
-
trange
(self, sample_every=None, dt=None)[source]¶ Create a vector of times matching probed data.
Note that the range does not start at 0 as one might expect, but at the first timestep (i.e.,
dt
).- Parameters
- sample_everyfloat, optional
The sampling period of the probe to create a range for. If None, a time value for every
dt
will be produced.Changed in version 2.0.0: Renamed from dt to sample_every
clra_nonlinearities¶
This is where the kernels for most operators are
(i.e. most of the Simulator.plan_*
functions
call a plan_*
function in here to generate the kernel).
Each plan function follows roughly the same template:
Do some checks on the arguments.
Generate the C code for the kernel, using Mako to fill in variable things like datatypes.
Compile the C code as a PyOpenCL Program, and set the arguments.
Create and return a
Plan
object responsible for executing thatpyopencl.Program
.
OpenCL kernels for everything other than GEMV.
-
nengo_ocl.clra_nonlinearities.
blockify_ij
(max_size, ra)[source]¶ Blockify a single matrix or vector using the offset method
-
nengo_ocl.clra_nonlinearities.
plan_elementwise_inc
(queue, A, X, Y, alpha=None, outer=False, inc=True, tag=None)[source]¶ Implements an element-wise increment Y += alpha * A * X
- Parameters
- alphanp.ndarray or None
Scalars to apply to each operation.
- outerbool
Perform an outer product.
A
andX
must be vectors.- incbool
Whether to increment
Y
(True), or set it (False).
-
nengo_ocl.clra_nonlinearities.
plan_linearfilter
(queue, X, Y, A, B, Xbuf, Ybuf, tag=None)[source]¶ Implements a filter of the form
y[n+1] + a[0] y[n] + … + a[i] y[n-i] = b[0] x[n] + … + b[j] x[n-j]
-
nengo_ocl.clra_nonlinearities.
plan_probes
(queue, periods, X, Y, tag=None)[source]¶ - Parameters
- Praggedarray of ints
The period (in time-steps) of each probe
-
nengo_ocl.clra_nonlinearities.
plan_conv2d
(queue, X, Y, filters, shape_in, shape_out, kernel_shape, conv=True, biases=None, padding=0, 0, strides=1, 1, channels_last=True, tag=None, transposed=False)[source]¶ - Parameters
- filters = ch x size_i x size_j x nf # conv transposed
filters = ch x size_i x size_j x nf x ni x nj # local transposed biases = nf x ni x nj
conv : whether this is a convolution (true) or local filtering (false)
clra_gemv¶
This contains kernels specific to the GEMV (matrix-vector multiply) operation, since it’s such an important and specialized operation. Most people will not need to know the details of this module.
OpenCL kernels for performing general matrix-vector multiplies (GEMV).
-
nengo_ocl.clra_gemv.
ref_impl
(p, items)[source]¶ Return an OCL function to calculate
items
of gemv operationp
.In this reference implementation, we create a work item per output number, or more specifically, a work grid of shape
(max_y_len, len(items))
. Each work item loops over the dot products and the elements within each dot product to compute the output valueY[global_id(1)][global_id(0)]
.
-
nengo_ocl.clra_gemv.
plan_sparse_dot_inc
(queue, A_indices, A_indptr, A_data, X, Y, inc=False, tag=None)[source]¶ Implements a sparse matrix-vector multiply: Y += A * X or Y = A * X
- Parameters
- A_indices, A_indptrPyOpenCL array
Column sparse row index specifications
- A_dataPyOpenCL array
Matrix values at those indices
- X, YCLRaggedArrays of length 1
Input/output data.
- incbool
Whether to increment
Y
(True), or set it (False).
Notes
This function crashes when there are >10M nonzero weights. A potential solution would be some way to tell each work item to do multiple rows.
RaggedArrays¶
You can think of a RaggedArray
a list of arrays.
Whereas NumPy allows lists of arrays
of the same size to be made into one big array
(e.g. if you’ve got five 3x2 arrays,
you can make a 5x3x2 array),
there’s no way to make arrays
of different sizes into one big one.
RaggedArray does this
by making one big memory buffer where all the data is stored,
and managing the reading and writing of that.
-
class
nengo_ocl.raggedarray.
RaggedArray
(arrays, names=None, dtype=None, align=False)[source]¶ A linear buffer partitioned into sections of various lengths.
Can also be viewed as an efficient way of storing a list of arrays, in the same underlying buffer.
-
class
nengo_ocl.clraggedarray.
CLRaggedArray
(queue, np_raggedarray)[source]¶ A linear device buffer partitioned into sections of various lengths.
Can also be viewed as an efficient way of storing a list of arrays on the device, in the same underlying buffer.
Operators¶
Additional operators, and functions for pruning/simplifying operators.
-
class
nengo_ocl.operators.
MultiDotInc
(Y, Y_in, beta, gamma, tag=None)[source]¶ y <- gamma + beta * y_in + \sum_i dot(A_i, x_i)
-
property
reads
¶ Signals that are read and not modified by this operator.
Reads occur after increments, and before updates.
-
property
incs
¶ Signals incremented by this operator.
Increments will be applied after sets (if it is set), and before reads.
-
property
sets
¶ Signals set by this operator.
Sets occur first, before increments. A signal that is set here cannot be set or updated by any other operator.
-
property
updates
¶ Signals updated by this operator.
Updates are the last operation to occur to a signal.
-
make_step
(self, signals, dt, rng)[source]¶ Returns a callable that performs the desired computation.
This method must be implemented by subclasses. To fully understand what an operator does, look at its implementation of
make_step
.- Parameters
- signalsSignalDict
A mapping from signals to their associated live ndarrays.
- dtfloat
Length of each simulation timestep, in seconds.
- rng
numpy.random.RandomState
Random number generator for stochastic operators.
-
property
-
nengo_ocl.operators.
signal_io_dicts
(operators)[source]¶ Organizes operators into dictionaries according to the signals they set/inc/read/update.
Copied from Nengo DL. See there for full documentation
-
nengo_ocl.operators.
remove_unmodified_resets
(operators)[source]¶ Remove any Reset operators that are targeting a signal that is never modified.
If a signal is reset, but never inced/updated after that, we can just set the default signal value to the reset value and remove the reset. Note: this wouldn’t normally happen, but it can happen if we removed some of the incs (e.g. in
remove_zero_incs
).
-
nengo_ocl.operators.
remove_zero_incs
(operators)[source]¶ Remove any operators where we know the input (and therefore output) is zero.
If the input to a DotInc/ElementwiseInc/Copy/ConvInc is zero then we know that the output of the op will be zero, so we can just get rid of it.
- Parameters
- operatorslist of
Operator
Operators in the model
- operatorslist of
- Returns
- new_operatorslist of
Operator
Modified list of operators
- new_operatorslist of
Notes
Copied from
nengo_dl/graph_optimizer.py
.
Python AST conversion¶
This module contains a parser to turn Python functions into OCL code.
Todo
Better testing, i.e., write test cases for all the test functions at the bottom of this file.
Todo
Get binary_and, or, xor, etc. functions working (priority = low)
this will require the ability to specify integer input variables
or perhaps just cast inputs to these functions to integers
Todo
A danger right now is that there is no check that the user uses all passed inputs in their function. For example, if the fn is meant to act on three arguments, and the user makes a mistake in their model that passes a 5-vector to the function, no warning is issued. There’s no obvious way to deal with this better, though.
Utils¶
Utility functions and compatibility imports.
-
nengo_ocl.utils.
equal_strides
(strides1, strides2, shape)[source]¶ Check whether two arrays have equal strides.
Code from https://github.com/inducer/compyte