Source code for pacman.operations.routing_info_allocator_algorithms.destination_based_key_allocator
# Copyright (c) 2017-2019 The University of Manchester
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from spinn_utilities.progress_bar import ProgressBar
from pacman.model.constraints.key_allocator_constraints import (
AbstractKeyAllocatorConstraint)
from pacman.model.routing_info import (
BaseKeyAndMask, RoutingInfo, PartitionRoutingInfo)
from pacman.model.routing_tables import MulticastRoutingTables
from pacman.utilities.utility_calls import (
check_algorithm_can_support_constraints)
from pacman.exceptions import PacmanConfigurationException
[docs]class DestinationBasedRoutingInfoAllocator(object):
""" A routing key allocator that operates for people who wish to have a\
separate key for each destination (making a multicast into a\
point-to-point cast).
"""
__slots__ = []
MAX_KEYS_SUPPORTED = 2048
MASK = 0xFFFFF800
def __call__(self, machine_graph, placements, n_keys_map):
"""
:param machine_graph: The graph to allocate the routing info for
:type machine_graph:\
:py:class:`pacman.model.graphs.machine.MachineGraph`
:param placements: The placements of the vertices
:type placements:\
:py:class:`pacman.model.placements.Placements`
:param n_keys_map: A map between the edges and the number of keys\
required by the edges
:type n_keys_map:\
:py:class:`pacman.model.routing_info.AbstractMachinePartitionNKeysMap`
:return: The routing information
:rtype: \
:py:class:`pacman.model.routing_info.RoutingInfo`, \
:py:class:`pacman.model.routing_tables.MulticastRoutingTable
:raise pacman.exceptions.PacmanRouteInfoAllocationException: \
If something goes wrong with the allocation
"""
# check that this algorithm supports the constraints put onto the
# partitions
check_algorithm_can_support_constraints(
constrained_vertices=machine_graph.partitions,
supported_constraints=[],
abstract_constraint_type=AbstractKeyAllocatorConstraint)
# take each edge and create keys from its placement
progress = ProgressBar(machine_graph.n_outgoing_edge_partitions,
"Allocating routing keys")
routing_infos = RoutingInfo()
routing_tables = MulticastRoutingTables()
for partition in progress.over(machine_graph.outgoing_edge_partitions):
for edge in partition.edges:
routing_infos.add_partition_info(
self._allocate_partition_route(
edge, placements, machine_graph, n_keys_map))
return routing_infos, routing_tables
def _allocate_partition_route(self, edge, placements, graph, n_keys_map):
destination = edge.post_vertex
placement = placements.get_placement_of_vertex(destination)
keys_and_masks = list([BaseKeyAndMask(
base_key=self._get_key_from_placement(placement), mask=self.MASK)])
partition = graph.get_outgoing_edge_partition_starting_at_vertex(
edge.pre_vertex)
n_keys = n_keys_map.n_keys_for_partition(partition)
if n_keys > self.MAX_KEYS_SUPPORTED:
raise PacmanConfigurationException(
"Only edges which require less than {} keys are"
" supported".format(self.MAX_KEYS_SUPPORTED))
return PartitionRoutingInfo(keys_and_masks, edge)
@staticmethod
def _get_key_from_placement(placement):
""" Return a key given a placement
:param placement: the associated placement
:type placement:\
:py:class:`pacman.model.placements.Placement`
:return: The key
:rtype: int
"""
return placement.x << 24 | placement.y << 16 | placement.p << 11