def _check_masks_are_correct(partition): """ Check that the masks between a fixed mask constraint and a fixed_field\ constraint. Raises error if not. :param AbstractSingleSourcePartition partition: the outgoing_edge_partition to search for these constraints :raise PacmanInvalidParameterException: if the masks are incompatible """ fixed_mask = locate_constraints_of_type( partition.constraints, FixedMaskConstraint)[0] fixed_field = locate_constraints_of_type( partition.constraints, FixedKeyFieldConstraint)[0] mask = fixed_mask.mask for field in fixed_field.fields: if field.mask & mask != field.mask: raise PacmanInvalidParameterException( "field.mask, mask", "The field mask {} is outside of the mask {}".format( field.mask, mask), "{}:{}".format(field.mask, mask)) for other_field in fixed_field.fields: if other_field != field and other_field.mask & field.mask != 0: raise PacmanInvalidParameterException( "field.mask, mask", "Field masks {} and {} overlap".format( field.mask, other_field.mask), "{}:{}".format(field.mask, mask))
def add_edge(self, edge, outgoing_edge_partition_name): # verify that the edge is one suitable for this graph if not isinstance(edge, self._allowed_edge_types): raise PacmanInvalidParameterException( "edge", edge.__class__, "Edges of this graph must be one of the following types:" " {}".format(self._allowed_edge_types)) if edge.pre_vertex not in self._vertices: raise PacmanInvalidParameterException( "edge", edge.pre_vertex, "pre-vertex must be known in graph") if edge.post_vertex not in self._vertices: raise PacmanInvalidParameterException( "edge", edge.post_vertex, "post-vertex must be known in graph") # Add the edge to the partition partition = None if ((edge.pre_vertex, outgoing_edge_partition_name) not in self._outgoing_edge_partitions_by_name): partition = OutgoingEdgePartition( outgoing_edge_partition_name, self._allowed_edge_types) self._outgoing_edge_partitions_by_pre_vertex[ edge.pre_vertex].add(partition) self._outgoing_edge_partitions_by_name[ edge.pre_vertex, outgoing_edge_partition_name] = partition else: partition = self._outgoing_edge_partitions_by_name[ edge.pre_vertex, outgoing_edge_partition_name] partition.add_edge(edge) # Add the edge to the indices self._outgoing_edges[edge.pre_vertex].add(edge) self._incoming_edges_by_partition_name[ (edge.post_vertex, outgoing_edge_partition_name)].append(edge) self._incoming_edges[edge.post_vertex].add(edge)
def _check_masks_are_correct(partition): """ Check that the masks between a fixed mask constraint\ and a fixed_field constraint. completes if its correct, raises error\ otherwise :param partition: \ the outgoing_edge_partition to search for these constraints :rtype: None: """ fixed_mask = locate_constraints_of_type(partition.constraints, FixedMaskConstraint)[0] fixed_field = locate_constraints_of_type(partition.constraints, FixedKeyFieldConstraint)[0] mask = fixed_mask.mask for field in fixed_field.fields: if field.mask & mask != field.mask: raise PacmanInvalidParameterException( "field.mask, mask", "The field mask {} is outside of the mask {}".format( field.mask, mask), "{}:{}".format(field.mask, mask)) for other_field in fixed_field.fields: if other_field != field and other_field.mask & field.mask != 0: raise PacmanInvalidParameterException( "field.mask, mask", "Field masks {} and {} overlap".format( field.mask, other_field.mask), "{}:{}".format(field.mask, mask))
def add_reverse_ip_tag(self, reverse_ip_tag, vertex): """ Add a reverse IP tag :param ~spinn_machine.tags.ReverseIPTag reverse_ip_tag: The tag to add :param MachineVertex vertex: The vertex by which the tag is to be used :raises PacmanInvalidParameterException: * If the combination of (board-address, tag) has already been\ assigned to an IP tag or Reverse IP tag * If the port of the tag has already been assigned on the given\ board-address """ if not isinstance(reverse_ip_tag, ReverseIPTag): raise PacmanInvalidParameterException( "reverse_ip_tag", str(reverse_ip_tag), "Only add reverse IP tags with this method.") if ((reverse_ip_tag.board_address, reverse_ip_tag.tag) in self._ip_tags or (reverse_ip_tag.board_address, reverse_ip_tag.tag) in self._reverse_ip_tags): raise PacmanInvalidParameterException( "reverse_ip_tag", reverse_ip_tag, "The tag has already been assigned on the given board") if reverse_ip_tag.port is not None: if (reverse_ip_tag.board_address, reverse_ip_tag.port) in self._ports_assigned: raise PacmanInvalidParameterException( "reverse_ip_tag", reverse_ip_tag, "The port has already been assigned on the given board") self._reverse_ip_tags[(reverse_ip_tag.board_address, reverse_ip_tag.tag)] = reverse_ip_tag self._reverse_ip_tags_by_vertex[vertex].append(reverse_ip_tag) if reverse_ip_tag.port is not None: self._ports_assigned.add( (reverse_ip_tag.board_address, reverse_ip_tag.port))
def __init__(self, out_going_links, outgoing_processors, incoming_processor=None, incoming_link=None): """ :param out_going_links: the edges this path entry goes down, each of\ which is between 0 and 5 :type out_going_links: iterable(int) :param outgoing_processors: the processors this path entry goes to,\ each of which is between 0 and 17 :type outgoing_processors: iterable(int) :param incoming_processor: \ the direction this entry came from (between 0 and 17) :type incoming_processor: int :param incoming_link: \ the direction this entry came from in link (between 0 and 5) :type incoming_link: int """ if isinstance(out_going_links, int): self._out_going_links = set() self._out_going_links.add(out_going_links) elif out_going_links is not None: self._out_going_links = set(int(link) for link in out_going_links) else: self._out_going_links = set() if isinstance(outgoing_processors, int): self._out_going_processors = set() self._out_going_processors.add(outgoing_processors) elif outgoing_processors is not None: self._out_going_processors = set( int(p) for p in outgoing_processors) else: self._out_going_processors = set() if incoming_link is not None and incoming_processor is not None: raise PacmanInvalidParameterException( "The incoming direction for a path can only be from either " "one link or one processors, not both", str(incoming_link), str(incoming_processor)) if (incoming_processor is not None and not isinstance(incoming_processor, int)): raise PacmanInvalidParameterException( "The incoming direction for a path can only be from either " "one link or one processors, not both", str(incoming_link), str(incoming_processor)) if incoming_link is not None and not isinstance(incoming_link, int): raise PacmanInvalidParameterException( "The incoming direction for a path can only be from either " "one link or one processors, not both", str(incoming_link), str(incoming_processor)) self._incoming_processor = (None if incoming_processor is None else int(incoming_processor)) self._incoming_link = (None if incoming_link is None else int(incoming_link))
def add_vertex(self, vertex): super(MachineGraph, self).add_vertex(vertex) if self._application_level_used: try: vertex.app_vertex.remember_machine_vertex(vertex) except AttributeError: if self.n_vertices == 1: self._application_level_used = False else: raise PacmanInvalidParameterException( "vertex", str(vertex), self.MISSING_APP_VERTEX_ERROR_MESSAGE) elif vertex.app_vertex: raise PacmanInvalidParameterException( "vertex", vertex, self.UNEXPECTED_APP_VERTEX_ERROR_MESSAGE)
def merge_entry(self, other): """ Merges the another entry with this one and returns a new\ MulticastRoutingTableByPartitionEntry :param MulticastRoutingTableByPartitionEntry other: the entry to merge into this one :return: a merged MulticastRoutingTableByPartitionEntry :raises PacmanInvalidParameterException: """ if not isinstance(other, MulticastRoutingTableByPartitionEntry): raise PacmanInvalidParameterException( "other", "type error", "The other parameter is not an instance of " "MulticastRoutingTableByPartitionEntry, and therefore cannot " "be merged.") # validate and merge valid_incoming_processor = self.__merge_noneables( self._incoming_processor, other.incoming_processor, "incoming_processor") valid_incoming_link = self.__merge_noneables(self._incoming_link, other.incoming_link, "incoming_link") merged_outgoing_processors = self._out_going_processors.union( other.processor_ids) merged_outgoing_links = self._out_going_links.union(other.link_ids) return MulticastRoutingTableByPartitionEntry( merged_outgoing_links, merged_outgoing_processors, valid_incoming_processor, valid_incoming_link)
def check_algorithm_can_support_constraints( constrained_vertices, supported_constraints, abstract_constraint_type): """ Helper method to find out if an algorithm can support all the\ constraints given the objects its expected to work on :param constrained_vertices: a list of constrained vertices which each has\ constraints given to the algorithm :type constrained_vertices: \ iterable(:py:class:`pacman.model.constraints.AbstractConstraint`) :param supported_constraints: The constraints supported :type supported_constraints: \ iterable(:py:class:`pacman.model.constraints.AbstractConstraint`) :param abstract_constraint_type: The overall abstract c type supported :type abstract_constraint_type:\ :py:class:`pacman.model.constraints.AbstractConstraint` :return: Nothing is returned :rtype: None :raise pacman.exceptions.PacmanInvalidParameterException: \ When the algorithm cannot support the constraints demanded of it """ for constrained_vertex in constrained_vertices: for c in constrained_vertex.constraints: if isinstance(c, abstract_constraint_type) and not \ _is_constraint_supported(c, supported_constraints): raise PacmanInvalidParameterException( "constraints", c.__class__, "Constraints of this class are not supported by this" " algorithm")
def add_edge(self, edge): # Check for an incompatible edge if not isinstance(edge, self._allowed_edge_types): raise PacmanInvalidParameterException( "edge", edge.__class__, "Edges of this graph must be one of the following types:" " {}".format(self._allowed_edge_types)) # Check for an incompatible pre vertex if self._pre_vertex is None: self._pre_vertex = edge.pre_vertex elif edge.pre_vertex != self._pre_vertex: raise PacmanConfigurationException( "A partition can only contain edges with the same" "pre_vertex") # Check for an incompatible traffic type if self._traffic_type is None: self._traffic_type = edge.traffic_type elif edge.traffic_type != self._traffic_type: raise PacmanConfigurationException( "A partition can only contain edges with the same" " traffic_type") self._edges.add(edge)
def add_outgoing_edge_partition(self, edge_partition): # verify that this partition is suitable for this graph if not isinstance(edge_partition, AbstractMachineEdgePartition): raise PacmanInvalidParameterException( "outgoing_edge_partition", str(edge_partition.__class__), "Partitions of this graph must be an " "AbstractMachineEdgePartition") # check this partition doesn't already exist if edge_partition in self._edge_partitions: raise PacmanAlreadyExistsException( str(AbstractMachineEdgePartition), edge_partition) self._edge_partitions.add(edge_partition) edge_partition.register_graph_code(id(self)) for pre_vertex in edge_partition.pre_vertices: key = (pre_vertex, edge_partition.identifier) self._outgoing_edge_partitions_by_name[key] = edge_partition if isinstance(edge_partition, MulticastEdgePartition): self._multicast_edge_partitions_by_pre_vertex[pre_vertex].add( edge_partition) elif isinstance(edge_partition, FixedRouteEdgePartition): self._fixed_route_edge_partitions_by_pre_vertex[ pre_vertex].add(edge_partition) elif isinstance(edge_partition, AbstractSDRAMPartition): self._sdram_edge_partitions_by_pre_vertex[pre_vertex].add( edge_partition) else: raise NotImplementedError( "Unexpected edge_partition: {}".format(edge_partition)) for edge in edge_partition.edges: self._register_edge(edge, edge_partition)
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)
def add_vertex(self, vertex): if not isinstance(vertex, self._allowed_vertex_types): raise PacmanInvalidParameterException( "vertex", vertex.__class__, "Vertices of this graph must be one of the following types:" " {}".format(self._allowed_vertex_types)) self._vertices.add(vertex)
def get_chip_and_core(constraints, chips=None): """ Get an assigned chip and core from a set of constraints :param constraints: The set of constraints to get the values from. Note\ that any type of constraint can be in the list but only those\ relevant will be used :type constraints: iterable of\ :py:class:`pacman.model.constraints.abstract_constraint.AbstractConstraint` :param chips: Optional list of tuples of (x, y) coordinates of chips,\ restricting the allowed chips :type chips: iterable of (int, int) :return: tuple of a chip x and y coordinates, and processor id, any of\ which might be None :rtype: (tuple of (int, int, int) """ x = None y = None p = None for constraint in constraints: if isinstance(constraint, PlacerChipAndCoreConstraint): x = _check_constrained_value(constraint.x, x) y = _check_constrained_value(constraint.y, y) p = _check_constrained_value(constraint.p, p) if chips is not None and x is not None and y is not None: if (x, y) not in chips: raise PacmanInvalidParameterException( "x, y and chips", "{}, {} and {}".format(x, y, chips), "The constraint cannot be met with the given chips") return x, y, p
def __init__(self, n_atoms, label, max_atoms_per_core, constraints=None): """ :param n_atoms: the number of atoms for the vertex :type n_atoms: int :param label: the label of the vertex :type label: str :param max_atoms_per_core: the max atoms that can be supported by a \ core. Note that this is translated into a partitioner max \ size constraint :type max_atoms_per_core: int :param constraints: any extra constraints to be added to this vertex. :type constraints: iterable of\ :py:class:`pacman.model.constraints.abstract_contraints.abstract_constraint.AbstractConstraint` """ AbstractConstrainedVertex.__init__(self, label, constraints) if n_atoms < 1: raise PacmanInvalidParameterException( "n_atoms", str(n_atoms), "Must be at least one atom in the vertex") self._n_atoms = n_atoms # add the max atom per core constraint max_atom_per_core_constraint = \ PartitionerMaximumSizeConstraint(max_atoms_per_core) self.add_constraint(max_atom_per_core_constraint)
def __merge_noneables(p1, p2, name): if p1 is None: return p2 if p2 is None or p1 == p2: return p1 raise PacmanInvalidParameterException( name, "invalid merge", "The two MulticastRoutingTableByPartitionEntry have different " + name + "s, and so can't be merged")
def add_ip_tag(self, ip_tag, vertex): """ Add an IP tag :param ip_tag: The tag to add :type ip_tag: :py:class:`spinn_machine.tags.IPTag` :param vertex: The machine vertex by which the tag is to be used :type vertex:\ :py:class:`pacman.model.graphs.machine.MachineVertex` :raises PacmanInvalidParameterException: * If the combination of (board-address, tag) has already been\ assigned to an IP tag with different properties * If the combination of (board-address, tag) has already been\ assigned to a reverse IP tag """ if not isinstance(ip_tag, IPTag): raise PacmanInvalidParameterException( "ip_tag", str(ip_tag), "Only add IP tags with this method.") existing_tag = None if (ip_tag.board_address, ip_tag.tag) in self._ip_tags: existing_tag = self._ip_tags[(ip_tag.board_address, ip_tag.tag)] if (existing_tag.ip_address != ip_tag.ip_address or not utility_calls.is_equal_or_None( existing_tag.port, ip_tag.port) or existing_tag.strip_sdp != ip_tag.strip_sdp): raise PacmanInvalidParameterException( "ip_tag", str(ip_tag), "The tag specified has already been assigned with" " different properties: {}".format(existing_tag)) if (ip_tag.board_address, ip_tag.tag) in self._reverse_ip_tags: raise PacmanInvalidParameterException( "ip_tag", str(ip_tag), "The tag has already been assigned to a reverse IP tag on" " the given board") if existing_tag is None: self._ip_tags[(ip_tag.board_address, ip_tag.tag)] = ip_tag self._ip_tags_by_vertex[vertex].append(ip_tag) else: self._ip_tags_by_vertex[vertex].append(existing_tag) # Update the port number if necessary if existing_tag.port is None and ip_tag.port is not None: existing_tag.port = ip_tag.port
def add_constraint(self, constraint): """ Add a new constraint to the collection of constraints :param AbstractConstraint constraint: constraint to add :raise PacmanInvalidParameterException: If the constraint is not valid """ if constraint is None: raise PacmanInvalidParameterException("constraint", constraint, "must not be None") if not isinstance(constraint, AbstractConstraint): raise PacmanInvalidParameterException( "constraint", constraint, "Must be a " + _get_class_name(AbstractConstraint)) try: self._constraints.add(constraint) except Exception: # pylint: disable=broad-except self._constraints = OrderedSet() self._constraints.add(constraint)
def new_edge_partition(self, name, edge): if edge.traffic_type == EdgeTrafficType.FIXED_ROUTE: return FixedRouteEdgePartition(identifier=name, pre_vertex=edge.pre_vertex) elif edge.traffic_type == EdgeTrafficType.MULTICAST: return MulticastEdgePartition(identifier=name, pre_vertex=edge.pre_vertex) else: raise PacmanInvalidParameterException( "edge", edge, "Unable to add an Edge with traffic type {} unless you first " "add a partition for it".format(edge.traffic_type))
def add_reverse_ip_tag(self, reverse_ip_tag, partitioned_vertex): """ Add a reverse iptag :param reverse_ip_tag: The tag to add :type reverse_ip_tag:\ :py:class:`spinn_machine.tags.reverse_iptag.ReverseIPTag` :param partitioned_vertex: The partitioned vertex by which the tag\ is to be used :type partitioned_vertex:\ :py:class:`pacman.model.partitioned_graph.partitioned_vertex.PartitionedVertex` :raises PacmanInvalidParameterException: * If the combination of (board-address, tag) has already\ been assigned to an IP tag or Reverse IP tag * If the port of the tag has already been assigned on\ the given board-address """ if ((reverse_ip_tag.board_address, reverse_ip_tag.tag) in self._ip_tags or (reverse_ip_tag.board_address, reverse_ip_tag.tag) in self._reverse_ip_tags): raise PacmanInvalidParameterException( "reverse_ip_tag", reverse_ip_tag, "The tag has already been assigned on the given board") if (reverse_ip_tag.board_address, reverse_ip_tag.port) in self._reverse_ip_tags: raise PacmanInvalidParameterException( "reverse_ip_tag", reverse_ip_tag, "The port has already been assigned on the given board") self._reverse_ip_tags[(reverse_ip_tag.board_address, reverse_ip_tag.tag)] = reverse_ip_tag if partitioned_vertex not in self._reverse_ip_tags_by_vertex: self._reverse_ip_tags_by_vertex[partitioned_vertex] = set() self._reverse_ip_tags_by_vertex[partitioned_vertex].add( reverse_ip_tag) self._ports_assigned.add( (reverse_ip_tag.board_address, reverse_ip_tag.port))
def add_constraint(self, constraint): """ Add a new constraint to the collection of constraints :param constraint: constraint to add :type constraint:\ :py:class:`pacman.model.constraints.AbstractConstraint` :rtype: None :raise pacman.exceptions.PacmanInvalidParameterException: \ If the constraint is not valid """ if constraint is None: raise PacmanInvalidParameterException( "constraint", constraint, "must not be None") if not isinstance(constraint, AbstractConstraint): raise PacmanInvalidParameterException( "constraint", constraint, "Must be a " + _get_class_name(AbstractConstraint)) try: self._constraints.add(constraint) except Exception: self._constraints = set() self._constraints.add(constraint)
def _register_edge(self, edge, partition): """ Add an edge to the graph. :param AbstractEdge edge: The edge to add :param AbstractEdgePartition partition: The name of the edge partition to add the edge to; each edge partition is the partition of edges that start at the same vertex :raises PacmanInvalidParameterException: If the edge is not of a valid type or if edges have already been added to this partition that start at a different vertex to this one """ # verify that the edge is one suitable for this graph if not isinstance(edge, self._allowed_edge_types): raise PacmanInvalidParameterException( "edge", edge.__class__, "Edges of this graph must be one of the following types:" " {}".format(self._allowed_edge_types)) if edge.pre_vertex.label not in self._vertex_by_label: raise PacmanInvalidParameterException( "Edge", str(edge.pre_vertex), "Pre-vertex must be known in graph") if edge.post_vertex.label not in self._vertex_by_label: raise PacmanInvalidParameterException( "Edge", str(edge.post_vertex), "Post-vertex must be known in graph") # Add the edge to the indices self._outgoing_edges[edge.pre_vertex].add(edge) self._incoming_edges_by_partition_name[ edge.post_vertex, partition.identifier].append(edge) self._incoming_edges[edge.post_vertex].add(edge) if edge in self._outgoing_edge_partition_by_edge: raise PacmanAlreadyExistsException("edge", edge) self._outgoing_edge_partition_by_edge[edge] = partition
def add_ip_tag(self, ip_tag, partitioned_vertex): """ Add an IP tag :param ip_tag: The tag to add :type ip_tag: :py:class:`spinn_machine.tags.iptag.IPTag` :param partitioned_vertex: The partitioned vertex by which the tag\ is to be used :type partitioned_vertex:\ :py:class:`pacman.model.partitioned_graph.partitioned_vertex.PartitionedVertex` :raises PacmanInvalidParameterException: * If the combination of (board-address, tag) has already\ been assigned to an IP tag with different properties * If the combination of (board-address, tag) has already\ been assigned to a reverse IP tag """ if (ip_tag.board_address, ip_tag.tag) in self._ip_tags: existing_tag = self._ip_tags[(ip_tag.board_address, ip_tag.tag)] if (existing_tag.ip_address != ip_tag.ip_address or existing_tag.port != ip_tag.port or existing_tag.strip_sdp != ip_tag.strip_sdp): raise PacmanInvalidParameterException( "ip_tag", str(ip_tag), "The tag specified has already been assigned with" " different properties: {}".format(existing_tag)) if (ip_tag.board_address, ip_tag.tag) in self._reverse_ip_tags: raise PacmanInvalidParameterException( "ip_tag", str(ip_tag), "The tag has already been assigned to a reverse IP tag on" " the given board") self._ip_tags[(ip_tag.board_address, ip_tag.tag)] = ip_tag if partitioned_vertex not in self._ip_tags_by_vertex: self._ip_tags_by_vertex[partitioned_vertex] = set() self._ip_tags_by_vertex[partitioned_vertex].add(ip_tag)
def add_constraint(self, constraint): """ Add a new constraint to the collection of constraints for the vertex :param constraint: constraint to add :type constraint:\ :py:class:`pacman.model.constraints.abstract_constraint.AbstractConstraint` :return: None :rtype: None :raise pacman.exceptions.PacmanInvalidParameterException: If the\ constraint is not valid """ if (constraint is None or not isinstance(constraint, AbstractConstraint)): raise PacmanInvalidParameterException( "constraint", constraint, "Must be a pacman.model." "constraints.abstract_constraint." "AbstractConstraint") self._constraints.add(constraint)
def locate_first_constraint_of_type(constraints, constraint_type): """ Locates the first constraint of a given type out of a list :param iterable(AbstractConstraint) constraints: The constraints to select from :param type(AbstractConstraint) constraint_type: The type of constraints to return :return: The first constraint of `constraint_type` that was found in the constraints given :rtype: AbstractConstraint :raises PacmanInvalidParameterException: If no such constraint is present """ for constraint in constraints: if isinstance(constraint, constraint_type): return constraint raise PacmanInvalidParameterException( "constraints", constraint_type.__class__, "Constraints of this class are not present")
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)
def round_n_atoms(self, n_atoms, label="n_atoms"): """ Utility function to allow supoer classes to make sure n_atom is an int :param n_atoms: Value convertable to int to be used for n_atoms :type n_atoms: int or float or numpy. :return: """ if isinstance(n_atoms, int): return n_atoms # Allow a float which has a near int value temp = int(round(n_atoms)) if abs(temp - n_atoms) < 0.001: if temp != n_atoms: logger.warning( "Size of the {} rounded from {} to {}. " "Please use int values for n_atoms", label, n_atoms, temp) return temp raise PacmanInvalidParameterException( label, n_atoms, "int value expected for {}".format(label))
def add_vertex(self, vertex): """ Add a vertex to this partitionable_graph :param vertex: a vertex to be added to the partitionable graph :type vertex:\ :py:class:`pacman.model.partitionable_graph.abstract_partitionable_vertex.AbstractPartitionableVertex` :return: None :rtype: None :raise pacman.exceptions.PacmanInvalidParameterException: \ If the vertex is not valid """ if vertex is not None and isinstance(vertex, AbstractPartitionableVertex): self._vertices.append(vertex) self._outgoing_edges[vertex] = dict() self._incoming_edges[vertex] = list() else: raise PacmanInvalidParameterException( "vertex", str(vertex), "Must be an instance of pacman.model.partitionable_graph" ".abstract_partitionable_vertex.AbstractPartitionableVertex")
def locate_first_constraint_of_type(constraints, constraint_type): """ Locates the first constraint of a given type out of a list :param constraints: The constraints to select from :type constraints: \ iterable(:py:class:`pacman.model.constraints.AbstractConstraint`) :param constraint_type: The type of constraints to return :type constraint_type:\ :py:class:`pacman.model.constraints.partitioner_constraints.AbstractPartitionConstraint` :return: The first constraint of constraint_type that was found in the\ constraints given :rtype: :py:class:`pacman.model.constraints.AbstractConstraint` :raises pacman.exceptions.PacmanInvalidParameterException: \ If no such constraint is present """ for constraint in constraints: if isinstance(constraint, constraint_type): return constraint raise PacmanInvalidParameterException( "constraints", constraint_type.__class__, "Constraints of this class are not present")
def check_algorithm_can_support_constraints(constrained_vertices, supported_constraints, abstract_constraint_type): """ Helper method to find out if an algorithm can support all the constraints given the objects its expected to work on :param list(AbstractVertex) constrained_vertices: a list of constrained vertices which each has constraints given to the algorithm :param list(type(AbstractConstraint)) supported_constraints: The constraints supported :param type(AbstractConstraint) abstract_constraint_type: The overall abstract c type supported :raise PacmanInvalidParameterException: When the algorithm cannot support the constraints demanded of it """ for constrained_vertex in constrained_vertices: for c in constrained_vertex.constraints: if isinstance(c, abstract_constraint_type) and not \ _is_constraint_supported(c, supported_constraints): raise PacmanInvalidParameterException( "constraints", c.__class__, "Constraints of this class are not supported by this" " algorithm")
def add_edge(self, edge, partition_id=None, partition_constraints=None): """ Add an edge to this partitionable_graph :param edge: an edge to be added to the partitionable_graph :type edge:\ :py:class:`pacman.model.partitionable_graph.abstract_partitionable_edge.AbstractPartitionableEdge` :param partition_id: the id for the outgoing partition that this edge\ is associated with :type partition_id: str :param partition_constraints: list of constraints to put onto the\ partition :type partition_constraints: iterable of :py:class:`pacman.model.constraints.abstract_constraints.abstract_constraint.AbstractConstraint` :return: None :rtype: None :raise pacman.exceptions.PacmanInvalidParameterException: If the edge\ is not valid """ if edge is not None and isinstance(edge, AbstractPartitionableEdge): self._edges.append(edge) # if the partition id is none, make a unique one for storage if partition_id is None: partition_id = str(uuid.uuid4()) # if this partition id not been seen before, add a new partition if partition_id not in self._outgoing_edges[edge.pre_vertex]: self._outgoing_edges[edge.pre_vertex][partition_id] = \ OutgoingEdgePartition(partition_id, partition_constraints) self._outgoing_edges[edge.pre_vertex][partition_id].add_edge(edge) self._incoming_edges[edge.post_vertex].append(edge) else: raise PacmanInvalidParameterException( "edge", str(edge), "Must be an instance of pacman.model.partitionable_graph" ".edge.AbstractPartitionableEdge")