| Version 1 (modified by pierre, 17 months ago) |
|---|
Simulator-specific optimizations
[WikiStart [Home]]
This page explains how to optimize your code, in pyNN, for particular simulators. Those are specific options/code instructions that will make your pyNN code tuned to a particular backend, sometimes breaking compatibility with the others. However, if you would like to speed up your code and if at a particular time, here are some tricks you should know
General observations
Assemblies
When recording an Assembly object, i.e the concatenation of several populations, you should notice that saving the recorded data to file is taking some time. In fact, even if the user is allowed to do that, this is something you could maybe avoid, in order to speed up the writing times of large data files. Merging all the indices and the recorded data from the populations within the Assembly involves sorting large arrays, and this is not optimal. So instead of doing:
>>> exc = Population(10000, IF_curr_exp) >>> inh = Population(2500, IF_curr_exp) >>> all_cells = exc + inh >>> all_cells.record() >>> run(simtime) >>> all_cells.printSpikes(file)
You should do:
>>> exc = Population(10000, IF_curr_exp) >>> inh = Population(2500, IF_curr_exp) >>> all_cells = exc + inh >>> all_cells.record() >>> run(simtime) >>> exc.printSpikes(file_exc) >>> inh.printSpikes(file_inh)
This is more convenient in a sense that data will be sorted by populations in two files at the end, and it will be faster.
NEST
Fast Connectors
In NEST, the pyNN.connectors objects are not taking advantages of the mpirun command, because they are based on the function nest.ConvergentConnect which does not scale well with the number of nodes. Therefore, if you want to reduce the building times of your network according to the number of nodes used by your parallel simulations, you should use the following Connectors:
- FastFixedProbabilityConnector
- FastDistanceDependentProbabilityConnector
- FastAllToAllConnector
- FastSmallWorldConnector
- FastFromListConnector
- FixedNumberPreConnector
However, note that those connectors (based on nest.DivergentConnect function) will not lead to the same networks.
SpikeSourcePoisson
The SpikeSourcePoisson in pyNN is meant to be an object that can be connected to various targets, and send the same spike train realisation to all its targets. However, quite often, you may end up by building a large network of cells that you would like to be able to bombard with external noise. Creating as many SpikeSourcePoisson as cells in your network is very inefficient in NEST, because those Stimulating Devices are not meant to be numerous. Moreover, in NEST, a single poisson_generator object is able to send independent realizations of the spike trains to all its targets. So instead of doing:
>>> population = Population(10000, IF_curr_exp)
>>> noise = Population(10000, SpikeSourcePoisson, {'rate' : 1000.})
>>> prj = Projection(noise, population, OneToOneConnector(weights=w))
You should use the native cell type poisson_generator from NEST and write:
>>> population = Population(10000, IF_curr_exp)
>>> noise = Population(1, native_cell_type("poisson_generator"), {'rate' : 1000.})
>>> prj = Projection(noise, population, AllToAllConnector(weights=w))
This will be much more efficient. However, you won't be able anymore to record the noise population, because those devices can not be recorded
BRIAN
Fast Connectors
In BRIAN, the pyNN.connectors objects are not taking advantages of the homogeneous delays, because they are made such that a user is always able to change the delays, even after connections have been created. However, BRIAN is much more efficient when using homogeneous delays in a projection. Building and simulations times are faster, and memory usage more efficient. Therefore, if you know in advance that you're creating a projection with homogeneous delay that will not be changed afterwards, then you should use the following connectors:
- FastFixedProbabilityConnector
- FastDistanceDependentProbabilityConnector
- FastAllToAllConnector
- FastSmallWorldConnector
- FastOneToOneConnector
So instead of doing, if your delay d is a constant:
>>> population = Population(10000, IF_curr_exp) >>> prj = Projection(population, population, OneToOneConnector(weights=w, delays=d))
You should use the FastConnectors and write:
>>> population = Population(10000, IF_curr_exp) >>> prj = Projection(population, population, FastOneToOneConnector(weights=w, delays=d))
This will be much more efficient. However, you won't be able anymore to change the delays of this projection.
