Skip to content

Commit

Permalink
Merge branch 'reduce-op-complexity' into roc3
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian-B committed Sep 11, 2023
2 parents d8299d0 + 402610e commit 2d2d248
Show file tree
Hide file tree
Showing 21 changed files with 282 additions and 197 deletions.
10 changes: 5 additions & 5 deletions spinnman/extended/extended_transceiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,18 +543,18 @@ def write_neighbour_memory(
if isinstance(data, int):
data_to_write = _ONE_WORD.pack(data)
process.write_link_memory_from_bytearray(
x, y, cpu, link, base_address, data_to_write, 0, 4)
(x, y, cpu), link, base_address, data_to_write, 0, 4)
elif isinstance(data, (bytes, bytearray)):
if n_bytes is None:
n_bytes = len(data)
process.write_link_memory_from_bytearray(
x, y, cpu, link, base_address, data, offset, n_bytes)
(x, y, cpu), link, base_address, data, offset, n_bytes)
else:
if n_bytes is None:
raise ValueError(
"n_bytes must be provided when using a reader")
process.write_link_memory_from_reader(
x, y, cpu, link, base_address, data, n_bytes)
(x, y, cpu), link, base_address, data, n_bytes)

def read_neighbour_memory(
self, x: int, y: int, link: int, base_address: int, length: int, *,
Expand Down Expand Up @@ -597,7 +597,7 @@ def read_neighbour_memory(
"and untested due to no known use.")
process = ReadMemoryProcess(self._scamp_connection_selector)
return process.read_link_memory(
x, y, cpu, link, base_address, length)
(x, y, cpu), link, base_address, length)
except Exception:
logger.info(self._where_is_xy(x, y))
raise
Expand Down Expand Up @@ -787,7 +787,7 @@ def get_router_diagnostic_filter(
ROUTER_REGISTER_BASE_ADDRESS + ROUTER_FILTER_CONTROLS_OFFSET +
position * ROUTER_DIAGNOSTIC_FILTER_SIZE)

response = self._call(ReadMemory(x, y, 0, memory_position, 4))
response = self._call(ReadMemory((x, y, 0), memory_position, 4))
return DiagnosticFilter.read_from_int(_ONE_WORD.unpack_from(
response.data, response.offset)[0])
except Exception:
Expand Down
4 changes: 2 additions & 2 deletions spinnman/messages/eieio/data_messages/eieio_data_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ def from_bytestring(data: bytes, offset: int) -> 'EIEIODataHeader':

# Convert the flags into types
# pylint: disable=no-value-for-parameter
eieio_type = EIEIOType[message_type]
prefix_type = EIEIOPrefix[format_flag]
eieio_type = EIEIOType(message_type)
prefix_type = EIEIOPrefix(format_flag)

prefix = None
payload_prefix = None
Expand Down
20 changes: 14 additions & 6 deletions spinnman/messages/eieio/eieio_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,24 @@ class EIEIOType(Enum):
Possible types of EIEIO packets.
"""
#: Indicates that data is keys which are 16 bits.
KEY_16_BIT = cast('EIEIOType', (0, 2, 0))
KEY_16_BIT = (0, 2, 0)
#: Indicates that data is keys and payloads of 16 bits.
KEY_PAYLOAD_16_BIT = cast('EIEIOType', (1, 2, 2))
KEY_PAYLOAD_16_BIT = (1, 2, 2)
#: Indicates that data is keys of 32 bits.
KEY_32_BIT = cast('EIEIOType', (2, 4, 0))
KEY_32_BIT = (2, 4, 0)
#: Indicates that data is keys and payloads of 32 bits.
KEY_PAYLOAD_32_BIT = cast('EIEIOType', (3, 4, 4))
KEY_PAYLOAD_32_BIT = (3, 4, 4)

def __init__(self, value, key_bytes: int, payload_bytes: int):
self._value_ = value
def __new__(cls, *args) -> 'EIEIOType':
obj = object.__new__(cls)
obj._value_ = args[0]
return obj

def __init__(self, encoded_value: int,
# Optionals just to make mypy SHUT UP!
# https://github.com/python/mypy/issues/10573
key_bytes: int = 0, payload_bytes: int = 0):
self._encoded_value = encoded_value
self._key_bytes = key_bytes
self._payload_bytes = payload_bytes

Expand Down
40 changes: 22 additions & 18 deletions spinnman/messages/scp/enums/signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.

from enum import Enum
from typing import cast


class SignalType(Enum):
Expand All @@ -29,27 +28,32 @@ class Signal(Enum):
"""
SCP Signals.
"""
INITIALISE: 'Signal' = cast('Signal', (0, SignalType.NEAREST_NEIGHBOUR))
POWER_DOWN: 'Signal' = cast('Signal', (1, SignalType.NEAREST_NEIGHBOUR))
STOP: 'Signal' = cast('Signal', (2, SignalType.NEAREST_NEIGHBOUR))
START: 'Signal' = cast('Signal', (3, SignalType.MULTICAST))
SYNC0: 'Signal' = cast('Signal', (4, SignalType.MULTICAST))
SYNC1: 'Signal' = cast('Signal', (5, SignalType.MULTICAST))
PAUSE: 'Signal' = cast('Signal', (6, SignalType.MULTICAST))
CONTINUE: 'Signal' = cast('Signal', (7, SignalType.MULTICAST))
EXIT: 'Signal' = cast('Signal', (8, SignalType.MULTICAST))
TIMER: 'Signal' = cast('Signal', (9, SignalType.MULTICAST))
USER_0: 'Signal' = cast('Signal', (10, SignalType.MULTICAST))
USER_1: 'Signal' = cast('Signal', (11, SignalType.MULTICAST))
USER_2: 'Signal' = cast('Signal', (12, SignalType.MULTICAST))
USER_3: 'Signal' = cast('Signal', (13, SignalType.MULTICAST))

def __init__(self, value, signal_type) -> None:
INITIALISE = (0, SignalType.NEAREST_NEIGHBOUR)
POWER_DOWN = (1, SignalType.NEAREST_NEIGHBOUR)
STOP = (2, SignalType.NEAREST_NEIGHBOUR)
START = (3, SignalType.MULTICAST)
SYNC0 = (4, SignalType.MULTICAST)
SYNC1 = (5, SignalType.MULTICAST)
PAUSE = (6, SignalType.MULTICAST)
CONTINUE = (7, SignalType.MULTICAST)
EXIT = (8, SignalType.MULTICAST)
TIMER = (9, SignalType.MULTICAST)
USER_0 = (10, SignalType.MULTICAST)
USER_1 = (11, SignalType.MULTICAST)
USER_2 = (12, SignalType.MULTICAST)
USER_3 = (13, SignalType.MULTICAST)

def __new__(cls, *args) -> 'Signal':
obj = object.__new__(cls)
obj._value_ = args[0]
return obj

def __init__(self, value: int, signal_type: SignalType) -> None:
"""
:param int value: The value used for the signal
:param SignalType signal_type: The "type" of the signal
"""
self._value_ = value
assert value >= 0
self._signal_type = signal_type

@property
Expand Down
16 changes: 7 additions & 9 deletions spinnman/messages/scp/impl/read_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

from spinn_utilities.overrides import overrides
from spinn_utilities.typing.coords import XYP
from spinnman.messages.scp import SCPRequestHeader
from spinnman.messages.scp.abstract_messages import AbstractSCPRequest
from spinnman.messages.scp.enums import SCPCommand
Expand All @@ -26,22 +27,19 @@ class ReadLink(AbstractSCPRequest[Response]):
"""
__slots__ = ()

def __init__(self, x: int, y: int, cpu: int, link: int, base_address: int,
size: int):
def __init__(self, coords: XYP, link: int, base_address: int, size: int):
"""
:param int x:
The x-coordinate of the chip to read from, between 0 and 255
:param int y:
The y-coordinate of the chip to read from, between 0 and 255
:param int cpu:
The CPU core to use, normally 0
(or if a BMP, the board slot number)
:param tuple(int,int,int) coords:
The coordinates of the core of the chip whose neighbour will be
read from; X and Y between 0 and 255,
CPU core normally 0 (or if a BMP then the board slot number)
:param int link: The ID of the link down which to send the query
:param int base_address:
The positive base address to start the read from
:param int size: The number of bytes to read, between 1 and 256
"""
# pylint: disable=too-many-arguments
x, y, cpu = coords
super().__init__(
SDPHeader(
flags=SDPFlag.REPLY_EXPECTED, destination_port=0,
Expand Down
12 changes: 6 additions & 6 deletions spinnman/messages/scp/impl/read_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

from spinn_utilities.overrides import overrides
from spinn_utilities.typing.coords import XYP
from spinnman.messages.scp import SCPRequestHeader
from spinnman.messages.scp.abstract_messages import (
AbstractSCPRequest, AbstractSCPResponse)
Expand Down Expand Up @@ -88,12 +89,11 @@ class ReadMemory(AbstractSCPRequest[Response]):
"""
__slots__ = ()

def __init__(self, x: int, y: int, cpu: int, base_address: int, size: int):
def __init__(self, coords: XYP, base_address: int, size: int):
"""
:param int x:
The x-coordinate of the chip to read from, between 0 and 255
:param int y:
The y-coordinate of the chip to read from, between 0 and 255
:param tuple coords:
The X,Y,P coordinates of the chip to read from;
X and Y between 0 and 255, P between 0 and 17
:param int base_address:
The positive base address to start the read from
:param int size: The number of bytes to read, between 1 and 256
Expand All @@ -102,7 +102,7 @@ def __init__(self, x: int, y: int, cpu: int, base_address: int, size: int):
* If the base address is not a positive number
* If the size is out of range
"""
# pylint: disable=too-many-arguments
x, y, cpu = coords
super().__init__(
SDPHeader(
flags=SDPFlag.REPLY_EXPECTED, destination_port=0,
Expand Down
15 changes: 7 additions & 8 deletions spinnman/messages/scp/impl/write_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

from spinn_utilities.overrides import overrides
from spinn_utilities.typing.coords import XYP
from spinnman.messages.scp import SCPRequestHeader
from spinnman.messages.scp.abstract_messages import AbstractSCPRequest
from spinnman.messages.scp.enums import SCPCommand
Expand All @@ -26,21 +27,19 @@ class WriteLink(AbstractSCPRequest[CheckOKResponse]):
"""
__slots__ = "_data_to_write",

def __init__(self, x: int, y: int, cpu: int, link: int, base_address: int,
data: bytes):
def __init__(self, coords: XYP, link: int, base_address: int, data: bytes):
"""
:param int x: The x-coordinate of the chip whose neighbour will be
written to, between 0 and 255
:param int y: The y-coordinate of the chip whose neighbour will be
written to, between 0 and 255
:param tuple(int,int,int) coords:
The coordinates of the core of the chip whose neighbour will be
written to; X and Y between 0 and 255,
CPU core normally 0 (or if a BMP then the board slot number)
:param int link: The link number to write to between 0 and 5
(or if a BMP, the FPGA between 0 and 2)
:param int base_address: The base_address to start writing to
:param bytes data: Up to 256 bytes of data to write
:param int cpu: The CPU core to use, normally 0
(or if a BMP, the board slot number)
"""
# pylint: disable=too-many-arguments
x, y, cpu = coords
super().__init__(
SDPHeader(
flags=SDPFlag.REPLY_EXPECTED, destination_port=0,
Expand Down
18 changes: 8 additions & 10 deletions spinnman/messages/scp/impl/write_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

from spinn_utilities.overrides import overrides
from spinn_utilities.typing.coords import XYP
from spinnman.constants import address_length_dtype
from spinnman.messages.scp import SCPRequestHeader
from spinnman.messages.scp.abstract_messages import AbstractSCPRequest
Expand All @@ -27,24 +28,21 @@ class WriteMemory(AbstractSCPRequest[CheckOKResponse]):
"""
__slots__ = "_data_to_write",

def __init__(
self, x: int, y: int, cpu: int, base_address: int, data: bytes):
def __init__(self, coords: XYP, base_address: int, data: bytes):
"""
:param int x: The x-coordinate of the chip, between 0 and 255;
this is not checked due to speed restrictions
:param int y: The y-coordinate of the chip, between 0 and 255;
this is not checked due to speed restrictions
:param int cpu:
The CPU core to use, normally 0 (only needed when writing ITCM or
DTCM)
:param tuple(int,int,int) coords:
The coordinates of the chip, X and Y between 0 and 255, and P
between 0 and 17 (normally 0 when writing to SDRAM; may be other
values when writing to ITCM or DTCM);
these are not checked due to speed restrictions
:param int base_address: The base_address to start writing to
the base address is not checked to see if its not valid
:param data: between 1 and 256 bytes of data to write;
this is not checked due to speed restrictions
:type data: bytearray or bytes
"""
# pylint: disable=too-many-arguments
size = len(data)
x, y, cpu = coords
super().__init__(
SDPHeader(
flags=SDPFlag.REPLY_EXPECTED, destination_port=0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ def __init__(self, value, struct_code):
self._struct_code = struct_code

@property
def struct_code(self):
def struct_code(self) -> str:
return self._struct_code

@property
def is_byte_array(self):
def is_byte_array(self) -> bool:
# can't use BYTE_ARRAY.value directly here
return self._value_ == 16

Expand Down
33 changes: 18 additions & 15 deletions spinnman/model/enums/executable_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.
from __future__ import annotations
from enum import Enum
from typing import FrozenSet, Sequence, cast
from typing import FrozenSet, Sequence
from spinnman.model.enums import CPUState


Expand All @@ -28,52 +28,55 @@ class ExecutableType(Enum):
supports_auto_pause_and_resume: bool

#: Runs immediately without waiting for barrier and then exits.
RUNNING: ExecutableType = cast("ExecutableType", (
RUNNING = (
0,
[CPUState.RUNNING],
[CPUState.FINISHED],
False,
"Runs immediately without waiting for barrier and then exits"))
"Runs immediately without waiting for barrier and then exits")
#: Calls ``spin1_start(SYNC_WAIT)`` and then eventually ``spin1_exit()``.
SYNC: ExecutableType = cast("ExecutableType", (
SYNC = (
1,
[CPUState.SYNC0],
[CPUState.FINISHED],
False,
"Calls spin1_start(SYNC_WAIT) and then eventually spin1_exit()"))
"Calls spin1_start(SYNC_WAIT) and then eventually spin1_exit()")
#: Calls ``simulation_run()`` and ``simulation_exit()`` /
#: ``simulation_handle_pause_resume()``.
USES_SIMULATION_INTERFACE: ExecutableType = cast("ExecutableType", (
USES_SIMULATION_INTERFACE = (
2,
[CPUState.SYNC0, CPUState.SYNC1, CPUState.PAUSED, CPUState.READY],
[CPUState.READY],
True,
"Calls simulation_run() and simulation_exit() / "
"simulation_handle_pause_resume()"))
"simulation_handle_pause_resume()")
#: Situation where there user has supplied no application but for some
#: reason still wants to run.
NO_APPLICATION: ExecutableType = cast("ExecutableType", (
NO_APPLICATION = (
3,
(),
(),
True,
"Situation where there user has supplied no application but for "
"some reason still wants to run"))
"some reason still wants to run")
#: Runs immediately without waiting for barrier and never ends.
SYSTEM: ExecutableType = cast("ExecutableType", (
SYSTEM = (
4,
[CPUState.RUNNING],
[CPUState.RUNNING],
True,
"Runs immediately without waiting for barrier and never ends"))
"Runs immediately without waiting for barrier and never ends")

def __new__(cls, *args) -> 'ExecutableType':
obj = object.__new__(cls)
obj._value_ = args[0]
obj. __doc__ = args[-1]
return obj

def __init__(self, value: int, start_state: Sequence[CPUState],
end_state: Sequence[CPUState],
supports_auto_pause_and_resume: bool, doc: str = ""):
# pylint: disable=too-many-arguments
self._value_ = value
self.__doc__ = doc
# pylint: disable=too-many-arguments, unused-argument
self.start_state: FrozenSet[CPUState] = frozenset(start_state)
self.end_state: FrozenSet[CPUState] = frozenset(end_state)
self.supports_auto_pause_and_resume = supports_auto_pause_and_resume
self.__doc__ = doc
2 changes: 1 addition & 1 deletion spinnman/processes/get_cpu_info_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def get_cpu_info(self, core_subsets: CoreSubsets) -> CPUInfos:
x, y = core_subset.x, core_subset.y
for p in core_subset.processor_ids:
self._send_request(
ReadMemory(x, y, 0, get_vcpu_address(p),
ReadMemory((x, y, 0), get_vcpu_address(p),
CPU_INFO_BYTES),
functools.partial(self.__handle_response, x, y, p))

Expand Down
Loading

0 comments on commit 2d2d248

Please sign in to comment.