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 and minor Changes #225

Merged
merged 36 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
adf14ee
More types
dkfellows Jun 23, 2023
4d69435
Types for more classes
dkfellows Jun 27, 2023
ad077c6
Need to publicly support len(eth_chips)
dkfellows Jun 27, 2023
8947c6b
De-circulate
dkfellows Jun 28, 2023
21aa279
Fix tests
dkfellows Jul 3, 2023
3a194d0
Mark as typed, remove abstractproperty
dkfellows Jul 4, 2023
09cc3b9
get_spinnaker_link_with_id never returns None
dkfellows Jul 4, 2023
33e30a8
Tidier way of writing MulticastRoutingEntry
dkfellows Jul 4, 2023
37893e6
Enable mypy
dkfellows Jul 7, 2023
7119cef
Merge branch 'master' into reduce-op-complexity
dkfellows Jul 7, 2023
f073534
Fix trivial failure
dkfellows Jul 7, 2023
0fa4f4c
Cut-n-paste error
dkfellows Jul 7, 2023
e5def17
mypy for Python 3.10 requires NotImplementedError in abstractmethods
dkfellows Jul 7, 2023
7673564
Flag as typed to downstream
dkfellows Jul 7, 2023
477657b
setUp is not a class method
dkfellows Jul 10, 2023
d362d8a
Types for json_machine.py
dkfellows Jul 10, 2023
1d91bcc
Forgot to handle filename case
dkfellows Jul 10, 2023
653286f
Merge branch 'master' into reduce-op-complexity
dkfellows Aug 4, 2023
e7acec1
Fix a few of my bloopers
dkfellows Aug 4, 2023
35c9225
Bleah
dkfellows Aug 4, 2023
ed7e20c
Pylint has its own fussiness too
dkfellows Aug 4, 2023
97d1520
Coverage exclusion updates from utils
dkfellows Aug 4, 2023
f59f9ab
whitespace tweak
dkfellows Aug 4, 2023
faac0c0
merged in master
Christian-B Aug 22, 2023
a830da7
add an immutable Core Subsets object
Christian-B Aug 30, 2023
2a7d97e
flake8
Christian-B Aug 30, 2023
7b0ab3c
super init can not be called as it calls add methods
Christian-B Aug 30, 2023
c1b9a39
merged in master
Christian-B Sep 11, 2023
9f6c338
merged in master
Christian-B Sep 11, 2023
36067af
Merge branch 'reduce-op-complexity' into roc3
Christian-B Sep 11, 2023
bac1b3c
merge
Christian-B Sep 11, 2023
62583a7
fix after merge
Christian-B Sep 11, 2023
8365c62
flake8
Christian-B Sep 11, 2023
2777f92
Merge branch 'reduce-op-complexity' into roc3
Christian-B Sep 12, 2023
fc783c7
merged in master
Christian-B Oct 2, 2023
df0f3de
merge
Christian-B Oct 17, 2023
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
9 changes: 9 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,12 @@

[run]
branch = True

[report]
# Coverage should ignore overloads; they're not real code
exclude_lines =
@overload
\.\.\.$
raise\s+NotImplementedError
if\s+TYPE_CHECKING:
#\s*(pragma|PRAGMA)[:\s]?\s*(no|NO)\s*(cover|COVER)
4 changes: 4 additions & 0 deletions .github/workflows/python_actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ jobs:

- 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:
Expand All @@ -65,6 +67,8 @@ jobs:
with:
package: spinn_machine
language: en_GB
- name: Lint with mypy
run: mypy spinn_machine

validate:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ include =
[options.package_data]
* =
spinn_machine.cfg
py.typed

[options.extras_require]
test =
Expand Down
3 changes: 2 additions & 1 deletion spinn_machine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
from .chip import Chip
from .core_subset import CoreSubset
from .core_subsets import CoreSubsets
from .frozen_core_subsets import FrozenCoreSubsets
from .link import Link
from .machine import Machine
from .multicast_routing_entry import MulticastRoutingEntry
Expand All @@ -90,6 +91,6 @@


__all__ = ["Chip", "CoreSubset", "CoreSubsets", "FixedRouteEntry",
"Link", "Machine", "MulticastRoutingEntry",
"FrozenCoreSubsets", "Link", "Machine", "MulticastRoutingEntry",
"Processor", "Router", "SpiNNakerTriadGeometry",
"virtual_machine"]
81 changes: 43 additions & 38 deletions spinn_machine/chip.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
# 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 (
Any, Collection, Dict, Iterable, Iterator, Optional, Tuple)
from spinn_utilities.ordered_set import OrderedSet
from spinn_machine.data import MachineDataView
from .processor import Processor
from .router import Router

standard_processors = {}

Expand All @@ -40,10 +42,13 @@ class Chip(object):
)

# pylint: disable=too-many-arguments, wrong-spelling-in-docstring
def __init__(self, x, y, n_processors, router, sdram, nearest_ethernet_x,
nearest_ethernet_y, ip_address=None,
tag_ids=None, down_cores=None, parent_link=None,
v_to_p_map=None):
def __init__(self, x: int, y: int, n_processors: int, router: Router,
sdram: int, nearest_ethernet_x: int, nearest_ethernet_y: int,
ip_address: Optional[str] = None,
tag_ids: Optional[Iterable[int]] = None,
down_cores: Optional[Collection[int]] = None,
parent_link: Optional[int] = None,
v_to_p_map: Optional[bytes] = None):
"""
:param int x: the x-coordinate of the chip's position in the
two-dimensional grid of chips
Expand All @@ -52,7 +57,7 @@ def __init__(self, x, y, n_processors, router, sdram, nearest_ethernet_x,
:param int n_processors:
the number of processors including monitor processors.
:param ~spinn_machine.Router router: a router for the chip
:param ~spinn_machine.SDRAM sdram: an SDRAM for the chip
:param int sdram: an SDRAM for the chip
:param ip_address:
the IP address of the chip, or ``None`` if no Ethernet attached
:type ip_address: str or None
Expand Down Expand Up @@ -83,17 +88,19 @@ def __init__(self, x, y, n_processors, router, sdram, nearest_ethernet_x,
self._sdram = sdram
self._ip_address = ip_address
if tag_ids is not None:
self._tag_ids = tag_ids
self._tag_ids = OrderedSet(tag_ids)
elif self._ip_address is None:
self._tag_ids = []
self._tag_ids = OrderedSet()
else:
self._tag_ids = self._IPTAG_IDS
self._nearest_ethernet_x = nearest_ethernet_x
self._nearest_ethernet_y = nearest_ethernet_y
self._parent_link = parent_link
self._v_to_p_map = v_to_p_map

def __generate_processors(self, n_processors, down_cores):
def __generate_processors(
self, n_processors: int,
down_cores: Optional[Collection[int]]) -> Dict[int, Processor]:
if down_cores is None:
if n_processors not in standard_processors:
processors = dict()
Expand All @@ -117,7 +124,7 @@ def __generate_processors(self, n_processors, down_cores):
MachineDataView.get_machine_version().n_non_user_cores)
return processors

def is_processor_with_id(self, processor_id):
def is_processor_with_id(self, processor_id: int) -> bool:
"""
Determines if a processor with the given ID exists in the chip.
Also implemented as ``__contains__(processor_id)``
Expand All @@ -128,7 +135,7 @@ def is_processor_with_id(self, processor_id):
"""
return processor_id in self._p

def get_processor_with_id(self, processor_id):
def get_processor_with_id(self, processor_id: int) -> Optional[Processor]:
"""
Return the processor with the specified ID, or ``None`` if the
processor does not exist.
Expand All @@ -139,12 +146,10 @@ def get_processor_with_id(self, processor_id):
or ``None`` if no such processor
:rtype: Processor or None
"""
if processor_id in self._p:
return self._p[processor_id]
return None
return self._p.get(processor_id)

@property
def x(self):
def x(self) -> int:
"""
The X-coordinate of the chip in the two-dimensional grid of chips.

Expand All @@ -153,7 +158,7 @@ def x(self):
return self._x

@property
def y(self):
def y(self) -> int:
"""
The Y-coordinate of the chip in the two-dimensional grid of chips.

Expand All @@ -162,7 +167,7 @@ def y(self):
return self._y

@property
def processors(self):
def processors(self) -> Iterator[Processor]:
"""
An iterable of available processors.

Expand All @@ -171,7 +176,7 @@ def processors(self):
return iter(self._p.values())

@property
def n_processors(self):
def n_processors(self) -> int:
"""
The total number of processors.

Expand All @@ -180,7 +185,7 @@ def n_processors(self):
return len(self._p)

@property
def n_user_processors(self):
def n_user_processors(self) -> int:
"""
The total number of processors that are not monitors.

Expand All @@ -189,7 +194,7 @@ def n_user_processors(self):
return self._n_user_processors

@property
def router(self):
def router(self) -> Router:
"""
The router object associated with the chip.

Expand All @@ -198,16 +203,16 @@ def router(self):
return self._router

@property
def sdram(self):
def sdram(self) -> int:
"""
The SDRAM associated with the chip.

:rtype: SDRAM
:rtype: int
"""
return self._sdram

@property
def ip_address(self):
def ip_address(self) -> Optional[str]:
"""
The IP address of the chip, or ``None`` if there is no Ethernet
connected to the chip.
Expand All @@ -217,7 +222,7 @@ def ip_address(self):
return self._ip_address

@property
def nearest_ethernet_x(self):
def nearest_ethernet_x(self) -> int:
"""
The X-coordinate of the nearest Ethernet chip.

Expand All @@ -226,7 +231,7 @@ def nearest_ethernet_x(self):
return self._nearest_ethernet_x

@property
def nearest_ethernet_y(self):
def nearest_ethernet_y(self) -> int:
"""
The Y-coordinate of the nearest Ethernet chip.

Expand All @@ -235,15 +240,15 @@ def nearest_ethernet_y(self):
return self._nearest_ethernet_y

@property
def tag_ids(self):
def tag_ids(self) -> Iterable[int]:
"""
The tag IDs supported by this chip.

:rtype: iterable(int)
"""
return self._tag_ids

def get_first_none_monitor_processor(self):
def get_first_none_monitor_processor(self) -> Optional[Processor]:
"""
Get the first processor in the list which is not a monitor core.

Expand All @@ -255,7 +260,7 @@ def get_first_none_monitor_processor(self):
return None

@property
def parent_link(self):
def parent_link(self) -> Optional[int]:
"""
The link down which the parent is found in the tree of chips rooted
at the machine root chip (probably 0, 0 in most cases). This will
Expand All @@ -265,7 +270,7 @@ def parent_link(self):
"""
return self._parent_link

def get_physical_core_id(self, virtual_p):
def get_physical_core_id(self, virtual_p: int) -> Optional[int]:
"""
Get the physical core ID from a virtual core ID.

Expand All @@ -277,7 +282,7 @@ def get_physical_core_id(self, virtual_p):
return None
return self._v_to_p_map[virtual_p]

def get_physical_core_string(self, virtual_p):
def get_physical_core_string(self, virtual_p: int) -> str:
"""
Get a string that can be appended to a core to show the physical
core, or an empty string if not possible.
Expand All @@ -290,7 +295,7 @@ def get_physical_core_string(self, virtual_p):
return ""
return f" (ph: {physical_p})"

def __iter__(self):
def __iter__(self) -> Iterator[Tuple[int, Processor]]:
"""
Get an iterable of processor identifiers and processors

Expand All @@ -301,7 +306,7 @@ def __iter__(self):
"""
return iter(self._p.items())

def __len__(self):
def __len__(self) -> int:
"""
The number of processors associated with this chip.

Expand All @@ -310,17 +315,17 @@ def __len__(self):
"""
return len(self._p)

def __getitem__(self, processor_id):
def __getitem__(self, processor_id: int) -> Processor:
if processor_id in self._p:
return self._p[processor_id]
# Note difference from get_processor_with_id(); this is to conform to
# standard Python semantics
raise KeyError(processor_id)

def __contains__(self, processor_id):
def __contains__(self, processor_id: int) -> bool:
return self.is_processor_with_id(processor_id)

def __str__(self):
def __str__(self) -> str:
return (
f"[Chip: x={self._x}, y={self._y}, "
f"sdram={self.sdram // (1024 * 1024)} MB, "
Expand All @@ -329,14 +334,14 @@ def __str__(self):
f"nearest_ethernet={self._nearest_ethernet_x}:"
f"{self._nearest_ethernet_y}]")

def __repr__(self):
def __repr__(self) -> str:
return self.__str__()

def __eq__(self, other):
def __eq__(self, other: Any) -> bool:
# Equality just on X,Y; that's most useful
if not isinstance(other, Chip):
return NotImplemented
return self._x == other.x and self._y == other.y

def __hash__(self):
def __hash__(self) -> int:
return self._x * 256 + self._y
4 changes: 2 additions & 2 deletions spinn_machine/config_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
BASE_CONFIG_FILE = "spinn_machine.cfg"


def unittest_setup():
def unittest_setup() -> None:
"""
Resets the configurations so only the local default configuration is
included.
Expand All @@ -34,7 +34,7 @@ def unittest_setup():
MachineDataWriter.mock()


def add_spinn_machine_cfg():
def add_spinn_machine_cfg() -> None:
"""
Add the local configuration and all dependent configuration files.
"""
Expand Down
Loading