Skip to content

Commit 341ef23

Browse files
authored
Merge branch 'master' into dead_code
2 parents ed05547 + 2bf15aa commit 341ef23

12 files changed

Lines changed: 169 additions & 76 deletions

mypy.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ spalloc="../spalloc/spalloc_client"
2727
fec="../SpiNNFrontEndCommon/spinn_front_end_common"
2828
test_base="../TestBase/spinnaker_testbase"
2929

30-
mypy --python-version 3.8 $utils $machine $man $pacman $spalloc $fec $test_base spynnaker unittests spynnaker_integration_tests proxy_integration_tests
30+
mypy $utils $machine $man $pacman $spalloc $fec $test_base spynnaker unittests spynnaker_integration_tests proxy_integration_tests

mypyd.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ spalloc="../spalloc/spalloc_client"
2727
fec="../SpiNNFrontEndCommon/spinn_front_end_common"
2828
test_base="../TestBase/spinnaker_testbase"
2929

30-
mypy --python-version 3.8 --disallow-untyped-defs $utils $machine $man $pacman $spalloc $fec $test_base spynnaker unittests spynnaker_integration_tests proxy_integration_tests
30+
mypy --disallow-untyped-defs $utils $machine $man $pacman $spalloc $fec $test_base spynnaker unittests spynnaker_integration_tests proxy_integration_tests
3131

spynnaker/pyNN/models/neural_projections/connectors/convolution_connector.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,9 @@ def __init__(self, kernel_weights: _Weights,
165165
self.__padding_shape = self.__decode_padding(padding)
166166
self.__filter_edges = filter_edges
167167

168+
self.__strides: NDArray[integer]
168169
if strides is None:
169-
self.__strides = numpy.array((1, 1), dtype=integer)
170+
self.__strides = numpy.array((1, 1), dtype=numpy.uint32)
170171
else:
171172
self.__strides = self.__to_2d_shape(strides, "strides")
172173
self.__pool_shape = self.__to_2d_shape(pool_shape, "pool_shape")
@@ -261,20 +262,20 @@ def __to_2d_shape(shape: _Shape, param_name: str) -> Optional[
261262
if shape is None:
262263
return None
263264
if numpy.isscalar(shape):
264-
return numpy.array([shape, shape], dtype=integer)
265+
return numpy.array([shape, shape], dtype=uint32)
265266
assert isinstance(shape, tuple)
266267
if len(shape) == 1:
267-
return numpy.array([shape[0], 1], dtype=integer)
268+
return numpy.array([shape[0], 1], dtype=uint32)
268269
elif len(shape) == 2:
269-
return numpy.array(shape, dtype=integer)
270+
return numpy.array(shape, dtype=uint32)
270271
raise SynapticConfigurationException(
271272
f"{param_name} must be an int or a tuple(int, int)")
272273

273274
def __decode_padding(self, padding: _Padding) -> NDArray[integer]:
274275
if isinstance(padding, (int, Iterable)):
275276
return self.__to_2d_shape(padding, "padding")
276277
elif padding is None or padding is False:
277-
return numpy.zeros(2, dtype=integer)
278+
return numpy.zeros(2, dtype=uint32)
278279
elif padding:
279280
return self.__kernel_weights.shape // 2
280281
else:

spynnaker/pyNN/models/neural_projections/connectors/fixed_number_post_connector.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def __build_post_neurons(
133133
self, synapse_info: SynapseInformation) -> List[NDArray[integer]]:
134134
rng = self.__rng or NumpyRNG()
135135
post_neurons: List[NDArray[integer]] = \
136-
[numpy.empty([0], dtype=integer)] * synapse_info.n_pre_neurons
136+
[numpy.empty([0], dtype=uint32)] * synapse_info.n_pre_neurons
137137
# Loop over all the pre neurons
138138
for m in range(synapse_info.n_pre_neurons):
139139
if post_neurons[m] is None:
@@ -226,9 +226,9 @@ def _n_post_neurons_in_slice(
226226
# this post-vertex slice
227227
this_post_neuron_array = post_neurons[n]
228228

229-
return numpy.count_nonzero(numpy.logical_and(
229+
return int(numpy.count_nonzero(numpy.logical_and(
230230
post_vertex_slice.lo_atom <= this_post_neuron_array,
231-
this_post_neuron_array <= post_vertex_slice.hi_atom))
231+
this_post_neuron_array <= post_vertex_slice.hi_atom)))
232232

233233
@overrides(AbstractConnector.get_n_connections_from_pre_vertex_maximum)
234234
def get_n_connections_from_pre_vertex_maximum(

spynnaker/pyNN/models/neural_projections/connectors/fixed_number_pre_connector.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ def get_delay_minimum(self, synapse_info: SynapseInformation) -> float:
133133
def __build_pre_neurons(self, synapse_info: SynapseInformation) -> List[
134134
NDArray[integer]]:
135135
rng = self.__rng or NumpyRNG()
136-
pre_neurons = [
137-
numpy.zeros([0], dtype=integer)] * synapse_info.n_post_neurons
136+
pre_neurons: List[NDArray[integer]] = [
137+
numpy.zeros([0], dtype=uint32)] * synapse_info.n_post_neurons
138138
# Loop over all the post neurons
139139
for m in range(synapse_info.n_post_neurons):
140140
# If the pre and post populations are the same

spynnaker/pyNN/models/neuron/population_machine_vertex.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# limitations under the License.
1414
import ctypes
1515
from enum import IntEnum
16-
import os
1716
from typing import List, Optional, Sequence
1817

1918
from numpy import floating
@@ -198,7 +197,7 @@ def __init__(
198197
self.COMMON_REGIONS,
199198
NeuronProvenance.N_ITEMS + SynapseProvenance.N_ITEMS +
200199
SpikeProcessingProvenance.N_ITEMS + MainProvenance.N_ITEMS,
201-
self._PROFILE_TAG_LABELS, self.__get_binary_file_name(app_vertex))
200+
self._PROFILE_TAG_LABELS, app_vertex.combined_binary_file_name)
202201
self.__key: Optional[int] = None
203202
self.__slice_index = slice_index
204203
self.__ring_buffer_shifts = ring_buffer_shifts
@@ -259,22 +258,6 @@ def _synaptic_matrices(self) -> SynapticMatrices:
259258
def _max_atoms_per_core(self) -> int:
260259
return self.__max_atoms_per_core
261260

262-
@staticmethod
263-
def __get_binary_file_name(app_vertex: PopulationVertex) -> str:
264-
"""
265-
Get the local binary filename for this vertex. Static because at
266-
the time this is needed, the local `app_vertex` is not set.
267-
268-
:param PopulationVertex app_vertex:
269-
The associated application vertex
270-
:rtype: str
271-
"""
272-
# Split binary name into title and extension
273-
name, ext = os.path.splitext(app_vertex.neuron_impl.binary_name)
274-
275-
# Reunite title and extension and return
276-
return name + app_vertex.synapse_executable_suffix + ext
277-
278261
@overrides(PopulationMachineCommon.parse_extra_provenance_items)
279262
def parse_extra_provenance_items(
280263
self, label: str, x: int, y: int, p: int,

spynnaker/pyNN/models/neuron/population_neurons_machine_vertex.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
from enum import IntEnum
15-
import os
1615
import ctypes
1716
from typing import List, Optional, Sequence
1817

@@ -147,7 +146,7 @@ def __init__(
147146
super().__init__(
148147
label, app_vertex, vertex_slice, sdram, self.COMMON_REGIONS,
149148
NeuronProvenance.N_ITEMS + NeuronMainProvenance.N_ITEMS,
150-
self._PROFILE_TAG_LABELS, self.__get_binary_file_name(app_vertex))
149+
self._PROFILE_TAG_LABELS, app_vertex.neuron_core_binary_file_name)
151150
self.__key: Optional[int] = None
152151
self.__sdram_partition: Optional[
153152
SourceSegmentedSDRAMMachinePartition] = None
@@ -210,22 +209,6 @@ def set_sdram_partition(
210209
"Trying to set SDRAM partition more than once")
211210
self.__sdram_partition = sdram_partition
212211

213-
@staticmethod
214-
def __get_binary_file_name(app_vertex: PopulationVertex) -> str:
215-
"""
216-
Get the local binary filename for this vertex. Static because at
217-
the time this is needed, the local app_vertex is not set.
218-
219-
:param PopulationVertex app_vertex:
220-
The associated application vertex
221-
:rtype: str
222-
"""
223-
# Split binary name into title and extension
224-
name, ext = os.path.splitext(app_vertex.neuron_impl.binary_name)
225-
226-
# Reunite title and extension and return
227-
return name + "_neuron" + ext
228-
229212
@overrides(PopulationMachineCommon.parse_extra_provenance_items)
230213
def parse_extra_provenance_items(
231214
self, label: str, x: int, y: int, p: int,

spynnaker/pyNN/models/neuron/population_synapses_machine_vertex_common.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def __init__(
171171
super().__init__(
172172
label, app_vertex, vertex_slice, sdram, self.COMMON_REGIONS,
173173
SynapseProvenance.N_ITEMS + SpikeProcessingFastProvenance.N_ITEMS,
174-
self._PROFILE_TAG_LABELS, self.__get_binary_file_name(app_vertex))
174+
self._PROFILE_TAG_LABELS, app_vertex.synapse_core_binary_file_name)
175175
self.__sdram_partition: Optional[
176176
SourceSegmentedSDRAMMachinePartition] = None
177177
self.__neuron_vertex: Optional[PopulationNeuronsMachineVertex] = None
@@ -199,19 +199,6 @@ def set_neuron_vertex_and_partition_id(
199199
self.__neuron_vertex = neuron_vertex
200200
self.__partition_id = partition_id
201201

202-
@staticmethod
203-
def __get_binary_file_name(app_vertex: PopulationVertex) -> str:
204-
"""
205-
Get the local binary filename for this vertex. Static because at
206-
the time this is needed, the local `app_vertex` is not set.
207-
208-
:param PopulationVertex app_vertex:
209-
The associated application vertex
210-
:rtype: str
211-
"""
212-
# Reunite title and extension and return
213-
return "synapses" + app_vertex.synapse_executable_suffix + ".aplx"
214-
215202
@overrides(PopulationMachineCommon.get_recorded_region_ids)
216203
def get_recorded_region_ids(self) -> Sequence[int]:
217204
ids = self._pop_vertex.synapse_recorder.recorded_ids_by_slice(

spynnaker/pyNN/models/neuron/population_vertex.py

Lines changed: 142 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from collections import defaultdict
1616
import logging
1717
import math
18+
import os
1819
from typing import (
1920
Any, Collection, Dict, Iterable, List, Optional, Sequence, Tuple, Union,
2021
cast, TYPE_CHECKING)
@@ -486,6 +487,73 @@ def set_max_atoms_per_dimension_per_core(
486487
def set_structure(self, structure: BaseStructure) -> None:
487488
self.__structure = structure
488489

490+
@property
491+
def combined_binary_file_name(self) -> str:
492+
"""
493+
The name of the combined binary file for the vertex.
494+
"""
495+
# Split binary name into title and extension
496+
name, ext = os.path.splitext(self.__neuron_impl.binary_name)
497+
498+
# Reunite title and extension and return
499+
return name + self.synapse_executable_suffix + ext
500+
501+
@property
502+
def neuron_core_binary_file_name(self) -> str:
503+
"""
504+
The name of the neuron core binary file for the vertex.
505+
"""
506+
# Split binary name into title and extension
507+
name, ext = os.path.splitext(self.__neuron_impl.binary_name)
508+
509+
# Reunite title and extension and return
510+
return name + "_neuron" + ext
511+
512+
@property
513+
def synapse_core_binary_file_name(self) -> str:
514+
"""
515+
The name of the synapse core binary file for the vertex.
516+
"""
517+
return "synapses" + self.synapse_executable_suffix + ".aplx"
518+
519+
@property
520+
def combined_binary_exists(self) -> bool:
521+
"""
522+
Whether the combined binary file exists.
523+
524+
:rtype: bool
525+
"""
526+
# If we are in virtual machine mode, we can work without binaries
527+
# so easier to assume they exist
528+
if get_config_bool("Machine", "virtual_board"):
529+
return True
530+
try:
531+
SpynnakerDataView().get_executable_path(
532+
self.combined_binary_file_name)
533+
return True
534+
except KeyError:
535+
return False
536+
537+
@property
538+
def split_binaries_exist(self) -> bool:
539+
"""
540+
Whether the split binary files exist.
541+
542+
:rtype: bool
543+
"""
544+
# If we are in virtual machine mode, we can work without binaries
545+
# so easier to assume they exist
546+
if get_config_bool("Machine", "virtual_board"):
547+
return True
548+
try:
549+
SpynnakerDataView().get_executable_path(
550+
self.neuron_core_binary_file_name)
551+
SpynnakerDataView().get_executable_path(
552+
self.synapse_core_binary_file_name)
553+
return True
554+
except KeyError:
555+
return False
556+
489557
@property
490558
def use_combined_core(self) -> bool:
491559
"""
@@ -495,6 +563,15 @@ def use_combined_core(self) -> bool:
495563
496564
:rtype: bool
497565
"""
566+
# If there are no binaries at all, complain!
567+
if not self.combined_binary_exists and not self.split_binaries_exist:
568+
raise SynapticConfigurationException(
569+
"This model has no binaries! Please compile the binaries"
570+
f" {self.combined_binary_file_name} and/or"
571+
f" ({self.synapse_core_binary_file_name} and"
572+
f" {self.neuron_core_binary_file_name})"
573+
" before running the simulation.")
574+
498575
# If we can't use a combined core, use a split core
499576
if not self.__synapse_dynamics.is_combined_core_capable:
500577
if not self.__synapse_dynamics.is_split_core_capable:
@@ -508,6 +585,13 @@ def use_combined_core(self) -> bool:
508585
f"The synapse dynamics {self.__synapse_dynamics} must be"
509586
" run using a synapse core separate from a neuron core."
510587
" Please set the number of synapse cores to 1 or greater.")
588+
if not self.split_binaries_exist:
589+
raise SynapticConfigurationException(
590+
"This model requires split binaries"
591+
f" {self.neuron_core_binary_file_name} and"
592+
f" {self.synapse_core_binary_file_name} but they do not "
593+
"exist. Please compile the split binaries before "
594+
"running the simulation.")
511595
return False
512596

513597
# If we can't use a split core, use a combined core
@@ -518,21 +602,67 @@ def use_combined_core(self) -> bool:
518602
f"The synapse dynamics {self.__synapse_dynamics} must be"
519603
" run using a combined synapse-neuron core."
520604
" Please set the number of synapse cores to 0.")
605+
if not self.combined_binary_exists:
606+
raise SynapticConfigurationException(
607+
"This model requires a combined binary"
608+
f" {self.combined_binary_file_name}, but it does not "
609+
"exist. Please compile the combined binary before "
610+
"running the simulation.")
521611
return True
522612

523613
# If the user has chosen to have a synapse core, add one
524614
if self.__n_synapse_cores is not None and self.__n_synapse_cores > 0:
615+
if not self.split_binaries_exist:
616+
raise SynapticConfigurationException(
617+
"This model is configured to use split binaries"
618+
f" {self.neuron_core_binary_file_name} and"
619+
f" {self.synapse_core_binary_file_name} but they do not "
620+
"exist. Please compile the split binaries before "
621+
"running the simulation.")
525622
return False
526623

624+
# If the user has chosen to have no synapse cores, use a combined core
625+
if self.__n_synapse_cores is not None and self.__n_synapse_cores == 0:
626+
if not self.combined_binary_exists:
627+
raise SynapticConfigurationException(
628+
"This model is configured to use a combined binary"
629+
f" {self.combined_binary_file_name}, but it does not "
630+
"exist. Please compile the combined binary before "
631+
"running the simulation.")
632+
return True
633+
527634
# If the time-step is less than 1, use combined core if no synapse
528635
# cores are needed, otherwise use split core
529636
# TODO: Look at if it is possible to include neurons in a combined
530637
# core calculation and update to allow a choice of combined core if
531638
# neurons and synapses fit on a single core
532639
if SpynnakerDataView().get_simulation_time_step_ms() < 1.0:
533-
return self.n_synapse_cores_required == 0
640+
use_combined = (self.n_synapse_cores_required == 0)
641+
642+
# We want combined, but it doesn't exist, so use split
643+
# (which is fine)
644+
if use_combined and not self.combined_binary_exists:
645+
return False
534646

535-
# If the timestep is 1 or greater, use a combined core generally
647+
# We want split, but it doesn't exist, so use combined, which needs
648+
# a warning as it might not work at this time-step!
649+
if not use_combined and not self.split_binaries_exist:
650+
logger.warning(
651+
"The synapse dynamics are set to use a split core, but "
652+
"the split binaries do not exist. Using the combined "
653+
"core instead, but this may not work at this time-step. "
654+
"To avoid this warning please build the split binaries "
655+
f"{self.neuron_core_binary_file_name} and "
656+
f"{self.synapse_core_binary_file_name}.")
657+
return True
658+
659+
# Use the recommended mode
660+
return use_combined
661+
662+
# If the timestep is 1 or greater, use a combined core generally,
663+
# unless only a split core exists!
664+
if not self.combined_binary_exists:
665+
return False
536666
return True
537667

538668
@property
@@ -616,7 +746,16 @@ def __update_n_synapse_cores(self) -> int:
616746

617747
# If the number of cores needed is more than the maximum, use the
618748
# maximum
619-
self.__n_synapse_cores = min(max_n_cores, n_synapse_cores)
749+
if n_synapse_cores > max_n_cores:
750+
logger.warning(
751+
f"Ideally this execution would need {n_synapse_cores} synapse "
752+
f"cores, but only {max_n_cores} cores are available. This may "
753+
"mean that the simulation does not work correctly. Potential "
754+
"solutions include increasing the time_scale_factor, or "
755+
"reducing the number of synapses incoming into each "
756+
"population")
757+
n_synapse_cores = max_n_cores
758+
self.__n_synapse_cores = n_synapse_cores
620759
assert self.__n_synapse_cores is not None
621760
return self.__n_synapse_cores
622761

0 commit comments

Comments
 (0)