def _get_usable_chips(self, chips, board_address, ip_tags,
                          reverse_ip_tags):
        """ Get all chips that are available on a board given the constraints

        :param chips: iterable of tuples of (x, y) coordinates of chips to \
                    look though for usable chips, or None to use all available\
                    chips
        :type chips: iterable of (int, int)
        :param board_address: the board address to check for usable chips on
        :type board_address: str or None
        :param ip_tags: list of ip tag constraints
        :type ip_tags: list of\
                    :py:class:`pacman.model.constraints.tag_allocator_constraints.tag_allocator_require_iptag_constraint.TagAllocatorRequireIptagConstraint`
        :param reverse_ip_tags: list of reverse ip tag constraints
        :type reverse_ip_tags: list of\
                    :py:class:`pacman.model.constraints.tag_allocator_constraints.tag_allocator_require_reverse_iptag_constraint.TagAllocatorRequireReverseIptagConstraint`
        :return: iterable of tuples of (x, y) coordinates of usable chips
        :rtype: iterable of tuple of (x, y)
        :raise PacmanInvalidParameterException:
                    * If the board address is unknown
                    * When either or both chip coordinates of any chip are none
                    * When a non-existent chip is specified
                    * When all the chips in the specified board have been used
        """
        if chips is not None:
            chips_to_use = list()
            area_code = None
            if board_address is not None:
                if board_address not in self._ethernet_area_codes:
                    raise exceptions.PacmanInvalidParameterException(
                        "board_address", str(board_address),
                        "Unrecognised board address")
                area_code = self._ethernet_area_codes[board_address]
            for (chip_x, chip_y) in chips:
                if ((chip_x is None and chip_y is not None)
                        or (chip_x is not None and chip_y is None)):
                    raise exceptions.PacmanInvalidParameterException(
                        "chip_x and chip_y",
                        "{} and {}".format(chip_x, chip_y),
                        "Either both or neither must be None")
                elif self._machine.get_chip_at(chip_x, chip_y) is None:
                    raise exceptions.PacmanInvalidParameterException(
                        "chip_x and chip_y",
                        "{} and {}".format(chip_x, chip_y),
                        "No such chip was found in the machine")
                elif ((chip_x, chip_y) in self._chips_available and
                      (area_code is None or (chip_x, chip_y) in area_code)):
                    chips_to_use.append((chip_x, chip_y))
            if len(chips_to_use) == 0:
                raise exceptions.PacmanInvalidParameterException(
                    "chips and board_address",
                    "{} and {}".format(chips, board_address),
                    "No valid chips found on the specified board")
            return chips_to_use
        elif board_address is not None:
            return self._ethernet_area_codes[board_address]
        elif ((ip_tags is not None and len(ip_tags) > 0)
              or (reverse_ip_tags is not None and len(reverse_ip_tags) > 0)):
            return self._get_usable_ip_tag_chips()
        return self._chips_available
예제 #2
0
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
    :return:
    """
    fixed_mask = utility_calls.locate_constraints_of_type(
        partition.constraints, KeyAllocatorFixedMaskConstraint)[0]
    fixed_field = utility_calls.locate_constraints_of_type(
        partition.constraints, KeyAllocatorFixedFieldConstraint)[0]
    mask = fixed_mask.mask
    for field in fixed_field.fields:
        if field.mask & mask != field.mask:
            raise exceptions.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 exceptions.PacmanInvalidParameterException(
                    "field.mask, mask", "Field masks {} and {} overlap".format(
                        field.mask, other_field.mask),
                    "{}:{}".format(field.mask, mask))
    def merge_entry(self, other):
        """ Merges the another entry with this one and returns a new\
            MulticastRoutingTableByPartitionEntry
        :param other: the MulticastRoutingTableByPartitionEntry to merge into\
                    this one
        :return: a merged MulticastRoutingTableByPartitionEntry
        """
        if not isinstance(other, MulticastRoutingTableByPartitionEntry):
            raise exceptions.PacmanInvalidParameterException(
                "other", "type error",
                "The other parameter is not a instance of "
                "MulticastRoutingTableByPartitionEntry, and therefore cannot "
                "be merged.")
        else:
            # validate fixed things
            if (self._incoming_processor is None
                    and other.incoming_processor is None):
                valid_incoming_processor = None
            elif (self._incoming_processor is not None
                  and other._incoming_processor is None):
                valid_incoming_processor = self._incoming_processor
            elif (self._incoming_processor is None
                  and other.incoming_processor is not None):
                valid_incoming_processor = other.incoming_processor
            elif self._incoming_processor == other._incoming_processor:
                valid_incoming_processor = self._incoming_processor
            else:
                raise exceptions.PacmanInvalidParameterException(
                    "incoming_processor", "invalid merge",
                    "The two MulticastRoutingTableByPartitionEntry have "
                    "different incoming_processors, and so can't be merged")

            if (self._incoming_link is None and other.incoming_link is None):
                valid_incoming_link = None
            elif (self._incoming_link is not None
                  and other._incoming_link is None):
                valid_incoming_link = self._incoming_link
            elif (self._incoming_link is None
                  and other.incoming_link is not None):
                valid_incoming_link = other.incoming_link
            elif self._incoming_link == other._incoming_link:
                valid_incoming_link = self._incoming_link
            else:
                raise exceptions.PacmanInvalidParameterException(
                    "incoming_link", "invalid merge",
                    "The two MulticastRoutingTableByPartitionEntry have "
                    "different incoming_links, and so can't be merged")

            # merge merge-able things
            merged_outgoing_processors = self._out_going_processors.union(
                other._out_going_processors)
            merged_outgoing_links = self._out_going_links.union(
                other._out_going_links)

            return MulticastRoutingTableByPartitionEntry(
                merged_outgoing_links, merged_outgoing_processors,
                valid_incoming_processor, valid_incoming_link)
    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
        :type out_going_links: iterable of ints between 0 and 5
        :param outgoing_processors: the processors this path entry goes to
        :type outgoing_processors: iterable of ints between 0 and 17
        :param incoming_processor:  the direction this entry came from
        :type incoming_processor: int between 0 and 17
        :param incoming_link: the direction this entry came from in link
        :type incoming_link: int between 0 and 5
        :return:
        """
        if isinstance(out_going_links, int):
            self._out_going_links = set()
            self._out_going_links.add(out_going_links)
        else:
            if out_going_links is not None:
                self._out_going_links = set(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)
        else:
            if outgoing_processors is not None:
                self._out_going_processors = set(outgoing_processors)
            else:
                self._out_going_processors = set()

        self._incoming_link = incoming_link
        self._incoming_processor = incoming_processor

        if (self._incoming_link is not None
                and self._incoming_processor is not None):
            raise exceptions.PacmanInvalidParameterException(
                "The incoming direction for a path can only be from either "
                "one link or one processors, not both",
                str(self._incoming_link), str(self._incoming_processor))
        if (self._incoming_link is not None
                and not isinstance(self._incoming_link, int)):
            raise exceptions.PacmanInvalidParameterException(
                "The incoming direction for a path can only be from either "
                "one link or one processors, not both",
                str(self._incoming_link), str(self._incoming_processor))
예제 #5
0
    def add_subvertex(self, subvertex):
        """ Add a subvertex to this partitioned_graph

        :param subvertex: a subvertex to be added to the partitioned graph
        :type subvertex:\
                    :py:class:`pacman.model.partitioned_graph.partitioned_vertex.PartitionedVertex`
        :return: None
        :rtype: None
        :raise pacman.exceptions.PacmanInvalidParameterException: If the\
                    subvertex is not valid
        """
        if not isinstance(subvertex, PartitionedVertex):
            raise exceptions.PacmanInvalidParameterException(
                "subvertex", str(subvertex),
                "This vertex is not a partitioned vertex, yet you are trying "
                "to add it to a partitioned graph.")

        if subvertex not in self._subvertices:
            self._subvertices.add(subvertex)
        else:
            raise exceptions.PacmanAlreadyExistsException(
                "PartitionedVertex", str(subvertex))
        self._outgoing_subedges[subvertex] = dict()
        self._incoming_subedges[subvertex] = list()

        # update id mapping
        self._subvertex_by_id[str(id(subvertex))] = subvertex
예제 #6
0
    def create_subedge(self, pre_subvertex, post_subvertex, label=None):
        """ Create a partitioned multicast edge

        :param pre_subvertex: the source partitioned vertex
        :param post_subvertex: the destination partitioned vertex
        :param label: the label of this partitioned edge
        :return:
        """
        if not isinstance(pre_subvertex, PartitionedVertex):
            raise exceptions.PacmanInvalidParameterException(
                "pre_subvertex", str(pre_subvertex),
                "Must be a PartitionedVertex")
        if not isinstance(post_subvertex, PartitionedVertex):
            raise exceptions.PacmanInvalidParameterException(
                "post_subvertex", str(post_subvertex), "PartitionedVertex")

        if label is None and self.label is not None:
            label = self.label

        return MultiCastPartitionedEdge(pre_subvertex, post_subvertex, label)
    def create_subedge(self, pre_subvertex, post_subvertex, label=None):
        """ Create a fixed route partitioned edge

        :param pre_subvertex: the source subvertex
        :param post_subvertex: the destination partitioned subvertex
        :param label: the label associated with the partitioned edge
        :param constraints: any constraints needed for the partitioned edge
        :return: the FixedRoutePartitionedEdge
        """
        if not isinstance(pre_subvertex, PartitionedVertex):
            raise exceptions.PacmanInvalidParameterException(
                "pre_subvertex", str(pre_subvertex),
                "Must be a PartitionedVertex")
        if not isinstance(post_subvertex, PartitionedVertex):
            raise exceptions.PacmanInvalidParameterException(
                "post_subvertex", str(post_subvertex),
                "Must be a PartitionedVertex")

        if label is None and self.label is not None:
            label = self.label

        return FixedRoutePartitionedEdge(pre_subvertex, post_subvertex, label)
예제 #8
0
    def add_subedge(self,
                    subedge,
                    partition_id=None,
                    partition_constraints=None):
        """ Add a subedge to this partitioned_graph

        :param subedge: a subedge to be added to the partitioned_graph
        :type subedge:\
                    :py:class:`pacman.model.partitioned_graph.abstract_partitioned_edge.AbstractPartitionedEdge`
        :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\
                    subedge is not valid
        """

        if not isinstance(subedge, AbstractPartitionedEdge):
            exceptions.PacmanInvalidParameterException(
                "subedge", str(subedge),
                "subedge must be a instance of a abstractPartitionedEdge.")

        if subedge in self._subedges:
            raise exceptions.PacmanAlreadyExistsException(
                "FixedRoutePartitionableEdge", str(subedge))

        self._subedges.add(subedge)

        # if the partition id is none, make a unique one for storage
        if partition_id is None:
            partition_id = str(uuid.uuid4())

        if subedge.pre_subvertex in self._outgoing_subedges:

            # if this partition id not been seen before, add a new partition
            if (partition_id
                    not in self._outgoing_subedges[subedge.pre_subvertex]):
                partition = OutgoingEdgePartition(partition_id,
                                                  partition_constraints)
                self._outgoing_subedges[subedge.pre_subvertex][partition_id] =\
                    partition
                self._partition_by_id[str(id(partition))] = partition

            self._outgoing_subedges[subedge.pre_subvertex][partition_id]\
                .add_edge(subedge)

            self._subedge_to_partition[subedge] = \
                self._outgoing_subedges[subedge.pre_subvertex][partition_id]
        else:
            raise exceptions.PacmanInvalidParameterException(
                "FixedRoutePartitionableEdge pre_subvertex",
                str(subedge.pre_subvertex),
                " Must exist in the partitioned_graph")

        if subedge.post_subvertex in self._incoming_subedges:
            self._incoming_subedges[subedge.post_subvertex].append(subedge)
        else:
            raise exceptions.PacmanInvalidParameterException(
                "FixedRoutePartitionableEdge post_subvertex",
                str(subedge.post_subvertex),
                " Must exist in the partitioned_graph")