Skip to content

Commit a84393e

Browse files
authored
Merge pull request #2 from SpiNNakerManchester/play
Test notebooks using nbmake
2 parents fe9433c + 2cb2edc commit a84393e

32 files changed

+417
-773
lines changed

.github/workflows/python_actions.yml

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Copyright (c) 2020 The University of Manchester
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# This workflow will install Python dependencies, run tests, lint and rat with a variety of Python versions
16+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
17+
18+
name: Python Actions
19+
20+
on: [push]
21+
22+
jobs:
23+
test:
24+
runs-on: ubuntu-latest
25+
timeout-minutes: 10
26+
strategy:
27+
matrix:
28+
python-version: [3.8, 3.9, "3.10", "3.11", "3.12"]
29+
30+
steps:
31+
- name: Set up Python ${{ matrix.python-version }}
32+
uses: actions/setup-python@v4
33+
with:
34+
python-version: ${{ matrix.python-version }}
35+
36+
- name: Checkout
37+
uses: actions/checkout@v4
38+
39+
- name: Checkout SupportScripts
40+
uses: actions/checkout@v4
41+
with:
42+
repository: SpiNNakerManchester/SupportScripts
43+
path: support
44+
45+
- name: Install pip, etc
46+
uses: ./support/actions/python-tools
47+
48+
- name: Install nbmake
49+
run: pip install pytest nbmake
50+
51+
- name: Install Spinnaker Dependencies
52+
uses: ./support/actions/install-spinn-deps
53+
with:
54+
repositories: >
55+
SpiNNUtils SpiNNMachine SpiNNMan PACMAN spalloc
56+
SpiNNFrontEndCommon sPyNNaker TestBase
57+
install: true
58+
59+
- name: Setup
60+
uses: ./support/actions/run-install
61+
62+
#- name: Setup PyNN
63+
# uses: ./support/actions/pynn-setup
64+
65+
- name: Create a spynnaker.cfg
66+
uses: ./support/actions/configure-spynnaker
67+
with:
68+
virtual: true
69+
70+
- name: Build test bash
71+
run: python integration_tests/bash_builder.py
72+
73+
- name: Test with nbmake
74+
run: bash integration_tests/pytest.bash
75+
76+
- name: Lint with flake8
77+
run: flake8 integration_tests spinnaker_jupyter_examples
78+
79+
- name: Lint with pylint
80+
uses: ./support/actions/pylint
81+
with:
82+
package: integration_tests spinnaker_jupyter_examples
83+
exitcheck: 31 # Action fails on any message
84+
language: en_GB
85+
86+

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
/.project
22
/.pydevproject
3+
.ipynb_checkpoints
4+
.pytest_cache
5+
.pytest.bash

00.Setup/Setup.ipynb

+15-23
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
"source": [
2121
"import configparser\n",
2222
"import os\n",
23-
"from unittest import SkipTest\n",
2423
"\n",
2524
"OVERRIDE_EXISTING = False\n",
2625
"FULL_PATH = os.path.expanduser('~/.spynnaker.cfg')\n",
@@ -50,23 +49,23 @@
5049
" return True\n",
5150
"\n",
5251
" # SkipTest as unittest considers this neither a failure nor a success\n",
53-
" raise SkipTest(f\"{FULL_PATH} already exists. \"\n",
54-
" \"To replace it change OVERRIDE_EXISTING to True\")\n",
52+
" print(f\"{FULL_PATH} already exists.\")\n",
53+
" print(\"To replace it change OVERRIDE_EXISTING to True\")\n",
54+
" return False\n",
5555
"\n",
5656
"\n",
57-
"check_should_create()\n",
58-
"\n",
5957
"# Make sure there is a spynnaker.cfg file\n",
60-
"with open(FULL_PATH, 'w') as cfg:\n",
61-
" cfg.write(\"[Machine]\\n\")\n",
62-
" cfg.write(\"spalloc_server = https://spinnaker.cs.man.ac.uk/spalloc/\\n\")\n",
63-
" cfg.write(\"\\n\")\n",
64-
" cfg.write(\"[Java]\\n\")\n",
65-
" cfg.write(\"use_java=True\\n\")\n",
66-
" cfg.write(\"\\n\")\n",
67-
" cfg.write(\"[Reports]\\n\")\n",
68-
" cfg.write(\"read_provenance_data = False\\n\")\n",
69-
" print(f\"New {FULL_PATH} created\")\n"
58+
"if check_should_create():\n",
59+
" with open(FULL_PATH, 'w') as cfg:\n",
60+
" cfg.write(\"[Machine]\\n\")\n",
61+
" cfg.write(\"spalloc_server = https://spinnaker.cs.man.ac.uk/spalloc/\\n\")\n",
62+
" cfg.write(\"\\n\")\n",
63+
" cfg.write(\"[Java]\\n\")\n",
64+
" cfg.write(\"use_java=True\\n\")\n",
65+
" cfg.write(\"\\n\")\n",
66+
" cfg.write(\"[Reports]\\n\")\n",
67+
" cfg.write(\"read_provenance_data = False\\n\")\n",
68+
" print(f\"New {FULL_PATH} created\")\n"
7069
]
7170
},
7271
{
@@ -82,14 +81,7 @@
8281
]
8382
}
8483
],
85-
"metadata": {
86-
"kernelspec": {
87-
"display_name": "EBRAINS-experimental",
88-
"language": "python",
89-
"name": "ebrains-experimental"
90-
},
91-
"title": "SpiNNaker Setup"
92-
},
84+
"metadata": {},
9385
"nbformat": 4,
9486
"nbformat_minor": 2
9587
}

01.RunningPyNNSimulations/RunningPyNNSimulationsOnSpiNNaker.ipynb

+20-62
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,9 @@
116116
"of the current is added over a number of timesteps, with the current decaying exponentially between each.\n",
117117
"A longer decay rate will result in more charge being added overall per spike that crosses the synapse.\n",
118118
"\n",
119-
"In the above example, the default parameters of the IF_curr_exp are used. These are shown below."
120-
]
121-
},
122-
{
123-
"cell_type": "code",
124-
"execution_count": null,
125-
"metadata": {},
126-
"outputs": [],
127-
"source": [
119+
"In the above example, the default parameters of the IF_curr_exp are used. These are shown below.\n",
120+
"\n",
121+
"```\n",
128122
"lif_curr_exp_params = {\n",
129123
" 'cm': 1.0, # The capacitance of the LIF neuron in nano-Farads\n",
130124
" 'tau_m': 20.0, # The time-constant of the RC circuit, in milliseconds\n",
@@ -135,7 +129,8 @@
135129
" 'tau_syn_E': 5.0, # The excitatory input current decay time-constant\n",
136130
" 'tau_syn_I': 5.0, # The inhibitory input current decay time-constant\n",
137131
" 'i_offset': 0.0, # A base input current to add each timestep\n",
138-
"}"
132+
"}\n",
133+
"```"
139134
]
140135
},
141136
{
@@ -147,19 +142,14 @@
147142
"value of the membrane voltage; the higher the membrane voltage, the more input is required to cause a\n",
148143
"spike. This is modelled as the reversal potential of the synapse; when the membrane potential equals the\n",
149144
"reversal potential, no current will flow across the synapse. A conductance-based version of the LIF model\n",
150-
"is provided, which, in addition to the above parameters, also supports the following."
151-
]
152-
},
153-
{
154-
"cell_type": "code",
155-
"execution_count": null,
156-
"metadata": {},
157-
"outputs": [],
158-
"source": [
145+
"is provided, which, in addition to the above parameters, also supports the following.",
146+
"\n",
147+
"```\n",
159148
"lif_cond_exp_extra_params = {\n",
160149
" 'e_rev_E': 0., # The reversal potential of the excitatory synapse\n",
161150
" 'e_rev_I': -80.0 # The reversal potential of the inhibitory synapse\n",
162-
"}"
151+
"}\n",
152+
"```"
163153
]
164154
},
165155
{
@@ -168,16 +158,10 @@
168158
"source": [
169159
"The initial value of the state variables of the neural model can also be set (such as the membrane voltage).\n",
170160
"This is done via the initialize function of the population, which takes the name of the state variable (e.g. v\n",
171-
"for the membrane voltage), and the value to be assigned e.g. the initial voltage can be set to -65.0mV as follows."
172-
]
173-
},
174-
{
175-
"cell_type": "code",
176-
"execution_count": null,
177-
"metadata": {},
178-
"outputs": [],
179-
"source": [
180-
"pop_1.initialize(v=-65.0)"
161+
"for the membrane voltage), and the value to be assigned e.g. the initial voltage can be set to -65.0mV as follows.\n",
162+
"```\n",
163+
"pop_1.initialize(v=-65.0)\n",
164+
"```"
181165
]
182166
},
183167
{
@@ -208,15 +192,7 @@
208192
"\n",
209193
"As well as a connector the Projection must also have a synapse_type which determines how the synapse\n",
210194
"behaves when spikes are received. For example a StaticSynapse which has fixed weights and delays is\n",
211-
"specified as shown below."
212-
]
213-
},
214-
{
215-
"cell_type": "code",
216-
"execution_count": null,
217-
"metadata": {},
218-
"outputs": [],
219-
"source": [
195+
"specified as shown below.\n",
220196
"synapse_type=sim.StaticSynapse(weight=0.75, delay=1.0)"
221197
]
222198
},
@@ -326,19 +302,14 @@
326302
"### STDP in PyNN\n",
327303
"The steps for creating a network using STDP are much the same as previously described, with the main\n",
328304
"difference being that some of the projections use a STDPMechanism to describe the plasticity. Below is an\n",
329-
"example of the creation of a projection with STDP."
330-
]
331-
},
332-
{
333-
"cell_type": "code",
334-
"execution_count": null,
335-
"metadata": {},
336-
"outputs": [],
337-
"source": [
305+
"example of the creation of a projection with STDP.\n",
306+
"\n",
307+
"```\n",
338308
"timing_rule = sim.SpikePairRule(tau_plus=20.0, tau_minus=20.0, A_plus=0.5, A_minus=0.5)\n",
339309
"weight_rule = sim.AdditiveWeightDependence(w_max=5.0, w_min=0.0)\n",
340310
"stdp_model = sim.STDPMechanism(timing_dependence=timing_rule, weight_dependence=weight_rule, weight=0.0, delay=5.0)\n",
341-
"stdp_projection = sim.Projection(input, pop_1, sim.OneToOneConnector(), synapse_type=stdp_model)"
311+
"stdp_projection = sim.Projection(input, pop_1, sim.OneToOneConnector(), synapse_type=stdp_model)\n",
312+
"```"
342313
]
343314
},
344315
{
@@ -423,22 +394,9 @@
423394
" - Create an STDP curve graph using a SpikeSourceArray stimulating a LIF population, with varying spike times for the SpikeSourceArray.\n",
424395
" - See the notebook for further extensions.\n"
425396
]
426-
},
427-
{
428-
"cell_type": "code",
429-
"execution_count": null,
430-
"metadata": {},
431-
"outputs": [],
432-
"source": []
433397
}
434398
],
435399
"metadata": {
436-
"kernelspec": {
437-
"display_name": "EBRAINS-experimental",
438-
"language": "python",
439-
"name": "ebrains-experimental"
440-
},
441-
"title": "Running PyNN Simulations on SpiNNaker"
442400
},
443401
"nbformat": 4,
444402
"nbformat_minor": 2

01.RunningPyNNSimulations/solutions/task1-solutions.ipynb

-6
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,6 @@
178178
}
179179
],
180180
"metadata": {
181-
"kernelspec": {
182-
"display_name": "EBRAINS-experimental",
183-
"language": "python",
184-
"name": "ebrains-experimental"
185-
},
186-
"title": "Task 1.1 Solutions"
187181
},
188182
"nbformat": 4,
189183
"nbformat_minor": 2

01.RunningPyNNSimulations/solutions/task2-solutions.ipynb

-6
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,6 @@
199199
}
200200
],
201201
"metadata": {
202-
"kernelspec": {
203-
"display_name": "EBRAINS-experimental",
204-
"language": "python",
205-
"name": "ebrains-experimental"
206-
},
207-
"title": "Task 1.2 Solutions"
208202
},
209203
"nbformat": 4,
210204
"nbformat_minor": 2

01.RunningPyNNSimulations/solutions/task3-solutions.ipynb

-6
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,6 @@
250250
}
251251
],
252252
"metadata": {
253-
"kernelspec": {
254-
"display_name": "EBRAINS-experimental",
255-
"language": "python",
256-
"name": "ebrains-experimental"
257-
},
258-
"title": "Task 1.3 Solutions"
259253
},
260254
"nbformat": 4,
261255
"nbformat_minor": 2

01.RunningPyNNSimulations/solutions/task4-solutions.ipynb

+1-7
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195
"source": [
196196
"weights = proj.get([\"weight\"], \"list\")\n",
197197
"p.end()\n",
198-
"print weights"
198+
"print(weights)"
199199
]
200200
},
201201
{
@@ -221,12 +221,6 @@
221221
}
222222
],
223223
"metadata": {
224-
"kernelspec": {
225-
"display_name": "EBRAINS-experimental",
226-
"language": "python",
227-
"name": "ebrains-experimental"
228-
},
229-
"title": "Task 1.4 Solutions"
230224
},
231225
"nbformat": 4,
232226
"nbformat_minor": 2

01.RunningPyNNSimulations/solutions/task5-solutions.ipynb

+3-8
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@
155155
"metadata": {},
156156
"outputs": [],
157157
"source": [
158-
"weights = proj.get([\"weight\"], \"list\", with_address=False)\n",
158+
"import numpy\n",
159+
"weights = numpy.array(proj.get(\"weight\", \"list\", with_address=False))\n",
159160
"pre_spikes = pre.get_data(\"spikes\").segments[0].spiketrains\n",
160161
"post_spikes = post.get_data(\"spikes\").segments[0].spiketrains\n",
161162
"p.end()"
@@ -177,7 +178,7 @@
177178
"metadata": {},
178179
"outputs": [],
179180
"source": [
180-
"weight_diff = weights[:] - 0.5\n",
181+
"weight_diff = weights - 0.5\n",
181182
"time_diff = [pre_neuron_spikes[0] - post_neuron_spikes[0] for pre_neuron_spikes, post_neuron_spikes in zip(pre_spikes, post_spikes)]"
182183
]
183184
},
@@ -203,12 +204,6 @@
203204
}
204205
],
205206
"metadata": {
206-
"kernelspec": {
207-
"display_name": "EBRAINS-experimental",
208-
"language": "python",
209-
"name": "ebrains-experimental"
210-
},
211-
"title": "Task 1.5 Solutions"
212207
},
213208
"nbformat": 4,
214209
"nbformat_minor": 2

0 commit comments

Comments
 (0)