The generation of a code snippet is done by a CodeGenerator
class.The templates are stored in the CodeObject.templater
attribute, which istypically implemented as a subdirectory of templates. The compilation andrunning of code is done by a CodeObject
. See the sections below for eachof these.
CodeRunner for mac 2.1.1 – 全能型代码程序编辑器 最新破解版 Posted by Rolos On 十一月 14, 2015 1 Comment 原价:9.99美元,约等于63元人民币. @@ -67,7 +67,7 @@ to see if the problem has already been reported. If it does exist, add a: thumbsup: to the issue to indicate this is also an issue for you, and add a comment to the existing issue if there is extra information you can contribute.
Code path¶
The following gives an outline of the key steps that happen for the codegeneration associated to a NeuronGroup
StateUpdater
. The items in greyare Brian core functions and methods and do not need to be implemented tocreate a new code generation target or device. The parts in yellow areused when creating a new device. The parts in green relate to generatingcode snippets from abstract code blocks. The parts in blue relate to creatingnew templates which these snippets are inserted into. The parts in redrelate to creating new runtime behaviour (compiling and running generatedcode).
In brief, what happens can be summarised as follows. Network.run
will callBrianObject.before_run
on each of the objects in the network. Objects suchas StateUpdater
, which is a subclass of CodeRunner
use this spot togenerate and compile their code. The process for doing this is to firstcreate the abstract code block, done in the StateUpdater.update_abstract_code
method. Then, a CodeObject
is created with this code block. In doing so,Brian will call out to the currently active Device
to get the CodeObject
and CodeGenerator
classes associated to the device, and this hierarchy ofcalls gives several hooks which can be changed to implement new targets.
Code generation¶
To implement a new language, or variant of an existing language, derive a classfrom CodeGenerator
. Good examples to look at are the NumpyCodeGenerator
,CPPCodeGenerator
and CythonCodeGenerator
classes in thebrian2.codegen.generators
package. Each CodeGenerator
has a class_name
attribute which is a string used by the user to refer to this code generator(for example, when defining function implementations).
The derived CodeGenerator
class should implement the methods marked asNotImplemented
in the base CodeGenerator
class. CodeGenerator
also hasseveral handy utility methods to make it easier to write these, see theexisting examples to get an idea of how these work.
Syntax translation¶
One aspect of writing a new language is that sometimes you need to translatefrom Python syntax into the syntax of another language. You are free todo this however you like, but we recommend using a NodeRenderer
classwhich allows you to iterate over the abstract syntax tree of an expression.See examples in brian2.parsing.rendering
.
Templates¶
In addition to snippet generation, you need to create templates for thenew language. See the templates
directories in brian2.codegen.runtime.*
for examples of these. They are written in the Jinja2 templating system. Thelocation of these templates is set as the CodeObject.templater
attribute.Examples such as CPPCodeObject
show how this is done.
Template structure¶
Languages typically define a common_group
template that is the base for allother templates. This template sets up the basic code structure that will be reused byall code objects, e.g. by defining a function header and body, and adding standardimports/includes. This template defines several blocks, in particular a maincode
clock containing the actual code that is specific to each code object. The specifictemplates such as reset
then derive from the common_group
base template andoverride the maincode
block. The base template can also define additional blocksthat are sometimes but not always overwritten. For example, the common_group.cpp
template of the C++ standalone code generator defines an extra_headers
block thatcan be overwritten by child templates to include additional header files needed for thecode in maincode
.
Template keywords¶
Templates also specify additional information necessary for the code generation processas Jinja comments ({#...#}
). The following keywords are recognized by Brian:
USES_VARIABLES
Lists variable names that are used by the template, even if they are not referred toin user code.
WRITES_TO_READ_ONLY_VARIABLES
Lists read-only variables that are modified by the template. Normally, read-onlyvariables are not considered to change during code execution, but e.g. synapsecreation requires changes to synaptic indices that are considered read-onlyotherwise.
ALLOWS_SCALAR_WRITE
The presence of this keyword means that in this template, writing to scalarvariables is permitted. Writing to scalar variables is not permitted by default,because it can be ambiguous in contexts that do not involve all neurons/synapses.For example, should the statement scalar_variable+=1
in a reset statementupdate the variable once or once for every spiking neuron?
ITERATE_ALL
Coderunner Extension
Lists indices that are iterated over completely. For example, during the stateupdate or threshold step, the template iterates over all neurons with the standardindex _idx
. When executing the reset statements on the other hand, not allneurons are concerned. This is only used for the numpy code generation target,where it allows avoiding expensive unnecessary indexing.
Code objects¶
To allow the final code block to be compiled and run, derive a class fromCodeObject
. This class should implement the placeholder methods defined inthe base class. The class should also have attributes templater
(whichshould be a Templater
object pointing to the directory where the templatesare stored)generator_class
(which should be the CodeGenerator
class), andclass_name
(which should be a string the user can use to refer to thiscode generation target.
Coderunner 3
Default functions¶
You will typically want to implement the default functions such as thetrigonometric, exponential and rand
functions. We usually put theseimplementations either in the same module as the CodeGenerator
class orthe CodeObject
class depending on whether they are language-specific orruntime target specific. See those modules for examples of implementingthese functions.
Code guide¶
brian2.codegen
: everything related to code generationbrian2.codegen.generators
: snippet generation,including theCodeGenerator
classes and default function implementations.brian2.codegen.runtime
: templates, compilation and running of code,includingCodeObject
and default function implementations.brian2.core.functions
,brian2.core.variables
: these define the valuesthat variable names can have.brian2.parsing
: tools for parsing expressions, etc.brian2.parsing.rendering
: AST tools for rendering expressions in Pythoninto different languages.brian2.utils
: various tools for string manipulation, file management, etc.
Additional information¶
Coderunner Download
For some additional (older, but still accurate) notes on code generation:
- Older notes on code generation
(Shortest import: frombrian2importCodeRunner)
brian2.groups.group.
CodeRunner
(*args, **kw)[source]¶Bases: brian2.core.base.BrianObject
A “code runner” that runs a CodeObject
every timestep and keeps areference to the Group
. Used in NeuronGroup
for Thresholder
,Resetter
and StateUpdater
.
On creation, we try to run the before_run method with an empty additionalnamespace (see Network.before_run
). If the namespace is already completethis might catch unit mismatches.
group : Group
template : Template
The template that should be used for code generation
code : str, optional
The abstract code that should be executed every time step. Theupdate_abstract_code
method might generate this code dynamicallybefore every run instead.
dt : Quantity
, optional
The time step to be used for the simulation. Cannot be combined withthe clock
argument.
user_code : str, optional
The abstract code as specified by the user, i.e. without any additionsof internal code that the user not necessarily knows about. This willbe used for warnings and error messages.
clock : Clock
, optional
The update clock to be used. If neither a clock, nor the dt
argumentis specified, the defaultclock
will be used.
when : str, optional
In which scheduling slot to execute the operation during a time step.Defaults to 'start'
.
order : int, optional
The priority of this operation for operations occurring at the same timestep and in the same scheduling slot. Defaults to 0.
name : str, optional
check_units : bool, optional
Whether the units should be checked for consistency before a run. Isactivated (True
) by default but should be switched off for stateupdaters (units are already checked for the equations and the generatedabstract code might have already replaced variables with their unit-lessvalues)
template_kwds : dict, optional
A dictionary of additional information that is passed to the template.
needed_variables: list of str, optional :
A list of variables that are neither present in the abstract code, norin the USES_VARIABLES
statement in the template. This is onlyrarely necessary, an example being a StateMonitor
where thenames of the variables are neither known to the template nor includedin the abstract code statements.
override_conditional_write: list of str, optional :
A list of variable names which are used as conditions (e.g. forrefractoriness) which should be ignored.
codeobj_class : class, optional
The CodeObject
class to run code with. If not specified, defaults tothe group
’s codeobj_class
attribute.
generate_empty_code : bool, optional
Whether to generate a CodeObject
if there is no abstract code toexecute. Defaults to True
but should be switched off e.g. for aStateUpdater
when there is nothing to do.
Methods
| Optional method to prepare the object before a run. |
| |
| |
| Update the abstract code for the code object. |
Details
before_run
(run_namespace)[source]¶Optional method to prepare the object before a run.
Called by Network.after_run
before the main simulation loop starts.
create_code_objects
(run_namespace)[source]¶
create_default_code_object
(run_namespace)[source]¶
update_abstract_code
(run_namespace)[source]¶Update the abstract code for the code object. Will be called inbefore_run
and should update the CodeRunner.abstract_code
attribute.
Does nothing by default.