From e1aa19e10ede03e66ea15908c108a51c42ad439b Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 5 Mar 2024 15:56:28 +0000 Subject: [PATCH 01/31] make chip a tuple --- spinn_machine/chip.py | 67 ++++++++++----------------------------- spinn_machine/machine.py | 5 ++- unittests/test_chip.py | 24 -------------- unittests/test_machine.py | 12 ------- 4 files changed, 18 insertions(+), 90 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 4d0dd6eb..d0030dad 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -12,8 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import ( - Any, Collection, Dict, Iterable, Iterator, Optional, Tuple) + Collection, Dict, Iterable, Iterator, Optional) from spinn_utilities.ordered_set import OrderedSet +from spinn_utilities.typing.coords import XY + from spinn_machine.data import MachineDataView from .processor import Processor from .router import Router @@ -21,7 +23,7 @@ standard_processors = {} -class Chip(object): +class Chip(tuple, XY): """ Represents a SpiNNaker chip with a number of cores, an amount of SDRAM shared between the cores, and a router. @@ -35,11 +37,14 @@ class Chip(object): # tag 0 is reserved for stuff like IO STD _IPTAG_IDS = OrderedSet(range(1, 8)) - __slots__ = ( - "_x", "_y", "_p", "_router", "_sdram", "_ip_address", - "_tag_ids", "_nearest_ethernet_x", "_nearest_ethernet_y", - "_n_user_processors", "_parent_link", "_v_to_p_map" - ) + def __new__(cls, 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): + return tuple.__new__(cls, (x, y)) # pylint: disable=too-many-arguments, wrong-spelling-in-docstring def __init__(self, x: int, y: int, n_processors: int, router: Router, @@ -81,8 +86,7 @@ def __init__(self, x: int, y: int, n_processors: int, router: Router, If processors contains any two processors with the same ``processor_id`` """ - self._x = x - self._y = y + # X and Y set by new self._p = self.__generate_processors(n_processors, down_cores) self._router = router self._sdram = sdram @@ -155,7 +159,7 @@ def x(self) -> int: :rtype: int """ - return self._x + return self[0] @property def y(self) -> int: @@ -164,7 +168,7 @@ def y(self) -> int: :rtype: int """ - return self._y + return self[1] @property def processors(self) -> Iterator[Processor]: @@ -295,54 +299,15 @@ def get_physical_core_string(self, virtual_p: int) -> str: return "" return f" (ph: {physical_p})" - def __iter__(self) -> Iterator[Tuple[int, Processor]]: - """ - Get an iterable of processor identifiers and processors - - :return: An iterable of ``(processor_id, processor)`` where: - * ``processor_id`` is the ID of a processor - * ``processor`` is the processor with the ID - :rtype: iterable(tuple(int,Processor)) - """ - return iter(self._p.items()) - - def __len__(self) -> int: - """ - The number of processors associated with this chip. - - :return: The number of items in the underlying iterator. - :rtype: int - """ - return len(self._p) - - 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: int) -> bool: - return self.is_processor_with_id(processor_id) - def __str__(self) -> str: if self._ip_address: ip_info = f"ip_address={self.ip_address} " else: ip_info = "" return ( - f"[Chip: x={self._x}, y={self._y}, {ip_info}" + f"[Chip: x={self[0]}, y={self[1]}, {ip_info}" f"n_cores={self.n_processors}, " f"mon={self.get_physical_core_id(0)}]") def __repr__(self) -> str: return self.__str__() - - 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) -> int: - return self._x * 256 + self._y diff --git a/spinn_machine/machine.py b/spinn_machine/machine.py index 52e2048b..efa10f85 100644 --- a/spinn_machine/machine.py +++ b/spinn_machine/machine.py @@ -566,12 +566,11 @@ def add_chip(self, chip: Chip): :raise SpinnMachineAlreadyExistsException: If a chip with the same x and y coordinates already exists """ - chip_id = (chip.x, chip.y) - if chip_id in self._chips: + if chip in self._chips: raise SpinnMachineAlreadyExistsException( "chip", f"{chip.x}, {chip.y}") - self._chips[chip_id] = chip + self._chips[chip] = chip # keep some stats about the self._n_cores_counter[chip.n_processors] += 1 diff --git a/unittests/test_chip.py b/unittests/test_chip.py index c4ff6a3d..3d2b40ad 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -52,25 +52,14 @@ def test_create_chip(self): self.assertEqual(new_chip.sdram, self._sdram) self.assertEqual(new_chip.router, self._router) self.assertEqual(new_chip.n_user_processors, self.n_processors - 1) - with self.assertRaises(KeyError): - self.assertIsNone(new_chip[42]) print(new_chip.__repr__()) self.assertEqual( "[Chip: x=0, y=1, ip_address=192.162.240.253 " "n_cores=18, mon=None]", new_chip.__repr__(),) self.assertEqual(new_chip.tag_ids, OrderedSet([1, 2, 3, 4, 5, 6, 7])) - self.assertEqual( - [p[0] for p in new_chip], - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]) - self.assertEqual( - [p[1].is_monitor for p in new_chip], - [True, False, False, False, False, False, False, False, False, - False, False, False, False, False, False, False, False, False]) self.assertTrue(new_chip.is_processor_with_id(3)) self.assertEqual(5, new_chip.get_processor_with_id(5).processor_id) - self.assertEqual(6, new_chip[6].processor_id) - self.assertTrue(7 in new_chip) self.assertIsNone(new_chip.get_processor_with_id(-1)) def test_get_first_none_monitor_processor(self): @@ -83,19 +72,6 @@ def test_get_first_none_monitor_processor(self): non_monitor = new_chip.get_first_none_monitor_processor() self.assertFalse(non_monitor.is_monitor) - def test_getitem_and_contains(self): - """ test the __getitem__ an __contains__ methods - - NOTE: Not sure if method being tested is required. - """ - new_chip = self._create_chip(self._x, self._y, self.n_processors, - self._router, self._sdram, self._ip) - new_chip[3] - with self.assertRaises(KeyError): - new_chip[self.n_processors] - self.assertTrue(3 in new_chip) - self.assertFalse(self.n_processors in new_chip) - def test_0_down(self): with self.assertRaises(NotImplementedError): Chip(1, 1, self.n_processors, self._router, self._sdram, 0, 0, diff --git a/unittests/test_machine.py b/unittests/test_machine.py index b417a22b..231bacc9 100644 --- a/unittests/test_machine.py +++ b/unittests/test_machine.py @@ -337,18 +337,6 @@ def test_negative_y(self): with self.assertRaises(SpinnMachineException): machine.validate() - def test_big_x(self): - machine = virtual_machine(8, 8) - machine.get_chip_at(1, 1)._x = 9 - with self.assertRaises(SpinnMachineException): - machine.validate() - - def test_big_y(self): - machine = virtual_machine(8, 8) - machine.get_chip_at(1, 1)._y = 9 - with self.assertRaises(SpinnMachineException): - machine.validate() - def test_weird_ethernet1(self): machine = virtual_machine(8, 8) machine.get_chip_at(1, 3)._ip_address = "1.2.3.4" From a86ccd83f75d9d1646506896f53564adf3c005d5 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 5 Mar 2024 15:59:22 +0000 Subject: [PATCH 02/31] flake8 --- spinn_machine/chip.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index d0030dad..b137660e 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -38,12 +38,12 @@ class Chip(tuple, XY): _IPTAG_IDS = OrderedSet(range(1, 8)) def __new__(cls, 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): + 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): return tuple.__new__(cls, (x, y)) # pylint: disable=too-many-arguments, wrong-spelling-in-docstring From cb5505c43bd7c3b59d26812ca5bd42515c07a454 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 5 Mar 2024 16:08:44 +0000 Subject: [PATCH 03/31] pylint: disable=unused-argument --- spinn_machine/chip.py | 1 + 1 file changed, 1 insertion(+) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index b137660e..1ba438ec 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -47,6 +47,7 @@ def __new__(cls, x: int, y: int, n_processors: int, router: Router, return tuple.__new__(cls, (x, y)) # pylint: disable=too-many-arguments, wrong-spelling-in-docstring + # pylint: disable=unused-argument 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, From 103f04ea56e7bebedf080721ace58ed1027d6436 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 07:10:46 +0000 Subject: [PATCH 04/31] merge --- spinn_machine/chip.py | 30 ------------------------------ unittests/test_chip.py | 5 ++--- 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 72c43e62..3371fe5a 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -384,36 +384,6 @@ def get_physical_core_string(self, virtual_p: int) -> str: return "" return f" (ph: {physical_p})" - def __iter__(self) -> Iterator[Tuple[int, Processor]]: - """ - Get an iterable of processor identifiers and processors - - :return: An iterable of ``(processor_id, processor)`` where: - * ``processor_id`` is the ID of a processor - * ``processor`` is the processor with the ID - :rtype: iterable(tuple(int,Processor)) - """ - return iter(self._p.items()) - - def __len__(self) -> int: - """ - The number of processors associated with this chip. - - :return: The number of items in the underlying iterator. - :rtype: int - """ - return len(self._p) - - 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: int) -> bool: - return self.is_processor_with_id(processor_id) - def __str__(self) -> str: if self._ip_address: ip_info = f"ip_address={self.ip_address} " diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 9811827f..43857bd3 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -89,10 +89,9 @@ def test_1_chip(self): def test_processors(self): new_chip = self._create_chip(self._x, self._y, self.n_processors, self._router, self._sdram, self._ip) - all_p = set() - for id in new_chip.all_processor_ids: - all_p.add(new_chip[id]) + all_p = set(new_chip.processors) self.assertEqual(len(all_p), new_chip.n_processors) + self.assertEqual(len(all_p), len(set(new_chip.processors_ids))) users = set(new_chip.user_processors) self.assertEqual(len(users), new_chip.n_user_processors) self.assertEqual(len(users), len(set(new_chip.user_processors_ids))) From c49d294ddcc516852dfe44d35d17b554a4947aea Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 07:31:40 +0000 Subject: [PATCH 05/31] add xy tests --- unittests/test_chip.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 43857bd3..ef18684d 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -91,7 +91,7 @@ def test_processors(self): self._router, self._sdram, self._ip) all_p = set(new_chip.processors) self.assertEqual(len(all_p), new_chip.n_processors) - self.assertEqual(len(all_p), len(set(new_chip.processors_ids))) + self.assertEqual(len(all_p), len(set(new_chip.all_processor_ids))) users = set(new_chip.user_processors) self.assertEqual(len(users), new_chip.n_user_processors) self.assertEqual(len(users), len(set(new_chip.user_processors_ids))) @@ -100,6 +100,25 @@ def test_processors(self): self.assertEqual(len(monitors), len(set(new_chip.monitor_processors_ids))) + def test_is_xy(self): + chip24 = self._create_chip( + 2, 4, self.n_processors, self._router, self._sdram, None) + chip36 = self._create_chip( + 3, 6, self.n_processors, self._router, self._sdram, None) + chip00 = self._create_chip( + 0, 0, self.n_processors, self._router, self._sdram, self._ip) + xy00 = (0, 0) + xy36 = (3, 6) + self.assertEqual(chip24, (2, 4)) + self.assertEqual((2, 4), chip24) + self.assertEqual(chip00, xy00) + self.assertEqual(xy00, chip00) + self.assertNotEqual(chip00, (0, 0, 0)) + self.assertNotEqual((0, 0, 0), chip00) + self.assertNotEqual(chip00, (0, 1)) + self.assertNotEqual((0, 1), chip00) + self.assertEqual([chip24, xy00, chip36], [chip24, (0,0), chip36]) + if __name__ == '__main__': unittest.main() From 73d4ab885cb168fdba09f87ffc27c8c4bdff4d17 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 07:55:25 +0000 Subject: [PATCH 06/31] test more lists --- unittests/test_chip.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/unittests/test_chip.py b/unittests/test_chip.py index ef18684d..f140f8f3 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -117,7 +117,9 @@ def test_is_xy(self): self.assertNotEqual((0, 0, 0), chip00) self.assertNotEqual(chip00, (0, 1)) self.assertNotEqual((0, 1), chip00) - self.assertEqual([chip24, xy00, chip36], [chip24, (0,0), chip36]) + self.assertEqual([chip24, chip00, chip36], [(2, 4), xy00, xy36]) + self.assertEqual([(2, 4), xy00, xy36], [chip24, chip00, chip36]) + self.assertEqual([chip24, xy00, chip36], [(2, 4), chip00, xy36]) if __name__ == '__main__': From 569f2bff32ec6cdc8d1ba4ff96f46d9398fcdde3 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 10:03:28 +0000 Subject: [PATCH 07/31] consistent method resolution --- spinn_machine/chip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 3371fe5a..1ceffb20 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -27,7 +27,7 @@ standard_monitor_processors = None # pylint: disable=invalid-name -class Chip(tuple, XY): +class Chip(XY, tuple): """ Represents a SpiNNaker chip with a number of cores, an amount of SDRAM shared between the cores, and a router. From 57e9d46cfcbfeecd7dc97a09149dcdf383fec224 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 10:39:48 +0000 Subject: [PATCH 08/31] use tuple[int,int] --- spinn_machine/chip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 1ceffb20..0f027270 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -27,7 +27,7 @@ standard_monitor_processors = None # pylint: disable=invalid-name -class Chip(XY, tuple): +class Chip(tuple[int, int]): """ Represents a SpiNNaker chip with a number of cores, an amount of SDRAM shared between the cores, and a router. From 1d63496da28f455c6a0b5c8ab4903686e5f9e76f Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 10:55:20 +0000 Subject: [PATCH 09/31] hack for python 3.8 --- spinn_machine/chip.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 0f027270..045ff947 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -13,6 +13,8 @@ # limitations under the License. from typing import ( Collection, Dict, Iterable, Iterator, Optional) +import sys + from spinn_utilities.ordered_set import OrderedSet from spinn_utilities.typing.coords import XY @@ -26,8 +28,13 @@ # One dict for the standard monitor processors standard_monitor_processors = None # pylint: disable=invalid-name +if sys.version_info.minor > 8: + SUPER = XY +else: + SUPER = (tuple, XY) + -class Chip(tuple[int, int]): +class Chip(SUPER): """ Represents a SpiNNaker chip with a number of cores, an amount of SDRAM shared between the cores, and a router. From 393b101dd15bf0a1fdabff7d0fc82c04943011c7 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 11:04:47 +0000 Subject: [PATCH 10/31] hack for python 3.8 V 2 --- spinn_machine/chip.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 045ff947..841d94cd 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -29,12 +29,12 @@ standard_monitor_processors = None # pylint: disable=invalid-name if sys.version_info.minor > 8: - SUPER = XY + SUPER = object else: - SUPER = (tuple, XY) + SUPER = tuple -class Chip(SUPER): +class Chip(XY, SUPER): """ Represents a SpiNNaker chip with a number of cores, an amount of SDRAM shared between the cores, and a router. From 12207d91e6cdb28d574db65e923f72fe7c4d6377 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 11:15:05 +0000 Subject: [PATCH 11/31] use just XY --- spinn_machine/chip.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 841d94cd..ff8951da 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -13,7 +13,6 @@ # limitations under the License. from typing import ( Collection, Dict, Iterable, Iterator, Optional) -import sys from spinn_utilities.ordered_set import OrderedSet from spinn_utilities.typing.coords import XY @@ -28,13 +27,8 @@ # One dict for the standard monitor processors standard_monitor_processors = None # pylint: disable=invalid-name -if sys.version_info.minor > 8: - SUPER = object -else: - SUPER = tuple - -class Chip(XY, SUPER): +class Chip(XY): """ Represents a SpiNNaker chip with a number of cores, an amount of SDRAM shared between the cores, and a router. From 4ae4a89f07227aae81959a24e6f0fcc43fa8975c Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 16:32:53 +0000 Subject: [PATCH 12/31] rename non_user cores to scamp cores --- spinn_machine/chip.py | 4 ++-- spinn_machine/version/abstract_version.py | 4 ++-- spinn_machine/version/version_spin1.py | 4 ++-- unittests/version/test_version3.py | 2 +- unittests/version/test_version5.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index ea899b8d..0ba7ddd0 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -115,14 +115,14 @@ def __generate_monitors(self): if standard_monitor_processors is None: standard_monitor_processors = dict() for i in range( - MachineDataView.get_machine_version().n_non_user_cores): + MachineDataView.get_machine_version().n_scamp_cores): standard_monitor_processors[i] = Processor.factory(i, True) return standard_monitor_processors def __generate_processors( self, n_processors: int, down_cores: Optional[Collection[int]]) -> Dict[int, Processor]: - n_monitors = MachineDataView.get_machine_version().n_non_user_cores + n_monitors = MachineDataView.get_machine_version().n_scamp_cores if down_cores is None: if n_processors not in standard_processors: processors = dict() diff --git a/spinn_machine/version/abstract_version.py b/spinn_machine/version/abstract_version.py index 7301c008..b50593c6 100644 --- a/spinn_machine/version/abstract_version.py +++ b/spinn_machine/version/abstract_version.py @@ -145,9 +145,9 @@ def max_cores_per_chip(self) -> int: @property @abstractmethod - def n_non_user_cores(self) -> int: + def n_scamp_cores(self) -> int: """ - The number of system cores per chip. + The number of scamp cores per chip. :rtype: int """ diff --git a/spinn_machine/version/version_spin1.py b/spinn_machine/version/version_spin1.py index a18e4f66..2d4520c6 100644 --- a/spinn_machine/version/version_spin1.py +++ b/spinn_machine/version/version_spin1.py @@ -29,8 +29,8 @@ def __init__(self) -> None: super().__init__(max_cores_per_chip=18, max_sdram_per_chip=123469792) @property - @overrides(AbstractVersion.n_non_user_cores) - def n_non_user_cores(self) -> int: + @overrides(AbstractVersion.n_scamp_cores) + def n_scamp_cores(self) -> int: return 1 @property diff --git a/unittests/version/test_version3.py b/unittests/version/test_version3.py index 4d529a1d..8c7779ef 100644 --- a/unittests/version/test_version3.py +++ b/unittests/version/test_version3.py @@ -33,7 +33,7 @@ def test_attributes(self): version = Version3() self.assertEqual(18, version.max_cores_per_chip) self.assertEqual(123469792, version.max_sdram_per_chip) - self.assertEqual(1, version.n_non_user_cores) + self.assertEqual(1, version.n_scamp_cores) self.assertEqual("Spin1 4 Chip", version.name) self.assertEqual(3, version.number) self.assertEqual((2, 2), version.board_shape) diff --git a/unittests/version/test_version5.py b/unittests/version/test_version5.py index f35aa164..3ca9d741 100644 --- a/unittests/version/test_version5.py +++ b/unittests/version/test_version5.py @@ -36,7 +36,7 @@ def test_attributes(self): version = Version5() self.assertEqual(18, version.max_cores_per_chip) self.assertEqual(123469792, version.max_sdram_per_chip) - self.assertEqual(1, version.n_non_user_cores) + self.assertEqual(1, version.n_scamp_cores) self.assertEqual("Spin1 48 Chip", version.name) self.assertEqual(5, version.number) self.assertEqual((8, 8), version.board_shape) From 07ffd695da513f1dc4587be1363db657bb5c01d8 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Wed, 6 Mar 2024 17:06:20 +0000 Subject: [PATCH 13/31] rename monitor processor to scamp processors --- spinn_machine/chip.py | 56 +++++++++++++++---------------- unittests/test_chip.py | 4 +-- unittests/test_json_machine.py | 4 +-- unittests/test_virtual_machine.py | 2 +- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 0ba7ddd0..4a6b916b 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -22,7 +22,7 @@ # One dict for each number of processors (none dead) standard_processors = {} # One dict for the standard monitor processors -standard_monitor_processors = None # pylint: disable=invalid-name +standard_scamp_processors = None # pylint: disable=invalid-name class Chip(object): @@ -42,7 +42,7 @@ class Chip(object): __slots__ = ( "_x", "_y", "_router", "_sdram", "_ip_address", "_tag_ids", "_nearest_ethernet_x", "_nearest_ethernet_y", - "_user_processors", "_monitor_processors", "_parent_link", + "_user_processors", "_scamp_processors", "_parent_link", "_v_to_p_map" ) @@ -88,7 +88,7 @@ def __init__(self, x: int, y: int, n_processors: int, router: Router, """ self._x = x self._y = y - self._monitor_processors = self.__generate_monitors() + self._scamp_processors = self.__generate_scamp() self._user_processors = self.__generate_processors( n_processors, down_cores) self._router = router @@ -105,19 +105,19 @@ def __init__(self, x: int, y: int, n_processors: int, router: Router, self._parent_link = parent_link self._v_to_p_map = v_to_p_map - def __generate_monitors(self): + def __generate_scamp(self): """ - Generates the monitors assuming all Chips have the same monitor cores + Generates the scamp assuming all Chips have the same scamp cores :return: Dict[int, Processor] """ - global standard_monitor_processors # pylint: disable=global-statement - if standard_monitor_processors is None: - standard_monitor_processors = dict() + global standard_scamp_processors # pylint: disable=global-statement + if standard_scamp_processors is None: + standard_scamp_processors = dict() for i in range( MachineDataView.get_machine_version().n_scamp_cores): - standard_monitor_processors[i] = Processor.factory(i, True) - return standard_monitor_processors + standard_scamp_processors[i] = Processor.factory(i, True) + return standard_scamp_processors def __generate_processors( self, n_processors: int, @@ -152,7 +152,7 @@ def is_processor_with_id(self, processor_id: int) -> bool: """ if processor_id in self._user_processors: return True - return processor_id in self._monitor_processors + return processor_id in self._scamp_processors def get_processor_with_id(self, processor_id: int) -> Optional[Processor]: """ @@ -167,7 +167,7 @@ def get_processor_with_id(self, processor_id: int) -> Optional[Processor]: """ if processor_id in self._user_processors: return self._user_processors[processor_id] - return self._monitor_processors.get(processor_id) + return self._scamp_processors.get(processor_id) @property def x(self) -> int: @@ -204,7 +204,7 @@ def processors(self) -> Iterator[Processor]: :rtype: iterable(Processor) """ - yield from self._monitor_processors.values() + yield from self._scamp_processors.values() yield from self._user_processors.values() @property @@ -214,7 +214,7 @@ def all_processor_ids(self) -> Iterator[int]: :rtype: iterable(int) """ - yield from self._monitor_processors.keys() + yield from self._scamp_processors.keys() yield from self._user_processors.keys() @property @@ -224,7 +224,7 @@ def n_processors(self) -> int: :rtype: int """ - return len(self._monitor_processors) + len(self._user_processors) + return len(self._scamp_processors) + len(self._user_processors) @property def user_processors(self) -> Iterator[Processor]: @@ -247,38 +247,38 @@ def user_processors_ids(self) -> Iterator[int]: @property def n_user_processors(self) -> int: """ - The total number of processors that are not monitors. + The total number of processors that are not used by scamp. :rtype: int """ return len(self._user_processors) @property - def monitor_processors(self) -> Iterator[Processor]: + def scamp_processors(self) -> Iterator[Processor]: """ - An iterable of available monitor processors. + An iterable of available scamp processors. :rtype: iterable(Processor) """ - return self._monitor_processors.values() + return self._scamp_processors.values() @property - def monitor_processors_ids(self) -> Iterator[int]: + def scamp_processors_ids(self) -> Iterator[int]: """ - An iterable of available user processors. + An iterable of available scamp processors. :rtype: iterable(Processor) """ - yield from self._monitor_processors + yield from self._scamp_processors @property def n_monitor_processors(self) -> int: """ - The total number of processors that are not monitors. + The total number of processors that are used by scamp. :rtype: int """ - return len(self._monitor_processors) + return len(self._scamp_processors) @property def router(self) -> Router: @@ -389,7 +389,7 @@ def __iter__(self) -> Iterator[Tuple[int, Processor]]: * ``processor`` is the processor with the ID :rtype: iterable(tuple(int,Processor)) """ - yield from self._monitor_processors.items() + yield from self._scamp_processors.items() yield from self._user_processors.items() def __len__(self) -> int: @@ -399,13 +399,13 @@ def __len__(self) -> int: :return: The number of items in the underlying iterator. :rtype: int """ - return len(self._monitor_processors) + len(self._user_processors) + return len(self._scamp_processors) + len(self._user_processors) def __getitem__(self, processor_id: int) -> Processor: if processor_id in self._user_processors: return self._user_processors[processor_id] - if processor_id in self._monitor_processors: - return self._monitor_processors[processor_id] + if processor_id in self._scamp_processors: + return self._scamp_processors[processor_id] # Note difference from get_processor_with_id(); this is to conform to # standard Python semantics raise KeyError(processor_id) diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 083e606e..a3a34d3f 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -120,10 +120,10 @@ def test_processors(self): users = set(new_chip.user_processors) self.assertEqual(len(users), new_chip.n_user_processors) self.assertEqual(len(users), len(set(new_chip.user_processors_ids))) - monitors = set(new_chip.monitor_processors) + monitors = set(new_chip.scamp_processors) self.assertEqual(users.union(monitors), all_p) self.assertEqual(len(monitors), - len(set(new_chip.monitor_processors_ids))) + len(set(new_chip.scamp_processors_ids))) if __name__ == '__main__': diff --git a/unittests/test_json_machine.py b/unittests/test_json_machine.py index b423f87c..3485c5d8 100644 --- a/unittests/test_json_machine.py +++ b/unittests/test_json_machine.py @@ -64,9 +64,9 @@ def test_monitor_exceptions(self): chip02 = vm[0, 2] # Hack in an extra monitor users = dict(chip02._user_processors) - monitors = dict(chip02._monitor_processors) + monitors = dict(chip02._scamp_processors) monitors[1] = users.pop(1) - chip02._monitor_processors = monitors + chip02._scamp_processors = monitors chip02._user_processors = users jpath = mktemp("json") # Should still be able to write json even with more than one monitor diff --git a/unittests/test_virtual_machine.py b/unittests/test_virtual_machine.py index 936b3324..247689a5 100644 --- a/unittests/test_virtual_machine.py +++ b/unittests/test_virtual_machine.py @@ -179,7 +179,7 @@ def test_new_vm_with_max_cores(self): self.assertEqual(n_cpus - 1, _chip.n_user_processors) self.assertEqual(1, _chip.n_monitor_processors) self.assertEqual(n_cpus - 1, len(list(_chip.user_processors))) - self.assertEqual(1, len(list(_chip.monitor_processors))) + self.assertEqual(1, len(list(_chip.scamp_processors))) count = sum(_chip.n_processors for _chip in vm.chips) self.assertEqual(count, 4 * n_cpus) From 5d25dca5625e425328410ba45f491355f8ad9cf8 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Thu, 7 Mar 2024 05:57:14 +0000 Subject: [PATCH 14/31] rename chip user processor(s) chip placable processor(s) --- spinn_machine/chip.py | 44 +++++++++++++++---------------- spinn_machine/json_machine.py | 12 ++++----- spinn_machine/machine.py | 2 +- unittests/test_chip.py | 8 +++--- unittests/test_json_machine.py | 4 +-- unittests/test_machine.py | 4 +-- unittests/test_virtual_machine.py | 4 +-- 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 4a6b916b..ecf03eea 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -42,7 +42,7 @@ class Chip(object): __slots__ = ( "_x", "_y", "_router", "_sdram", "_ip_address", "_tag_ids", "_nearest_ethernet_x", "_nearest_ethernet_y", - "_user_processors", "_scamp_processors", "_parent_link", + "_placable_processors", "_scamp_processors", "_parent_link", "_v_to_p_map" ) @@ -89,7 +89,7 @@ def __init__(self, x: int, y: int, n_processors: int, router: Router, self._x = x self._y = y self._scamp_processors = self.__generate_scamp() - self._user_processors = self.__generate_processors( + self._placable_processors = self.__generate_processors( n_processors, down_cores) self._router = router self._sdram = sdram @@ -150,7 +150,7 @@ def is_processor_with_id(self, processor_id: int) -> bool: :return: Whether the processor with the given ID exists :rtype: bool """ - if processor_id in self._user_processors: + if processor_id in self._placable_processors: return True return processor_id in self._scamp_processors @@ -165,8 +165,8 @@ def get_processor_with_id(self, processor_id: int) -> Optional[Processor]: or ``None`` if no such processor :rtype: Processor or None """ - if processor_id in self._user_processors: - return self._user_processors[processor_id] + if processor_id in self._placable_processors: + return self._placable_processors[processor_id] return self._scamp_processors.get(processor_id) @property @@ -205,7 +205,7 @@ def processors(self) -> Iterator[Processor]: :rtype: iterable(Processor) """ yield from self._scamp_processors.values() - yield from self._user_processors.values() + yield from self._placable_processors.values() @property def all_processor_ids(self) -> Iterator[int]: @@ -215,7 +215,7 @@ def all_processor_ids(self) -> Iterator[int]: :rtype: iterable(int) """ yield from self._scamp_processors.keys() - yield from self._user_processors.keys() + yield from self._placable_processors.keys() @property def n_processors(self) -> int: @@ -224,34 +224,34 @@ def n_processors(self) -> int: :rtype: int """ - return len(self._scamp_processors) + len(self._user_processors) + return len(self._scamp_processors) + len(self._placable_processors) @property - def user_processors(self) -> Iterator[Processor]: + def placeable_processors(self) -> Iterator[Processor]: """ - An iterable of available user processors. + An iterable of available placable/ none scamp processors. :rtype: iterable(Processor) """ - yield from self._user_processors.values() + yield from self._placable_processors.values() @property - def user_processors_ids(self) -> Iterator[int]: + def placable_processors_ids(self) -> Iterator[int]: """ - An iterable of available user processors. + An iterable of available placable/ non scamp processor ids. :rtype: iterable(Processor) """ - yield from self._user_processors + yield from self._placable_processors @property - def n_user_processors(self) -> int: + def n_placable_processors(self) -> int: """ - The total number of processors that are not used by scamp. + The total number of processors that are placable / not used by scamp. :rtype: int """ - return len(self._user_processors) + return len(self._placable_processors) @property def scamp_processors(self) -> Iterator[Processor]: @@ -342,7 +342,7 @@ def get_first_none_monitor_processor(self) -> Processor: :rtype: Processor ;raises StopIteration: If there is no user processor """ - return next(iter(self._user_processors.values())) + return next(iter(self._placable_processors.values())) @property def parent_link(self) -> Optional[int]: @@ -390,7 +390,7 @@ def __iter__(self) -> Iterator[Tuple[int, Processor]]: :rtype: iterable(tuple(int,Processor)) """ yield from self._scamp_processors.items() - yield from self._user_processors.items() + yield from self._placable_processors.items() def __len__(self) -> int: """ @@ -399,11 +399,11 @@ def __len__(self) -> int: :return: The number of items in the underlying iterator. :rtype: int """ - return len(self._scamp_processors) + len(self._user_processors) + return len(self._scamp_processors) + len(self._placable_processors) def __getitem__(self, processor_id: int) -> Processor: - if processor_id in self._user_processors: - return self._user_processors[processor_id] + if processor_id in self._placable_processors: + return self._placable_processors[processor_id] if processor_id in self._scamp_processors: return self._scamp_processors[processor_id] # Note difference from get_processor_with_id(); this is to conform to diff --git a/spinn_machine/json_machine.py b/spinn_machine/json_machine.py index e0d34c9e..122b7705 100644 --- a/spinn_machine/json_machine.py +++ b/spinn_machine/json_machine.py @@ -204,9 +204,9 @@ def _describe_chip(chip: Chip, standard, ethernet) -> JsonArray: if chip.ip_address is not None: details['ipAddress'] = chip.ip_address # Write the Resources ONLY if different from the e_values - if (chip.n_processors - chip.n_user_processors) != ethernet.monitors: + if (chip.n_processors - chip.n_placable_processors) != ethernet.monitors: exceptions["monitors"] = \ - chip.n_processors - chip.n_user_processors + chip.n_processors - chip.n_placable_processors if router_entries != ethernet.router_entries: exceptions["routerEntries"] = router_entries if chip.sdram != ethernet.sdram: @@ -215,9 +215,9 @@ def _describe_chip(chip: Chip, standard, ethernet) -> JsonArray: exceptions["tags"] = tags else: # Write the Resources ONLY if different from the s_values - if (chip.n_processors - chip.n_user_processors) != standard.monitors: + if (chip.n_processors - chip.n_placable_processors) != standard.monitors: exceptions["monitors"] = \ - chip.n_processors - chip.n_user_processors + chip.n_processors - chip.n_placable_processors if router_entries != standard.router_entries: exceptions["routerEntries"] = router_entries if chip.sdram != standard.sdram: @@ -243,7 +243,7 @@ def to_json() -> JsonObject: for chip in machine.chips: if chip.ip_address is None: std = _Desc( - monitors=chip.n_processors - chip.n_user_processors, + monitors=chip.n_processors - chip.n_placable_processors, router_entries=_int_value( chip.router.n_available_multicast_entries), sdram=chip.sdram, @@ -255,7 +255,7 @@ def to_json() -> JsonObject: # find the nth values to use for Ethernet chips chip = machine.boot_chip eth = _Desc( - monitors=chip.n_processors - chip.n_user_processors, + monitors=chip.n_processors - chip.n_placable_processors, router_entries=_int_value( chip.router.n_available_multicast_entries), sdram=chip.sdram, diff --git a/spinn_machine/machine.py b/spinn_machine/machine.py index 167616cf..1ca54375 100644 --- a/spinn_machine/machine.py +++ b/spinn_machine/machine.py @@ -1084,7 +1084,7 @@ def total_available_user_cores(self) -> int: :rtype: int """ - return sum(chip.n_user_processors for chip in self.chips) + return sum(chip.n_placable_processors for chip in self.chips) @property def total_cores(self) -> int: diff --git a/unittests/test_chip.py b/unittests/test_chip.py index a3a34d3f..62a9980d 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -53,7 +53,7 @@ def test_create_chip(self): self.assertEqual(new_chip.ip_address, self._ip) self.assertEqual(new_chip.sdram, self._sdram) self.assertEqual(new_chip.router, self._router) - self.assertEqual(new_chip.n_user_processors, self.n_processors - 1) + self.assertEqual(new_chip.n_placable_processors, self.n_processors - 1) with self.assertRaises(KeyError): self.assertIsNone(new_chip[42]) print(new_chip.__repr__()) @@ -117,9 +117,9 @@ def test_processors(self): for id in new_chip.all_processor_ids: all_p.add(new_chip[id]) self.assertEqual(len(all_p), new_chip.n_processors) - users = set(new_chip.user_processors) - self.assertEqual(len(users), new_chip.n_user_processors) - self.assertEqual(len(users), len(set(new_chip.user_processors_ids))) + users = set(new_chip.placeable_processors) + self.assertEqual(len(users), new_chip.n_placable_processors) + self.assertEqual(len(users), len(set(new_chip.placable_processors_ids))) monitors = set(new_chip.scamp_processors) self.assertEqual(users.union(monitors), all_p) self.assertEqual(len(monitors), diff --git a/unittests/test_json_machine.py b/unittests/test_json_machine.py index 3485c5d8..0b140ec5 100644 --- a/unittests/test_json_machine.py +++ b/unittests/test_json_machine.py @@ -63,11 +63,11 @@ def test_monitor_exceptions(self): MachineDataWriter.mock().set_machine(vm) chip02 = vm[0, 2] # Hack in an extra monitor - users = dict(chip02._user_processors) + users = dict(chip02._placable_processors) monitors = dict(chip02._scamp_processors) monitors[1] = users.pop(1) chip02._scamp_processors = monitors - chip02._user_processors = users + chip02._placable_processors = users jpath = mktemp("json") # Should still be able to write json even with more than one monitor to_json_path(jpath) diff --git a/unittests/test_machine.py b/unittests/test_machine.py index a58ded1d..b5415a5e 100644 --- a/unittests/test_machine.py +++ b/unittests/test_machine.py @@ -390,8 +390,8 @@ def test_too_few_cores(self): machine = virtual_machine(8, 8) # Hack to get n_processors return a low number chip01 = machine.get_chip_at(0, 1) - chip01._user_processors = dict( - list(chip01._user_processors.items())[:2]) + chip01._placable_processors = dict( + list(chip01._placable_processors.items())[:2]) with self.assertRaises(SpinnMachineException): machine.validate() diff --git a/unittests/test_virtual_machine.py b/unittests/test_virtual_machine.py index 247689a5..36b3b3ec 100644 --- a/unittests/test_virtual_machine.py +++ b/unittests/test_virtual_machine.py @@ -176,9 +176,9 @@ def test_new_vm_with_max_cores(self): vm = virtual_machine(2, 2, validate=True) _chip = vm[1, 1] self.assertEqual(n_cpus, _chip.n_processors) - self.assertEqual(n_cpus - 1, _chip.n_user_processors) + self.assertEqual(n_cpus - 1, _chip.n_placable_processors) self.assertEqual(1, _chip.n_monitor_processors) - self.assertEqual(n_cpus - 1, len(list(_chip.user_processors))) + self.assertEqual(n_cpus - 1, len(list(_chip.placeable_processors))) self.assertEqual(1, len(list(_chip.scamp_processors))) count = sum(_chip.n_processors for _chip in vm.chips) self.assertEqual(count, 4 * n_cpus) From 73e5557f92bcc8ce7385c6dcbf76890b5670ad6c Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Thu, 7 Mar 2024 05:57:58 +0000 Subject: [PATCH 15/31] rename monitor processor to scamp processors --- spinn_machine/chip.py | 2 +- unittests/test_virtual_machine.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index ecf03eea..2585db9b 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -272,7 +272,7 @@ def scamp_processors_ids(self) -> Iterator[int]: yield from self._scamp_processors @property - def n_monitor_processors(self) -> int: + def n_scamp_processors(self) -> int: """ The total number of processors that are used by scamp. diff --git a/unittests/test_virtual_machine.py b/unittests/test_virtual_machine.py index 36b3b3ec..0587ee68 100644 --- a/unittests/test_virtual_machine.py +++ b/unittests/test_virtual_machine.py @@ -177,7 +177,7 @@ def test_new_vm_with_max_cores(self): _chip = vm[1, 1] self.assertEqual(n_cpus, _chip.n_processors) self.assertEqual(n_cpus - 1, _chip.n_placable_processors) - self.assertEqual(1, _chip.n_monitor_processors) + self.assertEqual(1, _chip.n_scamp_processors) self.assertEqual(n_cpus - 1, len(list(_chip.placeable_processors))) self.assertEqual(1, len(list(_chip.scamp_processors))) count = sum(_chip.n_processors for _chip in vm.chips) From 45f5281ed10214f991fa8edfc659e9afced81573 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Thu, 7 Mar 2024 06:14:42 +0000 Subject: [PATCH 16/31] only expose processor virtual ids --- spinn_machine/chip.py | 38 ------------------------------- unittests/test_chip.py | 12 ++++------ unittests/test_virtual_machine.py | 4 ++-- 3 files changed, 6 insertions(+), 48 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index ea899b8d..c686c4df 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -187,26 +187,6 @@ def y(self) -> int: """ return self._y - @property - def processors(self) -> Iterator[Processor]: - """ - An iterable of available all processors. - - Deprecated: There are many more efficient methods instead. - - all_processor_ids - - n_processors - - n_user_processors - - user_processors - - user_processors_ids - - n_monitor_processors - - monitor_processors - - monitor_processors_ids - - :rtype: iterable(Processor) - """ - yield from self._monitor_processors.values() - yield from self._user_processors.values() - @property def all_processor_ids(self) -> Iterator[int]: """ @@ -226,15 +206,6 @@ def n_processors(self) -> int: """ return len(self._monitor_processors) + len(self._user_processors) - @property - def user_processors(self) -> Iterator[Processor]: - """ - An iterable of available user processors. - - :rtype: iterable(Processor) - """ - yield from self._user_processors.values() - @property def user_processors_ids(self) -> Iterator[int]: """ @@ -253,15 +224,6 @@ def n_user_processors(self) -> int: """ return len(self._user_processors) - @property - def monitor_processors(self) -> Iterator[Processor]: - """ - An iterable of available monitor processors. - - :rtype: iterable(Processor) - """ - return self._monitor_processors.values() - @property def monitor_processors_ids(self) -> Iterator[int]: """ diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 083e606e..69c7d534 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -113,17 +113,13 @@ def test_1_chip(self): def test_processors(self): new_chip = self._create_chip(self._x, self._y, self.n_processors, self._router, self._sdram, self._ip) - all_p = set() - for id in new_chip.all_processor_ids: - all_p.add(new_chip[id]) + all_p = set(new_chip.all_processor_ids) self.assertEqual(len(all_p), new_chip.n_processors) - users = set(new_chip.user_processors) + users = set(new_chip.user_processors_ids) self.assertEqual(len(users), new_chip.n_user_processors) - self.assertEqual(len(users), len(set(new_chip.user_processors_ids))) - monitors = set(new_chip.monitor_processors) + monitors = set(new_chip.monitor_processors_ids) self.assertEqual(users.union(monitors), all_p) - self.assertEqual(len(monitors), - len(set(new_chip.monitor_processors_ids))) + self.assertEqual(len(monitors), new_chip.n_monitor_processors) if __name__ == '__main__': diff --git a/unittests/test_virtual_machine.py b/unittests/test_virtual_machine.py index 936b3324..4c5595f0 100644 --- a/unittests/test_virtual_machine.py +++ b/unittests/test_virtual_machine.py @@ -178,8 +178,8 @@ def test_new_vm_with_max_cores(self): self.assertEqual(n_cpus, _chip.n_processors) self.assertEqual(n_cpus - 1, _chip.n_user_processors) self.assertEqual(1, _chip.n_monitor_processors) - self.assertEqual(n_cpus - 1, len(list(_chip.user_processors))) - self.assertEqual(1, len(list(_chip.monitor_processors))) + self.assertEqual(n_cpus - 1, len(list(_chip.user_processors_ids))) + self.assertEqual(1, len(list(_chip.monitor_processors_ids))) count = sum(_chip.n_processors for _chip in vm.chips) self.assertEqual(count, 4 * n_cpus) From 58b7d19a91997a16841f8e63ad1aabe8290ad583 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Thu, 7 Mar 2024 06:27:22 +0000 Subject: [PATCH 17/31] use chip.n_scamp_processors --- spinn_machine/json_machine.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/spinn_machine/json_machine.py b/spinn_machine/json_machine.py index 122b7705..9bde816b 100644 --- a/spinn_machine/json_machine.py +++ b/spinn_machine/json_machine.py @@ -204,9 +204,8 @@ def _describe_chip(chip: Chip, standard, ethernet) -> JsonArray: if chip.ip_address is not None: details['ipAddress'] = chip.ip_address # Write the Resources ONLY if different from the e_values - if (chip.n_processors - chip.n_placable_processors) != ethernet.monitors: - exceptions["monitors"] = \ - chip.n_processors - chip.n_placable_processors + if (chip.n_scamp_processors) != ethernet.monitors: + exceptions["monitors"] = chip.n_scamp_processors if router_entries != ethernet.router_entries: exceptions["routerEntries"] = router_entries if chip.sdram != ethernet.sdram: @@ -215,9 +214,8 @@ def _describe_chip(chip: Chip, standard, ethernet) -> JsonArray: exceptions["tags"] = tags else: # Write the Resources ONLY if different from the s_values - if (chip.n_processors - chip.n_placable_processors) != standard.monitors: - exceptions["monitors"] = \ - chip.n_processors - chip.n_placable_processors + if (chip.n_scamp_processors) != standard.monitors: + exceptions["monitors"] = chip.n_scamp_processors if router_entries != standard.router_entries: exceptions["routerEntries"] = router_entries if chip.sdram != standard.sdram: From ad983420b1ce5a109c966375d000adf96e2420bb Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Thu, 7 Mar 2024 06:31:51 +0000 Subject: [PATCH 18/31] flake8 --- unittests/test_chip.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 62a9980d..105eadfd 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -119,7 +119,8 @@ def test_processors(self): self.assertEqual(len(all_p), new_chip.n_processors) users = set(new_chip.placeable_processors) self.assertEqual(len(users), new_chip.n_placable_processors) - self.assertEqual(len(users), len(set(new_chip.placable_processors_ids))) + self.assertEqual(len(users), + len(set(new_chip.placable_processors_ids))) monitors = set(new_chip.scamp_processors) self.assertEqual(users.union(monitors), all_p) self.assertEqual(len(monitors), From 65091c2db3d7db0b39375243306c2b6ac631dcc5 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Thu, 7 Mar 2024 17:16:50 +0000 Subject: [PATCH 19/31] merge fixes --- spinn_machine/chip.py | 33 --------------------------------- unittests/test_chip.py | 5 ++--- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 220b40cb..46a8307a 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -385,39 +385,6 @@ def get_physical_core_string(self, virtual_p: int) -> str: return "" return f" (ph: {physical_p})" - def __iter__(self) -> Iterator[Tuple[int, Processor]]: - """ - Get an iterable of processor identifiers and processors - - :return: An iterable of ``(processor_id, processor)`` where: - * ``processor_id`` is the ID of a processor - * ``processor`` is the processor with the ID - :rtype: iterable(tuple(int,Processor)) - """ - yield from self._monitor_processors.items() - yield from self._user_processors.items() - - def __len__(self) -> int: - """ - The number of processors associated with this chip. - - :return: The number of items in the underlying iterator. - :rtype: int - """ - return len(self._monitor_processors) + len(self._user_processors) - - def __getitem__(self, processor_id: int) -> Processor: - if processor_id in self._user_processors: - return self._user_processors[processor_id] - if processor_id in self._monitor_processors: - return self._monitor_processors[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: int) -> bool: - return self.is_processor_with_id(processor_id) - def __str__(self) -> str: if self._ip_address: ip_info = f"ip_address={self.ip_address} " diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 18d63b6a..f74cf66b 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -55,8 +55,6 @@ def test_create_chip(self): self.assertEqual(new_chip.router, self._router) self.assertEqual(new_chip.n_placable_processors, self.n_processors - 1) self.assertEqual(new_chip.n_placable_processors, self.n_processors - 1) - with self.assertRaises(KeyError): - self.assertIsNone(new_chip[42]) print(new_chip.__repr__()) self.assertEqual( "[Chip: x=0, y=1, ip_address=192.162.240.253 " @@ -97,7 +95,8 @@ def test_processors(self): self.assertEqual(len(all_p), len(set(new_chip.all_processor_ids))) users = set(new_chip.placeable_processors) self.assertEqual(len(users), new_chip.n_placable_processors) - self.assertEqual(len(users), len(set(new_chip.placeable_processors_ids))) + self.assertEqual(len(users), + len(set(new_chip.placable_processors_ids))) monitors = set(new_chip.scamp_processors) self.assertEqual(users.union(monitors), all_p) self.assertEqual(len(monitors), From cd27fc063be4dd4e55f88e0be4878b06a2542c25 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Thu, 7 Mar 2024 17:55:11 +0000 Subject: [PATCH 20/31] flake8 --- unittests/test_chip.py | 1 - 1 file changed, 1 deletion(-) diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 3c60282c..f088bbf3 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -87,7 +87,6 @@ def test_1_chip(self): with self.assertRaises(Exception): new_chip.get_first_none_monitor_processor() - def test_processors(self): new_chip = self._create_chip(self._x, self._y, self.n_processors, self._router, self._sdram, self._ip) From ac0941fb3fb3eb440240e5701717777d8c005f45 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 09:43:03 +0000 Subject: [PATCH 21/31] processors are now just a tuple of ints --- spinn_machine/chip.py | 77 +++++++++------------------------- unittests/test_chip.py | 8 ++-- unittests/test_json_machine.py | 7 +--- unittests/test_machine.py | 3 +- 4 files changed, 26 insertions(+), 69 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 81f5b6f3..e4a19f2a 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -18,7 +18,6 @@ from spinn_utilities.typing.coords import XY from spinn_machine.data import MachineDataView -from .processor import Processor from .router import Router # global values so Chip objects can share processor dict objects @@ -32,11 +31,6 @@ class Chip(XY): """ Represents a SpiNNaker chip with a number of cores, an amount of SDRAM shared between the cores, and a router. - The chip is iterable over the processors, yielding - ``(processor_id, processor)`` where: - - * ``processor_id`` is the ID of a processor - * ``processor`` is the :py:class:`Processor` with ``processor_id`` """ # tag 0 is reserved for stuff like IO STD @@ -93,7 +87,8 @@ def __init__(self, x: int, y: int, n_processors: int, router: Router, ``processor_id`` """ # X and Y set by new - self._scamp_processors = self.__generate_scamp() + self._scamp_processors = range( + MachineDataView.get_machine_version().n_scamp_cores) self._placable_processors = self.__generate_processors( n_processors, down_cores) self._router = router @@ -110,41 +105,22 @@ def __init__(self, x: int, y: int, n_processors: int, router: Router, self._parent_link = parent_link self._v_to_p_map = v_to_p_map - def __generate_scamp(self): - """ - Generates the scamp assuming all Chips have the same scamp cores - - :return: Dict[int, Processor] - """ - global standard_scamp_processors # pylint: disable=global-statement - if standard_scamp_processors is None: - standard_scamp_processors = dict() - for i in range( - MachineDataView.get_machine_version().n_scamp_cores): - standard_scamp_processors[i] = Processor.factory(i, True) - return standard_scamp_processors - def __generate_processors( self, n_processors: int, - down_cores: Optional[Collection[int]]) -> Dict[int, Processor]: + down_cores: Optional[Collection[int]]) -> tuple[int]: n_monitors = MachineDataView.get_machine_version().n_scamp_cores if down_cores is None: - if n_processors not in standard_processors: - processors = dict() - for i in range(n_monitors, n_processors): - processors[i] = Processor.factory(i) - standard_processors[n_processors] = processors - return standard_processors[n_processors] + return tuple(range(n_monitors, n_processors)) else: - processors = dict() + processors = list() for i in range(n_monitors): if i in down_cores: raise NotImplementedError( f"Declaring monitor core {i} as down is not supported") for i in range(n_monitors, n_processors): if i not in down_cores: - processors[i] = Processor.factory(i) - return processors + processors.append(i) + return tuple(processors) def is_processor_with_id(self, processor_id: int) -> bool: """ @@ -159,21 +135,6 @@ def is_processor_with_id(self, processor_id: int) -> bool: return True return processor_id in self._scamp_processors - 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. - - :param int processor_id: the ID of the processor to return - :return: - the processor with the specified ID, - or ``None`` if no such processor - :rtype: Processor or None - """ - if processor_id in self._placable_processors: - return self._placable_processors[processor_id] - return self._scamp_processors.get(processor_id) - @property def x(self) -> int: """ @@ -199,8 +160,8 @@ def all_processor_ids(self) -> Iterator[int]: :rtype: iterable(int) """ - yield from self._scamp_processors.keys() - yield from self._placable_processors.keys() + yield from self._scamp_processors + yield from self._placable_processors @property def n_processors(self) -> int: @@ -212,13 +173,13 @@ def n_processors(self) -> int: return len(self._scamp_processors) + len(self._placable_processors) @property - def placable_processors_ids(self) -> Iterator[int]: + def placable_processors_ids(self) -> tuple[int]: """ An iterable of available placable/ non scamp processor ids. - :rtype: iterable(Processor) + :rtype: iterable(int) """ - yield from self._placable_processors + return self._placable_processors @property def n_placable_processors(self) -> int: @@ -230,13 +191,13 @@ def n_placable_processors(self) -> int: return len(self._placable_processors) @property - def scamp_processors_ids(self) -> Iterator[int]: + def scamp_processors_ids(self) -> tuple[int]: """ An iterable of available scamp processors. - :rtype: iterable(Processor) + :rtype: iterable(int) """ - yield from self._scamp_processors + return self._scamp_processors @property def n_scamp_processors(self) -> int: @@ -302,14 +263,14 @@ def tag_ids(self) -> Iterable[int]: """ return self._tag_ids - def get_first_none_monitor_processor(self) -> Processor: + def get_first_none_monitor_processor_id(self) -> int: """ Get the first processor in the list which is not a monitor core. - :rtype: Processor - ;raises StopIteration: If there is no user processor + :rtype: int + ;raises IndexError: If there is no user processors """ - return next(iter(self._placable_processors.values())) + return self._placable_processors[0] @property def parent_link(self) -> Optional[int]: diff --git a/unittests/test_chip.py b/unittests/test_chip.py index f088bbf3..94341e92 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -17,6 +17,7 @@ from spinn_utilities.ordered_set import OrderedSet from spinn_machine import Link, Router, Chip from spinn_machine.config_setup import unittest_setup +from spinn_machine.data import MachineDataView class TestingChip(unittest.TestCase): @@ -62,8 +63,6 @@ def test_create_chip(self): new_chip.__repr__(),) self.assertEqual(new_chip.tag_ids, OrderedSet([1, 2, 3, 4, 5, 6, 7])) self.assertTrue(new_chip.is_processor_with_id(3)) - self.assertEqual(5, new_chip.get_processor_with_id(5).processor_id) - self.assertIsNone(new_chip.get_processor_with_id(-1)) def test_get_first_none_monitor_processor(self): """ test the get_first_none_monitor_processor @@ -72,8 +71,9 @@ def test_get_first_none_monitor_processor(self): """ new_chip = self._create_chip(self._x, self._y, self.n_processors, self._router, self._sdram, self._ip) - non_monitor = new_chip.get_first_none_monitor_processor() - self.assertFalse(non_monitor.is_monitor) + non_monitor = new_chip.get_first_none_monitor_processor_id() + self.assertEqual(non_monitor, + MachineDataView.get_machine_version().n_scamp_cores) def test_0_down(self): # Chip where 0 the monitor is down diff --git a/unittests/test_json_machine.py b/unittests/test_json_machine.py index 0b140ec5..65a5a06a 100644 --- a/unittests/test_json_machine.py +++ b/unittests/test_json_machine.py @@ -63,11 +63,8 @@ def test_monitor_exceptions(self): MachineDataWriter.mock().set_machine(vm) chip02 = vm[0, 2] # Hack in an extra monitor - users = dict(chip02._placable_processors) - monitors = dict(chip02._scamp_processors) - monitors[1] = users.pop(1) - chip02._scamp_processors = monitors - chip02._placable_processors = users + chip02._scamp_processors = tuple([0, 1]) + chip02._placable_processors = tuple([2, 3, 4, 5, 6, 7, 8, 9]) jpath = mktemp("json") # Should still be able to write json even with more than one monitor to_json_path(jpath) diff --git a/unittests/test_machine.py b/unittests/test_machine.py index c14ff40d..42679a44 100644 --- a/unittests/test_machine.py +++ b/unittests/test_machine.py @@ -378,8 +378,7 @@ def test_too_few_cores(self): machine = virtual_machine(8, 8) # Hack to get n_processors return a low number chip01 = machine.get_chip_at(0, 1) - chip01._placable_processors = dict( - list(chip01._placable_processors.items())[:2]) + chip01._placable_processors = tuple([1, 2]) with self.assertRaises(SpinnMachineException): machine.validate() From a1beaa911bf9d4b7344985c506e11c4b9c3d2d0b Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 09:50:47 +0000 Subject: [PATCH 22/31] fix typing for 3.8 --- spinn_machine/chip.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index e4a19f2a..2ed9bcbf 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -11,8 +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 ( - Collection, Dict, Iterable, Iterator, Optional) +from typing import (Collection, Iterable, Iterator, Optional, Tuple) from spinn_utilities.ordered_set import OrderedSet from spinn_utilities.typing.coords import XY @@ -107,7 +106,7 @@ def __init__(self, x: int, y: int, n_processors: int, router: Router, def __generate_processors( self, n_processors: int, - down_cores: Optional[Collection[int]]) -> tuple[int]: + down_cores: Optional[Collection[int]]) -> Tuple[int]: n_monitors = MachineDataView.get_machine_version().n_scamp_cores if down_cores is None: return tuple(range(n_monitors, n_processors)) @@ -173,7 +172,7 @@ def n_processors(self) -> int: return len(self._scamp_processors) + len(self._placable_processors) @property - def placable_processors_ids(self) -> tuple[int]: + def placable_processors_ids(self) -> Tuple[int]: """ An iterable of available placable/ non scamp processor ids. @@ -191,7 +190,7 @@ def n_placable_processors(self) -> int: return len(self._placable_processors) @property - def scamp_processors_ids(self) -> tuple[int]: + def scamp_processors_ids(self) -> Tuple[int]: """ An iterable of available scamp processors. From 72490c74c7cb83b15ae88eca4797d83e0a0526c1 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 09:55:59 +0000 Subject: [PATCH 23/31] remove chip.get_first_none_monitor_processor( --- spinn_machine/chip.py | 9 --------- unittests/test_chip.py | 11 ----------- 2 files changed, 20 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index 2ed9bcbf..f94f95c1 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -262,15 +262,6 @@ def tag_ids(self) -> Iterable[int]: """ return self._tag_ids - def get_first_none_monitor_processor_id(self) -> int: - """ - Get the first processor in the list which is not a monitor core. - - :rtype: int - ;raises IndexError: If there is no user processors - """ - return self._placable_processors[0] - @property def parent_link(self) -> Optional[int]: """ diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 94341e92..99fb7def 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -64,17 +64,6 @@ def test_create_chip(self): self.assertEqual(new_chip.tag_ids, OrderedSet([1, 2, 3, 4, 5, 6, 7])) self.assertTrue(new_chip.is_processor_with_id(3)) - def test_get_first_none_monitor_processor(self): - """ test the get_first_none_monitor_processor - - NOTE: Not sure if method being tested is required. - """ - new_chip = self._create_chip(self._x, self._y, self.n_processors, - self._router, self._sdram, self._ip) - non_monitor = new_chip.get_first_none_monitor_processor_id() - self.assertEqual(non_monitor, - MachineDataView.get_machine_version().n_scamp_cores) - def test_0_down(self): # Chip where 0 the monitor is down with self.assertRaises(NotImplementedError): From 93d9f68c4af1dfcb2d483e6092643ef76aad55ef Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 14:35:34 +0000 Subject: [PATCH 24/31] remove Processor class. info moved to Version --- spinn_machine/__init__.py | 1 - spinn_machine/processor.py | 140 ---------------------- spinn_machine/version/abstract_version.py | 18 +++ spinn_machine/version/version_spin1.py | 11 ++ unittests/test_processor.py | 53 -------- unittests/version/test_version3.py | 5 + unittests/version/test_version5.py | 5 + 7 files changed, 39 insertions(+), 194 deletions(-) delete mode 100644 spinn_machine/processor.py delete mode 100644 unittests/test_processor.py diff --git a/spinn_machine/__init__.py b/spinn_machine/__init__.py index a0d534ad..f4eb48f2 100644 --- a/spinn_machine/__init__.py +++ b/spinn_machine/__init__.py @@ -83,7 +83,6 @@ from .link import Link from .machine import Machine from .multicast_routing_entry import MulticastRoutingEntry -from .processor import Processor from .router import Router from .spinnaker_triad_geometry import SpiNNakerTriadGeometry from .virtual_machine import virtual_machine diff --git a/spinn_machine/processor.py b/spinn_machine/processor.py deleted file mode 100644 index 0cea7104..00000000 --- a/spinn_machine/processor.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright (c) 2014 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. -from typing import Dict -from .exceptions import SpinnMachineInvalidParameterException - -non_monitor: Dict[int, 'Processor'] = dict() -monitor: Dict[int, 'Processor'] = dict() - - -class Processor(object): - """ - A processor object included in a SpiNNaker chip. - """ - - CLOCK_SPEED = 200 * 1000 * 1000 - DTCM_AVAILABLE = 2 ** 16 - - __slots__ = ( - "_processor_id", "_clock_speed", "_is_monitor", "_dtcm_available" - ) - - def __init__(self, processor_id: int, - clock_speed: int = CLOCK_SPEED, - is_monitor: bool = False, - dtcm_available: int = DTCM_AVAILABLE): - """ - :param int processor_id: - ID of the processor in the chip - :param int clock_speed: - The number of CPU cycles per second of the processor - :param bool is_monitor: - Determines if the processor is considered the - monitor processor, and so should not be otherwise allocated - :param int dtcm_available: - Data Tightly Coupled Memory available - :raise spinn_machine.exceptions.SpinnMachineInvalidParameterException: - If the clock speed is negative - """ - - if clock_speed < 0: - raise SpinnMachineInvalidParameterException( - "clock_speed", str(clock_speed), - "Clock speed cannot be less than 0") - - self._processor_id = processor_id - self._clock_speed = clock_speed - self._is_monitor = is_monitor - self._dtcm_available = dtcm_available - - @property - def processor_id(self) -> int: - """ - The ID of the processor. - - :rtype: int - """ - return self._processor_id - - @property - def dtcm_available(self) -> int: - """ - The amount of DTCM available on this processor. - - :rtype: int - """ - return self._dtcm_available - - @property - def cpu_cycles_available(self) -> int: - """ - The number of CPU cycles available from this processor per ms. - - :rtype: int - """ - return self._clock_speed // 1000 - - @property - def clock_speed(self) -> int: - """ - The clock speed of the processor in cycles per second. - - :rtype: int - """ - return self._clock_speed - - @property - def is_monitor(self) -> bool: - """ - Determines if the processor is the monitor, and therefore not - to be allocated. - - .. warning:: - Currently rejection processors are also marked as monitors. - - :rtype: bool - """ - return self._is_monitor - - def __str__(self) -> str: - return ( - f"[CPU: id={self._processor_id}, " - f"clock_speed={self._clock_speed // 1000000} MHz, " - f"monitor={self._is_monitor}]") - - def __repr__(self) -> str: - return self.__str__() - - @staticmethod - def factory(processor_id: int, is_monitor: bool = False) -> 'Processor': - """ - Retrieves or creates a Processor with this id and monitor setting - - To keep the memory usage down this class keeps a cache of - Processor objects and reuses these as much as possible. - - :param int processor_id: - :param bool is_monitor: - :rtype: Processor - """ - if is_monitor: - if processor_id not in monitor: - monitor[processor_id] = Processor( - processor_id, is_monitor=is_monitor) - return monitor[processor_id] - else: - if processor_id not in non_monitor: - non_monitor[processor_id] = Processor( - processor_id, is_monitor=is_monitor) - return non_monitor[processor_id] diff --git a/spinn_machine/version/abstract_version.py b/spinn_machine/version/abstract_version.py index b50593c6..0c69aea8 100644 --- a/spinn_machine/version/abstract_version.py +++ b/spinn_machine/version/abstract_version.py @@ -212,6 +212,24 @@ def chip_core_map(self) -> Mapping[XY, int]: """ raise NotImplementedError + @property + @abstractmethod + def clock_speed_hz(self) -> int: + """ + The processor clock speed in Hz + + :rtype: int + """ + + @property + @abstractmethod + def dtch_bytes(self) -> int: + """ + The dth available on a processor in bytes + + :rtype: int + """ + @abstractmethod def get_potential_ethernet_chips( self, width: int, height: int) -> Sequence[XY]: diff --git a/spinn_machine/version/version_spin1.py b/spinn_machine/version/version_spin1.py index 2d4520c6..b7ccf9cf 100644 --- a/spinn_machine/version/version_spin1.py +++ b/spinn_machine/version/version_spin1.py @@ -42,3 +42,14 @@ def n_router_entries(self) -> int: @overrides(AbstractVersion.minimum_cores_expected) def minimum_cores_expected(self) -> int: return 5 + + @property + @overrides(AbstractVersion.clock_speed_hz) + def clock_speed_hz(self) -> int: + return 200 + + @property + @overrides(AbstractVersion.dtch_bytes) + def dtch_bytes(self) -> int: + return 2 ** 16 + diff --git a/unittests/test_processor.py b/unittests/test_processor.py deleted file mode 100644 index 5421a966..00000000 --- a/unittests/test_processor.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2014 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. - -import unittest -from spinn_machine import Processor -from spinn_machine.config_setup import unittest_setup - - -class TestingProcessor(unittest.TestCase): - - def setUp(self): - unittest_setup() - - def test_creating_processors(self): - processors = list() - flops = 1000 - for i in range(18): - processors.append(Processor(i, flops)) - - for _id in range(18): - self.assertEqual(processors[_id].processor_id, _id) - self.assertEqual(processors[_id].clock_speed, flops) - self.assertFalse(processors[_id].is_monitor) - - def test_creating_monitor_processors(self): - processors = list() - flops = 1000 - for i in range(18): - processors.append(Processor(i, flops, is_monitor=True)) - - for _id in range(18): - self.assertEqual(processors[_id].processor_id, _id) - self.assertEqual(processors[_id].clock_speed, flops) - self.assertTrue(processors[_id].is_monitor) - - def test_creating_processors_with_negative_clock_speed(self): - with self.assertRaises(Exception): - Processor(processor_id=1, clock_speed=-5) - - -if __name__ == '__main__': - unittest.main() diff --git a/unittests/version/test_version3.py b/unittests/version/test_version3.py index 8c7779ef..3a5df54b 100644 --- a/unittests/version/test_version3.py +++ b/unittests/version/test_version3.py @@ -135,6 +135,11 @@ def test_create_machin(self): machine = version.create_machine(width=2, height=2) self.assertIsInstance(machine, FullWrapMachine) + def test_processor_info(self): + version = Version3() + self.assertEqual(200, version.clock_speed_hz) + self.assertEqual(65536, version.dtch_bytes) + if __name__ == '__main__': unittest.main() diff --git a/unittests/version/test_version5.py b/unittests/version/test_version5.py index 3ca9d741..16149d40 100644 --- a/unittests/version/test_version5.py +++ b/unittests/version/test_version5.py @@ -145,6 +145,11 @@ def test_create_machin(self): machine = version.create_machine(12, 12) self.assertIsInstance(machine, FullWrapMachine) + def test_processor_info(self): + version = Version5() + self.assertEqual(200, version.clock_speed_hz) + self.assertEqual(65536, version.dtch_bytes) + if __name__ == '__main__': unittest.main() From a108ce22920be1e8ef62cb765b787ade3b7dd637 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 15:08:32 +0000 Subject: [PATCH 25/31] a chip is also an (x,y) --- spinn_machine/machine.py | 12 +++++------- spinn_machine/machine_factory.py | 8 ++++---- unittests/test_chip.py | 1 + 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/spinn_machine/machine.py b/spinn_machine/machine.py index 09b9ffbf..35a72090 100644 --- a/spinn_machine/machine.py +++ b/spinn_machine/machine.py @@ -581,7 +581,7 @@ def add_chip(self, chip: Chip): if chip.ip_address is not None: self._ethernet_connected_chips.append(chip) - if (chip.x == 0) and (chip.y == 0): + if (chip == (0, 0)): self._boot_ethernet_address = chip.ip_address def add_chips(self, chips: Iterable[Chip]): @@ -903,8 +903,7 @@ def add_fpga_links(self) -> None: # # handle the first chip - ex = ethernet_connected_chip.x - ey = ethernet_connected_chip.y + (ex, ey) = ethernet_connected_chip ip = ethernet_connected_chip.ip_address assert ip is not None @@ -1152,7 +1151,7 @@ def unreachable_outgoing_local_chips(self) -> List[XY]: for chip in self._chips.values(): # If no links out of the chip work, remove it moves = [(1, 0), (1, 1), (0, 1), (-1, 0), (-1, -1), (0, -1)] - x, y = chip.x, chip.y + x, y = chip nearest_ethernet_x = chip.nearest_ethernet_x nearest_ethernet_y = chip.nearest_ethernet_y for link, (x_move, y_move) in enumerate(moves): @@ -1182,7 +1181,7 @@ def unreachable_incoming_local_chips(self) -> List[XY]: """ removable_coords: List[XY] = list() for chip in self._chips.values(): - x, y = chip.x, chip.y + x, y = chip nearest_ethernet_x = chip.nearest_ethernet_x nearest_ethernet_y = chip.nearest_ethernet_y # Go through all the chips that surround this one @@ -1289,8 +1288,7 @@ def get_unused_xy(self) -> XY: # get a set of xys that could be connected to any existing Ethernet xys_by_ethernet: Set[XY] = set() for ethernet in self.ethernet_connected_chips: - xys_by_ethernet.update( - self.get_xys_by_ethernet(ethernet.x, ethernet.y)) + xys_by_ethernet.update(self.get_xys_by_ethernet(ethernet)) x = 0 while (True): for y in range(self.height): diff --git a/spinn_machine/machine_factory.py b/spinn_machine/machine_factory.py index ff016d99..e603d985 100644 --- a/spinn_machine/machine_factory.py +++ b/spinn_machine/machine_factory.py @@ -57,12 +57,12 @@ def _machine_ignore( for x, y, d, _ in dead_links: links_map[(x, y)].add(d) for chip in original.chips: - if (chip.x, chip.y) in dead_chips: + if chip in dead_chips: continue - if (chip.x, chip.y) in links_map: + if chip in links_map: links = [] for link in chip.router.links: - if link.source_link_id not in links_map[(chip.x, chip.y)]: + if link.source_link_id not in links_map[chip]: links.append(link) router = Router(links, chip.router.n_available_multicast_entries) chip = Chip( @@ -201,7 +201,7 @@ def machine_repair(original: Machine, removed_chips: Iterable[XY] = ()): f"Please report this to " \ f"spinnakerusers@googlegroups.com \n\n" if repair_machine: - dead_chips.add((chip.x, chip.y)) + dead_chips.add(chip) logger.warning(msg) else: logger.error(msg) diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 99fb7def..0cfcc404 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -49,6 +49,7 @@ def test_create_chip(self): new_chip = self._create_chip(self._x, self._y, self.n_processors, self._router, self._sdram, self._ip) + self.assertEqual(new_chip, (self._x, self._y)) self.assertEqual(new_chip.x, self._x) self.assertEqual(new_chip.y, self._y) self.assertEqual(new_chip.ip_address, self._ip) From 6b6349ee26f181e421575e9d48ffe8e160582eec Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 15:16:59 +0000 Subject: [PATCH 26/31] use x and y --- spinn_machine/machine.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spinn_machine/machine.py b/spinn_machine/machine.py index 35a72090..1e496504 100644 --- a/spinn_machine/machine.py +++ b/spinn_machine/machine.py @@ -1287,8 +1287,9 @@ def get_unused_xy(self) -> XY: """ # get a set of xys that could be connected to any existing Ethernet xys_by_ethernet: Set[XY] = set() - for ethernet in self.ethernet_connected_chips: - xys_by_ethernet.update(self.get_xys_by_ethernet(ethernet)) + for ethernet_x, ethernet_y in self.ethernet_connected_chips: + xys_by_ethernet.update(self.get_xys_by_ethernet( + ethernet_x, ethernet_y)) x = 0 while (True): for y in range(self.height): From 9a443de6f808ea617789087902c226a489efa784 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 15:22:29 +0000 Subject: [PATCH 27/31] flake8 --- spinn_machine/version/version_spin1.py | 1 - 1 file changed, 1 deletion(-) diff --git a/spinn_machine/version/version_spin1.py b/spinn_machine/version/version_spin1.py index b7ccf9cf..34c51059 100644 --- a/spinn_machine/version/version_spin1.py +++ b/spinn_machine/version/version_spin1.py @@ -52,4 +52,3 @@ def clock_speed_hz(self) -> int: @overrides(AbstractVersion.dtch_bytes) def dtch_bytes(self) -> int: return 2 ** 16 - From e8a06cf74ed5fde52f479736aab2b81a26eebe32 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 15:26:55 +0000 Subject: [PATCH 28/31] remove unsused import --- unittests/test_chip.py | 1 - 1 file changed, 1 deletion(-) diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 0cfcc404..e7d73cb8 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -17,7 +17,6 @@ from spinn_utilities.ordered_set import OrderedSet from spinn_machine import Link, Router, Chip from spinn_machine.config_setup import unittest_setup -from spinn_machine.data import MachineDataView class TestingChip(unittest.TestCase): From e564c676c9580fc997d8f8a9df4f709f472a589b Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 15:35:18 +0000 Subject: [PATCH 29/31] dtcm --- spinn_machine/version/abstract_version.py | 4 ++-- spinn_machine/version/version_spin1.py | 4 ++-- unittests/version/test_version3.py | 2 +- unittests/version/test_version5.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spinn_machine/version/abstract_version.py b/spinn_machine/version/abstract_version.py index 0c69aea8..c289fb65 100644 --- a/spinn_machine/version/abstract_version.py +++ b/spinn_machine/version/abstract_version.py @@ -223,9 +223,9 @@ def clock_speed_hz(self) -> int: @property @abstractmethod - def dtch_bytes(self) -> int: + def dtcm_bytes(self) -> int: """ - The dth available on a processor in bytes + The Data Tightly Coupled Memory available on a processor in bytes :rtype: int """ diff --git a/spinn_machine/version/version_spin1.py b/spinn_machine/version/version_spin1.py index 34c51059..24a20b47 100644 --- a/spinn_machine/version/version_spin1.py +++ b/spinn_machine/version/version_spin1.py @@ -49,6 +49,6 @@ def clock_speed_hz(self) -> int: return 200 @property - @overrides(AbstractVersion.dtch_bytes) - def dtch_bytes(self) -> int: + @overrides(AbstractVersion.dtcm_bytes) + def dtcm_bytes(self) -> int: return 2 ** 16 diff --git a/unittests/version/test_version3.py b/unittests/version/test_version3.py index 3a5df54b..5d5795ed 100644 --- a/unittests/version/test_version3.py +++ b/unittests/version/test_version3.py @@ -138,7 +138,7 @@ def test_create_machin(self): def test_processor_info(self): version = Version3() self.assertEqual(200, version.clock_speed_hz) - self.assertEqual(65536, version.dtch_bytes) + self.assertEqual(65536, version.dtcm_bytes) if __name__ == '__main__': diff --git a/unittests/version/test_version5.py b/unittests/version/test_version5.py index 16149d40..a4ec4387 100644 --- a/unittests/version/test_version5.py +++ b/unittests/version/test_version5.py @@ -148,7 +148,7 @@ def test_create_machin(self): def test_processor_info(self): version = Version5() self.assertEqual(200, version.clock_speed_hz) - self.assertEqual(65536, version.dtch_bytes) + self.assertEqual(65536, version.dtcm_bytes) if __name__ == '__main__': From 2a08943c0bd7dbb965b39cf6b50c8c767a6f6539 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 15:35:36 +0000 Subject: [PATCH 30/31] remove Processor --- spinn_machine/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spinn_machine/__init__.py b/spinn_machine/__init__.py index f4eb48f2..57c9644d 100644 --- a/spinn_machine/__init__.py +++ b/spinn_machine/__init__.py @@ -91,5 +91,4 @@ __all__ = ["Chip", "CoreSubset", "CoreSubsets", "FixedRouteEntry", "FrozenCoreSubsets", "Link", "Machine", "MulticastRoutingEntry", - "Processor", "Router", "SpiNNakerTriadGeometry", - "virtual_machine"] + "Router", "SpiNNakerTriadGeometry", "virtual_machine"] From 5cc17e8f221e276a743bd2388e1c96b68018761c Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Tue, 12 Mar 2024 15:43:35 +0000 Subject: [PATCH 31/31] mypy fixes --- spinn_machine/chip.py | 16 +++++----------- spinn_machine/version/abstract_version.py | 2 ++ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index f94f95c1..3a1779fd 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -19,12 +19,6 @@ from spinn_machine.data import MachineDataView from .router import Router -# global values so Chip objects can share processor dict objects -# One dict for each number of processors (none dead) -standard_processors = {} -# One dict for the standard monitor processors -standard_scamp_processors = None # pylint: disable=invalid-name - class Chip(XY): """ @@ -86,8 +80,8 @@ def __init__(self, x: int, y: int, n_processors: int, router: Router, ``processor_id`` """ # X and Y set by new - self._scamp_processors = range( - MachineDataView.get_machine_version().n_scamp_cores) + self._scamp_processors = tuple(range( + MachineDataView.get_machine_version().n_scamp_cores)) self._placable_processors = self.__generate_processors( n_processors, down_cores) self._router = router @@ -106,7 +100,7 @@ def __init__(self, x: int, y: int, n_processors: int, router: Router, def __generate_processors( self, n_processors: int, - down_cores: Optional[Collection[int]]) -> Tuple[int]: + down_cores: Optional[Collection[int]]) -> Tuple[int, ...]: n_monitors = MachineDataView.get_machine_version().n_scamp_cores if down_cores is None: return tuple(range(n_monitors, n_processors)) @@ -172,7 +166,7 @@ def n_processors(self) -> int: return len(self._scamp_processors) + len(self._placable_processors) @property - def placable_processors_ids(self) -> Tuple[int]: + def placable_processors_ids(self) -> Tuple[int, ...]: """ An iterable of available placable/ non scamp processor ids. @@ -190,7 +184,7 @@ def n_placable_processors(self) -> int: return len(self._placable_processors) @property - def scamp_processors_ids(self) -> Tuple[int]: + def scamp_processors_ids(self) -> Tuple[int, ...]: """ An iterable of available scamp processors. diff --git a/spinn_machine/version/abstract_version.py b/spinn_machine/version/abstract_version.py index c289fb65..c437c48a 100644 --- a/spinn_machine/version/abstract_version.py +++ b/spinn_machine/version/abstract_version.py @@ -220,6 +220,7 @@ def clock_speed_hz(self) -> int: :rtype: int """ + raise NotImplementedError @property @abstractmethod @@ -229,6 +230,7 @@ def dtcm_bytes(self) -> int: :rtype: int """ + raise NotImplementedError @abstractmethod def get_potential_ethernet_chips(