diff --git a/spinn_machine/__init__.py b/spinn_machine/__init__.py index a0d534ad..57c9644d 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 @@ -92,5 +91,4 @@ __all__ = ["Chip", "CoreSubset", "CoreSubsets", "FixedRouteEntry", "FrozenCoreSubsets", "Link", "Machine", "MulticastRoutingEntry", - "Processor", "Router", "SpiNNakerTriadGeometry", - "virtual_machine"] + "Router", "SpiNNakerTriadGeometry", "virtual_machine"] diff --git a/spinn_machine/chip.py b/spinn_machine/chip.py index ea899b8d..3a1779fd 100644 --- a/spinn_machine/chip.py +++ b/spinn_machine/chip.py @@ -11,42 +11,35 @@ # 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 typing import (Collection, Iterable, Iterator, Optional, Tuple) + 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 -# 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_monitor_processors = None # pylint: disable=invalid-name - -class Chip(object): +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 _IPTAG_IDS = OrderedSet(range(1, 8)) - __slots__ = ( - "_x", "_y", "_router", "_sdram", "_ip_address", - "_tag_ids", "_nearest_ethernet_x", "_nearest_ethernet_y", - "_user_processors", "_monitor_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 + # 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, @@ -86,10 +79,10 @@ 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 - self._monitor_processors = self.__generate_monitors() - self._user_processors = self.__generate_processors( + # X and Y set by new + 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 self._sdram = sdram @@ -105,41 +98,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_monitors(self): - """ - Generates the monitors assuming all Chips have the same monitor cores - - :return: Dict[int, Processor] - """ - global standard_monitor_processors # pylint: disable=global-statement - if standard_monitor_processors is None: - standard_monitor_processors = dict() - for i in range( - MachineDataView.get_machine_version().n_non_user_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 + 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: """ @@ -150,24 +124,9 @@ 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._monitor_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._user_processors: - return self._user_processors[processor_id] - return self._monitor_processors.get(processor_id) + return processor_id in self._scamp_processors @property def x(self) -> int: @@ -176,7 +135,7 @@ def x(self) -> int: :rtype: int """ - return self._x + return self[0] @property def y(self) -> int: @@ -185,27 +144,7 @@ def y(self) -> int: :rtype: 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() + return self[1] @property def all_processor_ids(self) -> Iterator[int]: @@ -214,8 +153,8 @@ def all_processor_ids(self) -> Iterator[int]: :rtype: iterable(int) """ - yield from self._monitor_processors.keys() - yield from self._user_processors.keys() + yield from self._scamp_processors + yield from self._placable_processors @property def n_processors(self) -> int: @@ -224,61 +163,43 @@ def n_processors(self) -> int: :rtype: int """ - return len(self._monitor_processors) + len(self._user_processors) + return len(self._scamp_processors) + len(self._placable_processors) @property - def user_processors(self) -> Iterator[Processor]: + def placable_processors_ids(self) -> Tuple[int, ...]: """ - An iterable of available user processors. + An iterable of available placable/ non scamp processor ids. - :rtype: iterable(Processor) - """ - yield from self._user_processors.values() - - @property - def user_processors_ids(self) -> Iterator[int]: - """ - An iterable of available user processors. - - :rtype: iterable(Processor) + :rtype: iterable(int) """ - yield from self._user_processors + return self._placable_processors @property - def n_user_processors(self) -> int: + def n_placable_processors(self) -> int: """ - The total number of processors that are not monitors. + 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 monitor_processors(self) -> Iterator[Processor]: + def scamp_processors_ids(self) -> Tuple[int, ...]: """ - An iterable of available monitor processors. + An iterable of available scamp processors. - :rtype: iterable(Processor) - """ - return self._monitor_processors.values() - - @property - def monitor_processors_ids(self) -> Iterator[int]: - """ - An iterable of available user processors. - - :rtype: iterable(Processor) + :rtype: iterable(int) """ - yield from self._monitor_processors + return self._scamp_processors @property - def n_monitor_processors(self) -> int: + def n_scamp_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: @@ -335,15 +256,6 @@ def tag_ids(self) -> Iterable[int]: """ return self._tag_ids - def get_first_none_monitor_processor(self) -> Processor: - """ - Get the first processor in the list which is not a monitor core. - - :rtype: Processor - ;raises StopIteration: If there is no user processor - """ - return next(iter(self._user_processors.values())) - @property def parent_link(self) -> Optional[int]: """ @@ -380,57 +292,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)) - """ - 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} " 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/json_machine.py b/spinn_machine/json_machine.py index b230e362..8a3e8169 100644 --- a/spinn_machine/json_machine.py +++ b/spinn_machine/json_machine.py @@ -205,9 +205,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_user_processors) != ethernet.monitors: - exceptions["monitors"] = \ - chip.n_processors - chip.n_user_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: @@ -216,9 +215,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_user_processors) != standard.monitors: - exceptions["monitors"] = \ - chip.n_processors - chip.n_user_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: @@ -244,7 +242,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, @@ -256,7 +254,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..1e496504 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 @@ -582,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]): @@ -904,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 @@ -1084,7 +1082,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: @@ -1153,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): @@ -1183,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,9 +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.x, ethernet.y)) + 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): 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/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 7301c008..c437c48a 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 """ @@ -212,6 +212,26 @@ 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 + """ + raise NotImplementedError + + @property + @abstractmethod + def dtcm_bytes(self) -> int: + """ + The Data Tightly Coupled Memory available on a processor in bytes + + :rtype: int + """ + raise NotImplementedError + @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 a18e4f66..24a20b47 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 @@ -42,3 +42,13 @@ 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.dtcm_bytes) + def dtcm_bytes(self) -> int: + return 2 ** 16 diff --git a/unittests/test_chip.py b/unittests/test_chip.py index 1919d2aa..8a1ad102 100644 --- a/unittests/test_chip.py +++ b/unittests/test_chip.py @@ -49,55 +49,21 @@ 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) 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]) + self.assertEqual(new_chip.n_placable_processors, self.n_processors - 1) + self.assertEqual(new_chip.n_placable_processors, self.n_processors - 1) 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): - """ 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() - 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): # Chip where 0 the monitor is down @@ -114,17 +80,33 @@ 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) - 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) + users = set(new_chip.placable_processors_ids) + self.assertEqual(len(users), new_chip.n_placable_processors) + monitors = set(new_chip.scamp_processors_ids) self.assertEqual(users.union(monitors), all_p) - 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, 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__': diff --git a/unittests/test_json_machine.py b/unittests/test_json_machine.py index b423f87c..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._user_processors) - monitors = dict(chip02._monitor_processors) - monitors[1] = users.pop(1) - chip02._monitor_processors = monitors - chip02._user_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 0c0f842d..d5e7405e 100644 --- a/unittests/test_machine.py +++ b/unittests/test_machine.py @@ -338,18 +338,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" @@ -391,8 +379,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._user_processors = dict( - list(chip01._user_processors.items())[:2]) + chip01._placable_processors = tuple([1, 2]) with self.assertRaises(SpinnMachineException): machine.validate() 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/test_virtual_machine.py b/unittests/test_virtual_machine.py index 936b3324..ac405269 100644 --- a/unittests/test_virtual_machine.py +++ b/unittests/test_virtual_machine.py @@ -176,10 +176,10 @@ 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(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, _chip.n_placable_processors) + self.assertEqual(1, _chip.n_scamp_processors) + self.assertEqual(n_cpus - 1, len(list(_chip.placable_processors_ids))) + self.assertEqual(1, len(list(_chip.scamp_processors_ids))) count = sum(_chip.n_processors for _chip in vm.chips) self.assertEqual(count, 4 * n_cpus) diff --git a/unittests/version/test_version3.py b/unittests/version/test_version3.py index 4d529a1d..5d5795ed 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) @@ -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.dtcm_bytes) + if __name__ == '__main__': unittest.main() diff --git a/unittests/version/test_version5.py b/unittests/version/test_version5.py index f35aa164..a4ec4387 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) @@ -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.dtcm_bytes) + if __name__ == '__main__': unittest.main()