diff --git a/.github/workflows/python_actions.yml b/.github/workflows/python_actions.yml index 175e2672..71096bbe 100644 --- a/.github/workflows/python_actions.yml +++ b/.github/workflows/python_actions.yml @@ -42,6 +42,9 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install pip, etc uses: ./support/actions/python-tools + - name: Install mypy + run: pip install mypy + - name: Install Spinnaker Dependencies uses: ./support/actions/install-spinn-deps with: @@ -76,6 +79,9 @@ jobs: exitcheck: 31 # Action fails on any message language: en_GB + - name: Lint with mypy + run: mypy $BASE_PKG + validate: runs-on: ubuntu-latest strategy: diff --git a/gfe_examples/Conways/partitioned_example_a_no_vis_no_buffer/conways_basic_cell.py b/gfe_examples/Conways/partitioned_example_a_no_vis_no_buffer/conways_basic_cell.py index 477674b7..53f5c23e 100644 --- a/gfe_examples/Conways/partitioned_example_a_no_vis_no_buffer/conways_basic_cell.py +++ b/gfe_examples/Conways/partitioned_example_a_no_vis_no_buffer/conways_basic_cell.py @@ -13,10 +13,14 @@ # limitations under the License. from enum import IntEnum +from typing import Iterable, Optional from spinn_utilities.overrides import overrides +from spinn_machine.tags import IPTag, ReverseIPTag from pacman.model.graphs.machine import MachineVertex +from pacman.model.placements import Placement from pacman.model.resources import VariableSDRAM from spinn_front_end_common.data import FecDataView +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinn_front_end_common.utilities.constants import ( SYSTEM_BYTES_REQUIREMENT, BYTES_PER_WORD) from spinn_front_end_common.utilities.exceptions import ConfigurationException @@ -72,7 +76,9 @@ def add_neighbour(self, neighbour): @overrides( MachineDataSpecableVertex.generate_machine_data_specification) def generate_machine_data_specification( - self, spec, placement, iptags, reverse_iptags): + self, spec: DataSpecificationGenerator, placement: Placement, + iptags: Optional[Iterable[IPTag]], + reverse_iptags: Optional[Iterable[ReverseIPTag]]): if len(self._neighbours) != 8: raise ValueError( f"Only {len(self._neighbours)} neighbours, not 8") @@ -149,7 +155,7 @@ def get_data(self): @property @overrides(MachineVertex.sdram_required) - def sdram_required(self): + def sdram_required(self) -> VariableSDRAM: fixed_sdram = (SYSTEM_BYTES_REQUIREMENT + self.TRANSMISSION_DATA_SIZE + self.STATE_DATA_SIZE + self.NEIGHBOUR_INITIAL_STATES_SIZE + diff --git a/gfe_examples/Conways/partitioned_example_b_no_vis_buffer/conways_basic_cell.py b/gfe_examples/Conways/partitioned_example_b_no_vis_buffer/conways_basic_cell.py index 4d7cfc71..c9cb1a07 100644 --- a/gfe_examples/Conways/partitioned_example_b_no_vis_buffer/conways_basic_cell.py +++ b/gfe_examples/Conways/partitioned_example_b_no_vis_buffer/conways_basic_cell.py @@ -13,10 +13,14 @@ # limitations under the License. from enum import IntEnum +from typing import Iterable, List, Optional from spinn_utilities.overrides import overrides +from spinn_machine.tags import IPTag, ReverseIPTag from pacman.model.graphs.machine import MachineVertex +from pacman.model.placements import Placement from pacman.model.resources import VariableSDRAM from spinn_front_end_common.data import FecDataView +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinn_front_end_common.utilities.constants import ( SYSTEM_BYTES_REQUIREMENT, BYTES_PER_WORD) from spinn_front_end_common.utilities.helpful_functions import ( @@ -80,7 +84,9 @@ def add_neighbour(self, neighbour): @overrides(MachineDataSpecableVertex.generate_machine_data_specification) def generate_machine_data_specification( - self, spec, placement, iptags, reverse_iptags): + self, spec: DataSpecificationGenerator, placement: Placement, + iptags: Optional[Iterable[IPTag]], + reverse_iptags: Optional[Iterable[ReverseIPTag]]): # pylint: disable=arguments-differ if len(self._neighbours) != 8: raise ValueError( @@ -147,7 +153,7 @@ def get_data(self): @property @overrides(MachineVertex.sdram_required) - def sdram_required(self): + def sdram_required(self) -> VariableSDRAM: fixed_sdram = ( SYSTEM_BYTES_REQUIREMENT + self.TRANSMISSION_DATA_SIZE + @@ -166,10 +172,10 @@ def __repr__(self): return self.label @overrides(AbstractReceiveBuffersToHost.get_recorded_region_ids) - def get_recorded_region_ids(self): + def get_recorded_region_ids(self) -> List[int]: return [Channels.STATE_LOG] @overrides(AbstractReceiveBuffersToHost.get_recording_region_base_address) - def get_recording_region_base_address(self, placement): + def get_recording_region_base_address(self, placement: Placement) -> int: return locate_memory_region_for_placement( placement, DataRegions.RESULTS) diff --git a/gfe_examples/hello_world/hello_world_vertex.py b/gfe_examples/hello_world/hello_world_vertex.py index accfb261..58f93e78 100644 --- a/gfe_examples/hello_world/hello_world_vertex.py +++ b/gfe_examples/hello_world/hello_world_vertex.py @@ -14,10 +14,14 @@ from enum import IntEnum import logging +from typing import Iterable, List, Optional from spinn_utilities.log import FormatAdapter from spinn_utilities.overrides import overrides +from spinn_machine.tags import IPTag, ReverseIPTag from pacman.model.graphs.machine import MachineVertex +from pacman.model.placements import Placement from pacman.model.resources import ConstantSDRAM +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinn_front_end_common.utilities.constants import SYSTEM_BYTES_REQUIREMENT from spinn_front_end_common.utilities.helpful_functions import ( locate_memory_region_for_placement) @@ -53,7 +57,7 @@ def __init__(self, n_hellos, label=None): @property @overrides(MachineVertex.sdram_required) - def sdram_required(self): + def sdram_required(self) -> ConstantSDRAM: return ConstantSDRAM( SYSTEM_BYTES_REQUIREMENT + get_recording_header_size(len(Channels)) + @@ -61,7 +65,9 @@ def sdram_required(self): @overrides(MachineDataSpecableVertex.generate_machine_data_specification) def generate_machine_data_specification( - self, spec, placement, iptags, reverse_iptags): + self, spec: DataSpecificationGenerator, placement: Placement, + iptags: Optional[Iterable[IPTag]], + reverse_iptags: Optional[Iterable[ReverseIPTag]]): # Generate the system data region for simulation .c requirements self.generate_system_region(spec) @@ -84,10 +90,10 @@ def read(self): return str(bytearray(raw_data)) @overrides(AbstractReceiveBuffersToHost.get_recorded_region_ids) - def get_recorded_region_ids(self): + def get_recorded_region_ids(self) -> List[int]: return [Channels.HELLO] @overrides(AbstractReceiveBuffersToHost.get_recording_region_base_address) - def get_recording_region_base_address(self, placement): + def get_recording_region_base_address(self, placement: Placement) -> int: return locate_memory_region_for_placement( placement, DataRegions.STRING_DATA) diff --git a/gfe_examples/hello_world_untimed/hello_world_vertex.py b/gfe_examples/hello_world_untimed/hello_world_vertex.py index 4453829d..3fd41e88 100644 --- a/gfe_examples/hello_world_untimed/hello_world_vertex.py +++ b/gfe_examples/hello_world_untimed/hello_world_vertex.py @@ -14,9 +14,11 @@ from enum import IntEnum import logging +from typing import List from spinn_utilities.log import FormatAdapter from spinn_utilities.overrides import overrides from pacman.model.graphs.machine import MachineVertex +from pacman.model.placements import Placement from pacman.model.resources import VariableSDRAM from spinn_front_end_common.data import FecDataView from spinn_front_end_common.utilities.constants import ( @@ -29,6 +31,7 @@ AbstractReceiveBuffersToHost) from spinn_front_end_common.interface.buffer_management import ( recording_utilities) +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinnaker_graph_front_end.utilities import SimulatorVertex from spinnaker_graph_front_end.utilities.data_utils import ( generate_steps_system_data_region) @@ -76,7 +79,7 @@ def __init__(self, label): @property @overrides(MachineVertex.sdram_required) - def sdram_required(self): + def sdram_required(self) -> VariableSDRAM: fixed = ( SYSTEM_BYTES_REQUIREMENT + recording_utilities.get_recording_header_size(len(Channels)) + @@ -85,7 +88,8 @@ def sdram_required(self): return VariableSDRAM(fixed, variable) @overrides(AbstractGeneratesDataSpecification.generate_data_specification) - def generate_data_specification(self, spec, placement): + def generate_data_specification( + self, spec: DataSpecificationGenerator, placement: Placement): # pylint: disable=arguments-differ # Generate the system data region for simulation .c requirements @@ -124,10 +128,10 @@ def read(self): return str(raw_data, self._ENCODING) @overrides(AbstractReceiveBuffersToHost.get_recorded_region_ids) - def get_recorded_region_ids(self): + def get_recorded_region_ids(self) -> List[int]: return [Channels.HELLO] @overrides(AbstractReceiveBuffersToHost.get_recording_region_base_address) - def get_recording_region_base_address(self, placement): + def get_recording_region_base_address(self, placement: Placement) -> int: return locate_memory_region_for_placement( placement, DataRegions.STRING_DATA) diff --git a/gfe_examples/live_io/live_io.py b/gfe_examples/live_io/live_io.py index 6bdbc411..1ec45f39 100644 --- a/gfe_examples/live_io/live_io.py +++ b/gfe_examples/live_io/live_io.py @@ -48,7 +48,7 @@ def start_sending(label, c): def end_sim(label, c): - # pylint: disable=unused-argument + # pylint: disable=unused-argument,global-statement global running running = False diff --git a/gfe_examples/live_io/live_io_vertex.py b/gfe_examples/live_io/live_io_vertex.py index ee9e49e5..42bf4fa9 100644 --- a/gfe_examples/live_io/live_io_vertex.py +++ b/gfe_examples/live_io/live_io_vertex.py @@ -14,11 +14,15 @@ from enum import IntEnum import logging +from typing import Iterable, Optional from spinn_utilities.log import FormatAdapter from spinn_utilities.overrides import overrides +from spinn_machine.tags import IPTag, ReverseIPTag from pacman.model.graphs.common import Slice from pacman.model.graphs.machine import MachineVertex +from pacman.model.placements import Placement from pacman.model.resources import ConstantSDRAM +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinn_front_end_common.utilities.constants import ( SYSTEM_BYTES_REQUIREMENT, BYTES_PER_WORD) from spinn_front_end_common.abstract_models.impl import ( @@ -46,7 +50,7 @@ def __init__(self, n_keys, send_partition="LiveOut", label=None): @property @overrides(MachineVertex.sdram_required) - def sdram_required(self): + def sdram_required(self) -> ConstantSDRAM: return ConstantSDRAM( SYSTEM_BYTES_REQUIREMENT + N_KEY_DATA_BYTES) @@ -55,7 +59,9 @@ def get_n_keys_for_partition(self, partition_id): @overrides(MachineDataSpecableVertex.generate_machine_data_specification) def generate_machine_data_specification( - self, spec, placement, iptags, reverse_iptags): + self, spec: DataSpecificationGenerator, placement: Placement, + iptags: Optional[Iterable[IPTag]], + reverse_iptags: Optional[Iterable[ReverseIPTag]]): # Generate the system data region for simulation .c requirements self.generate_system_region(spec) diff --git a/gfe_examples/sync_test/sync_test_vertex.py b/gfe_examples/sync_test/sync_test_vertex.py index 3dfabaaa..13bf8de5 100644 --- a/gfe_examples/sync_test/sync_test_vertex.py +++ b/gfe_examples/sync_test/sync_test_vertex.py @@ -18,8 +18,10 @@ from spinn_utilities.overrides import overrides from spinnman.model.enums import ExecutableType from pacman.model.graphs.machine import MachineVertex +from pacman.model.placements import Placement from pacman.model.resources import ConstantSDRAM from spinn_front_end_common.data import FecDataView +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinn_front_end_common.utilities.constants import ( SYSTEM_BYTES_REQUIREMENT, BYTES_PER_WORD) from spinn_front_end_common.abstract_models import ( @@ -54,21 +56,22 @@ def __init__(self, lead, app_vertex, label=None): self._lead = lead @overrides(AbstractHasAssociatedBinary.get_binary_file_name) - def get_binary_file_name(self): + def get_binary_file_name(self) -> str: return "sync_test.aplx" @overrides(AbstractHasAssociatedBinary.get_binary_start_type) - def get_binary_start_type(self): + def get_binary_start_type(self) -> ExecutableType: return ExecutableType.USES_SIMULATION_INTERFACE @property @overrides(MachineVertex.sdram_required) - def sdram_required(self): + def sdram_required(self) -> ConstantSDRAM: return ConstantSDRAM(SYSTEM_BYTES_REQUIREMENT + BYTES_PER_WORD * 2) @overrides( AbstractGeneratesDataSpecification.generate_data_specification) - def generate_data_specification(self, spec, placement): + def generate_data_specification( + self, spec: DataSpecificationGenerator, placement: Placement): # Generate the system data region for simulation .c requirements generate_system_data_region(spec, DataRegions.SYSTEM.value, self) diff --git a/gfe_examples/template/template_vertex.py b/gfe_examples/template/template_vertex.py index 61d82695..c23070c1 100644 --- a/gfe_examples/template/template_vertex.py +++ b/gfe_examples/template/template_vertex.py @@ -14,11 +14,15 @@ from enum import IntEnum import logging +from typing import Iterable, List, Optional from spinn_utilities.log import FormatAdapter from spinn_utilities.overrides import overrides +from spinn_machine.tags import IPTag, ReverseIPTag from pacman.model.graphs.machine import MachineVertex +from pacman.model.placements import Placement from pacman.model.resources import VariableSDRAM from spinn_front_end_common.data import FecDataView +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinn_front_end_common.utilities.constants import ( SYSTEM_BYTES_REQUIREMENT, BYTES_PER_WORD) from spinn_front_end_common.utilities.helpful_functions import ( @@ -68,7 +72,7 @@ def __init__(self, label): @property @overrides(MachineVertex.sdram_required) - def sdram_required(self): + def sdram_required(self) -> VariableSDRAM: constant_sdram = ( SYSTEM_BYTES_REQUIREMENT + self.TRANSMISSION_REGION_N_BYTES + recording_utilities.get_recording_header_size( @@ -82,7 +86,9 @@ def sdram_required(self): @overrides(MachineDataSpecableVertex.generate_machine_data_specification) def generate_machine_data_specification( - self, spec, placement, iptags, reverse_iptags): + self, spec: DataSpecificationGenerator, placement: Placement, + iptags: Optional[Iterable[IPTag]], + reverse_iptags: Optional[Iterable[ReverseIPTag]]): # Generate the system data region for simulation .c requirements self.generate_system_region(spec, DataRegions.SYSTEM) @@ -125,10 +131,10 @@ def read(self): return raw_data @overrides(AbstractReceiveBuffersToHost.get_recorded_region_ids) - def get_recorded_region_ids(self): + def get_recorded_region_ids(self) -> List[int]: return [RecordingChannels.RECORDING] @overrides(AbstractReceiveBuffersToHost.get_recording_region_base_address) - def get_recording_region_base_address(self, placement): + def get_recording_region_base_address(self, placement: Placement) -> int: return locate_memory_region_for_placement( placement, DataRegions.RECORDED_DATA) diff --git a/gfe_integration_tests/sdram_edge_tests/common/sdram_machine_vertex.py b/gfe_integration_tests/sdram_edge_tests/common/sdram_machine_vertex.py index 9ebdeb63..ec1f9ab9 100644 --- a/gfe_integration_tests/sdram_edge_tests/common/sdram_machine_vertex.py +++ b/gfe_integration_tests/sdram_edge_tests/common/sdram_machine_vertex.py @@ -12,14 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. from enum import IntEnum - +from typing import Iterable, Optional from spinnman.model.enums import ExecutableType +from spinn_machine.tags import IPTag, ReverseIPTag from pacman.model.graphs import AbstractSupportsSDRAMEdges -from pacman.model.graphs.machine import MachineVertex +from pacman.model.graphs.machine import MachineVertex, SDRAMMachineEdge +from pacman.model.placements import Placement from pacman.model.resources import ConstantSDRAM from spinn_front_end_common.abstract_models import AbstractHasAssociatedBinary from spinn_front_end_common.abstract_models.impl import ( MachineDataSpecableVertex) +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinn_front_end_common.interface.simulation import simulation_utilities from spinn_front_end_common.utilities.constants import ( SIMULATION_N_BYTES, BYTES_PER_WORD, SARK_PER_MALLOC_SDRAM_USAGE) @@ -60,7 +63,7 @@ def add_outgoing_sdram_partition(self, partition): @overrides(MachineVertex.sdram_required) - def sdram_required(self): + def sdram_required(self) -> ConstantSDRAM: if (len(self.__incoming_sdram_partitions) + len(self.__outgoing_sdram_partitions) == 0): raise ValueError("Isolated SDRAM vertex!") @@ -79,7 +82,7 @@ def sdram_required(self): outgoing_sdram_requirements) @overrides(AbstractSupportsSDRAMEdges.sdram_requirement) - def sdram_requirement(self, sdram_machine_edge): + def sdram_requirement(self, sdram_machine_edge: SDRAMMachineEdge) -> int: if self.__sdram_cost is None: raise NotImplementedError( "This vertex has no cost so is not expected to appear " @@ -87,16 +90,18 @@ def sdram_requirement(self, sdram_machine_edge): return self.__sdram_cost @overrides(AbstractHasAssociatedBinary.get_binary_file_name) - def get_binary_file_name(self): + def get_binary_file_name(self) -> str: return "sdram.aplx" @overrides(AbstractHasAssociatedBinary.get_binary_start_type) - def get_binary_start_type(self): + def get_binary_start_type(self) -> ExecutableType: return ExecutableType.USES_SIMULATION_INTERFACE @overrides(MachineDataSpecableVertex.generate_machine_data_specification) def generate_machine_data_specification( - self, spec, placement, iptags, reverse_iptags): + self, spec: DataSpecificationGenerator, placement: Placement, + iptags: Optional[Iterable[IPTag]], + reverse_iptags: Optional[Iterable[ReverseIPTag]]): # reserve memory regions spec.reserve_memory_region( region=DataRegions.SYSTEM, size=SIMULATION_N_BYTES, diff --git a/gfe_integration_tests/sdram_edge_tests/test_constant_internal/sdram_splitter_internal.py b/gfe_integration_tests/sdram_edge_tests/test_constant_internal/sdram_splitter_internal.py index a9482b88..4fac689a 100644 --- a/gfe_integration_tests/sdram_edge_tests/test_constant_internal/sdram_splitter_internal.py +++ b/gfe_integration_tests/sdram_edge_tests/test_constant_internal/sdram_splitter_internal.py @@ -11,6 +11,7 @@ # 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. +from typing import List from spinn_utilities.overrides import overrides from pacman.model.graphs.common import Slice from pacman.model.graphs.machine import SDRAMMachineEdge @@ -25,45 +26,48 @@ class SDRAMSplitterInternal(AbstractSplitterCommon): """ __slots__ = [ - "_partition_type", - "_pre_vertex", - "_pre_slice", - "_post_slice", - "_post_vertex", - "_app_edge", + "__pre_vertex", + "__post_vertex", "_sdram_part"] def __init__(self): super().__init__() - self._pre_vertex = None - self._post_vertex = None - self._pre_slice = None - self._post_slice = None - self._app_edge = None + self.__pre_vertex = None + self.__post_vertex = None self._sdram_part = None + @property + def _pre_vertex(self) -> SDRAMMachineVertex: + assert isinstance(self.__pre_vertex, SDRAMMachineVertex) + return self.__pre_vertex + + @property + def _post_vertex(self): + assert isinstance(self.__post_vertex, SDRAMMachineVertex) + return self.__post_vertex + @overrides(AbstractSplitterCommon.get_out_going_vertices) - def get_out_going_vertices(self, partition_id): + def get_out_going_vertices(self, partition_id: str) -> List[SDRAMMachineVertex]: return [self._pre_vertex] @overrides(AbstractSplitterCommon.get_in_coming_vertices) - def get_in_coming_vertices(self, partition_id): + def get_in_coming_vertices(self, partition_id: str) -> list[SDRAMMachineVertex]: return [self._post_vertex] def create_machine_vertices(self, chip_counter): # slices - self._pre_slice = Slice(0, int(self.governed_app_vertex.n_atoms / 2)) - self._post_slice = Slice( + pre_slice = Slice(0, int(self.governed_app_vertex.n_atoms / 2)) + post_slice = Slice( int(self.governed_app_vertex.n_atoms / 2) + 1, int(self.governed_app_vertex.n_atoms - 1)) # mac verts - self._pre_vertex = SDRAMMachineVertex( - vertex_slice=self._pre_slice, label=None, + self.__pre_vertex = SDRAMMachineVertex( + vertex_slice=pre_slice, label=None, app_vertex=self.governed_app_vertex, sdram_cost=20) self.governed_app_vertex.remember_machine_vertex(self._pre_vertex) - self._post_vertex = SDRAMMachineVertex( - vertex_slice=self._post_slice, label=None, + self.__post_vertex = SDRAMMachineVertex( + vertex_slice=post_slice, label=None, app_vertex=self.governed_app_vertex) self.governed_app_vertex.remember_machine_vertex(self._post_vertex) @@ -78,21 +82,24 @@ def create_machine_vertices(self, chip_counter): chip_counter.add_core(self._post_vertex.sdram_required) @overrides(AbstractSplitterCommon.get_out_going_slices) - def get_out_going_slices(self): + def get_out_going_slices(self) -> List[Slice]: return [self._post_vertex.vertex_slice] @overrides(AbstractSplitterCommon.get_in_coming_slices) - def get_in_coming_slices(self): + def get_in_coming_slices(self) -> List[Slice]: return [self._pre_vertex.vertex_slice] @overrides(AbstractSplitterCommon.machine_vertices_for_recording) - def machine_vertices_for_recording(self, variable_to_record): + def machine_vertices_for_recording( + self, variable_to_record: str) -> List[SDRAMMachineVertex]: return [self._pre_vertex, self._post_vertex] @overrides(AbstractSplitterCommon.reset_called) - def reset_called(self): + def reset_called(self) -> None: pass @overrides(AbstractSplitterCommon.get_internal_sdram_partitions) - def get_internal_sdram_partitions(self): + def get_internal_sdram_partitions( + self) -> List[ConstantSDRAMMachinePartition]: + assert isinstance(self._sdram_part, ConstantSDRAMMachinePartition) return [self._sdram_part] diff --git a/gfe_integration_tests/sdram_edge_tests/test_multi_dest_internal/sdram_splitter.py b/gfe_integration_tests/sdram_edge_tests/test_multi_dest_internal/sdram_splitter.py index a1f7c1c6..a866a3d8 100644 --- a/gfe_integration_tests/sdram_edge_tests/test_multi_dest_internal/sdram_splitter.py +++ b/gfe_integration_tests/sdram_edge_tests/test_multi_dest_internal/sdram_splitter.py @@ -11,6 +11,7 @@ # 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. +from typing import List from spinn_utilities.overrides import overrides from pacman.model.graphs.common import Slice from pacman.model.graphs.machine import ( @@ -26,44 +27,51 @@ class SDRAMSplitter(AbstractSplitterCommon): N_VERTS = 3 __slots__ = [ - "_pre_vertex", - "_pre_slice", - "_post_slices", + "__pre_vertex", "_post_vertices", "_partition"] def __init__(self): super().__init__() - self._pre_vertex = None - self._post_vertices = list() - self._pre_slice = None - self._post_slices = list() + self.__pre_vertex = None + self._post_vertices: list[SDRAMMachineVertex] = list() + + @property + def _pre_vertex(self) -> SDRAMMachineVertex: + assert isinstance(self.__pre_vertex, SDRAMMachineVertex) + return self.__pre_vertex + + @property + def __post_vertex(self): + assert isinstance(self.__post_vertex, SDRAMMachineVertex) + return self.__post_vertex @overrides(AbstractSplitterCommon.get_out_going_vertices) - def get_out_going_vertices(self, partition_id): + def get_out_going_vertices(self, partition_id: str) -> List[SDRAMMachineVertex]: return self._post_vertices @overrides(AbstractSplitterCommon.get_in_coming_vertices) - def get_in_coming_vertices(self, partition_id): + def get_in_coming_vertices(self, partition_id: str) -> SDRAMMachineVertex: return [self._pre_vertex] def create_machine_vertices(self, chip_counter): # slices - self._pre_slice = Slice( + pre_slice = Slice( 0, int(self.governed_app_vertex.n_atoms / self.N_VERTS)) + post_slices = list() for count in range(1, self.N_VERTS): - self._post_slices.append(Slice( - self._pre_slice.n_atoms * count, - self._pre_slice.n_atoms * count + self._pre_slice.n_atoms)) + post_slices.append(Slice( + pre_slice.n_atoms * count, + pre_slice.n_atoms * count + pre_slice.n_atoms)) # mac verts - self._pre_vertex = SDRAMMachineVertex( - vertex_slice=self._pre_slice, label=None, + self.__pre_vertex = SDRAMMachineVertex( + vertex_slice=pre_slice, label=None, app_vertex=self.governed_app_vertex, sdram_cost=20) self.governed_app_vertex.remember_machine_vertex(self._pre_vertex) - for vertex_slice in self._post_slices: + for vertex_slice in post_slices: post_vertex = SDRAMMachineVertex( vertex_slice=vertex_slice, label=None, app_vertex=self.governed_app_vertex) @@ -84,20 +92,25 @@ def create_machine_vertices(self, chip_counter): return 1 @overrides(AbstractSplitterCommon.get_out_going_slices) - def get_out_going_slices(self): + def get_out_going_slices(self) -> List[Slice]: return [v.vertex_slice for v in self._post_vertices] @overrides(AbstractSplitterCommon.get_in_coming_slices) - def get_in_coming_slices(self): + def get_in_coming_slices(self) -> List[Slice]: return [self._pre_vertex.vertex_slice] @overrides(AbstractSplitterCommon.machine_vertices_for_recording) - def machine_vertices_for_recording(self, variable_to_record): + def machine_vertices_for_recording( + self, variable_to_record: str) -> List[SDRAMMachineVertex]: return [self._pre_vertex].extend(self._post_vertices) @overrides(AbstractSplitterCommon.reset_called) - def reset_called(self): + def reset_called(self) -> None: pass - def get_internal_sdram_partitions(self): + @overrides(AbstractSplitterCommon.get_internal_sdram_partitions) + def get_internal_sdram_partitions( + self) -> List[DestinationSegmentedSDRAMMachinePartition]: + assert isinstance( + self._partition, DestinationSegmentedSDRAMMachinePartition) return [self._partition] diff --git a/gfe_integration_tests/sdram_edge_tests/test_multi_src_internal/sdram_splitter.py b/gfe_integration_tests/sdram_edge_tests/test_multi_src_internal/sdram_splitter.py index 8bbffb2b..85947749 100644 --- a/gfe_integration_tests/sdram_edge_tests/test_multi_src_internal/sdram_splitter.py +++ b/gfe_integration_tests/sdram_edge_tests/test_multi_src_internal/sdram_splitter.py @@ -11,6 +11,7 @@ # 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. +from typing import List from spinn_utilities.overrides import overrides from pacman.model.graphs.common import Slice from pacman.model.graphs.machine import SDRAMMachineEdge @@ -27,43 +28,47 @@ class SDRAMSplitter(AbstractSplitterCommon): __slots__ = [ "_pre_vertices", - "_pre_slices", - "_post_slice", - "_post_vertex", + "__post_vertex", "_partition"] def __init__(self): super().__init__() - self._pre_vertices = list() - self._post_vertex = None - self._pre_slices = list() - self._post_slice = None + self._pre_vertices: List[SourceSegmentedSDRAMMachinePartition] = list() + self.__post_vertex = None + + @property + def _post_vertex(self): + assert isinstance(self.__post_vertex, SDRAMMachineVertex) + return self.__post_vertex @overrides(AbstractSplitterCommon.get_out_going_vertices) - def get_out_going_vertices(self, partition_id): + def get_out_going_vertices( + self, partition_id: str) -> SourceSegmentedSDRAMMachinePartition: return [self._post_vertex] @overrides(AbstractSplitterCommon.get_in_coming_vertices) - def get_in_coming_vertices(self, partition_id): + def get_in_coming_vertices( + self, partition_id: str) -> List[SourceSegmentedSDRAMMachinePartition]: return self._pre_vertices def create_machine_vertices(self, chip_counter): # slices - self._post_slice = Slice( + post_slice = Slice( 0, int(self.governed_app_vertex.n_atoms / self.N_VERTS)) + pre_slices = list() for count in range(1, self.N_VERTS): - self._pre_slices.append(Slice( - self._post_slice.n_atoms * count, - self._post_slice.n_atoms * count + self._post_slice.n_atoms)) + pre_slices.append(Slice( + post_slice.n_atoms * count, + post_slice.n_atoms * count + post_slice.n_atoms)) # mac verts - self._post_vertex = SDRAMMachineVertex( - vertex_slice=self._post_slice, label=None, + self.__post_vertex = SDRAMMachineVertex( + vertex_slice=post_slice, label=None, app_vertex=self.governed_app_vertex) self.governed_app_vertex.remember_machine_vertex(self._post_vertex) - for vertex_slice in self._pre_slices: + for vertex_slice in pre_slices: pre_vertex = SDRAMMachineVertex( vertex_slice=vertex_slice, label=None, app_vertex=self.governed_app_vertex, sdram_cost=20) @@ -82,21 +87,25 @@ def create_machine_vertices(self, chip_counter): chip_counter.add_core(pre_vertex.sdram_required) @overrides(AbstractSplitterCommon.get_out_going_slices) - def get_out_going_slices(self): + def get_out_going_slices(self) -> Slice: return [self._post_vertex.vertex_slice] @overrides(AbstractSplitterCommon.get_in_coming_slices) - def get_in_coming_slices(self): + def get_in_coming_slices(self) -> List[Slice]: return [v.vertex_slice for v in self._pre_vertices] @overrides(AbstractSplitterCommon.machine_vertices_for_recording) - def machine_vertices_for_recording(self, variable_to_record): + def machine_vertices_for_recording( + self, variable_to_record: str) -> List[SourceSegmentedSDRAMMachinePartition]: return [self._post_vertex].extend(self._pre_vertices) @overrides(AbstractSplitterCommon.reset_called) - def reset_called(self): + def reset_called(self) -> None: pass @overrides(AbstractSplitterCommon.get_internal_sdram_partitions) - def get_internal_sdram_partitions(self): + def get_internal_sdram_partitions( + self) -> SourceSegmentedSDRAMMachinePartition: + assert isinstance( + self._partition, SourceSegmentedSDRAMMachinePartition) return [self._partition] diff --git a/gfe_integration_tests/test_extra_monitor/sdram_writer.py b/gfe_integration_tests/test_extra_monitor/sdram_writer.py index 9a01fbb9..43f10a67 100644 --- a/gfe_integration_tests/test_extra_monitor/sdram_writer.py +++ b/gfe_integration_tests/test_extra_monitor/sdram_writer.py @@ -13,14 +13,18 @@ # limitations under the License. from enum import IntEnum +from typing import Iterable, Optional from spinn_utilities.overrides import overrides +from spinn_machine.tags import IPTag, ReverseIPTag from spinnman.model.enums import ExecutableType from pacman.model.graphs.machine import MachineVertex +from pacman.model.placements import Placement from pacman.model.resources import ConstantSDRAM from spinn_front_end_common.abstract_models import ( AbstractHasAssociatedBinary) from spinn_front_end_common.abstract_models.impl import ( MachineDataSpecableVertex) +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinn_front_end_common.interface.simulation import simulation_utilities from spinn_front_end_common.utilities.constants import ( SIMULATION_N_BYTES, SYSTEM_BYTES_REQUIREMENT, BYTES_PER_KB) @@ -55,7 +59,9 @@ def get_binary_start_type(self): @overrides(MachineDataSpecableVertex.generate_machine_data_specification) def generate_machine_data_specification( - self, spec, placement, iptags, reverse_iptags): + self, spec: DataSpecificationGenerator, placement: Placement, + iptags: Optional[Iterable[IPTag]], + reverse_iptags: Optional[Iterable[ReverseIPTag]]): # Reserve SDRAM space for memory areas: self._reserve_memory_regions(spec) diff --git a/gfe_integration_tests/test_profile/profiled_vertex.py b/gfe_integration_tests/test_profile/profiled_vertex.py index a71e4f64..abf4668e 100644 --- a/gfe_integration_tests/test_profile/profiled_vertex.py +++ b/gfe_integration_tests/test_profile/profiled_vertex.py @@ -13,15 +13,20 @@ # limitations under the License. from enum import IntEnum +from typing import Iterable, Optional import logging from spinn_utilities.log import FormatAdapter from spinn_utilities.overrides import overrides +from spinn_machine.tags import IPTag, ReverseIPTag from pacman.model.graphs.machine import MachineVertex +from pacman.model.placements import Placement from pacman.model.resources import ConstantSDRAM from spinn_front_end_common.utilities.constants import SYSTEM_BYTES_REQUIREMENT from spinn_front_end_common.abstract_models.impl import ( MachineDataSpecableVertex) -from spinn_front_end_common.interface.profiling import AbstractHasProfileData +from spinn_front_end_common.interface.ds import DataSpecificationGenerator +from spinn_front_end_common.interface.profiling import ( + AbstractHasProfileData, ProfileData) from spinn_front_end_common.interface.profiling.profile_utils import ( get_profile_region_size, reserve_profile_region, write_profile_region_data, get_profiling_data) @@ -52,14 +57,16 @@ def __init__(self, label=None): @property @overrides(MachineVertex.sdram_required) - def sdram_required(self): + def sdram_required(self) -> ConstantSDRAM: return ConstantSDRAM( SYSTEM_BYTES_REQUIREMENT + get_profile_region_size(N_SAMPLES)) @overrides(MachineDataSpecableVertex.generate_machine_data_specification) def generate_machine_data_specification( - self, spec, placement, iptags, reverse_iptags): + self, spec: DataSpecificationGenerator, placement: Placement, + iptags: Optional[Iterable[IPTag]], + reverse_iptags: Optional[Iterable[ReverseIPTag]]): # Generate the system data region for simulation .c requirements self.generate_system_region(spec) @@ -71,6 +78,6 @@ def generate_machine_data_specification( spec.end_specification() @overrides(AbstractHasProfileData.get_profile_data) - def get_profile_data(self, placement): + def get_profile_data(self, placement: Placement) -> ProfileData: return get_profiling_data( DataRegions.PROFILE.value, PROFILE_TAGS, placement) diff --git a/spinnaker_graph_front_end/__init__.py b/spinnaker_graph_front_end/__init__.py index eb3362bf..9542e3ca 100644 --- a/spinnaker_graph_front_end/__init__.py +++ b/spinnaker_graph_front_end/__init__.py @@ -113,6 +113,7 @@ def setup(model_binary_module=None, :raise ~spinn_front_end_common.utilities.exceptions.ConfigurationException: if mutually exclusive options are given. """ + # pylint: disable=global-statement global __simulator # pylint: disable=redefined-outer-name logger.info( @@ -223,6 +224,7 @@ def add_machine_vertex_instance(machine_vertex): app_vertex = AbstractOneAppOneMachineVertex( machine_vertex, machine_vertex.label) FecDataView.add_vertex(app_vertex) + # pylint: disable=protected-access machine_vertex._app_vertex = app_vertex diff --git a/spinnaker_graph_front_end/py.typed b/spinnaker_graph_front_end/py.typed new file mode 100644 index 00000000..91eaa0c5 --- /dev/null +++ b/spinnaker_graph_front_end/py.typed @@ -0,0 +1,13 @@ +# 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. diff --git a/spinnaker_graph_front_end/utilities/data_utils.py b/spinnaker_graph_front_end/utilities/data_utils.py index c064e514..e6b73f30 100644 --- a/spinnaker_graph_front_end/utilities/data_utils.py +++ b/spinnaker_graph_front_end/utilities/data_utils.py @@ -12,12 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. +from typing import TYPE_CHECKING from spinn_front_end_common.utilities.constants import SIMULATION_N_BYTES +from spinn_front_end_common.interface.ds import DataSpecificationGenerator from spinn_front_end_common.interface.simulation.simulation_utilities import ( get_simulation_header_array, get_simulation_header_array_no_timestep) +if TYPE_CHECKING: + from .simulator_vertex import SimulatorVertex -def generate_system_data_region(spec, region_id, machine_vertex): +def generate_system_data_region( + spec: DataSpecificationGenerator, region_id: int, + machine_vertex: 'SimulatorVertex'): """ Generate a system data region for time-based simulations. @@ -38,7 +44,9 @@ def generate_system_data_region(spec, region_id, machine_vertex): machine_vertex.get_binary_file_name())) -def generate_steps_system_data_region(spec, region_id, machine_vertex): +def generate_steps_system_data_region( + spec: DataSpecificationGenerator, region_id: int, + machine_vertex: 'SimulatorVertex'): """ Generate a system data region for step-based simulations. diff --git a/spinnaker_graph_front_end/utilities/simulator_vertex.py b/spinnaker_graph_front_end/utilities/simulator_vertex.py index 1454a4e6..1cc510e7 100644 --- a/spinnaker_graph_front_end/utilities/simulator_vertex.py +++ b/spinnaker_graph_front_end/utilities/simulator_vertex.py @@ -36,7 +36,7 @@ class SimulatorVertex(MachineVertex, AbstractHasAssociatedBinary): __slots__ = ["_binary_name", "__front_end"] - def __init__(self, label, binary_name, vertex_slice=None): + def __init__(self, label, binary_name: str, vertex_slice=None): """ :param str label: The label for the vertex. @@ -56,11 +56,11 @@ def __init__(self, label, binary_name, vertex_slice=None): self.__front_end = sys.modules["spinnaker_graph_front_end"] @overrides(AbstractHasAssociatedBinary.get_binary_file_name) - def get_binary_file_name(self): + def get_binary_file_name(self) -> str: return self._binary_name @overrides(AbstractHasAssociatedBinary.get_binary_start_type) - def get_binary_start_type(self): + def get_binary_start_type(self) -> ExecutableType: return ExecutableType.USES_SIMULATION_INTERFACE @property