Skip to content

Commit

Permalink
Abstract, BAse Version5 and Mockable Transceivers
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian-B committed Aug 2, 2023
1 parent e02a343 commit deea761
Show file tree
Hide file tree
Showing 14 changed files with 1,249 additions and 134 deletions.
10 changes: 5 additions & 5 deletions spinnman/data/spinnman_data_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from spinn_utilities.log import FormatAdapter
from spinn_utilities.overrides import overrides
from spinn_machine.data.machine_data_writer import MachineDataWriter
from spinnman.transceiver.transceiver import Transceiver
from spinnman.transceiver import AbstractTransceiver
from .spinnman_data_view import _SpiNNManDataModel, SpiNNManDataView

logger = FormatAdapter(logging.getLogger(__name__))
Expand Down Expand Up @@ -98,11 +98,11 @@ def set_transceiver(self, transceiver):
"""
Sets the transceiver object.
:param Transceiver transceiver:
:raises TypeError: If the transceiver is not a Transceiver
:param AbstractTransceiver transceiver:
:raises TypeError: If the transceiver is not a AbstractTransceiver
"""
if not isinstance(transceiver, Transceiver):
raise TypeError("transceiver should be a Transceiver")
if not isinstance(transceiver, AbstractTransceiver):
raise TypeError("transceiver should be a AbstractTransceiver")
if self.__data._transceiver:
raise NotImplementedError(
"Over writing and existing transceiver not supported")
Expand Down
70 changes: 7 additions & 63 deletions spinnman/extended/extended_transceiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,9 @@
from spinn_utilities.log import FormatAdapter
from spinn_utilities.logger_utils import warn_once
from spinn_machine import CoreSubsets
from spinnman.constants import SYSTEM_VARIABLE_BASE_ADDRESS
from spinnman.transceiver.transceiver import Transceiver
from spinnman.constants import (
ROUTER_REGISTER_BASE_ADDRESS, ROUTER_FILTER_CONTROLS_OFFSET,
ROUTER_DIAGNOSTIC_FILTER_SIZE)
from spinnman.data import SpiNNManDataView
from spinnman.exceptions import SpinnmanException
from spinnman.extended import (
BMPSetLed, DeAllocSDRAMProcess, ReadADC, SetLED, WriteMemoryFloodProcess)
Expand All @@ -42,8 +39,8 @@
from spinnman.processes import (
GetHeapProcess, ReadMemoryProcess, SendSingleCommandProcess,
WriteMemoryProcess)
from spinnman.transceiver.transceiver import (
_EXECUTABLE_ADDRESS, _ONE_BYTE, _ONE_WORD)
from spinnman.transceiver.version5Transceiver import Version5Transceiver
from spinnman.transceiver.watchdog_setter import WatchdogSetter
from spinnman.utilities.utility_functions import (
work_out_bmp_from_machine_details)

Expand Down Expand Up @@ -117,7 +114,7 @@ def create_transceiver_from_hostname(
return ExtendedTransceiver(version, connections=connections)


class ExtendedTransceiver(Transceiver):
class ExtendedTransceiver(Version5Transceiver, WatchdogSetter):
"""
An encapsulation of various communications with the SpiNNaker board.
Expand Down Expand Up @@ -215,59 +212,6 @@ def is_connected(self, connection=None):
return connection.is_connected()
return any(c.is_connected() for c in self._scamp_connections)

def __set_watch_dog_on_chip(self, x, y, watch_dog):
"""
Enable, disable or set the value of the watch dog timer on a
specific chip.
.. warning::
This method is currently deprecated and untested as there is no
known use. Same functionality provided by ybug and bmpc.
Retained in case needed for hardware debugging.
:param int x: chip X coordinate to write new watchdog parameter to
:param int y: chip Y coordinate to write new watchdog parameter to
:param watch_dog:
Either a boolean indicating whether to enable (True) or
disable (False) the watchdog timer, or an int value to set the
timer count to
:type watch_dog: bool or int
"""
# build what we expect it to be
warn_once(logger, "The set_watch_dog_on_chip method is deprecated "
"and untested due to no known use.")
value_to_set = watch_dog
watchdog = SystemVariableDefinition.software_watchdog_count
if isinstance(watch_dog, bool):
value_to_set = watchdog.default if watch_dog else 0

# build data holder
data = _ONE_BYTE.pack(value_to_set)

# write data
address = SYSTEM_VARIABLE_BASE_ADDRESS + watchdog.offset
self.write_memory(x=x, y=y, base_address=address, data=data)

def set_watch_dog(self, watch_dog):
"""
Enable, disable or set the value of the watch dog timer.
.. warning::
This method is currently deprecated and untested as there is no
known use. Same functionality provided by ybug and bmpc.
Retained in case needed for hardware debugging.
:param watch_dog:
Either a boolean indicating whether to enable (True) or
disable (False) the watch dog timer, or an int value to set the
timer count to.
:type watch_dog: bool or int
"""
warn_once(logger, "The set_watch_dog method is deprecated and "
"untested due to no known use.")
for x, y in SpiNNManDataView.get_machine().chip_coordinates:
self.__set_watch_dog_on_chip(x, y, watch_dog)

def get_iobuf_from_core(self, x, y, p):
"""
Get the contents of IOBUF for a given core.
Expand Down Expand Up @@ -383,7 +327,7 @@ def execute(
with self._chip_execute_lock(x, y):
# Write the executable
self.write_memory(
x, y, _EXECUTABLE_ADDRESS, executable, n_bytes,
x, y, self._EXECUTABLE_ADDRESS, executable, n_bytes,
is_filename=is_filename)

# Request the start of the executable
Expand Down Expand Up @@ -530,7 +474,7 @@ def write_neighbour_memory(self, x, y, link, base_address, data,
process.write_link_memory_from_reader(
x, y, cpu, link, base_address, data, n_bytes)
elif isinstance(data, int):
data_to_write = _ONE_WORD.pack(data)
data_to_write = self._ONE_WORD.pack(data)
process.write_link_memory_from_bytearray(
x, y, cpu, link, base_address, data_to_write, 0, 4)
else:
Expand Down Expand Up @@ -647,7 +591,7 @@ def write_memory_flood(
process.write_memory_from_reader(
nearest_neighbour_id, base_address, reader, n_bytes)
elif isinstance(data, int):
data_to_write = _ONE_WORD.pack(data)
data_to_write = self._ONE_WORD.pack(data)
process.write_memory_from_bytearray(
nearest_neighbour_id, base_address, data_to_write, 0)
else:
Expand Down Expand Up @@ -767,7 +711,7 @@ def get_router_diagnostic_filter(self, x, y, position):
process = SendSingleCommandProcess(
self._scamp_connection_selector)
response = process.execute(ReadMemory(x, y, memory_position, 4))
return DiagnosticFilter.read_from_int(_ONE_WORD.unpack_from(
return DiagnosticFilter.read_from_int(self._ONE_WORD.unpack_from(
response.data, response.offset)[0])
# pylint: disable=no-member
except Exception:
Expand Down
6 changes: 3 additions & 3 deletions spinnman/spalloc/spalloc_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from spinnman.constants import SCP_SCAMP_PORT, UDP_BOOT_CONNECTION_DEFAULT_PORT
from spinnman.exceptions import SpinnmanTimeoutException
from spinnman.exceptions import SpallocException
from spinnman.transceiver.transceiver import Transceiver
from spinnman.transceiver.version5Transceiver import Version5Transceiver
from .spalloc_state import SpallocState
from .proxy_protocol import ProxyProtocol
from .session import Session, SessionAware
Expand Down Expand Up @@ -635,14 +635,14 @@ def _keepalive_handle(self, handle):
self.__keepalive_handle = handle

@overrides(SpallocJob.create_transceiver)
def create_transceiver(self) -> Transceiver:
def create_transceiver(self) -> Version5Transceiver:
if self.get_state() != SpallocState.READY:
raise SpallocException("job not ready to execute scripts")
proxies = [
self.connect_to_board(x, y) for (x, y) in self.get_connections()]
# Also need a boot connection
proxies.append(self.connect_for_booting())
return Transceiver(version=5, connections=proxies)
return Version5Transceiver(version=5, connections=proxies)

def __repr__(self):
return f"SpallocJob({self._url})"
Expand Down
4 changes: 2 additions & 2 deletions spinnman/spalloc/spalloc_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from spinn_utilities.abstract_base import AbstractBase, abstractmethod
from spinn_utilities.abstract_context_manager import AbstractContextManager
from spinnman.constants import SCP_SCAMP_PORT
from spinnman.transceiver.transceiver import Transceiver
from spinnman.transceiver.version5Transceiver import Version5Transceiver
from spinnman.connections.udp_packet_connections import UDPConnection
from .spalloc_state import SpallocState
from .spalloc_boot_connection import SpallocBootConnection
Expand Down Expand Up @@ -121,7 +121,7 @@ def open_udp_listener_connection(self) -> UDPConnection:
"""

@abstractmethod
def create_transceiver(self) -> Transceiver:
def create_transceiver(self) -> Version5Transceiver:
"""
Create a transceiver that will talk to this job. The transceiver will
only be configured to talk to the SCP ports of the boards of the job.
Expand Down
8 changes: 5 additions & 3 deletions spinnman/transceiver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from spinnman.transceiver.transceiver_factory import (
create_transceiver_from_hostname)
from .abstract_transceiver import AbstractTransceiver
from .mockable_transceiver import MockableTransceiver
from .transceiver_factory import (create_transceiver_from_hostname)

__all__ = ["create_transceiver_from_hostname"]
__all__ = ["AbstractTransceiver", "create_transceiver_from_hostname",
"MockableTransceiver"]
Loading

0 comments on commit deea761

Please sign in to comment.