Source code for pacman.operations.routing_info_allocator_algorithms.basic_routing_info_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.routing_info import (
RoutingInfo, PartitionRoutingInfo, BaseKeyAndMask)
from pacman.utilities.utility_calls import (
check_algorithm_can_support_constraints)
from pacman.exceptions import PacmanRouteInfoAllocationException
from pacman.model.constraints.key_allocator_constraints import (
AbstractKeyAllocatorConstraint, ContiguousKeyRangeContraint)
MAX_KEYS_SUPPORTED = 2048
MASK = 0xFFFFF800
[docs]class BasicRoutingInfoAllocator(object):
""" An basic algorithm that can produce routing keys and masks for\
edges in a graph based on the x,y,p of the placement\
of the preceding vertex.
.. note::
No constraints are supported, and that the number of keys\
required by each edge must be 2048 or less, and that all edges coming\
out of a vertex will be given the same key/mask assignment.
"""
__slots__ = []
def __call__(self, machine_graph, placements, n_keys_map):
"""
:param machine_graph:\
The machine 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.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.PartitionRoutingInfo`
: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.outgoing_edge_partitions,
supported_constraints=[ContiguousKeyRangeContraint],
abstract_constraint_type=AbstractKeyAllocatorConstraint)
# take each edge and create keys from its placement
progress = ProgressBar(
machine_graph.n_vertices, "Allocating routing keys")
routing_infos = RoutingInfo()
for vertex in progress.over(machine_graph.vertices):
for partition in machine_graph.\
get_outgoing_edge_partitions_starting_at_vertex(vertex):
routing_infos.add_partition_info(
self._allocate_key_for_partition(
partition, vertex, placements, n_keys_map))
return routing_infos
def _allocate_key_for_partition(
self, partition, vertex, placements, n_keys_map):
n_keys = n_keys_map.n_keys_for_partition(partition)
if n_keys > MAX_KEYS_SUPPORTED:
raise PacmanRouteInfoAllocationException(
"This routing info allocator can only support up to {} keys "
"for any given edge; cannot therefore allocate keys to {}, "
"which is requesting {} keys".format(
MAX_KEYS_SUPPORTED, partition, n_keys))
placement = placements.get_placement_of_vertex(vertex)
if placement is None:
raise PacmanRouteInfoAllocationException(
"The vertex '{}' has no placement".format(vertex))
keys_and_masks = list([BaseKeyAndMask(
base_key=self._get_key_from_placement(placement), mask=MASK)])
return PartitionRoutingInfo(keys_and_masks, partition)
@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