Source code for spinn_front_end_common.interface.interface_functions.insert_edges_to_extra_monitor_functionality

# 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.application import ApplicationEdge
from pacman.model.graphs.machine import MachineEdge
from spinn_front_end_common.utilities.constants import (
    PARTITION_ID_FOR_MULTICAST_DATA_SPEED_UP)
from spinn_front_end_common.utility_models import (
    DataSpeedUpPacketGatherMachineVertex as DataSpeedUp,
    ExtraMonitorSupport, ExtraMonitorSupportMachineVertex)


[docs]class InsertEdgesToExtraMonitorFunctionality(object): """ Inserts edges between vertices who use MC speed up and its local\ MC data gatherer. """ def __call__(self, machine_graph, placements, machine, vertex_to_ethernet_connected_chip_mapping, application_graph=None, graph_mapper=None): """ :param machine_graph: the machine graph instance :param placements: the placements :param machine: the machine object :param application_graph: the application graph :param vertex_to_ethernet_connected_chip_mapping: \ mapping between ethernet connected chips and packet gatherers :param graph_mapper: the graph mapper :rtype: None """ # pylint: disable=too-many-arguments n_app_vertices = 0 if application_graph is not None: n_app_vertices = application_graph.n_vertices progress = ProgressBar( machine_graph.n_vertices + n_app_vertices, "Inserting edges between vertices which require FR speed up " "functionality.") for vertex in progress.over(machine_graph.vertices, False): if isinstance(vertex, ExtraMonitorSupportMachineVertex): self._process_vertex( vertex, machine, placements, machine_graph, vertex_to_ethernet_connected_chip_mapping, application_graph, graph_mapper) if application_graph is not None: for vertex in progress.over(application_graph.vertices, False): if isinstance(vertex, ExtraMonitorSupport): machine_verts = graph_mapper.get_machine_vertices(vertex) for machine_vertex in machine_verts: self._process_vertex( machine_vertex, machine, placements, machine_graph, vertex_to_ethernet_connected_chip_mapping, application_graph, graph_mapper) progress.end() def _process_vertex( self, vertex, machine, placements, machine_graph, vertex_to_ethernet_connected_chip_mapping, application_graph, graph_mapper): """ Inserts edges as required for a given vertex :param vertex: the extra monitor core :param machine: the spinnMachine instance :param placements: the placements object :param machine_graph: machine graph object :param vertex_to_ethernet_connected_chip_mapping: \ the ethernet to multicast gatherer map :param application_graph: app graph object :param graph_mapper: the mapping between app and machine graph :rtype: None """ # pylint: disable=too-many-arguments data_gatherer_vertex = self._get_gatherer_vertex( machine, vertex_to_ethernet_connected_chip_mapping, placements, vertex) # locate if edge is already built; if not, build it and do mapping if not self._has_edge_already( vertex, data_gatherer_vertex, machine_graph): machine_edge = MachineEdge( vertex, data_gatherer_vertex, traffic_type=DataSpeedUp.TRAFFIC_TYPE) machine_graph.add_edge( machine_edge, PARTITION_ID_FOR_MULTICAST_DATA_SPEED_UP) if application_graph is not None: app_source = graph_mapper.get_application_vertex(vertex) app_dest = graph_mapper.get_application_vertex( data_gatherer_vertex) # locate if edge is already built; if not, build it and map it if not self._has_edge_already( app_source, app_dest, application_graph): app_edge = ApplicationEdge( app_source, app_dest, traffic_type=DataSpeedUp.TRAFFIC_TYPE) application_graph.add_edge( app_edge, PARTITION_ID_FOR_MULTICAST_DATA_SPEED_UP) graph_mapper.add_edge_mapping(machine_edge, app_edge) @staticmethod def _get_gatherer_vertex(machine, v_to_2_chip_map, placements, vertex): placement = placements.get_placement_of_vertex(vertex) chip = machine.get_chip_at(placement.x, placement.y) ethernet_chip = machine.get_chip_at( chip.nearest_ethernet_x, chip.nearest_ethernet_y) return v_to_2_chip_map[ethernet_chip.x, ethernet_chip.y] @staticmethod def _has_edge_already(source, destination, graph): """ Checks if a edge already exists :param source: the source of the edge :param destination: destination of the edge :param graph: which graph to look in :return: Whether the edge was found :rtype: bool """ return any(edge.pre_vertex == source for edge in graph.get_edges_ending_at_vertex(destination))