From f8029b00b5e25039b987458d06dca6b73db99fb3 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Mon, 31 Jul 2023 15:17:10 +0100 Subject: [PATCH 1/6] Add makefiles for IF_curr_delta STDP --- .../Makefile | 28 +++++++++++++++++++ .../Makefile | 28 +++++++++++++++++++ neural_modelling/makefiles/neuron/Makefile | 2 ++ 3 files changed, 58 insertions(+) create mode 100644 neural_modelling/makefiles/neuron/IF_curr_delta_stdp_mad_nearest_pair_additive/Makefile create mode 100644 neural_modelling/makefiles/neuron/IF_curr_delta_stdp_mad_pair_additive/Makefile diff --git a/neural_modelling/makefiles/neuron/IF_curr_delta_stdp_mad_nearest_pair_additive/Makefile b/neural_modelling/makefiles/neuron/IF_curr_delta_stdp_mad_nearest_pair_additive/Makefile new file mode 100644 index 0000000000..fdea17760e --- /dev/null +++ b/neural_modelling/makefiles/neuron/IF_curr_delta_stdp_mad_nearest_pair_additive/Makefile @@ -0,0 +1,28 @@ +# Copyright (c) 2017 The University of Manchester +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +APP = $(notdir $(CURDIR)) + +NEURON_MODEL_H = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.h +INPUT_TYPE_H = $(NEURON_DIR)/neuron/input_types/input_type_delta.h +NEURON_IMPL_H = $(NEURON_DIR)/neuron/implementations/neuron_impl_standard.h +THRESHOLD_TYPE_H = $(NEURON_DIR)/neuron/threshold_types/threshold_type_static.h +SYNAPSE_TYPE_H = $(NEURON_DIR)/neuron/synapse_types/synapse_types_delta_impl.h +SYNAPSE_DYNAMICS = $(NEURON_DIR)/neuron/plasticity/stdp/synapse_dynamics_stdp_mad_impl.c +TIMING_DEPENDENCE = $(NEURON_DIR)/neuron/plasticity/stdp/timing_dependence/timing_nearest_pair_impl.c +TIMING_DEPENDENCE_H = $(NEURON_DIR)/neuron/plasticity/stdp/timing_dependence/timing_nearest_pair_impl.h +WEIGHT_DEPENDENCE = $(NEURON_DIR)/neuron/plasticity/stdp/weight_dependence/weight_additive_one_term_impl.c +WEIGHT_DEPENDENCE_H = $(NEURON_DIR)/neuron/plasticity/stdp/weight_dependence/weight_additive_one_term_impl.h + +include ../neural_build.mk diff --git a/neural_modelling/makefiles/neuron/IF_curr_delta_stdp_mad_pair_additive/Makefile b/neural_modelling/makefiles/neuron/IF_curr_delta_stdp_mad_pair_additive/Makefile new file mode 100644 index 0000000000..e2fb883d0d --- /dev/null +++ b/neural_modelling/makefiles/neuron/IF_curr_delta_stdp_mad_pair_additive/Makefile @@ -0,0 +1,28 @@ +# Copyright (c) 2017 The University of Manchester +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +APP = $(notdir $(CURDIR)) + +NEURON_MODEL_H = $(NEURON_DIR)/neuron/models/neuron_model_lif_impl.h +INPUT_TYPE_H = $(NEURON_DIR)/neuron/input_types/input_type_delta.h +NEURON_IMPL_H = $(NEURON_DIR)/neuron/implementations/neuron_impl_standard.h +THRESHOLD_TYPE_H = $(NEURON_DIR)/neuron/threshold_types/threshold_type_static.h +SYNAPSE_TYPE_H = $(NEURON_DIR)/neuron/synapse_types/synapse_types_delta_impl.h +SYNAPSE_DYNAMICS = $(NEURON_DIR)/neuron/plasticity/stdp/synapse_dynamics_stdp_mad_impl.c +TIMING_DEPENDENCE = $(NEURON_DIR)/neuron/plasticity/stdp/timing_dependence/timing_pair_impl.c +TIMING_DEPENDENCE_H = $(NEURON_DIR)/neuron/plasticity/stdp/timing_dependence/timing_pair_impl.h +WEIGHT_DEPENDENCE = $(NEURON_DIR)/neuron/plasticity/stdp/weight_dependence/weight_additive_one_term_impl.c +WEIGHT_DEPENDENCE_H = $(NEURON_DIR)/neuron/plasticity/stdp/weight_dependence/weight_additive_one_term_impl.h + +include ../neural_build.mk diff --git a/neural_modelling/makefiles/neuron/Makefile b/neural_modelling/makefiles/neuron/Makefile index 05505edf79..d9b72886d0 100644 --- a/neural_modelling/makefiles/neuron/Makefile +++ b/neural_modelling/makefiles/neuron/Makefile @@ -39,6 +39,8 @@ ifneq ($(SPYNNAKER_DEBUG), DEBUG) IZK_cond_exp_stdp_mad_pair_additive \ IZK_cond_exp_dual_stdp_mad_pair_additive \ IF_curr_alpha_stdp_mad_pair_additive \ + IF_curr_delta_stdp_mad_pair_additive \ + IF_curr_delta_stdp_mad_nearest_pair_additive \ IF_curr_exp_stdp_mad_recurrent_pre_stochastic_multiplicative \ IF_curr_exp_stdp_mad_pfister_triplet_additive endif From fd0fe7d490f768805e4eaf573162acff20733ce2 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Fri, 25 Aug 2023 10:59:34 +0100 Subject: [PATCH 2/6] use correct config method to check for none --- .../spynnaker_neuron_network_specification_report.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spynnaker/pyNN/extra_algorithms/spynnaker_neuron_network_specification_report.py b/spynnaker/pyNN/extra_algorithms/spynnaker_neuron_network_specification_report.py index ff642a64d4..f5f112ab38 100644 --- a/spynnaker/pyNN/extra_algorithms/spynnaker_neuron_network_specification_report.py +++ b/spynnaker/pyNN/extra_algorithms/spynnaker_neuron_network_specification_report.py @@ -13,7 +13,7 @@ # limitations under the License. import logging import os -from spinn_utilities.config_holder import get_config_str +from spinn_utilities.config_holder import get_config_str_or_none from spinn_utilities.log import FormatAdapter from spinn_utilities.progress_bar import ProgressBar from spynnaker.pyNN.data import SpynnakerDataView @@ -54,7 +54,7 @@ def spynnaker_neuron_graph_network_specification_report(): # create holders for data dot_diagram, exeNotFoundExn = _get_diagram(_GRAPH_TITLE) - graph_format = get_config_str("Reports", "network_graph_format") + graph_format = get_config_str_or_none("Reports", "network_graph_format") if graph_format is None: if (SpynnakerDataView.get_n_vertices() + SpynnakerDataView.get_n_partitions()) > CUTOFF: From 817618fd5fe664910ecd67b81b1ec0d2d66c3e76 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 29 Aug 2023 12:37:31 +0100 Subject: [PATCH 3/6] get_config_str_or_none --- spynnaker/pyNN/spinnaker.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spynnaker/pyNN/spinnaker.py b/spynnaker/pyNN/spinnaker.py index cfa4639d5d..11ab541cfe 100644 --- a/spynnaker/pyNN/spinnaker.py +++ b/spynnaker/pyNN/spinnaker.py @@ -22,7 +22,8 @@ from pyNN import __version__ as pynn_version from spinn_utilities.log import FormatAdapter -from spinn_utilities.config_holder import get_config_bool, get_config_str +from spinn_utilities.config_holder import ( + get_config_bool, get_config_str_or_none) from spinn_utilities.overrides import overrides from spinn_front_end_common.interface.abstract_spinnaker_base import ( @@ -488,7 +489,7 @@ def _execute_delay_support_adder(self): """ Runs, times and logs the DelaySupportAdder if required. """ - name = get_config_str("Mapping", "delay_support_adder") + name = get_config_str_or_none("Mapping", "delay_support_adder") if name is None: return with FecTimer("DelaySupportAdder", TimerWork.OTHER): From 6aef595cb8ee71708da43f816dcbb6e74990225b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 19:55:42 +0000 Subject: [PATCH 4/6] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/c_actions.yml | 4 ++-- .github/workflows/publish.yml | 4 ++-- .github/workflows/python_actions.yml | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/c_actions.yml b/.github/workflows/c_actions.yml index 3eef2fc94b..9a24941bdc 100644 --- a/.github/workflows/c_actions.yml +++ b/.github/workflows/c_actions.yml @@ -23,9 +23,9 @@ jobs: timeout-minutes: 10 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Checkout SupportScripts - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: SpiNNakerManchester/SupportScripts path: support diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 18e566b850..5dadd7a779 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -28,9 +28,9 @@ jobs: timeout-minutes: 10 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Checkout SupportScripts - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: SpiNNakerManchester/SupportScripts path: support diff --git a/.github/workflows/python_actions.yml b/.github/workflows/python_actions.yml index e72e34bfb4..d3c5713451 100644 --- a/.github/workflows/python_actions.yml +++ b/.github/workflows/python_actions.yml @@ -34,9 +34,9 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Checkout SupportScripts - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: SpiNNakerManchester/SupportScripts path: support @@ -97,9 +97,9 @@ jobs: python-version: ["3.8"] steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Checkout SupportScripts - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: SpiNNakerManchester/SupportScripts path: support From b3ef18607a18cdf06f3cc62b902cd072eea2a3e7 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Thu, 14 Sep 2023 19:38:06 +0100 Subject: [PATCH 5/6] Add tests for new IF_curr_delta STDP binaries --- .../test_stdp/test_IF_curr_delta_stdp.py | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 spynnaker_integration_tests/test_stdp/test_IF_curr_delta_stdp.py diff --git a/spynnaker_integration_tests/test_stdp/test_IF_curr_delta_stdp.py b/spynnaker_integration_tests/test_stdp/test_IF_curr_delta_stdp.py new file mode 100644 index 0000000000..ec0b758b2b --- /dev/null +++ b/spynnaker_integration_tests/test_stdp/test_IF_curr_delta_stdp.py @@ -0,0 +1,223 @@ +# Copyright (c) 2023 The University of Manchester +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy +import unittest +import pyNN.spiNNaker as sim +from spinnaker_testbase import BaseTestCase + + +class TestIFCurrDeltaSTDP(BaseTestCase): + + def mad_pair_additive_delta(self): + timestep = 1 + spike_current = 20 + input_population_size = 2 + + # Spikes set so the calculated weights for each STDP projection + # should be identical + spike_times1 = [[1,27,55], [1,27,55]] + spike_times2 = [[1,33,59], [1,33,59]] + training_times = [28] + save_spike_times = [90] + runtime = save_spike_times[-1] + 10 + + sim.setup(timestep=timestep) + + IF_curr_delta_model = sim.IF_curr_delta() + + # Set up populations + ssa1 = sim.Population( + input_population_size, sim.SpikeSourceArray(spike_times1), + label='ssa1') + ssa2 = sim.Population( + input_population_size, sim.SpikeSourceArray(spike_times2), + label='ssa2') + save_neuron = sim.Population( + 1, sim.SpikeSourceArray(save_spike_times), label='save_neuron') + injector_neurons_exc = sim.Population( + input_population_size, IF_curr_delta_model, + label='injector_neurons_exc') + injector_neurons_inh = sim.Population( + input_population_size, IF_curr_delta_model, + label='injector_neurons_inh') + teacher_population = sim.Population( + 1, sim.SpikeSourceArray(training_times), + label='teacher_population') + output_neuron = sim.Population( + 1, IF_curr_delta_model, label='output_neuron') + + # Set up projections + static_synapse = sim.StaticSynapse(weight=spike_current, delay=1) + teaching_synapse = sim.StaticSynapse(weight=spike_current, delay=2) + + # SSA -> injectors + sim.Projection( + ssa1, injector_neurons_exc, sim.OneToOneConnector(), + static_synapse, receptor_type='excitatory') + sim.Projection( + ssa2, injector_neurons_inh, sim.OneToOneConnector(), + static_synapse, receptor_type='excitatory') + + # save -> injectors + sim.Projection(save_neuron, injector_neurons_exc, + sim.AllToAllConnector(allow_self_connections=True), + static_synapse, receptor_type='excitatory') + sim.Projection(save_neuron, injector_neurons_inh, + sim.AllToAllConnector(allow_self_connections=True), + static_synapse, receptor_type='excitatory') + + # teacher -> output + sim.Projection(teacher_population, output_neuron, + sim.AllToAllConnector(allow_self_connections=True), + teaching_synapse, receptor_type='excitatory') + + # stdp models for injector -> output + stdp_model = sim.STDPMechanism( + timing_dependence=sim.SpikePairRule( + tau_plus=10, tau_minus=12, A_plus=1, A_minus=-1), + weight_dependence=sim.AdditiveWeightDependence(w_min=0, w_max=20), + weight=0, delay=1) + stdp_model2 = sim.STDPMechanism( + timing_dependence=sim.SpikePairRule( + tau_plus=10, tau_minus=12, A_plus=1, A_minus=-1), + weight_dependence=sim.AdditiveWeightDependence(w_min=0, w_max=20), + weight=0, delay=1) + + injector_proj_exc = sim.Projection( + injector_neurons_exc, output_neuron, + sim.AllToAllConnector(allow_self_connections=True), + stdp_model, receptor_type='excitatory') + injector_proj_inh = sim.Projection( + injector_neurons_inh, output_neuron, + sim.AllToAllConnector(allow_self_connections=True), + stdp_model2, receptor_type='inhibitory') + + sim.run(runtime) + + weights_exc = injector_proj_exc.get(["weight"], "list") + weights_inh = injector_proj_inh.get(["weight"], "list") + + print(weights_exc) + print(weights_inh) + + sim.end() + + self.assertTrue(numpy.allclose(weights_exc, weights_inh, rtol=0.001)) + + def nearest_pair_additive_delta(self): + timestep = 1 + spike_current = 20 + input_population_size = 2 + + # Spikes set so the calculated weights for each STDP projection + # should be identical + spike_times1 = [[1,27,51], [1,27,51]] + spike_times2 = [[1,33,60], [1,33,60]] + training_times = [28] + save_spike_times = [90] + runtime = save_spike_times[-1] + 10 + + sim.setup(timestep=timestep) + + IF_curr_delta_model = sim.IF_curr_delta() + + # Set up populations + ssa1 = sim.Population( + input_population_size, sim.SpikeSourceArray(spike_times1), + label='ssa1') + ssa2 = sim.Population( + input_population_size, sim.SpikeSourceArray(spike_times2), + label='ssa2') + save_neuron = sim.Population( + 1, sim.SpikeSourceArray(save_spike_times), label='save_neuron') + injector_neurons_exc = sim.Population( + input_population_size, IF_curr_delta_model, + label='injector_neurons_exc') + injector_neurons_inh = sim.Population( + input_population_size, IF_curr_delta_model, + label='injector_neurons_inh') + teacher_population = sim.Population( + 1, sim.SpikeSourceArray(training_times), + label='teacher_population') + output_neuron = sim.Population( + 1, IF_curr_delta_model, label='output_neuron') + + # Set up projections + static_synapse = sim.StaticSynapse(weight=spike_current, delay=1) + teaching_synapse = sim.StaticSynapse(weight=spike_current, delay=2) + + # SSA -> injectors + sim.Projection( + ssa1, injector_neurons_exc, sim.OneToOneConnector(), + static_synapse, receptor_type='excitatory') + sim.Projection( + ssa2, injector_neurons_inh, sim.OneToOneConnector(), + static_synapse, receptor_type='excitatory') + + # save -> injectors + sim.Projection(save_neuron, injector_neurons_exc, + sim.AllToAllConnector(allow_self_connections=True), + static_synapse, receptor_type='excitatory') + sim.Projection(save_neuron, injector_neurons_inh, + sim.AllToAllConnector(allow_self_connections=True), + static_synapse, receptor_type='excitatory') + + # teacher -> output + sim.Projection(teacher_population, output_neuron, + sim.AllToAllConnector(allow_self_connections=True), + teaching_synapse, receptor_type='excitatory') + + # stdp models for injector -> output + stdp_model = sim.STDPMechanism( + timing_dependence=sim.extra_models.SpikeNearestPairRule( + tau_plus=10, tau_minus=12, A_plus=1, A_minus=-1), + weight_dependence=sim.AdditiveWeightDependence(w_min=0, w_max=20), + weight=0, delay=1) + stdp_model2 = sim.STDPMechanism( + timing_dependence=sim.extra_models.SpikeNearestPairRule( + tau_plus=10, tau_minus=12, A_plus=1, A_minus=-1), + weight_dependence=sim.AdditiveWeightDependence(w_min=0, w_max=20), + weight=0, delay=1) + + injector_proj_exc = sim.Projection( + injector_neurons_exc, output_neuron, + sim.AllToAllConnector(allow_self_connections=True), + stdp_model, receptor_type='excitatory') + injector_proj_inh = sim.Projection( + injector_neurons_inh, output_neuron, + sim.AllToAllConnector(allow_self_connections=True), + stdp_model2, receptor_type='inhibitory') + + sim.run(runtime) + + weights_exc = injector_proj_exc.get(["weight"], "list") + weights_inh = injector_proj_inh.get(["weight"], "list") + + print(weights_exc) + print(weights_inh) + + sim.end() + + self.assertTrue(numpy.allclose(weights_exc, weights_inh, rtol=0.001)) + + def test_mad_pair_additive_delta(self): + self.runsafe(self.mad_pair_additive_delta) + + def test_nearest_pair_additive_delta(self): + self.runsafe(self.nearest_pair_additive_delta) + + +if __name__ == '__main__': + unittest.main() From 4c56de4c936678b2d18dbc55a1b7add0a2270227 Mon Sep 17 00:00:00 2001 From: Andrew Gait Date: Thu, 14 Sep 2023 19:42:41 +0100 Subject: [PATCH 6/6] flake8 whitespaces --- .../test_stdp/test_IF_curr_delta_stdp.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spynnaker_integration_tests/test_stdp/test_IF_curr_delta_stdp.py b/spynnaker_integration_tests/test_stdp/test_IF_curr_delta_stdp.py index ec0b758b2b..0ce6fb41c8 100644 --- a/spynnaker_integration_tests/test_stdp/test_IF_curr_delta_stdp.py +++ b/spynnaker_integration_tests/test_stdp/test_IF_curr_delta_stdp.py @@ -27,8 +27,8 @@ def mad_pair_additive_delta(self): # Spikes set so the calculated weights for each STDP projection # should be identical - spike_times1 = [[1,27,55], [1,27,55]] - spike_times2 = [[1,33,59], [1,33,59]] + spike_times1 = [[1, 27, 55], [1, 27, 55]] + spike_times2 = [[1, 33, 59], [1, 33, 59]] training_times = [28] save_spike_times = [90] runtime = save_spike_times[-1] + 10 @@ -123,8 +123,8 @@ def nearest_pair_additive_delta(self): # Spikes set so the calculated weights for each STDP projection # should be identical - spike_times1 = [[1,27,51], [1,27,51]] - spike_times2 = [[1,33,60], [1,33,60]] + spike_times1 = [[1, 27, 51], [1, 27, 51]] + spike_times2 = [[1, 33, 60], [1, 33, 60]] training_times = [28] save_spike_times = [90] runtime = save_spike_times[-1] + 10