def test_new_multicast_routing_tables(self):
        key_combo = 0xff35
        mask = 0xffff
        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_entries1 = MulticastRoutingEntry(key_combo, mask, proc_ids,
                                                   link_ids, True)
        multicast_entries2 = MulticastRoutingEntry(key_combo - 1, mask - 1,
                                                   proc_ids, link_ids, True)
        mrt = list()

        t1 = MulticastRoutingTable(0, 0, [multicast_entries1])
        t2 = MulticastRoutingTable(1, 0, [multicast_entries2])
        mrt.append(t1)
        mrt.append(t2)
        tables = MulticastRoutingTables(mrt)
        retrieved_tables = tables.routing_tables
        self.assertEqual(len(retrieved_tables), len(mrt))
        for tab in retrieved_tables:
            self.assertIn(tab, mrt)

        self.assertEqual(tables.get_routing_table_for_chip(0, 0), t1)
        self.assertEqual(tables.get_routing_table_for_chip(1, 0), t2)
        self.assertEqual(tables.get_routing_table_for_chip(2, 0), None)
Esempio n. 2
0
    def _generate_routing_tables(self, routing_tables,
                                 routing_tables_by_partition, ethernet_chip):
        """ from the routing. use the partition id as key, and build mc\
        routing tables.

        :param routing_tables: the routing tables to store routing tables in
        :param routing_tables_by_partition: the routing output
        :param ethernet_chip: the ethernet chip being used
        :return: dict of chip x and chip yto key to get there
        :rtype: dict
        """
        for fake_chip_x, fake_chip_y in \
                routing_tables_by_partition.get_routers():
            multicast_routing_table = MulticastRoutingTable(
                *self._real_machine.get_global_xy(fake_chip_x, fake_chip_y,
                                                  ethernet_chip.x,
                                                  ethernet_chip.y))

            # build routing table entries
            for partition, entry in iteritems(
                    routing_tables_by_partition.get_entries_for_router(
                        fake_chip_x, fake_chip_y)):
                multicast_routing_table.add_multicast_routing_entry(
                    MulticastRoutingEntry(
                        routing_entry_key=partition.identifier,
                        mask=ROUTING_MASK,
                        processor_ids=entry.processor_ids,
                        link_ids=entry.link_ids,
                        defaultable=entry.defaultable))

            # add routing table to pile
            routing_tables.add_routing_table(multicast_routing_table)
    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 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_multicast_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
    def test_new_multicast_routing_table(self):
        """
        test that creating a multicast routing entry and adding it to the table
        works
        """
        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)
    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 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_multicast_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
 def _create_routing_table(self, chip, partitions_in_table, routing_infos):
     table = MulticastRoutingTable(chip.x, chip.y)
     for partition in partitions_in_table:
         r_info = routing_infos.get_routing_info_from_partition(partition)
         entry = partitions_in_table[partition]
         for key_and_mask in r_info.keys_and_masks:
             table.add_multicast_routing_entry(MulticastRoutingEntry(
                 routing_entry_key=key_and_mask.key_combo,
                 defaultable=entry.defaultable, mask=key_and_mask.mask,
                 link_ids=entry.link_ids,
                 processor_ids=entry.processor_ids))
     return table
Esempio n. 7
0
 def _create_routing_table(self, chip, partitions_in_table, routing_infos):
     table = MulticastRoutingTable(chip.x, chip.y)
     for partition in partitions_in_table:
         r_info = routing_infos.get_routing_info_from_partition(partition)
         entry = partitions_in_table[partition]
         for key_and_mask in r_info.keys_and_masks:
             table.add_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))
     return table
    def test_add_routing_table_for_duplicate_chip(self):
        key_combo = 0xff35
        mask = 0xffff
        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_entries1 = MulticastRoutingEntry(key_combo, mask, proc_ids,
                                                   link_ids, True)

        multicast_entries2 = MulticastRoutingEntry(key_combo - 1, mask,
                                                   proc_ids, link_ids, True)
        mrt = list()
        mrt.append(MulticastRoutingTable(3, 0, [multicast_entries1]))
        mrt.append(MulticastRoutingTable(3, 0, [multicast_entries2]))
        with self.assertRaises(PacmanAlreadyExistsException):
            MulticastRoutingTables(mrt)
 def test_new_multicast_routing_table_duplicate_entry(self):
     """
     test that adding multiple identical entries into a multicast table
     causes an error
     """
     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_multicast_routing_entry(multicast_entries[0])
Esempio n. 10
0
def test_router_compressor_on_error():
    compressor = MundyOnChipRouterCompression()
    routing_tables = MulticastRoutingTables([MulticastRoutingTable(0, 0)])
    transceiver = MockTransceiverError()
    machine = virtual_machine(version=5)
    with pytest.raises(SpinnFrontEndException):
        compressor(routing_tables,
                   transceiver,
                   machine,
                   app_id=17,
                   provenance_file_path="")
 def test_new_multicast_routing_table_duplicate_entry(self):
     """
     test that adding multiple identical entries into a multicast table
     causes an error
     """
     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_multicast_routing_entry(multicast_entries[0])
    def test_new_multicast_routing_table(self):
        """
        test that creating a multicast routing entry and adding it to the table
        works
        """
        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)
    def test_new_multicast_routing_table_duplicate_key_combo(self):

        key_combo = 0xff35
        mask = 0xffff
        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, mask, proc_ids, link_ids,
                                      True))
        with self.assertRaises(PacmanAlreadyExistsException):
            MulticastRoutingTable(0, 0, multicast_entries)
Esempio n. 14
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

            mask = router_entry.mask
            if mask & _UPPER_16_BITS == _UPPER_16_BITS:
                for extra_bits in self._get_merge_masks(mask, previous_masks):
                    new_mask = _UPPER_16_BITS | extra_bits
                    new_key = router_entry.routing_entry_key & new_mask
                    new_n_keys = ~new_mask & _32_BITS

                    # Get candidates for this particular possible merge
                    potential_merges = self._mergeable_entries(
                        router_entry, entries, new_key, new_mask,
                        new_key + new_n_keys, keys_merged)

                    # Only do a merge if there's real merging to do
                    if len(potential_merges) > 1:
                        merged_routes.add_multicast_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])
                        break
                else:
                    # print("Was not able to merge", hex(key))
                    merged_routes.add_multicast_routing_entry(router_entry)
                    keys_merged.add(router_entry.routing_entry_key)
            else:
                merged_routes.add_multicast_routing_entry(router_entry)
                keys_merged.add(router_entry.routing_entry_key)
        return merged_routes
    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

            mask = router_entry.mask
            if mask & _UPPER_16_BITS == _UPPER_16_BITS:
                for extra_bits in self._get_merge_masks(mask, previous_masks):
                    new_mask = _UPPER_16_BITS | extra_bits
                    new_key = router_entry.routing_entry_key & new_mask
                    new_n_keys = ~new_mask & _32_BITS

                    # Get candidates for this particular possible merge
                    potential_merges = self._mergeable_entries(
                        router_entry, entries, new_key, new_mask,
                        new_key + new_n_keys, keys_merged)

                    # Only do a merge if there's real merging to do
                    if len(potential_merges) > 1:
                        merged_routes.add_multicast_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])
                        break
                else:
                    # print("Was not able to merge", hex(key))
                    merged_routes.add_multicast_routing_entry(router_entry)
                    keys_merged.add(router_entry.routing_entry_key)
            else:
                merged_routes.add_multicast_routing_entry(router_entry)
                keys_merged.add(router_entry.routing_entry_key)
        return merged_routes
Esempio n. 16
0
    def test(self):
        """Test minimising a table of the form:

            0000 -> N NE
            0001 -> E
            0101 -> SW
            1000 -> N NE
            1001 -> E
            1110 -> SW
            1100 -> N NE
            0X00 -> S SW

        The result (worked out by hand) should be:

            0000 -> N NE
            0X00 -> S SW
            1X00 -> N NE
            X001 -> E
            X1XX -> SW
        """

        original_tables = MulticastRoutingTables()
        original_table = MulticastRoutingTable(x=0, y=0)
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b0000, 0b1111, [1, 2], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b0001, 0b1111, [0], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b0101, 0b1111, [4], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b1000, 0b1111, [1, 2], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b1001, 0b1111, [0], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b1110, 0b1111, [4], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b1100, 0b1111, [1, 2], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b0000, 0b1011, [4, 5], [], False))
        original_tables.add_routing_table(original_table)

        mundy_compressor = MundyRouterCompressor()
        compressed_tables = mundy_compressor(original_tables)
        compressed_table = compressed_tables.get_routing_table_for_chip(0, 0)

        # TODO: FIX THIS SO THAT WE TEST THAT THE RESULT IS VALID
        # result_table_expected = MulticastRoutingTable(x=0, y=0)
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b0000, 0b1111, [1, 2], [], False))
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b0000, 0b1011, [4, 5], [], False))
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b1000, 0b1011, [1, 2], [], False))
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b0001, 0b0111, [0], [], False))
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b0100, 0b0100, [4], [], False))

        # Minimise as far as possible
        assert compressed_table.number_of_entries == 5
        # assert compressed_table == result_table_expected
        compare_table(original_table, compressed_table)
 def test_new_multicast_routing_table_empty(self):
     """
     tests creating a basic multicast routing table
     """
     MulticastRoutingTable(0, 0)
Esempio n. 18
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 = int(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 & _32_BITS))
                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 & _32_BITS
                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)):
                    last_key_added = base_key + n_keys
                    merged_routes.add_multicast_routing_entry(
                        MulticastRoutingEntry(int(base_key),
                                              n_keys_mask,
                                              processors,
                                              links,
                                              defaultable=False))
                    pos = next_pos
                    merge_done = True

            if not merge_done:
                merged_routes.add_multicast_routing_entry(entries[pos])
                last_key_added = (entries[pos].routing_entry_key +
                                  (~entries[pos].mask & _32_BITS))
            pos += 1

        return merged_routes
 def _read_routing_table(self, txrx, table, app_id):
     machine_routing_table = MulticastRoutingTable(table.x, table.y)
     for routing_entry in txrx.get_multicast_routes(
             table.x, table.y, app_id):
         machine_routing_table.add_multicast_routing_entry(routing_entry)
     return machine_routing_table
 def _read_routing_table(self, txrx, table, app_id):
     machine_routing_table = MulticastRoutingTable(table.x, table.y)
     for routing_entry in txrx.get_multicast_routes(
             table.x, table.y, app_id):
         machine_routing_table.add_multicast_routing_entry(routing_entry)
     return machine_routing_table
    def test(self):
        """Test minimising a table of the form:

            0000 -> N NE
            0001 -> E
            0101 -> SW
            1000 -> N NE
            1001 -> E
            1110 -> SW
            1100 -> N NE
            0X00 -> S SW

        The result (worked out by hand) should be:

            0000 -> N NE
            0X00 -> S SW
            1X00 -> N NE
            X001 -> E
            X1XX -> SW
        """

        original_tables = MulticastRoutingTables()
        original_table = MulticastRoutingTable(x=0, y=0)
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b0000, 0b1111, [1, 2], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b0001, 0b1111, [0], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b0101, 0b1111, [4], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b1000, 0b1111, [1, 2], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b1001, 0b1111, [0], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b1110, 0b1111, [4], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b1100, 0b1111, [1, 2], [], False))
        original_table.add_multicast_routing_entry(
            MulticastRoutingEntry(0b0000, 0b1011, [4, 5], [], False))
        original_tables.add_routing_table(original_table)

        mundy_compressor = MundyRouterCompressor()
        compressed_tables = mundy_compressor(original_tables)
        compressed_table = compressed_tables.get_routing_table_for_chip(0, 0)

        # TODO: FIX THIS SO THAT WE TEST THAT THE RESULT IS VALID
        # result_table_expected = MulticastRoutingTable(x=0, y=0)
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b0000, 0b1111, [1, 2], [], False))
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b0000, 0b1011, [4, 5], [], False))
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b1000, 0b1011, [1, 2], [], False))
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b0001, 0b0111, [0], [], False))
        # result_table_expected.add_multicast_routing_entry(
        #     MulticastRoutingEntry(0b0100, 0b0100, [4], [], False))

        # Minimise as far as possible
        assert compressed_table.number_of_entries == 5
        # assert compressed_table == result_table_expected
        compare_table(original_table, compressed_table)