Source code for spinn_front_end_common.interface.interface_functions.edge_to_n_keys_mapper
# 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.graphs.common import EdgeTrafficType
from pacman.model.routing_info import DictBasedMachinePartitionNKeysMap
from spinn_front_end_common.abstract_models import (
AbstractProvidesNKeysForPartition)
from spinn_front_end_common.utilities.exceptions import ConfigurationException
[docs]class EdgeToNKeysMapper(object):
""" Works out the number of keys needed for each edge.
"""
__slots__ = []
def __call__(self, machine_graph=None, graph_mapper=None):
if machine_graph is None:
raise ConfigurationException(
"A machine graph is required for this mapper. "
"Please choose and try again")
if graph_mapper is not None:
return self._allocate_by_app_graph_simple(
machine_graph, graph_mapper)
else:
return self._allocate_by_machine_graph_only(machine_graph)
def _allocate_by_app_graph_simple(
self, machine_graph, graph_mapper):
# Generate an n_keys map for the graph and add constraints
n_keys_map = DictBasedMachinePartitionNKeysMap()
# generate progress bar
progress = ProgressBar(
machine_graph.n_vertices,
"Getting number of keys required by each edge using "
"application graph")
# iterate over each partition in the graph
for vertex in progress.over(machine_graph.vertices):
partitions = machine_graph.\
get_outgoing_edge_partitions_starting_at_vertex(
vertex)
for partition in partitions:
if partition.traffic_type == EdgeTrafficType.MULTICAST:
self._process_application_partition(
partition, n_keys_map, graph_mapper)
return n_keys_map
def _allocate_by_machine_graph_only(self, machine_graph):
# Generate an n_keys map for the graph and add constraints
n_keys_map = DictBasedMachinePartitionNKeysMap()
# generate progress bar
progress = ProgressBar(
machine_graph.n_vertices,
"Getting number of keys required by each edge using "
"machine graph")
for vertex in progress.over(machine_graph.vertices):
partitions = machine_graph.\
get_outgoing_edge_partitions_starting_at_vertex(
vertex)
for partition in partitions:
if partition.traffic_type == EdgeTrafficType.MULTICAST:
self._process_machine_partition(partition, n_keys_map)
return n_keys_map
@staticmethod
def _process_application_partition(partition, n_keys_map, graph_mapper):
vertex_slice = graph_mapper.get_slice(
partition.pre_vertex)
vertex = graph_mapper.get_application_vertex(
partition.pre_vertex)
if isinstance(vertex, AbstractProvidesNKeysForPartition):
n_keys = vertex.get_n_keys_for_partition(partition, graph_mapper)
else:
n_keys = vertex_slice.n_atoms
n_keys_map.set_n_keys_for_partition(partition, n_keys)
@staticmethod
def _process_machine_partition(partition, n_keys_map):
if isinstance(partition.pre_vertex, AbstractProvidesNKeysForPartition):
n_keys = partition.pre_vertex.get_n_keys_for_partition(
partition, None)
else:
n_keys = 1
n_keys_map.set_n_keys_for_partition(partition, n_keys)