Source code for pacman.model.graphs.application.application_graph

# 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
# 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 <>.

from .application_edge import ApplicationEdge
from .application_vertex import ApplicationVertex
from .application_edge_partition import ApplicationEdgePartition
from spinn_utilities.default_ordered_dict import DefaultOrderedDict
from spinn_utilities.ordered_set import OrderedSet
from spinn_utilities.overrides import overrides
from pacman.exceptions import (
    PacmanAlreadyExistsException, PacmanInvalidParameterException)
from pacman.model.graphs.graph import Graph

[docs]class ApplicationGraph(Graph): """ An application-level abstraction of a graph. """ __slots__ = [ # The sets of edge partitions by pre-vertex "_outgoing_edge_partitions_by_pre_vertex", ] def __init__(self, label): """ :param label: The label on the graph, or None :type label: str or None """ super().__init__(ApplicationVertex, ApplicationEdge, label) self._outgoing_edge_partitions_by_pre_vertex = \ DefaultOrderedDict(OrderedSet)
[docs] def forget_machine_graph(self): """ Forget the whole mapping from this graph to an application graph. """ for v in self.vertices: v.forget_machine_vertices() for e in self.edges: e.forget_machine_edges()
[docs] def forget_machine_edges(self): """ Ensure that all application edges in this graph forget what machine edges they map to. The mapping of vertices is unaffected. """ for e in self.edges: e.forget_machine_edges()
[docs] @overrides(Graph.new_edge_partition) def new_edge_partition(self, name, edge): return ApplicationEdgePartition( identifier=name, pre_vertex=edge.pre_vertex)
[docs] @overrides(Graph.add_outgoing_edge_partition) def add_outgoing_edge_partition(self, edge_partition): # verify that this partition is suitable for this graph if not isinstance(edge_partition, ApplicationEdgePartition): raise PacmanInvalidParameterException( "outgoing_edge_partition", edge_partition.__class__, "Partitions of this graph must be an ApplicationEdgePartition") # check this partition doesn't already exist key = (edge_partition.pre_vertex, edge_partition.identifier) if key in self._outgoing_edge_partitions_by_name: raise PacmanAlreadyExistsException( str(ApplicationEdgePartition), key) edge_partition.register_graph_code(id(self)) self._outgoing_edge_partitions_by_pre_vertex[ edge_partition.pre_vertex].add(edge_partition) self._outgoing_edge_partitions_by_name[key] = edge_partition for edge in edge_partition.edges: self._register_edge(edge, edge_partition)
@property @overrides(Graph.outgoing_edge_partitions) def outgoing_edge_partitions(self): # This is based on the assumption that an Application partition is # always SingleSourced return self._outgoing_edge_partitions_by_name.values() @property @overrides(Graph.n_outgoing_edge_partitions) def n_outgoing_edge_partitions(self): # This is based on the assumption that an Application partition is # always SingleSourced return len(self._outgoing_edge_partitions_by_name)
[docs] def get_outgoing_edge_partitions_starting_at_vertex(self, vertex): """ Get all the edge partitions that start at the given vertex. :param AbstractVertex vertex: The vertex at which the edge partitions to find starts :rtype: iterable(AbstractEdgePartition) """ return self._outgoing_edge_partitions_by_pre_vertex[vertex]
[docs] def clone(self): """ Makes as shallow as possible copy of the graph. Vertices and edges are copied over. Partition will be new objects. :return: A shallow copy of this graph :rtype: ApplicationGraph """ new_graph = ApplicationGraph(label=self.label) for vertex in self.vertices: new_graph.add_vertex(vertex) for outgoing_partition in self.outgoing_edge_partitions: for edge in outgoing_partition.edges: new_graph.add_edge(edge, outgoing_partition.identifier) return new_graph