Source code for pacman.utilities.vertex_sorter

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

import sys
from six import itervalues
from spinn_utilities.ordered_default_dict import DefaultOrderedDict


[docs]class ConstraintOrder(object): """ A constraint order definition for sorting. """ __slots__ = [ # The class of the constraint "_constraint_class", # The order of the constraint relative to other constraints to be # sorted "_relative_order", # Properties of the constraint instances that must not be None for # the constraint to match this ordering "_required_optional_properties" ] def __init__( self, constraint_class, relative_order, required_optional_properties=None): """ :param constraint_class: The class of the constraint :param relative_order:\ The order of the constraint relative to other constraints to be\ sorted :param required_optional_properties:\ Properties of the constraint instances that must not be None for\ the constraint to match this ordering """ self._constraint_class = constraint_class self._relative_order = relative_order self._required_optional_properties = required_optional_properties @property def constraint_class(self): """ property method for the constraint class """ return self._constraint_class @property def relative_order(self): """ property method for the relative order """ return self._relative_order @property def required_optional_properties(self): """ property method for the required optional properties """ return self._required_optional_properties
[docs]class VertexSorter(object): """ Sorts vertices based on constraints with given criteria. """ __slots__ = [ # Group constraints based on the class "_constraints" ] def __init__(self, constraint_order): """ :param constraint_order:\ The order in which the constraints are to be sorted :type constraint_order: list(:py:class:`ConstraintOrder`) """ # Group constraints based on the class self._constraints = DefaultOrderedDict(list) for c in constraint_order: self._constraints[c.constraint_class].append( (c.relative_order, c.required_optional_properties)) # Sort each list of constraint by the number of optional properties, # largest first for constraints in itervalues(self._constraints): constraints.sort(key=len, reverse=True)
[docs] def sort(self, vertices): """ Sort the given set of vertices by the constraint ordering :param vertices: The vertices to sort :return: The sorted list of vertices """ vertices_with_rank = list() for vertex in vertices: # Get all the ranks of the constraints ranks = [sys.maxsize] for c in vertex.constraints: # If the constraint is one to sort by if c.__class__ in self._constraints: current_ranks = self._constraints[c.__class__] for (rank, required_param) in current_ranks: if self._matches(c, required_param): ranks.append(rank) # Sort and store the ranks for overall ordering ranks.sort() vertices_with_rank.append((vertex, ranks)) # Sort the vertices - because ranks is a list, things with the same # min rank will be sorted by the next highest rank and so on vertices_with_rank.sort(key=lambda thing: thing[1]) results = [vertex for vertex, _ in vertices_with_rank] return results
@staticmethod def _matches(constraint, opts): """ Determines if the constraint matches the given optional required\ parameters """ if opts is None: return True return all(getattr(constraint, opt) is not None for opt in opts)