Source code for spinnman.processes.get_machine_process

import logging

from spinn_machine import Processor, Router, Chip, SDRAM, Machine, Link

from spinnman.constants import ROUTER_REGISTER_P2P_ADDRESS
from spinnman.exceptions import SpinnmanUnexpectedResponseCodeException
from spinnman.messages.scp.impl \
    import ReadMemory, ReadLink, GetChipInfo
from spinnman.model import P2PTable
from spinnman.model.enums import CPUState
from .abstract_multi_connection_process import AbstractMultiConnectionProcess
from .abstract_process import AbstractProcess

logger = logging.getLogger(__name__)


[docs]class GetMachineProcess(AbstractMultiConnectionProcess): """ A process for getting the machine details over a set of connections """ def __init__(self, connection_selector, ignore_chips, ignore_cores, ignore_links, max_core_id, max_sdram_size=None): AbstractMultiConnectionProcess.__init__(self, connection_selector) self._ignore_chips = ignore_chips if ignore_chips is not None else {} self._ignore_cores = ignore_cores if ignore_cores is not None else {} self._ignore_links = ignore_links if ignore_links is not None else {} self._max_core_id = max_core_id self._max_sdram_size = max_sdram_size self._p2p_column_data = list() # A dictionary of (x, y) -> ChipInfo self._chip_info = dict() def _make_chip(self, width, height, chip_info): """ Creates a chip from a ChipSummaryInfo structure :param chip_info: The ChipSummaryInfo structure to create the chip\ from :type chip_info: \ :py:class:`spinnman.model.ChipSummaryInfo` :return: The created chip :rtype: :py:class:`spinn_machine.Chip` """ # Create the processor list processors = list() max_core_id = chip_info.n_cores - 1 core_states = chip_info.core_states if self._max_core_id is not None and max_core_id > self._max_core_id: max_core_id = self._max_core_id for virtual_core_id in range(max_core_id + 1): # Add the core provided it is not to be ignored if ((chip_info.x, chip_info.y, virtual_core_id) not in self._ignore_cores): if virtual_core_id == 0: processors.append(Processor( virtual_core_id, is_monitor=True)) elif core_states[virtual_core_id] == CPUState.IDLE: processors.append(Processor(virtual_core_id)) else: logger.warn("Not using core {}, {}, {} in state {}".format( chip_info.x, chip_info.y, virtual_core_id, core_states[virtual_core_id])) # Create the router links = list() for link in chip_info.working_links: dest_x, dest_y = Machine.get_chip_over_link( chip_info.x, chip_info.y, link, width, height) if ((chip_info.x, chip_info.y, link) not in self._ignore_links and (dest_x, dest_y) not in self._ignore_chips and (dest_x, dest_y) in self._chip_info): opposite_link_id = (link + 3) % 6 links.append(Link( chip_info.x, chip_info.y, link, dest_x, dest_y, opposite_link_id, opposite_link_id)) router = Router( links=links, n_available_multicast_entries=( chip_info.n_free_multicast_routing_entries)) # Create the chip's SDRAM object sdram_size = chip_info.largest_free_sdram_block if (self._max_sdram_size is not None and sdram_size > self._max_sdram_size): sdram_size = self._max_sdram_size sdram = SDRAM(size=sdram_size) # Create the chip chip = Chip( x=chip_info.x, y=chip_info.y, processors=processors, router=router, sdram=sdram, ip_address=chip_info.ethernet_ip_address, nearest_ethernet_x=chip_info.nearest_ethernet_x, nearest_ethernet_y=chip_info.nearest_ethernet_y) return chip def _receive_p2p_data(self, scp_read_response): self._p2p_column_data.append( (scp_read_response.data, scp_read_response.offset)) def _receive_chip_info(self, scp_read_chip_info_response): chip_info = scp_read_chip_info_response.chip_info self._chip_info[chip_info.x, chip_info.y] = chip_info def _receive_error(self, request, exception, tb): # If we get an ReadLink with a # SpinnmanUnexpectedResponseCodeException, this is a failed link # and so can be ignored if isinstance(request, ReadLink): if isinstance(exception, SpinnmanUnexpectedResponseCodeException): return AbstractProcess._receive_error(self, request, exception, tb)
[docs] def get_machine_details(self, boot_x, boot_y, width, height): # Get the P2P table - 8 entries are packed into each 32-bit word p2p_column_bytes = P2PTable.get_n_column_bytes(height) for column in range(width): offset = P2PTable.get_column_offset(column) self._send_request( ReadMemory( x=boot_x, y=boot_y, base_address=(ROUTER_REGISTER_P2P_ADDRESS + offset), size=p2p_column_bytes), self._receive_p2p_data) self._finish() self.check_for_error() p2p_table = P2PTable(width, height, self._p2p_column_data) # Get the chip information for each chip for (x, y) in p2p_table.iterchips(): self._send_request( GetChipInfo(x, y), self._receive_chip_info) self._finish() try: self.check_for_error() except: # Ignore errors so far, as any error here just means that a chip # is down that wasn't marked as down pass # Warn about unexpected missing chips for (x, y) in p2p_table.iterchips(): if (x, y) not in self._chip_info: logger.warn("Chip {}, {} was expected but didn't reply".format( x, y)) # Build a Machine def chip_xy(chip): return chip.x, chip.y chips = [ self._make_chip(width, height, chip_info) for chip_info in sorted(self._chip_info.values(), key=chip_xy) if (chip_info.x, chip_info.y) not in self._ignore_chips] machine = Machine(chips, boot_x, boot_y) return machine
[docs] def get_chip_info(self): """ Get the chip information for the machine. Note that\ get_machine_details must have been called first """ return self._chip_info