Source code for pacman.operations.chip_id_allocator_algorithms.malloc_based_chip_id_allocator

# pacman imports
from pacman import exceptions
from pacman.model.graphs import AbstractFPGAVertex, AbstractSpiNNakerLinkVertex
from pacman.model.graphs import AbstractVirtualVertex
from pacman.utilities.algorithm_utilities import machine_algorithm_utilities
from pacman.utilities.algorithm_utilities import ElementAllocatorAlgorithm
from spinn_utilities.progress_bar import ProgressBar

# general imports
import logging
import math
logger = logging.getLogger(__name__)


[docs]class MallocBasedChipIdAllocator(ElementAllocatorAlgorithm): """ A Chip id Allocation Allocator algorithm that keeps track of chip ids and attempts to allocate them as requested """ __slots__ = [ # dict of [spinnaker link data] = (x,y, link data) "_virtual_chips" ] def __init__(self): ElementAllocatorAlgorithm.__init__(self, 0, math.pow(2, 32)) # we only want one virtual chip per 'link' self._virtual_chips = dict() def __call__(self, machine, graph=None): if graph is not None: # Go through the groups and allocate keys progress_bar = ProgressBar( graph.n_vertices + machine.n_chips, "Allocating virtual identifiers") # allocate standard ids for real chips for x, y in machine.chip_coordinates: expected_chip_id = (x << 8) + y self._allocate_elements(expected_chip_id, 1) progress_bar.update() # allocate ids for virtual chips for vertex in graph.vertices: if isinstance(vertex, AbstractVirtualVertex): link_data = None if isinstance(vertex, AbstractFPGAVertex): link_data = machine.get_fpga_link_with_id( vertex.fpga_id, vertex.fpga_link_id, vertex.board_address) if link_data is None: raise exceptions.PacmanConfigurationException( "No FPGA Link {} on FPGA {} found on board " "{}. This would be true if another chip was " "found connected at this point".format( vertex.fpga_link_id, vertex.fpga_id, vertex.board_address)) elif isinstance(vertex, AbstractSpiNNakerLinkVertex): link_data = machine.get_spinnaker_link_with_id( vertex.spinnaker_link_id, vertex.board_address) if link_data is None: raise exceptions.PacmanConfigurationException( "No SpiNNaker Link {} found on board " "{}. This would be true if another chip was " "found connected at this point".format( vertex.spinnaker_link_id, vertex.board_address)) else: raise exceptions.PacmanConfigurationException( "Unknown virtual vertex type {}".format( vertex.__class__)) virtual_x, virtual_y = self._assign_virtual_chip_info( machine, link_data) vertex.set_virtual_chip_coordinates(virtual_x, virtual_y) progress_bar.update() progress_bar.end() return machine def _assign_virtual_chip_info(self, machine, link_data): if link_data not in self._virtual_chips: chip_id_x, chip_id_y = self._allocate_id() machine_algorithm_utilities.create_virtual_chip( machine, link_data, chip_id_x, chip_id_y) self._virtual_chips[link_data] = (chip_id_x, chip_id_y) return chip_id_x, chip_id_y chip_id_x, chip_id_y = self._virtual_chips[link_data] return chip_id_x, chip_id_y def _allocate_id(self): """ Allocate a chip id from the free space """ # can always assume there's at least one element in the free space, # otherwise it will have already been deleted already. free_space_chunk = self._free_space_tracker[0] chip_id = free_space_chunk.start_address self._allocate_elements(chip_id, 1) return (chip_id >> 8), (chip_id & 0xFFFF)