def _convert_to_pacman_router_table(
            self, mundy_compressed_router_table_entries, router_x_coord,
            router_y_coord):
        """

        :param mundy_compressed_router_table_entries: rig version of the table
        :param router_x_coord: the x coord of this routing table
        :param router_y_coord: the y coord of this routing table
        :return: pacman version of the table
        """

        table = MulticastRoutingTable(router_x_coord, router_y_coord)
        if (len(mundy_compressed_router_table_entries) >
                self.max_supported_length):
            raise exceptions.PacmanElementAllocationException(
                "The routing table {}:{} after compression will still not fit"
                " within the machines router ({} entries)".format(
                    router_x_coord, router_y_coord,
                    len(mundy_compressed_router_table_entries)))
        for entry in mundy_compressed_router_table_entries:

            table.add_mutlicast_routing_entry(
                MulticastRoutingEntry(
                    entry.key, entry.mask,  # Key and mask
                    ((int(c) - 6) for c in entry.route if c.is_core),  # Cores
                    (int(l) for l in entry.route if l.is_link),  # Links
                    False))  # NOT defaultable
        return table
Esempio n. 2
0
    def __call__(self, routing_infos, routing_table_by_partitions, machine):
        """

        :param routing_infos:
        :param routing_table_by_partitions:
        :param machine:
        :return:
        """
        progress_bar = ProgressBar(len(list(machine.chips)),
                                   "Generating routing tables")
        routing_tables = MulticastRoutingTables()
        for chip in machine.chips:
            partitions_in_table = routing_table_by_partitions.\
                get_entries_for_router(chip.x, chip.y)
            if len(partitions_in_table) != 0:
                routing_table = MulticastRoutingTable(chip.x, chip.y)
                for partition in partitions_in_table:
                    keys_and_masks = routing_infos.\
                        get_keys_and_masks_from_partition(partition)
                    entry = partitions_in_table[partition]
                    for key_and_mask in keys_and_masks:
                        multicast_routing_entry = MulticastRoutingEntry(
                            routing_entry_key=key_and_mask.key_combo,
                            defaultable=entry.defaultable,
                            mask=key_and_mask.mask,
                            link_ids=entry.out_going_links,
                            processor_ids=entry.out_going_processors)
                        routing_table.add_mutlicast_routing_entry(
                            multicast_routing_entry)
                routing_tables.add_routing_table(routing_table)
            progress_bar.update()
        progress_bar.end()

        return {"router_tables": routing_tables}
 def test_new_multicast_routing_table_duplicate_entry(self):
     """
     test that adding multiple identical entries into a multicast table
     causes an error
     :return:
     """
     key_combo = 0xff35
     mask = 0xff35
     proc_ids = list()
     link_ids = list()
     for i in range(18):
         proc_ids.append(i)
     for i in range(6):
         link_ids.append(i)
     multicast_entries = list()
     for i in range(5):
         multicast_entries.append(MulticastRoutingEntry(
             key_combo + i, mask + i, proc_ids, link_ids, True))
     mrt = MulticastRoutingTable(0, 0, multicast_entries)
     with self.assertRaises(PacmanAlreadyExistsException):
         mrt.add_mutlicast_routing_entry(multicast_entries[0])
def add_routing_key_entries(
        routing_paths, subedge_routing_info, out_going_subedge,
        routing_tables):
    """
    creates and adds entries for routing tables as required for the path
    :param routing_paths: the routing paths object generated from routing info
    :param subedge_routing_info: the subedge info object that contains keys
    :param out_going_subedge: the edge this is aossicated with
    :param routing_tables: the routing tables to adjust
    :return: None
    """
    path_entries = routing_paths.get_entries_for_edge(out_going_subedge)

    # iterate through the entries in each path, adding a router entry if
    # required
    for path_entry in path_entries:

        # locate the router
        router = routing_tables.get_routing_table_for_chip(
            path_entry.router_x, path_entry.router_y)
        if router is None:
            router = MulticastRoutingTable(
                path_entry.router_x, path_entry.router_y)
            routing_tables.add_routing_table(router)

        # add entries as required, or merge them if entries already exist
        for key_and_mask in subedge_routing_info.keys_and_masks:
            multicast_routing_entry = MulticastRoutingEntry(
                routing_entry_key=key_and_mask.key_combo,
                defaultable=path_entry.defaultable, mask=key_and_mask.mask,
                link_ids=path_entry.out_going_links,
                processor_ids=path_entry.out_going_processors)
            stored_entry = \
                router.get_multicast_routing_entry_by_routing_entry_key(
                    key_and_mask.key_combo, key_and_mask.mask)
            if stored_entry is None:
                router.add_mutlicast_routing_entry(MulticastRoutingEntry(
                    routing_entry_key=key_and_mask.key_combo,
                    defaultable=path_entry.defaultable,
                    mask=key_and_mask.mask,
                    link_ids=path_entry.out_going_links,
                    processor_ids=path_entry.out_going_processors))
            else:
                merged_entry = stored_entry.merge(multicast_routing_entry)
                router.remove_multicast_routing_entry(stored_entry)
                router.add_mutlicast_routing_entry(merged_entry)
    def test_new_multicast_routing_table(self):
        """
        test that creating a multicast routing entry and adding it to the table
        works
        :return:
        """
        key_combo = 0xff000
        mask = 0xff000
        proc_ids = list()
        link_ids = list()
        for i in range(18):
            proc_ids.append(i)
        for i in range(6):
            link_ids.append(i)
        multicast_entries = list()
        for i in range(5):
            multicast_entries.append(
                MulticastRoutingEntry(key_combo + i, mask + i, proc_ids,
                                      link_ids, True))
        mrt = MulticastRoutingTable(0, 0, multicast_entries)
        self.assertEqual(mrt.x, 0)
        self.assertEqual(mrt.y, 0)

        mre = mrt.multicast_routing_entries
        for entry in mre:
            self.assertIn(entry, multicast_entries)
        self.assertEqual(len(mre), len(multicast_entries))
        for i in range(5):
            self.assertEqual(
                mrt.get_multicast_routing_entry_by_routing_entry_key(
                    key_combo + i, mask + i),
                multicast_entries[i])
        self.assertEqual(mrt.get_multicast_routing_entry_by_routing_entry_key(
            key_combo + 5, mask + 5), None)
        self.assertEqual(mrt.get_multicast_routing_entry_by_routing_entry_key(
            key_combo - 1, mask - 1), None)
Esempio n. 6
0
    def _merge_routes(self, router_table, previous_masks):
        merged_routes = MulticastRoutingTable(router_table.x, router_table.y)
        keys_merged = set()

        entries = router_table.multicast_routing_entries
        for router_entry in entries:
            if router_entry.routing_entry_key in keys_merged:
                continue

            # print "key =", hex(router_entry.routing_entry_key)

            mask = router_entry.mask
            if mask & 0xFFFF0000L == 0xFFFF0000L:
                merge_done = False

                for extra_bits in self._get_merge_masks(mask, previous_masks):

                    new_mask = 0xFFFF0000L | extra_bits
                    # print "trying mask =", hex(new_mask), hex(extra_bits)

                    new_key = router_entry.routing_entry_key & new_mask
                    new_n_keys = ~new_mask & 0xFFFFFFFFL
                    new_last_key = new_key + new_n_keys

                    # Check that all the cores on this chip have the same route
                    # as this is the only way we can merge here
                    mergable = True
                    potential_merges = set()
                    for router_entry_2 in entries:
                        key = router_entry_2.routing_entry_key
                        n_keys = ~router_entry_2.mask & 0xFFFFFFFFL
                        last_key = key + n_keys
                        masked_key = (router_entry_2.routing_entry_key
                                      & new_mask)
                        overlap = (min(new_last_key, last_key) -
                                   max(new_key, key)) > 0
                        in_range = new_key <= key and new_last_key >= last_key

                        if (new_key == masked_key and
                            (not in_range or
                             (router_entry_2.routing_entry_key in keys_merged)
                             or (router_entry.processor_ids !=
                                 router_entry_2.processor_ids) or
                             (router_entry.link_ids !=
                              router_entry_2.link_ids))):
                            # print(
                            #     "    ", hex(key), "and", hex(key2),
                            #     "have mismatched routes")
                            mergable = False
                            break
                        elif new_key == masked_key:
                            # print(
                            #     "    ", hex(key), "and", hex(key2),
                            #     "can be merged")
                            potential_merges.add(router_entry_2)
                        elif overlap:
                            mergable = False
                            break

                    if mergable and len(potential_merges) > 1:
                        # print("Merging", [
                        #     hex(route.routing_entry_key)
                        #     for route in potential_merges], "using mask =",
                        #     hex(new_mask), "and key =", hex(masked_key),
                        #     "and route =", router_entry.processor_ids,
                        #     router_entry.link_ids)

                        # if masked_key in merged_routes:
                        #     raise Exception(
                        #         "Attempting to merge an existing key")
                        merged_routes.add_mutlicast_routing_entry(
                            MulticastRoutingEntry(new_key,
                                                  new_mask,
                                                  router_entry.processor_ids,
                                                  router_entry.link_ids,
                                                  defaultable=False))
                        keys_merged.update([
                            route.routing_entry_key
                            for route in potential_merges
                        ])
                        merge_done = True
                        break

                if not merge_done:
                    # print "Was not able to merge", hex(key)
                    merged_routes.add_mutlicast_routing_entry(router_entry)
                    keys_merged.add(router_entry.routing_entry_key)
            else:
                merged_routes.add_mutlicast_routing_entry(router_entry)
                keys_merged.add(router_entry.routing_entry_key)
Esempio n. 7
0
    def _merge_routes(self, router_table, previous_masks):
        merged_routes = MulticastRoutingTable(router_table.x, router_table.y)

        # Order the routes by key
        entries = sorted(
            router_table.multicast_routing_entries,
            key=lambda entry: entry.routing_entry_key)

        # Find adjacent entries that can be merged
        pos = 0
        last_key_added = 0
        while pos < len(entries):
            links = entries[pos].link_ids
            processors = entries[pos].processor_ids
            next_pos = pos + 1

            # Keep going until routes are not the same or too many keys are
            # generated
            base_key = long(entries[pos].routing_entry_key)
            while (next_pos < len(entries) and
                    entries[next_pos].link_ids == links and
                    entries[next_pos].processor_ids == processors and
                    (base_key & entries[next_pos].routing_entry_key) >
                    last_key_added):
                base_key = (
                    base_key & entries[next_pos].routing_entry_key)
                next_pos += 1
            next_pos -= 1

            # print "Pre decision", hex(base_key)

            # If there is something to merge, merge it if possible
            merge_done = False
            if next_pos != pos:

                # print "At merge, base_key =", hex(base_key)

                # Find the next nearest power of 2 to the number of keys
                # that will be covered
                last_key = (
                    entries[next_pos].routing_entry_key +
                    (~entries[next_pos].mask & 0xFFFFFFFFL))
                n_keys = (last_key - base_key) + 1
                next_log_n_keys = int(math.ceil(math.log(n_keys, 2)))
                n_keys = (1 << next_log_n_keys) - 1
                n_keys_mask = ~n_keys & 0xFFFFFFFFL
                base_key = base_key & n_keys_mask
                if ((base_key + n_keys) >= last_key and
                        base_key > last_key_added and
                        (next_pos + 1 >= len(entries) or
                         entries[pos].routing_entry_key + n_keys <
                         entries[next_pos + 1].routing_entry_key)):
                    # print "Merged into", hex(base_key), hex(n_keys_mask)
                    # for i in range(pos, next_pos + 1):
                    #     print "    ", hex(entries[i].routing_entry_key)
                    last_key_added = base_key + n_keys
                    # print "    Last key:", hex(last_key_added)
                    merged_routes.add_mutlicast_routing_entry(
                        MulticastRoutingEntry(
                            base_key, n_keys_mask,
                            processors, links, defaultable=False))
                    pos = next_pos
                    merge_done = True

            if not merge_done:
                merged_routes.add_mutlicast_routing_entry(entries[pos])
                last_key_added = (
                    entries[pos].routing_entry_key +
                    (~entries[pos].mask & 0xFFFFFFFFL))
                # print "Not Merged", hex(entries[pos].routing_entry_key),\
                # hex(entries[pos].mask)
            pos += 1

        return merged_routes