Source code for spinn_front_end_common.interface.interface_functions.edge_to_n_keys_mapper
# pacman imports
from pacman.model.routing_info \
import DictBasedMachinePartitionNKeysMap
# utilities imports
from spinn_utilities.progress_bar import ProgressBar
# front end common imports
from spinn_front_end_common.abstract_models import \
AbstractProvidesIncomingPartitionConstraints, \
AbstractProvidesNKeysForPartition, \
AbstractProvidesOutgoingPartitionConstraints
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, application_graph=None,
graph_mapper=None):
# Generate an n_keys map for the graph and add constraints
n_keys_map = DictBasedMachinePartitionNKeysMap()
if machine_graph is None:
raise ConfigurationException(
"A machine graph is required for this mapper. "
"Please choose and try again")
if (application_graph is None) != (graph_mapper is None):
raise ConfigurationException(
"Can only do one graph. semantically doing 2 graphs makes no "
"sense. Please choose and try again")
if application_graph is not None:
# 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:
added_constraints = False
constraints = self._process_application_partition(
partition, n_keys_map, graph_mapper)
if not added_constraints:
partition.add_constraints(constraints)
else:
self._check_constraints_equal(
constraints, partition.constraints)
else:
# 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:
added_constraints = False
constraints = self._process_machine_partition(
partition, n_keys_map)
if not added_constraints:
partition.add_constraints(constraints)
else:
self._check_constraints_equal(
constraints, partition.constraints)
return n_keys_map
@staticmethod
def _check_constraints_equal(constraints, stored_constraints):
"""
:param constraints:
:param stored_constraints:
:rtype: None
"""
for constraint in constraints:
if constraint not in stored_constraints:
raise ConfigurationException(
"Two edges within the same partition have different "
"constraints")
@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 not isinstance(vertex, AbstractProvidesNKeysForPartition):
n_keys_map.set_n_keys_for_partition(
partition, vertex_slice.n_atoms)
else:
n_keys_map.set_n_keys_for_partition(
partition,
vertex.get_n_keys_for_partition(
partition, graph_mapper))
constraints = list()
if isinstance(vertex,
AbstractProvidesOutgoingPartitionConstraints):
constraints.extend(
vertex.get_outgoing_partition_constraints(partition))
for edge in partition.edges:
app_edge = graph_mapper.get_application_edge(edge)
if isinstance(app_edge.post_vertex,
AbstractProvidesIncomingPartitionConstraints):
constraints.extend(
app_edge.post_vertex.get_incoming_partition_constraints(
partition))
constraints.extend(partition.constraints)
return constraints
@staticmethod
def _process_machine_partition(partition, n_keys_map):
if not isinstance(partition.pre_vertex,
AbstractProvidesNKeysForPartition):
n_keys_map.set_n_keys_for_partition(partition, 1)
else:
n_keys_map.set_n_keys_for_partition(
partition,
partition.pre_vertex.get_n_keys_for_partition(partition, None))
constraints = list()
if isinstance(partition.pre_vertex,
AbstractProvidesOutgoingPartitionConstraints):
constraints.extend(
partition.pre_vertex.get_outgoing_partition_constraints(
partition))
for edge in partition.edges:
if isinstance(edge.post_vertex,
AbstractProvidesIncomingPartitionConstraints):
constraints.extend(
edge.post_vertex.get_incoming_partition_constraints(
partition))
constraints.extend(partition.constraints)
return constraints