Synaptic matrix types are made up of two components: SynapseMatrixConnectivity and SynapseMatrixWeight. SynapseMatrixConnectivity defines what data structure is used to store the synaptic matrix:
- SynapseMatrixConnectivity::DENSE stores synaptic matrices as a dense matrix. Large dense matrices require a large amount of memory and if they contain a lot of zeros it may be inefficient.
- SynapseMatrixConnectivity::SPARSE stores synaptic matrices in a(padded) 'ragged array' format. In general, this is less efficient to traverse using a GPU than the dense matrix format but does result in significant memory savings for large matrices. Sparse matrix connectivity is stored using several variables whose names, like state variables, have the name of the synapse population appended to them:
const unsigned int maxRowLength
: a constant set via the SynapseGroup::setMaxConnections
method which specifies the maximum number of connections in any given row (this is the width the structure is padded to).
unsigned int *rowLength
(sized to number of presynaptic neurons): actual length of the row of connections associated with each presynaptic neuron
unsigned int *ind
(sized to maxRowLength * number of presynaptic neurons
): Indices of corresponding postsynaptic neurons concatenated for each presynaptic neuron. For example, consider a network of two presynaptic neurons connected to three postsynaptic neurons: 0th presynaptic neuron connected to 1st and 2nd postsynaptic neurons, the 1st presynaptic neuron connected only to the 0th neuron. Indexing starts from 0 and X represents a padding value: maxRowLength = 2
ind = [1 2 0 X]
rowLength = [2 1]
Weight update model variables associated with the sparsely connected synaptic population will be kept in an array using the same indexing as ind. For example, a variable caled g
will be kept in an array such as: g=
[g_Pre0-Post1 g_pre0-post2 g_pre1-post0 X]
- SynapseMatrixConnectivity::BITMASK is an alternative sparse matrix implementation where which synapses within the matrix are present is specified as a binary array (see Insect olfaction model). This structure is somewhat less efficient than the
SynapseMatrixConnectivity::SPARSE
format and doesn't allow individual weights per synapse. However it does require the smallest amount of GPU memory for large networks.
- SynapseMatrixConnectivity::PROCEDURAL is a new approach where, rather than being stored in memory, connectivity described using Sparse connectivity initialisation is generated 'on the fly' as spikes are processed (see [3] for more information). Therefore, this approach offers very large memory savings for a small performance cost but does not currently support plasticity.
- SynapseMatrixConnectivity::TOEPLITZ is another new approach where, kernel-based connectivity like convolutions described using Toeplitz connectivity initialisation is generated 'on the fly' as spikes are processed. As well as offering the large memory savings of
SynapseMatrixConnectivity::PROCEDURAL
, if the batch size is large enough it also out-performs both SynapseMatrixConnectivity::SPARSE
and SynapseMatrixConnectivity::PROCEDURAL
.
In Python, SynapseMatrixConnectivity::SPARSE connectivity can be manually initialised from lists of pre and postsynaptic indices using the pygenn.SynapseGroup.set_sparse_connections method. Furthermore the SynapseMatrixWeight
defines how
Only certain combinations of SynapseMatrixConnectivity
and SynapseMatrixWeight
are sensible therefore, to reduce confusion, the SynapseMatrixType
enumeration defines the following options which can be passed to ModelSpec::addSynapsePopulation pygenn.GeNNModel.add_synapse_population :
In Python, these matrix types can be selected by their unqualified name e.g. "DENSE_INDIVIDUALG".
Previous | Top | Next