Skip to content

Commit

Permalink
Merge pull request #273 from SpiNNakerManchester/t_machine
Browse files Browse the repository at this point in the history
Typing of all SpinnMachine methods
  • Loading branch information
Christian-B authored Nov 13, 2024
2 parents a184515 + c71e6c9 commit 0460454
Show file tree
Hide file tree
Showing 29 changed files with 126 additions and 109 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/python_actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ jobs:
coverage-package: spinn_machine
flake8-packages: spinn_machine unittests
pylint-packages: spinn_machine
mypy-packages: spinn_machine unittests
mypy-packages: unittests
mypy-full_packages: spinn_machine
secrets: inherit
2 changes: 1 addition & 1 deletion mypy.bash
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@

utils="../SpiNNUtils/spinn_utilities"

mypy --python-version 3.8 $utils spinn_machine
mypy --python-version 3.8 $utils spinn_machine unittests
24 changes: 24 additions & 0 deletions mypyd.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

# Copyright (c) 2024 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.

# This bash assumes that other repositories are installed in paralled

# requires the latest mypy
# pip install --upgrade mypy

utils="../SpiNNUtils/spinn_utilities"

mypy --python-version 3.8 --disallow-untyped-defs $utils spinn_machine
4 changes: 3 additions & 1 deletion spinn_machine/chip.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# limitations under the License.
from typing import (Iterable, Iterator, Optional, Tuple)

from typing_extensions import Self

from spinn_utilities.ordered_set import OrderedSet
from spinn_utilities.typing.coords import XY

Expand All @@ -33,7 +35,7 @@ def __new__(cls, x: int, y: int, scamp_processors: Iterable[int],
sdram: int, nearest_ethernet_x: int, nearest_ethernet_y: int,
ip_address: Optional[str] = None,
tag_ids: Optional[Iterable[int]] = None,
parent_link: Optional[int] = None):
parent_link: Optional[int] = None) -> Self:
return tuple.__new__(cls, (x, y))

# pylint: disable=too-many-arguments, wrong-spelling-in-docstring
Expand Down
2 changes: 1 addition & 1 deletion spinn_machine/core_subset.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __init__(self, x: int, y: int, processor_ids: Iterable[int]):
for processor_id in processor_ids:
self.add_processor(processor_id)

def add_processor(self, processor_id: int):
def add_processor(self, processor_id: int) -> None:
"""
Adds a processor ID to this subset
Expand Down
6 changes: 3 additions & 3 deletions spinn_machine/core_subsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(self, core_subsets: Iterable[CoreSubset] = ()):
for core_subset in core_subsets:
self.add_core_subset(core_subset)

def add_core_subset(self, core_subset: CoreSubset):
def add_core_subset(self, core_subset: CoreSubset) -> None:
"""
Add a core subset to the set
Expand All @@ -44,7 +44,7 @@ def add_core_subset(self, core_subset: CoreSubset):
for processor_id in core_subset.processor_ids:
self.add_processor(x, y, processor_id)

def add_core_subsets(self, core_subsets: Iterable[CoreSubset]):
def add_core_subsets(self, core_subsets: Iterable[CoreSubset]) -> None:
"""
Merges a core subsets into this one.
Expand All @@ -53,7 +53,7 @@ def add_core_subsets(self, core_subsets: Iterable[CoreSubset]):
for core_subset in core_subsets:
self.add_core_subset(core_subset)

def add_processor(self, x: int, y: int, processor_id: int):
def add_processor(self, x: int, y: int, processor_id: int) -> None:
"""
Add a processor on a given chip to the set.
Expand Down
2 changes: 1 addition & 1 deletion spinn_machine/data/machine_data_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def get_machine_version(cls) -> AbstractVersion:
return cls.__data._machine_version

@classmethod
def set_v_to_p_map(cls, v_to_p_map: Dict[XY, bytes]):
def set_v_to_p_map(cls, v_to_p_map: Dict[XY, bytes]) -> None:
"""
Registers the mapping from Virtual to int physical core ids
Expand Down
9 changes: 5 additions & 4 deletions spinn_machine/data/machine_data_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def get_user_accessed_machine(self) -> bool:
"""
return self.__data._user_accessed_machine

def set_machine(self, machine: Machine):
def set_machine(self, machine: Machine) -> None:
"""
Sets the machine.
Expand All @@ -94,19 +94,20 @@ def clear_machine(self) -> None:
"""
self.__data._machine = None

def set_machine_generator(self, machine_generator: Callable[[], None]):
def set_machine_generator(
self, machine_generator: Callable[[], None]) -> None:
"""
Registers a function that can be called to give a machine. Note that
if the function does not actually register a machine when called, an
exception will be thrown.
:param function machine_generator:
:param machine_generator:
"""
if not callable(machine_generator):
raise TypeError("machine_generator must be callable")
self.__data._machine_generator = machine_generator

def add_monitor_core(self, all_chips: bool):
def add_monitor_core(self, all_chips: bool) -> None:
"""
Accepts a simple of the monitor cores to be added.
Expand Down
20 changes: 11 additions & 9 deletions spinn_machine/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Any


class SpinnMachineException(Exception):
"""
Expand All @@ -27,10 +29,10 @@ class SpinnMachineAlreadyExistsException(SpinnMachineException):
"_item",
"_value"]

def __init__(self, item: str, value):
def __init__(self, item: str, value: Any) -> None:
"""
:param str item: The item of which there is already one of
:param str value: The value of the item
:param item: The item of which there is already one of
:param value: The value of the item
"""
super().__init__(
f"There can only be one {item} with a value of {value}")
Expand All @@ -45,7 +47,7 @@ def item(self) -> str:
return self._item

@property
def value(self):
def value(self) -> Any:
"""
The value of the item.
"""
Expand All @@ -61,12 +63,12 @@ class SpinnMachineInvalidParameterException(SpinnMachineException):
"_problem",
"_value"]

def __init__(self, parameter: str, value, problem: str):
def __init__(self, parameter: str, value: Any, problem: str) -> None:
"""
:param str parameter:
:param parameter:
The name of the parameter that has an invalid value
:param str value: The value of the parameter that is invalid
:param str problem: The reason for the exception
:param value: The value of the parameter that is invalid
:param problem: The reason for the exception
"""
super().__init__(
f"It is invalid to set {parameter} to {value}: {problem}")
Expand All @@ -82,7 +84,7 @@ def parameter(self) -> str:
return self._parameter

@property
def value(self):
def value(self) -> Any:
"""
The value of the parameter.
"""
Expand Down
6 changes: 3 additions & 3 deletions spinn_machine/frozen_core_subsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ def __init__(self, core_subsets: Iterable[CoreSubset] = ()):
super().add_processor(x, y, processor_id)

@overrides(CoreSubsets.add_core_subset)
def add_core_subset(self, core_subset: CoreSubset):
def add_core_subset(self, core_subset: CoreSubset) -> None:
raise RuntimeError("This object is immutable")

@overrides(CoreSubsets.add_core_subsets)
def add_core_subsets(self, core_subsets: Iterable[CoreSubset]):
def add_core_subsets(self, core_subsets: Iterable[CoreSubset]) -> None:
raise RuntimeError("This object is immutable")

@overrides(CoreSubsets.add_processor)
def add_processor(self, x: int, y: int, processor_id: int):
def add_processor(self, x: int, y: int, processor_id: int) -> None:
raise RuntimeError("This object is immutable")
2 changes: 1 addition & 1 deletion spinn_machine/json_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def _int_value(value: int) -> int:


# pylint: disable=wrong-spelling-in-docstring
def _describe_chip(chip: Chip, standard, ethernet) -> JsonArray:
def _describe_chip(chip: Chip, standard: _Desc, ethernet: _Desc) -> JsonArray:
"""
Produce a JSON-suitable description of a single chip.
Expand Down
2 changes: 1 addition & 1 deletion spinn_machine/link_data_objects/spinnaker_link_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def __hash__(self) -> int:
self.connected_chip_x, self.connected_chip_y,
self.connected_link, self.board_address))

def __str__(self):
def __str__(self) -> str:
return (f"id:{self._spinnaker_link_id} x:{self.connected_chip_x} "
f"y:{self.connected_chip_y} link:{self._spinnaker_link_id} "
f"{self.board_address}")
Expand Down
10 changes: 5 additions & 5 deletions spinn_machine/machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ def wrap(self) -> str:
"""
raise NotImplementedError

def add_chip(self, chip: Chip):
def add_chip(self, chip: Chip) -> None:
"""
Add a chip to the machine.
Expand All @@ -569,7 +569,7 @@ def add_chip(self, chip: Chip):
if (chip == (0, 0)):
self._boot_ethernet_address = chip.ip_address

def add_chips(self, chips: Iterable[Chip]):
def add_chips(self, chips: Iterable[Chip]) -> None:
"""
Add some chips to the machine.
Expand Down Expand Up @@ -668,7 +668,7 @@ def is_link_at(self, x: int, y: int, link: int) -> bool:
"""
return (x, y) in self._chips and self._chips[x, y].router.is_link(link)

def __contains__(self, x_y_tuple: XY):
def __contains__(self, x_y_tuple: XY) -> bool:
"""
Determine if a chip exists at the given coordinates.
Expand Down Expand Up @@ -862,7 +862,7 @@ def add_spinnaker_links(self) -> None:

def _add_spinnaker_link(
self, spinnaker_link_id: int, x: int, y: int, link: int,
board_address: str):
board_address: str) -> None:
link_data = SpinnakerLinkData(
spinnaker_link_id, x, y, link, board_address)
self._spinnaker_links[board_address, spinnaker_link_id] = link_data
Expand All @@ -888,7 +888,7 @@ def add_fpga_links(self) -> None:

def _add_fpga_link(
self, fpga_id: int, fpga_link: int, x: int, y: int, link: int,
board_address: str, ex: int, ey: int):
board_address: str, ex: int, ey: int) -> None:
# pylint: disable=too-many-arguments
link_data = FPGALinkData(
fpga_link_id=fpga_link, fpga_id=fpga_id,
Expand Down
6 changes: 2 additions & 4 deletions spinn_machine/machine_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,24 +121,22 @@ def _generate_uni_direction_link_error(
f"Please report this to [email protected] \n\n"


def machine_repair(original: Machine, removed_chips: Iterable[XY] = ()):
def machine_repair(
original: Machine, removed_chips: Iterable[XY] = ()) -> Machine:
"""
Remove chips that can't be reached or that can't reach other chips
due to missing links.
Also remove any one way links.
:param original: the original machine
:type original: Machine
:param removed_chips: List of chips (x and y coordinates) that have been
removed while the machine was being created.
One-way links to these chip are expected repairs so always done and
never logged
:type removed_chips: list(tuple(int,int))
:raises SpinnMachineException: if repair_machine is false and an unexpected
repair is needed.
:return: Either the original machine or a repaired replacement
:rtype: Machine
"""
repair_machine = get_config_bool("Machine", "repair_machine")
dead_chips: Set[XY] = set()
Expand Down
2 changes: 1 addition & 1 deletion spinn_machine/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def __init__(

self._n_available_multicast_entries = n_available_multicast_entries

def add_link(self, link: Link):
def add_link(self, link: Link) -> None:
"""
Add a link to the router of the chip.
Expand Down
4 changes: 2 additions & 2 deletions spinn_machine/spinnaker_triad_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def __init__(
for y, row in enumerate(nearest_ethernets)]

@staticmethod
def __hexagonal_metric_distance(xy: XY, centre: _Centre):
def __hexagonal_metric_distance(xy: XY, centre: _Centre) -> float:
"""
Get the hexagonal metric distance of a point from the centre of
the hexagon.
Expand Down Expand Up @@ -138,7 +138,7 @@ def __hexagonal_metric_distance(xy: XY, centre: _Centre):
return max(abs(dx), abs(dy), abs(dx - dy))

def __locate_nearest_ethernet(
self, xy: XY, ethernet_chips: Sequence[XY], centre: _Centre):
self, xy: XY, ethernet_chips: Sequence[XY], centre: _Centre) -> XY:
"""
Get the coordinate of the nearest Ethernet chip down and left from
a given chip.
Expand Down
17 changes: 4 additions & 13 deletions spinn_machine/tags/abstract_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,28 @@ class AbstractTag(object):
"_port"
]

def __init__(self, board_address, tag, port):
def __init__(self, board_address: str, tag: int, port: int):
self._board_address = board_address
self._tag = tag
self._port = port

@property
def board_address(self):
def board_address(self) -> str:
"""
The board address of the tag.
"""
return self._board_address

@property
def tag(self):
def tag(self) -> int:
"""
The tag ID of the tag.
"""
return self._tag

@property
def port(self):
def port(self) -> int:
"""
The port of the tag.
"""
return self._port

@port.setter
def port(self, port):
"""
Set the port; will fail if the port is already set.
"""
if self._port is not None:
raise RuntimeError("Port cannot be set more than once")
self._port = port
Loading

0 comments on commit 0460454

Please sign in to comment.