-
Notifications
You must be signed in to change notification settings - Fork 377
Add support for axonal delays #2989
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
JanVogelsang
wants to merge
105
commits into
nest:master
Choose a base branch
from
JanVogelsang:stdp_long_axonal_delays
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 99 commits
Commits
Show all changes
105 commits
Select commit
Hold shift + click to select a range
101a5cc
Handle axonal delay in original stdp-pl synapse
suku248 bb37f53
Add first version of framework for STDP with long axonal delay
0bbfc27
Use ring buffer to temporarily store spike data for retrospective cor…
suku248 7362c26
Added stdp-pl python test and fixed postsynaptic trace history cleanu…
JanVogelsang 1e73b4c
Adding python test for stdp with axonal delays and fixing correction-…
JanVogelsang 811f18e
Applied clang-format v13
JanVogelsang 92a0ca0
Made stdp test runnable
JanVogelsang e69c17c
Improved stdp pl synapse hom test
JanVogelsang 78aadfa
Merged master
JanVogelsang 9d1729e
Update stdp_pl_synapse_hom_ax_delay.h
JanVogelsang dee2589
Fixed formatting
JanVogelsang cd6887b
Merge branch 'stdp_long_axonal_delays' of github.com:JanVogelsang/nes…
JanVogelsang b624ad5
Removed old tests
JanVogelsang d76f654
Made whole kernel axonal-delay aware
JanVogelsang 1e171b0
Fixed issues with min and max delays
JanVogelsang 780915b
Fixed default delays
JanVogelsang 0f91f45
Improved BadDelay exception
JanVogelsang c2dbd84
Improved stdp bugfix
JanVogelsang bf0f6fc
Fixed issues with correction-based STDP
JanVogelsang 75a870c
Fixed issues with correction-based STDP
JanVogelsang c9be932
Fixed issues with correction-based STDP
JanVogelsang cf704e6
Added detailed timers
JanVogelsang 5f60ede
Added stopwatch for time spent for correction
JanVogelsang 68d3a93
Added ignore and fire neuron and collecting number of corrections
JanVogelsang 9731013
Added ignore and fire neuron
JanVogelsang c447b9f
Fixed ignore and fire for corrections
JanVogelsang ed5147e
Reducing correction entry vector size when clearing
JanVogelsang cb83c25
Fixing detailed timers
JanVogelsang 0f540fb
Fixing detailed timers
JanVogelsang 16e68d4
Fixing detailed timers
JanVogelsang e90d973
Fixing detailed timers
JanVogelsang 4f70a06
Merge remote-tracking branch 'nest-master/master' into stdp_long_axon…
JanVogelsang eec3e7b
Fixing bugs related to the addition of axonal delays into the kernel
JanVogelsang f0e183b
Fixing bugs
JanVogelsang 4222534
Fixed remaining bugs
JanVogelsang 4fb5665
Merge remote-tracking branch 'nest-master/master' into stdp_long_axon…
JanVogelsang bd77090
Merging master and fixing format
JanVogelsang be79118
Fixed python formatting
JanVogelsang 7531a9e
Fixed models
JanVogelsang 5ef7af8
Fixed remaining issues in models
JanVogelsang fc5677c
Fixed remaining issues in models
JanVogelsang d086729
Fixed sonata
JanVogelsang adabcaf
Merge remote-tracking branch 'nest-master/master' into stdp_long_axon…
JanVogelsang 7144093
Merged master
JanVogelsang fc5474d
Fixed black fomatting
JanVogelsang fbec6c2
Modified archiving node to work with NESTML
JanVogelsang 371029a
Added stdp power-law synapse with homogeneous axonal delays
JanVogelsang 3b84bf1
Added many-to-one example to generate results for the paper
JanVogelsang 71c3a48
Added many-to-one example to generate results for the paper and some …
JanVogelsang 76f47db
Removed grayscale versions of figures
JanVogelsang 227a0bb
Merge remote-tracking branch 'nest-master/master' into stdp_long_axon…
JanVogelsang 0a8a2f4
Added more results
JanVogelsang 2f0fa6d
Merged master
JanVogelsang 0806b1f
Merged master
JanVogelsang 96c082c
Merged master
JanVogelsang b32ceea
Removed SpikeData from CorrectionEntry class
JanVogelsang f6000fb
Removed SpikeData from CorrectionEntry class
JanVogelsang 9b50af3
New results
JanVogelsang c9c9391
New results
JanVogelsang 7b38dde
Fixed detailed timers
JanVogelsang 73ac032
Generated plots for presentation
JanVogelsang 66a019a
Cleanup
JanVogelsang 0bbf711
Added axonal delays as a member to connection class activated by dema…
JanVogelsang ebaa796
Updated plots
JanVogelsang 343c290
Merge branch 'refs/heads/stdp_long_axonal_delays_paper' into stdp_lon…
JanVogelsang 0a1fee5
Cleanup
JanVogelsang 5564296
Cleanup
JanVogelsang e5223ef
Merge remote-tracking branch 'refs/remotes/nest-master/master' into s…
JanVogelsang 5e88d27
Merging master
JanVogelsang bd9ef84
Merge branch 'refs/heads/nest-master' into stdp_long_axonal_delays
JanVogelsang 120bc78
Cleanup
JanVogelsang c9b7df7
Black formatting
JanVogelsang d58bf7d
Fixed layer implementation
JanVogelsang ed26325
Fixing tests
JanVogelsang bf8a30a
Fixed formatting
JanVogelsang 4d84321
Removed debugging files
JanVogelsang edefa0a
Bugfixes
JanVogelsang 18b74b5
Bugfixes
JanVogelsang b050da0
Bugfixes
JanVogelsang cca3d98
Now throwing an exception if connections change during simulation and…
JanVogelsang bda2f0b
Merge branch 'stdp_long_axonal_delays' of github.com:JanVogelsang/nes…
JanVogelsang e137c86
Added docstring for sizes of newly introduces bitfields
JanVogelsang 5fdd66a
Applied suggestions
JanVogelsang 79304c2
Merge remote-tracking branch 'nest-master/master' into stdp_long_axon…
JanVogelsang 7d3a2a8
Applied suggestions
JanVogelsang 24a1005
Added documentation, example, additional tests, and improved user int…
JanVogelsang 81b913e
Formatting
JanVogelsang 7446f15
Formatting
JanVogelsang 5fbc81d
Merge remote-tracking branch 'nest-master/master' into stdp_long_axon…
JanVogelsang e4cc119
Merged master
JanVogelsang 73bdc9a
Bugfixes
JanVogelsang 4480839
add modified content
jessica-mitchell 7860494
add indexing to new files
jessica-mitchell 4ea9718
rm notebook
jessica-mitchell 9091464
update image
jessica-mitchell 4b6e7d2
Bugfixes
JanVogelsang b2ae907
Merge branch 'stdp_long_axonal_delays' of github.com:jessica-mitchell…
JanVogelsang 9b38135
Merge branch 'jessica-mitchell-stdp_long_axonal_delays' into stdp_lon…
JanVogelsang edaea29
Adjusted docs and now supporting ax-delay synapse and arbitrary neuro…
JanVogelsang bfb3f61
Fixed spatial implementation
JanVogelsang c57da34
Merge branch 'master' into stdp_long_axonal_delays
JanVogelsang d016563
Formatting
JanVogelsang 6532f98
Merge branch 'stdp_long_axonal_delays' of github.com:JanVogelsang/nes…
JanVogelsang 6958b3a
Bugfix
JanVogelsang f2b004a
Adjusted SP tests
JanVogelsang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
.. _axonal_delays_dev: | ||
|
||
Axonal Delays | ||
============= | ||
|
||
Adding axonal delays to NEST is non-trivial when it comes to their interaction with spike-timing dependent plasticity (STDP). | ||
Axonal delays lower than their dendritic counterpart are non-problematic, however larger axonal delays cause causality | ||
issues due to the way how and when pre- and post-synaptic spikes are processed in NEST by synapses implementing STDP weight dynamics. | ||
|
||
If a pre-synaptic spike is processed at a synapse, it will also process all post-synaptic spikes that reached the synapse | ||
between the last and current pre-synaptic spike. Weight changes due facilitation (post-synaptic spike following a | ||
pre-synaptic one) or depression (pre-synaptic spike following a post-synaptic one) are only relevant at the time when pre-synaptic spikes | ||
reach the synapse, as this is the only point in time when the exact weight is of importance. Post-synaptic spikes can | ||
therefore be archived in the post-synaptic neuron until the next pre-synaptic spike is processed by the synapse. | ||
As all pre-synaptic spikes are delivered to their target synapse and neuron right after they have been communicated, | ||
they might be processed before they would actually reach the synapse when taking axonal delays into account. | ||
If the axonal delay is now larger than the dendritic delay, post-synaptic | ||
spikes occurring at time `t` will reach the synapse before pre-synaptic spikes occurring before `t`, | ||
but might not be taken into account by the pre-synaptic spike, if it was already communicated, | ||
and thus delivered, before `t`. Each pre-synaptic spike sent over a connection | ||
with a predominant axonal delay must therefore also process post-synaptic spikes which have not yet occurred, | ||
but could be emitted in the future. Multiple implementations were implemented and | ||
benchmarked before coming to the conclusion that the implementation at hand should be used inside NEST. | ||
|
||
The main idea of the axonal delays implementation in NEST is based on the fact, that neurons only emit few spikes per second. | ||
It should thus be rare that a post-synaptic spike occurs right after a pre-synaptic one in the critical region before | ||
the pre-synaptic spike reaches the synapse, but has already been processed. In typical networks, there will most likely | ||
only be few occurrences where causality becomes an issue. In order to still guarantee correct synaptic weights, | ||
incorrect STDP weight changes are rolled back, re-calculated, and the weight of pre-synaptic spike, which already reached | ||
the target neuron's ring buffer, is corrected. Undoing the STDP weight changes and re-calculating them obviously comes | ||
with a cost, however as only few such occurrences are to be expected, this solution is more efficient than restructuring | ||
the kernel to make sure axonal delays are always handled correctly (see Alternative implementations). | ||
|
||
Changes to the kernel and neuron models | ||
--------------------------------------- | ||
|
||
Introducing axonal delays changes the way the min- and max-delays must be calculated, as they are now a combination of | ||
dendritic and axonal delays. The default value for the delay which is now referring to the dendritic delay remains 1, | ||
while the default value for axonal_delay is set to 0. In the default case, purely dendritic delay is assumed. | ||
|
||
The ``ArchivingNode`` was made axonal-delay-aware. Each pre-synaptic spike after which a correction could potentially follow, | ||
will be archived in the post-synaptic neuron in a dynamic ring-buffer-like structure. Post-synaptic spikes will then | ||
trigger a correction for all relevant pre-synaptic spikes in this buffer. The way spikes are received at a neuron is | ||
model-dependent, as the implementation of spike accumulation and buffering until being processed might vary between | ||
neuron models. Neurons models will therefore also have to handle correction of previously handled spikes differently. | ||
In the simplest case, all incoming spikes to a neuron are simply accumulated in a single scalar value per time slot. | ||
A correction of a previously handled spike would therefore just subtract the previous, wrong weight and add the new, | ||
corrected weight. Therefore, simply sending another spike with the difference of the old and new weight would be | ||
sufficient in this case. However, some neurons might have different buffers for spikes being sent over inhibitory and | ||
excitatory connections, which could be distinguished by the sign of the weight. If a new spike is now sent to correct | ||
an old one, the sign might be negative even though both the old and new weight were originally positive, the new weight | ||
is just smaller. In such a case, the spike would be accumulated in the wrong buffer. | ||
|
||
Instead of sending a regular ``SpikeEvent`` to signal a correction, a ``CorrectionSpikeEvent`` is sent. Overloading the handle | ||
function now allows handling the correction in the correct way, depending on the model implementation. | ||
Furthermore, neuron models must now call ``ArchivingNode::pre_run_hook_()`` in their derived pre_run_hook implementation | ||
and call ``reset_correction_entries_stdp_ax_delay_()`` at the end of their update implementation. | ||
Currently, only the ``iaf_psc_alpha`` neuron model supports STDP with axonal delays. | ||
All other neurons will act as if the delay of incoming connections was purely dendritic. | ||
|
||
Synapse models only support dendritic delay by default. If axonal delays are required, the synapse model must be derived | ||
from ``AxonalDelayConnection`` instead of ``Connection``. The ``AxonalDelayConnection`` is derived from ``Connection`` and adds a single | ||
double-precision member for the axonal delay. The main differences compared to synapses with purely dendritic delays are | ||
different handling of delays inside the send function and the addition of the ``correct_synapse_stdp_ax_delay`` which is | ||
called by the ``ConnectionManager`` when a synapse needs to re-calculate its weight given a new post-synaptic spike and a previous pre-synaptic one. | ||
Currently, only the ``stdp_pl_synapse_hom_ax_delay`` synapse model supports axonal delays. | ||
|
||
Changes to the python interface | ||
------------------------------- | ||
|
||
In general, the kernel was made axonal-delay-aware and this is reflected in the user interface, as it is now possible | ||
to set the ``names::dendritic_delay`` and ``names::axonal_delay`` for each synapse (given that the synapse model is | ||
derived from ``AxonalDelayConnection``). | ||
|
||
Remaining work | ||
--------------- | ||
|
||
|
||
Currently, only one neuron and synapse model are supporting axonal delays. All neuron models that support STDP could | ||
also support axonal delays, without sacrificing performance, changing their behavior, or requiring more memory, but need | ||
to be adapted slightly (i.e., implement handle for ``CorrectionSpikeEvent``, call ``ArchivingNode::pre_run_hook_`` and call | ||
``reset_correction_entries_stdp_ax_delay_``). | ||
|
||
Existing STDP synapse models need one version with and one without axonal delays. Alternatively, synapse models could | ||
be templatized to either use only dendritic or dendritic and axonal delays. However, this branching should be resolved | ||
at compile time to not negatively impact performance. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -159,6 +159,7 @@ More topics | |
|
||
* :ref:`sim_gap_junctions` | ||
* :ref:`weight_normalization` | ||
* :ref:`delays` | ||
|
||
|
||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
.. _delays: | ||
|
||
Delays | ||
====== | ||
|
||
|
||
In NEST, transmission delays are specified with the ``delay`` parameter. | ||
Delays are considered fully dendritic by all built-in models and therefore, the ``delay`` parameter is still used by | ||
most models. | ||
|
||
Since NEST 3.9, it is also possible to specify both explicit, heterogeneous axonal and dendritic delays for models | ||
supporting this feature. This is useful for STDP models and other models relying on the timing of spike arrival at the | ||
synapse. | ||
|
||
Currently, only ``stdp_pl_synapse_hom_ax_delay`` supports explicitly specifying axonal and dendritic delays with the | ||
``axonal_delay`` and ``dendtritic_delay`` parameters. For STDP with predominant axonal delays, neuron models must be | ||
adjusted to correctly handle these delays. At this point, only ``iaf_psc_alpha`` supports STDP with predominant axonal | ||
delays. | ||
|
||
When using ``stdp_pl_synapse_hom_ax_delay``: | ||
|
||
- The parameter ``delay`` is no longer valid. This is to prevent ambiguity between the two types of delays. | ||
- The parameter names ``dendritic_delay`` and ``axonal_delay`` have to be used to specify delay. | ||
- If these parameters are not explicitly provided, then the default values are used: | ||
|
||
``dendritic_delay: 1.0`` and ``axonal_delay: 0.0``. | ||
- If only axonal delay is provided and no dendritic delay, the dendritic delay is assumed to be 0 and vice-versa. | ||
|
||
|
||
Use of ``axonal_delay`` and ``dendritic_delay`` is the same as ``delay``: | ||
|
||
|
||
**Using syn_spec** | ||
|
||
.. code-block:: python | ||
|
||
nest.Create("iaf_psc_alpha") | ||
nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom", "delay": 1.0}) | ||
|
||
.. code-block:: python | ||
|
||
nest.Create("iaf_psc_alpha") | ||
nest.Connect(neuron, neuron, syn_spec= | ||
{"synapse_model": "stdp_pl_synapse_hom_ax_delay", "axonal_delay": 1.0, "dendritic_delay": 1.0}) | ||
|
||
**Using SetStatus** | ||
|
||
.. code-block:: python | ||
|
||
conn = nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom"}) | ||
nest.SetStatus(conn, {"delay": 1.0}) | ||
|
||
.. code-block:: python | ||
|
||
conn = nest.Connect(neuron, neuron, syn_spec={"synapse_model": "stdp_pl_synapse_hom_ax_delay"}) | ||
nest.SetStatus(conn, {"axonal_delay": 1.0, "dendritic_delay": 1.0}) | ||
|
||
**Using SetDefaults** | ||
|
||
.. code-block:: python | ||
|
||
nest.SetDefaults("stdp_pl_synapse_hom", {"delay": 1.0}) | ||
|
||
.. code-block:: python | ||
|
||
nest.SetDefaults("stdp_pl_synapse_hom_ax_delay", {"axonal_delay": 1.0, "dendritic_delay": 1.0}) | ||
|
||
|
||
.. seealso:: | ||
|
||
:doc:`Example using axonal delays </auto_examples/axonal_delays>` | ||
|
||
For details on further developments see :ref:`axonal_delays_dev`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not entirely understand the logic here, in part because the old code lacks comments. First of all, which bitfields belong together, i.e., should fit into some given space such as 4 or 8 bytes? Furthermore, we had 21 bits for delay in the past, now we go for an implementation-defined size (number of bytes in an
unsigned int
). Is there any specific reason for choosing this size? If so, comment on it. If not, wouldn't it make more sense to use a well defined size, e.g., always 32 bits? That would make for 18:14 split, which seems generous towards the dendritic delays.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now, in case of axonal+dendritic delays we use a 18:14 split, which is a lot and could be reduced by a few bits in case they were required for anything else. But right now we simply don't need more bits for anything, so this should be fine. However, I am not sure how to best guarantee that the underlying data type (here:
unsigned int
) always has exactly 32 bits. For the single-delay-value case (which represents total delay, but will also be interpreted as pure dendritic delay by some models) we could also just use 21 bits as before, but we don't need those remaining 11 bits for anything else, so there is no reason to use a bitfield here (which might add a tiny bit of unnecessary computational overhead). However, one must definitely ensure that we always have at least 21b for this value, i.e., enforce 32 bits.According to StackOverflow, this would be a solution:
I think we should therefore use these values in all locations where we want to specify size explicitly. Then we could also remove the StaticAssert calls, which become redundant.