Source code for pacman.model.graphs.abstract_edge_partition

# 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.abstract_base import (
    AbstractBase, abstractmethod, abstractproperty)
from spinn_utilities.ordered_set import OrderedSet
from pacman.exceptions import (
    PacmanConfigurationException, PacmanInvalidParameterException)
from pacman.model.graphs.common import ConstrainedObject

_REPR_TEMPLATE = "{}(identifier={}, edges={}, constraints={}, label={})"


[docs]class AbstractEdgePartition(ConstrainedObject, metaclass=AbstractBase): """ A collection of edges which start at a single vertex which have the\ same semantics and so can share a single key or block of SDRAM\ (depending on edge type). """ __slots__ = [ # The partition identifier "_identifier", # The edges in the partition "_edges", # The type of edges to accept "_allowed_edge_types", # The weight of traffic going down this partition "_traffic_weight", # The label of the graph "_label", # class name "_class_name", # Safety code generated by the graph when added to that graph "_graph_code" ] def __init__( self, identifier, allowed_edge_types, constraints, label, traffic_weight, class_name): """ :param str identifier: The identifier of the partition :param allowed_edge_types: The types of edges allowed :type allowed_edge_types: type or tuple(type, ...) :param iterable(AbstractConstraint) constraints: Any initial constraints :param str label: An optional label of the partition :param int traffic_weight: The weight of traffic going down this partition """ super().__init__(constraints) self._label = label self._identifier = identifier self._edges = OrderedSet() self._allowed_edge_types = allowed_edge_types self._traffic_weight = traffic_weight self._class_name = class_name self._graph_code = None @property def label(self): """ The label of the edge partition. :rtype: str """ return self._label
[docs] def add_edge(self, edge, graph_code): """ Add an edge to the edge partition. .. note:: This method should only be called by the ``add_edge`` method of the graph that owns the partition. Calling it from anywhere else, even with the correct graph_code, will lead to unsupported inconsistency. :param AbstractEdge edge: the edge to add :param int graph_code: A code to check the correct graph is calling this method :raises PacmanInvalidParameterException: If the edge does not belong in this edge partition """ if graph_code != self._graph_code: raise PacmanConfigurationException( "Only one graph should add edges") if self._graph_code is None: raise PacmanConfigurationException( "Only Graphs can add edges to partitions") # Check for an incompatible edge if not isinstance(edge, self._allowed_edge_types): raise PacmanInvalidParameterException( "edge", str(edge.__class__), "Edges of this graph must be one of the following types:" " {}".format(self._allowed_edge_types)) self._edges.add(edge)
[docs] def register_graph_code(self, graph_code): """ Allows the graph to register its code when the partition is added """ if self._graph_code is not None: raise PacmanConfigurationException( "Illegal attempt to add partition {} to a second " "graph".format(self)) self._graph_code = graph_code
@property def identifier(self): """ The identifier of this edge partition. :rtype: str """ return self._identifier @property def edges(self): """ The edges in this edge partition. .. note:: The order in which the edges are added is preserved for when they are requested later. If not, please talk to the software team. :rtype: iterable(AbstractEdge) """ return self._edges @property def n_edges(self): """ The number of edges in the edge partition. :rtype: int """ return len(self._edges) @property def traffic_weight(self): """ The weight of the traffic in this edge partition compared to\ other partitions. :rtype: int """ return self._traffic_weight def __repr__(self): edges = "" for edge in self._edges: if edge.label is not None: edges += edge.label + "," else: edges += str(edge) + "," return _REPR_TEMPLATE.format( self._class_name, self._identifier, edges, self.constraints, self.label) def __str__(self): return self.__repr__() def __contains__(self, edge): """ Check if the edge is contained within this partition :param AbstractEdge edge: the edge to search for. :rtype: bool """ return edge in self._edges
[docs] @abstractmethod def clone_without_edges(self): """ Make a copy of this edge partition without any of the edges in it This follows the design pattern that only the graph adds edges to partitions already added to the graph :return: The copied edge partition but excluding edges """
@abstractproperty def pre_vertices(self): """ Provides the vertices associated with this partition .. note:: Most edge partitions will be :py:class:`AbstractSingleSourcePartition` and therefore provide the ``pre_vertex`` method. :rtype: iter(AbstractVertex) """