Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into kernel-transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
C.A.P. Linssen committed Sep 20, 2024
2 parents fb19510 + eaf1b3c commit d67bf55
Show file tree
Hide file tree
Showing 53 changed files with 3,692 additions and 1,310 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 42 additions & 4 deletions doc/running/running_nest_compartmental.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ As an example for a HH-type channel:
All of the currents within a compartment (marked by ``@mechanism::channel``) are added up within a compartment.

For a complete example, please see `cm_default.nestml <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/resources/concmech.nestml>`_ and its associated unit test, `compartmental_model_test.py <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/concmech_model_test.py>`_.
For a complete example, please see `cm_default.nestml <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/resources/concmech.nestml>`_ and its associated unit test, `test__compartmental_model.py <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/test__concmech_model.py>`_.


Concentration description
Expand Down Expand Up @@ -111,12 +111,14 @@ As an example a description of a calcium concentration model where we pretend th
The only difference here is that the equation that is marked with the ``@mechanism::concentration`` descriptor is not an inline equation but an ODE. This is because in case of the ion-channel what we want to simulate is the current which relies on the evolution of some state variables like gating variables in case of the HH-models, and the compartment voltage. The concentration though can be more simply described by an evolving state directly.

For a complete example, please see `concmech.nestml <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/resources/concmech.nestml>`_ and its associated unit test, `compartmental_model_test.py <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/concmech_model_test.py>`_.
For a complete example, please see `concmech.nestml <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/resources/concmech.nestml>`_ and its associated unit test, `test__concmech_model.py <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/test__concmech_model.py>`_.

Synapse description
-------------------

Here synapse models are based on convolutions over a buffer of incoming spikes. This means that the equation for the current-contribution must contain a convolve() call and a description of the kernel used for that convolution is needed. The descriptor for synapses is ``@mechanism::receptor``.
Here synapse models are based on convolutions over a buffer of incoming spikes. This means that the equation for the
current-contribution must contain a convolve() call and a description of the kernel used for that convolution is needed.
The descriptor for synapses is ``@mechanism::receptor``.

.. code-block:: nestml
Expand All @@ -133,13 +135,49 @@ Here synapse models are based on convolutions over a buffer of incoming spikes.
input:
<spike_name> <- spike
For a complete example, please see `concmech.nestml <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/resources/concmech.nestml>`_ and its associated unit test, `compartmental_model_test.py <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/concmech_model_test.py>`_.
For a complete example, please see `concmech.nestml <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/resources/concmech.nestml>`_ and its associated unit test, `test__concmech_model.py <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/test__concmech_model.py>`_.

Continuous input description
----------------------------

The continuous inputs are defined by an inline with the descriptor @mechanism::continuous_input. This inline needs to
include one input of type continuous and may include any states, parameters and functions.

.. code-block:: nestml
model <neuron_name>:
equations:
inline <current_equation_name> real = \
<some equation based on state variables, parameters, membrane potential and other equation names \
and MUST contain at least one reference to a continuous input port like <continuous_name>> \
@mechanism::continuous_input
input:
<continuous_name> real <- continuous
For a complete example, please see `continuous_test.nestml <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/resources/continuous_test.nestml>`_ and its associated unit test, `test__continuous_input.py <https://github.com/nest/nestml/blob/master/tests/nest_compartmental_tests/test__continuous_input.py>`_.

Mechanism interdependence
-------------------------

Above examples of explicit interdependence inbetween concentration and channel models where already described. Note that it is not necessary to describe the basic interaction inherent through the contribution to the overall current of the compartment. During a simulation step all currents of channels and synapses are added up and contribute to the change of the membrane potential (v_comp) in the next timestep. Thereby one must only express a dependence explicitly if the mechanism depends on the activity of a specific channel- or synapse-type amongst multiple in a given compartment or some concentration.

Technical Notes
---------------

We have put an emphasis on delivering good performance for neurons with high spatial complexity. We utilize vectorization, therefore, you should compile NEST with the OpenMP flag enabled. This, of course, can only be utilized if your hardware supports SIMD instructions. In that case, you can expect a performance improvement of about 3/4th of the theoretical maximum.

Let's say you have an AVX2 SIMD instruction set available, which can fit 4 doubles (4*64-bit) into its vector register. In this case you can expect about a 3x performance improvement as long as your neuron has enough compartments. We vectorize the simulation steps of all instances of the same mechanism you have defined in your NESTML model, meaning that you will get a better complexity/performance ratio the more instances of the same mechanism are used.

Here is a small benchmark example that shows the performance ratio (y-axis) as the number of compartments per neuron (x-axis) increases.

.. figure:: https://raw.githubusercontent.com/nest/nestml/master/doc/fig/performance_ratio_nonVec_vs_vec_compartmental.png
:width: 326px
:height: 203px
:align: left
:target: #

Be aware that we are using the -ffast-math flag when compiling the model by default. This can potentially lead to precision problems and inconsistencies across different systems. If you encounter unexpected results or want to be on the safe side, you can disable this by removing the flag from the CMakeLists.txt, which is part of the generated code. Note, however, that this may inhibit the compiler's ability to vectorize parts of the code in some cases.

See also
--------
Expand Down
2 changes: 1 addition & 1 deletion extras/convert_cm_default_to_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def get_replacement_patterns():
# file names
'cm_default' : '{{neuronSpecificFileNamesCmSyns[\"main\"]}}',
'cm_tree' : '{{neuronSpecificFileNamesCmSyns[\"tree\"]}}',
'cm_compartmentcurrents': '{{neuronSpecificFileNamesCmSyns[\"compartmentcurrents\"]}}',
'cm_neuroncurrents': '{{neuronSpecificFileNamesCmSyns[\"neuroncurrents\"]}}',
# class names
'CompTree' : 'CompTree{{cm_unique_suffix}}',
'Compartment' : 'Compartment{{cm_unique_suffix}}',
Expand Down
4 changes: 2 additions & 2 deletions models/neurons/aeif_cond_alpha_neuron.nestml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ model aeif_cond_alpha_neuron:
b pA = 80.5 pA # Spike-triggered adaptation
Delta_T mV = 2.0 mV # Slope factor
tau_w ms = 144.0 ms # Adaptation time constant
V_th mV = -50.4 mV # Threshold Potential
V_th mV = -50.4 mV # Spike initiation threshold
V_peak mV = 0 mV # Spike detection threshold

# synaptic parameters
Expand Down Expand Up @@ -112,7 +112,7 @@ model aeif_cond_alpha_neuron:
# neuron not refractory, so evolve all ODEs (including V_m)
integrate_odes()

onCondition(V_m >= V_th):
onCondition(V_m >= V_peak):
# threshold crossing
refr_t = refr_T # start of the refractory period
is_refractory = true
Expand Down
2 changes: 1 addition & 1 deletion models/neurons/aeif_cond_exp_neuron.nestml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ model aeif_cond_exp_neuron:
b pA = 80.5 pA # Spike-triggered adaptation
Delta_T mV = 2.0 mV # Slope factor
tau_w ms = 144.0 ms # Adaptation time constant
V_th mV = -50.4 mV # Threshold Potential
V_th mV = -50.4 mV # Spike initiation threshold
V_peak mV = 0 mV # Spike detection threshold

# synaptic parameters
Expand Down
10 changes: 6 additions & 4 deletions models/synapses/stdp_triplet_synapse.nestml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ A connection with spike time dependent plasticity accounting for spike triplet e

Nearest-neighbour variant of pre- and postsynaptic spike coupling.

.. note::

See https://github.com/nest/nestml/issues/703 for a potential edge-case issue with this model.


References
++++++++++
Expand Down Expand Up @@ -56,8 +60,7 @@ model stdp_triplet_synapse:

onReceive(post_spikes):
# potentiate synapse
#w_ nS = Wmax * ( w / Wmax + tr_r1 * ( A2_plus + A3_plus * tr_o2 ) )
w_ nS = w + tr_r1 * ( A2_plus + A3_plus * tr_o2 )
w_ nS = w + tr_r1 * ( A2_plus + A3_plus * (tr_o2 - 1) ) # ``tr_o2 - 1`` to get the value just before the increment; see https://github.com/nest/nestml/issues/703
w = min(Wmax, w_)

# increment post trace values
Expand All @@ -66,8 +69,7 @@ model stdp_triplet_synapse:

onReceive(pre_spikes):
# depress synapse
#w_ nS = Wmax * ( w / Wmax - tr_o1 * ( A2_minus + A3_minus * tr_r2 ) )
w_ nS = w - tr_o1 * ( A2_minus + A3_minus * tr_r2 )
w_ nS = w - tr_o1 * ( A2_minus + A3_minus * tr_r2 )
w = max(Wmin, w_)

# increment pre trace values
Expand Down
36 changes: 36 additions & 0 deletions pynestml/cocos/co_co_cm_continuous_input_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
#
# co_co_cm_continuous_input_model.py
#
# This file is part of NEST.
#
# Copyright (C) 2004 The NEST Initiative
#
# NEST is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# NEST is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with NEST. If not, see <http://www.gnu.org/licenses/>.

from pynestml.cocos.co_co import CoCo
from pynestml.meta_model.ast_model import ASTModel
from pynestml.utils.continuous_input_processing import ContinuousInputProcessing


class CoCoCmContinuousInputModel(CoCo):
@classmethod
def check_co_co(cls, neuron: ASTModel):
"""
Checks if this compartmental condition applies to the handed over neuron.
If yes, it checks the presence of expected functions and declarations.
:param neuron: a single neuron instance.
:type neuron: ast_neuron
"""
return ContinuousInputProcessing.check_co_co(neuron)
7 changes: 1 addition & 6 deletions pynestml/cocos/co_co_nest_synapse_delay_not_assigned_to.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,10 @@
# You should have received a copy of the GNU General Public License
# along with NEST. If not, see <http://www.gnu.org/licenses/>.

from pynestml.cocos.co_co import CoCo
from pynestml.meta_model.ast_assignment import ASTAssignment
from pynestml.meta_model.ast_model import ASTModel
from pynestml.cocos.co_co import CoCo
from pynestml.symbol_table.scope import ScopeType
from pynestml.symbols.symbol import SymbolKind
from pynestml.symbols.variable_symbol import BlockType
from pynestml.utils.ast_utils import ASTUtils
from pynestml.utils.logger import LoggingLevel, Logger
from pynestml.utils.messages import Messages
from pynestml.visitors.ast_visitor import ASTVisitor


Expand Down
2 changes: 2 additions & 0 deletions pynestml/cocos/co_cos_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from pynestml.cocos.co_co_inline_expression_not_assigned_to import CoCoInlineExpressionNotAssignedTo
from pynestml.cocos.co_co_input_port_not_assigned_to import CoCoInputPortNotAssignedTo
from pynestml.cocos.co_co_cm_channel_model import CoCoCmChannelModel
from pynestml.cocos.co_co_cm_continuous_input_model import CoCoCmContinuousInputModel
from pynestml.cocos.co_co_convolve_cond_correctly_built import CoCoConvolveCondCorrectlyBuilt
from pynestml.cocos.co_co_convolve_has_correct_parameter import CoCoConvolveHasCorrectParameter
from pynestml.cocos.co_co_input_port_not_assigned_to import CoCoInputPortNotAssignedTo
Expand Down Expand Up @@ -148,6 +149,7 @@ def check_compartmental_model(cls, neuron: ASTModel) -> None:
CoCoCmChannelModel.check_co_co(neuron)
CoCoCmConcentrationModel.check_co_co(neuron)
CoCoCmSynapseModel.check_co_co(neuron)
CoCoCmContinuousInputModel.check_co_co(neuron)

@classmethod
def check_inline_expressions_have_rhs(cls, model: ASTModel):
Expand Down
Loading

0 comments on commit d67bf55

Please sign in to comment.