Releases: genn-team/genn
Service release 2.2
Release Notes for GeNN v2.2
This release includes minor new features, some core code improvements and several bug fixes on GeNN v2.1.
User Side Changes
-
GeNN now analyses automatically which parameters each kernel needs access to and these and only these are passed in the kernel argument list in addition to the global time t. These parameters can be a combination of extraGlobalNeuronKernelParameters and extraGlobalSynapseKernelParameters in either neuron or synapse kernel. In the unlikely case that users wish to call kernels directly, the correct call can be found in the
stepTimeGPU()
function.
Reflecting these changes, the predefined Poisson neurons now simply have two extraGlobalNeuronParameterrates
andoffset
which replace the previous pointer argument ofstepTimeGPU()
to the array of input rates and integer offset to indicate the current input pattern. TheseextraGlobalNeuronKernelParameters
are passed to the neuron kernel automatically, but the rates themselves within the array are of course not updated automatically (this is exactly as before with the specifically generated kernel arguments for Poisson neurons).
In case of doubt, please refer to classol::runGPU. The C arrays d_pattern and d_baserates were prepared earlier in the user side code in classol::allocate_device_mem_patterns.
The concept of "directInput" has been removed. Users can easily achieve the same functionality by adding an additional variable (if there are individual inputs to neurons), an extraGlobalNeuronParameter (if the input is homogeneous but time dependent) or, obviously, a simple parameter if it's homogeneous and constant.Note: The global time variable "t" is now provided by GeNN; please make sure that you are not duplicating its definition or shadowing it. This could have severe consequences for simulation correctness (e.g. time not advancing in cases of over-shadowing).
-
We introduced the namespace GENN_PREFERENCES which contains variables that determine the behaviour of GeNN.
-
We introduced a new code snippet called "supportCode" for neuron models, weightupdate models and post-synaptic models. This code snippet is intended to contain user-defined functions that are used from the other code snippets. We advise where possible to define the support code functions with the CUDA keywords "host device" so that they are available for both GPU and CPU version. Alternatively one can define separate versions for host and device in the snippet. The snippets are automatically made available to the relevant code parts. This is regulated through namespaces so that name clashes between different models do not matter. An exception are hash defines. They can in principle be used in the supportCode snippet but need to be protected specifically using
ifndef. For example
#ifndef clip(x)
#define clip(x) x > 10.0? 10.0 : x
#endif
Note: If there are conflicting definitions for hash defines, the one that appears first in the GeNN generated code will then prevail.
- The new convenience macros spikeCount_XX and spike_XX where "XX" is the name of the neuron group are now also available for events: spikeEventCount_XX and spikeEvent_XX. They access the values for the current time step even if there are synaptic delays and spikes events are stored in circular queues.
- The old buildmodel.[sh|bat] scripts have been superseded by new genn-buildmodel.[sh|bat] scripts. These scripts accept UNIX style option switches, allow both relative and absolute model file paths, and allow the user to specify the directory in which all output files are placed (-o ). Debug (-d), CPU-only (-c) and show help (-h) are also defined.
- We have introduced a CPU-only "-c" genn-buildmodel switch, which, if it's defined, will generate a GeNN version that is completely independent from CUDA and hence can be used on computers without CUDA installation or CUDA enabled hardware. Obviously, this then can also only run on CPU. CPU only mode can either be switched on by defining CPU_ONLY in the model description file or by passing appropriate parameters during the build, in particular
genn-buildmodel.[sh|bat] \<modelfile\> -c
make release CPU_ONLY=1
- The new genn-buildmodel "-o" switch allows the user to specify the output directory for all generated files - the default is the current directory. For example, a user project could be in '/home/genn_project', whilst the GeNN directory could be '/usr/local/genn'. The GeNN directory is kept clean, unless the user decides to build the sample projects inside of it without copying them elsewhere. This allows the deployment of GeNN to a read-only directory, like '/usr/local' or 'C:\Program Files'. It also allows multiple users - i.e. on a compute cluster - to use GeNN simultaneously, without overwriting each other's code-generation files, etcetera.
- The ARM architecture is now supported - e.g. the NVIDIA Jetson development platform.
- The NVIDIA CUDA SM_5* (Maxwell) architecture is now supported.
- An error is now thrown when the user tries to use double precision floating-point numbers on devices with architecture older than SM_13, since these devices do not support double precision.
- All GeNN helper functions and classes, such as
toString()
andNNmodel
, are defined in the header files atgenn/lib/include/
, for examplestringUtils.h
andmodelSpec.h
, which should be individually included before the functions and classes may be used. The functions and classes are actually implementated in the static librarygenn\lib\lib\genn.lib
(Windows) orgenn/lib/lib/libgenn.a
(Mac, Linux), which must be linked into the final executable if any GeNN functions or classes are used. - In the
modelDefinition()
file, only the header filemodelSpec.h
should be included - i.e. not the source filemodelSpec.cc
. This is because the declaration and definition ofNNmodel
, and associated functions, has been separated intomodelSpec.h
andmodelSpec.cc
, respectively. This is to enable NNmodel code to be precompiled separately. Henceforth, only the header filemodelSpec.h
should be included in model definition files! - In the
modelDefinition()
file, DT is now preferrably defined usingmodel.setDT(<val>);
, rather than #define DT <val>
, in order to prevent problems with DT macro redefinition. For backward-compatibility reasons, the old #define DT <val>
method may still be used, however users are advised to adopt the new method. - In preparation for multi-GPU support in GeNN, we have separated out the compilation of generated code from user-side code. This will eventually allow us to optimise and compile different parts of the model with different CUDA flags, depending on the CUDA device chosen to execute that particular part of the model. As such, we have had to use a header file
definitions.h
as the generated code interface, rather than therunner.cc
file. In practice, this means that user-side code should includemyModel_CODE/definitions.h
, rather thanmyModel_CODE/runner.cc
. Includingrunner.cc
will likely result in pages of linking errors at best!
Developer Side Changes
- Blocksize optimization and device choice now obtain the ptxas information on memory usage from a CUDA driver API call rather than from parsing ptxas output of the nvcc compiler. This adds robustness to any change in the syntax of the compiler output.
- The information about device choice is now stored in variables in the namespace
GENN_PREFERENCES
. This includeschooseDevice
,optimiseBlockSize
,optimizeCode
,debugCode
,showPtxInfo
,defaultDevice
.asGoodAsZero
has also been moved into this namespace. - We have also introduced the namespace GENN_FLAGS that contains unsigned int variables that attach names to numeric flags that can be used within GeNN.
- The definitions of all generated variables and functions such as pullXXXStateFromDevice etc, are now generated into definitions.h. This is useful where one wants to compile separate object files that cannot all include the full definitions in e.g. "runnerGPU.cc". One example where this is useful is the brian2genn interface.
- A number of feature tests have been added that can be found in the
featureTests
directory. They can be run with the respectiverunTests.sh
scripts. ThecleanTests.sh
scripts can be used to remove all generated code after testing.
Improvements
- Improved method of obtaining ptxas compiler information on register and shared memory usage and an improved algorithm for estimating shared memory usage requirements for different block sizes.
- Replaced pageable CPU-side memory with page-locked memory. This can significantly speed up simulations in which a lot of data is regularly copied to and from a CUDA device.
- GeNN library objects and the main generateALL binary objects are now compiled separately, and only when a change has been made to an object's source, rather than recompiling all software for a minor change in a single source file. This should speed up compilation in some instances.
Bug fixes:
- Fixed a minor bug with delayed synapses, where delaySlot is declared but not referenced.
- We fixed a bug where on rare occasions a synchronisation problem occurred in sparse synapse populations.
- We fixed a bug where the combined spike event condition from several synapse populations was not assembled correctly in the code generation phase (the parameter values of the first synapse population over-rode the values of all other populations in the combined condition).
Please refer to...
Service release 2.1
Release Notes for GeNN v2.1
This release includes some new features and several bug fixes
on GeNN v2.0.
User Side Changes
- Block size debugging flag and the asGoodAsZero variables are moved into include/global.h.
- NGRADSYNAPSES dynamics have changed (See Bug fix #4) and this change is applied to the example projects. If you are using this synapse model,
you may want to consider changing model parameters. - The delay slots are now such that NO_DELAY is 0 delay slots (previously 1) and 1 means an actual delay of 1 time step.
- The convenience function convertProbabilityToRandomNumberThreshold(float , uint64_t *, int) was changed so that it actually converts firing probability/timestep into a threshold value for the GeNN random number generator (as its name always suggested). The previous functionality of converting a *rate in kHz into a firing threshold number for the GeNN random number generator is now provided with the name convertRateToRandomNumberThreshold(float *, uint64_t *, int)
- Every model definition function
modelDefinition()
now needs to end with callingNNmodel::finalize()
for the defined network model. This will lock down the model and prevent any further changes to it by the supported methods. It also triggers necessary analysis of the model structure that should only be performed once. If thefinalize()
function is not called, GeNN will issue an error and exit before code generation. - To be more consistent in function naming the
pull<SYNAPSENAME>FromDevice
andpush<SYNAPSENAME>ToDevice
have been renamed topull<SYNAPSENAME>StateFromDevice
andpush<SYNAPSENAME>StateToDevice
. The old versions are still supported through macro definitions to make the transition easier. - New convenience macros are now provided to access the current spike numbers and identities of neurons that spiked. These are called spikeCount_XX and spike_XX where "XX" is the name of the neuron group. They access the values for the current time step even if there are synaptic delays and spikes are stored in circular queues.
- There is now a pre-defined neuron type "SPIKECOURCE" which is empty and can be used to define PyNN style spike source arrays.
- The macros FLOAT and DOUBLE were replaced with GENN_FLOAT and GENN_DOUBLE due to name clashes with typedefs in Windows that define FLOAT and DOUBLE.
Developer Side Changes
- We introduced a file definitions.h, which is generated and filled with useful macros such as spkQuePtrShift which tells users where in the circular spike queue their spikes start.
Improvements
- Improved debugging information for block size optimisation
and device choice. - Changed the device selection logic so that device occupancy has larger priority than device capability version.
- A new HH model called TRAUBMILES_PSTEP where one can set the number of inner loops as a parameter is introduced. It uses the TRAUBMILES_SAFE method.
- An alternative method is added for the insect olfaction model in order
to fix the number of connections to a maximum of 10K in order to avoid
negative conductance tails. - We introduced a #define for an "int_" function that translates floating points to integers.
Bug fixes:
- AtomicAdd replacement for old GPUs were used by mistake if the model runs in double precision.
- Timing of individual kernels is fixed and improved.
- More careful setting of maximum number of connections in sparse connectivity, covering mixed dense/sparse network scenarios.
- NGRADSYNAPSES was not scaling correctly with varying time step.
- Fixed a bug where learning kernel with sparse connectivity was going out of range in an array.
- Fixed synapse kernel name substitutions where the "dd_" prefix was omitted by mistake.
Please refer to the full documentation for further details, tutorials and complete code documentation.
GeNN 2.0
Release Notes for GeNN v2.0
Version 2.0 of GeNN comes with a lot of improvements and added features, some of which have necessitated some changes to the structure of parameter arrays among others.
User Side Changes
- Users are now required to call
initGeNN()
in the model definition function before adding any populations to the neuronal network model. - glbscnt is now call glbSpkCnt for consistency with glbSpkEvntCnt.
- There is no longer a privileged parameter
Epre
. Spike type events
are now defined by a code stringspkEvntThreshold
, the same way proper spikes are. The only difference is that Spike type events are specific to a synapse type rather than a neuron type. - The function setSynapseG has been deprecated. In a
GLOBALG
scenario, the variables of a synapse group are set to the initial values provided in themodeldefinition
function. - Due to the split of synaptic models into weightUpdateModel and postSynModel, the parameter arrays used during model definition need to be carefully split as well so that each side gets the right parameters. For example, previously
float myPNKC_p[3]= {
0.0, // 0 - Erev: Reversal potential
-20.0, // 1 - Epre: Presynaptic threshold potential
1.0 // 2 - tau_S: decay time constant for S [ms]
};
would define the parameter array of three parameters, Erev
, Epre
, and tau_S
for a synapse of type NSYNAPSE
. This now needs to be "split" into
float *myPNKC_p= NULL;
float postExpPNKC[2]={
1.0, // 0 - tau_S: decay time constant for S [ms]
0.0 // 1 - Erev: Reversal potential
};
i.e. parameters Erev
and tau_S
are moved to the post-synaptic model and its parameter array of two parameters. Epre
is discontinued as a parameter for NSYNAPSE
. As a consequence the weightupdate model of NSYNAPSE
has no parameters and one can pass NULL
for the parameter array in addSynapsePopulation
.
The correct parameter lists for all defined neuron and synapse model types are listed in the User Manual.
Note:
If the parameters are not redefined appropriately this will lead to uncontrolled behaviour of models and likely to sgementation faults and crashes.
- Advanced users can now define variables as type
scalar
when introducing new neuron or synapse types. This will at the code generation stage be translated to the model's floating point type (ftype),float
ordouble
. This works for defining variables as well as in all code snippets. Users can also use the expressionsSCALAR_MAX
andSCALAR_MIN
forFLT_MIN
,FLT_MAX
,DBL_MIN
andDBL_MAX
, respectively. Corresponding definitions ofscalar
,SCALAR_MIN
andSCALAR_MAX
are also available for user-side code whenever the code-generated filerunner.cc
has been included. - The example projects have been re-organized so that wrapper scripts of the
generate_run
type are now all located together with the models they run instead of in a commontools
directory. Generally the structure now is that each example project contains the wrapper scriptgenerate_run
and amodel
subdirectory which contains the model description file and the user side code complete with Makefiles for Unix and Windows operating systems. The generated code will be deposited in themodel
subdirectory in its ownmodelname_CODE
folder. Simulation results will always be deposited in a new sub-folder of the main project directory. - The
addSynapsePopulation(...)
function has now more mandatory parameters relating to the introduction of separate weightupdate models (pre-synaptic models) and postynaptic models. The correct syntax for theaddSynapsePopulation(...)
can be found with detailed explanations in teh User Manual. - We have introduced a simple performance profiling method that users can employ to get an overview over the differential use of time by different kernels. To enable the timers in GeNN generated code, one needs to declare
networkmodel.setTiming(TRUE);
This will make available and operate GPU-side cudeEvent based timers whose cumulative value can be found in the double precision variables neuron_tme
, synapse_tme
and learning_tme
. They measure the accumulated time that has been spent calculating the neuron kernel, synapse kernel and learning kernel, respectively. CPU-side timers for the simulation functions are also available and their cumulative values can be obtained through
float x= sdkGetTimerValue(&neuron_timer);
float y= sdkGetTimerValue(&synapse_timer);
float z= sdkGetTimerValue(&learning_timer);
The \ref ex_mbody example shows how these can be used in the user-side code. To enable timing profiling in this example, simply enable it for GeNN:
model.setTiming(TRUE);
in MBody1.cc
's modelDefinition
function and define the macro TIMING
in classol_sim.h
#define TIMING
This will have the effect that timing information is output into OUTNAME_output/OUTNAME.timingprofile
.
Developer Side Changes
allocateSparseArrays()
has been changed to take the number of connections, connN, as an argument rather than expecting it to have been set in the Connetion struct before the function is called as was the arrangement previously.- For the case of sparse connectivity, there is now a reverse mapping implemented with revers index arrays and a remap array that points to the original positions of variable values in teh forward array. By this mechanism, revers lookups from post to pre synaptic indices are possible but value changes in the sparse array values do only need to be done once.
- SpkEvnt code is no longer generated whenever it is not actually used. That is also true on a somewhat finer granularity where variable queues for synapse delays are only maintained if the corresponding variables are used in synaptic code. True spikes on the other hand are always detected in case the user is interested in them.
Please refer to the full documentation for further details, tutorials and complete code documentation.