Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typing of all SpinnMachine methods #273

Merged
merged 11 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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