Esempio n. 1
0
    def _build_data(self, routing_table):
        """ Convert the router table into the data needed by the router\
            compressor c code.

        :param ~.MulticastRoutingTables routing_table:
            the pacman router table instance
        :return: The byte array of data
        :rtype: bytearray
        """

        # write header data of the app ID to load the data, if to store
        # results in SDRAM and the router table entries

        data = b''
        if self._compress_only_when_needed is None:
            data += _THREE_WORDS.pack(
                self._app_id,
                int(self._compress_as_much_as_possible),
                # Write the size of the table
                routing_table.number_of_entries)
        else:
            # Mundys compressor can not be changed so uses it own structure
            data += _FOUR_WORDS.pack(
                self._app_id, int(self._compress_only_when_needed),
                int(self._compress_as_much_as_possible),
                # Write the size of the table
                routing_table.number_of_entries)

        for entry in routing_table.multicast_routing_entries:
            data += _FOUR_WORDS.pack(
                entry.routing_entry_key, entry.mask,
                Router.convert_routing_table_entry_to_spinnaker_route(entry),
                make_source_hack(entry=entry))
        return bytearray(data)
    def _process_edge(
            self, placements, source_placement, net_graph, edge,
            chip_route_nets, machine, routing_by_partition,
            out_going_partition):
        dest_placement = placements.get_placement_of_vertex(
            edge.post_vertex)
        traversal = self._recursive_trace_to_destination(
            source_placement.x, source_placement.y,
            out_going_partition, dest_placement.x, dest_placement.y,
            machine, routing_by_partition)
        for (chip, entry) in traversal:
            route = Router.convert_routing_table_entry_to_spinnaker_route(
                entry)
            chip_route_nets[chip][route].append(out_going_partition)
            net_graph[out_going_partition] = set()

            # Add constraints to the net graph dependent on which nets take
            # different routes at this point.
            routes_in_chip = chip_route_nets[chip]
            for other_route, other_partitions in iteritems(routes_in_chip):
                if other_route != route:
                    for other_partition in other_partitions:
                        # This partition cannot share an identifier with any of
                        # the other partitions who take a different route at
                        # this point.
                        if other_partition != out_going_partition:
                            net_graph[out_going_partition].add(other_partition)
                            net_graph[other_partition].add(out_going_partition)
Esempio n. 3
0
    def test_partition_with_more_sdram_than_default(self):
        """
        test that the partitioner works when its machine is slightly malformed
        in that it has more SDRAM available
        """
        n_processors = 18
        (e, ne, n, w, _, _) = range(6)

        links = list()
        links.append(Link(0, 0, e, 0, 1))

        _sdram = SDRAM(128 * (2**21))

        links = list()

        links.append(Link(0, 0, e, 1, 1))
        links.append(Link(0, 1, ne, 1, 0))
        links.append(Link(1, 1, n, 0, 0))
        links.append(Link(1, 0, w, 0, 1))
        r = Router(links, False, 1024)

        ip = "192.162.240.253"
        chips = list()
        for x in range(5):
            for y in range(5):
                if x == y == 0:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0, ip))
                else:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0))

        self.machine = machine_from_chips(chips)
        splitter_partitioner(self.graph, self.machine, 3000,
                             PreAllocatedResourceContainer())
Esempio n. 4
0
    def test_partition_with_more_sdram_than_default(self):
        """
        test that the partitioner works when its machine is slightly malformed
        in that it has more sdram avilable
        """
        self.setup()
        flops = 20000000
        (e, _, n, w, _, s) = range(6)

        processors = list()
        for i in range(18):
            processors.append(Processor(i, flops))

        links = list()
        links.append(Link(0, 0, 0, 0, 1, s, s))

        _sdram = SDRAM(128 * (2**21))

        links = list()

        links.append(Link(0, 0, 0, 1, 1, n, n))
        links.append(Link(0, 1, 1, 1, 0, s, s))
        links.append(Link(1, 1, 2, 0, 0, e, e))
        links.append(Link(1, 0, 3, 0, 1, w, w))
        r = Router(links, False, 100, 1024)

        ip = TestBasicPartitioner.TheTestAddress
        chips = list()
        for x in range(5):
            for y in range(5):
                chips.append(Chip(x, y, processors, r, _sdram, 0, 0, ip))

        self.machine = Machine(chips, 0, 0)
        self.bp(self.graph, self.machine)
Esempio n. 5
0
    def _build_routing_table_data(self, app_id, routing_table):
        """ builds routing data as needed for the compressor cores

        :param int app_id: appid of the application to load entries with
        :param ~.AbsractMulticastRoutingTable routing_table:
            the uncompressed routing table
        :return: data array
        :rtype: bytearray
        """
        data = b''
        data += self._TWO_WORDS.pack(app_id, routing_table.number_of_entries)

        # sort entries based on generality
        sorted_routing_table = sorted(
            routing_table.multicast_routing_entries,
            key=lambda rt_entry: ordered_covering_generality(
                rt_entry.routing_entry_key, rt_entry.mask))

        # write byte array for the sorted table
        for entry in sorted_routing_table:
            data += self._FOUR_WORDS.pack(
                entry.routing_entry_key, entry.mask,
                Router.convert_routing_table_entry_to_spinnaker_route(entry),
                make_source_hack(entry=entry))
        return bytearray(data)
Esempio n. 6
0
    def test_partition_with_more_sdram_than_default(self):
        """
        test that the partitioner works when its machine is slightly malformed
        in that it has more SDRAM available
        """
        self.setup()
        n_processors = 18
        (e, ne, n, w, _, _) = range(6)

        links = list()
        links.append(Link(0, 0, e, 0, 1))

        _sdram = SDRAM(128 * (2**21))

        links = list()

        links.append(Link(0, 0, e, 1, 1))
        links.append(Link(0, 1, ne, 1, 0))
        links.append(Link(1, 1, n, 0, 0))
        links.append(Link(1, 0, w, 0, 1))
        r = Router(links, False, 1024)

        ip = TestBasicPartitioner.TheTestAddress
        chips = list()
        for x in range(5):
            for y in range(5):
                if x == y == 0:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0, ip))
                else:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0))

        self.machine = machine_from_chips(chips)
        self.sp(self.graph, self.machine, 3000)
 def __encode_route(self, entry):
     """
     :param ~spinn_machine.MulticastRoutingEntry entry:
     :rtype: int
     """
     route = self._app_id << _BIT_SHIFT_TO_MOVE_APP_ID
     route |= Router.convert_routing_table_entry_to_spinnaker_route(entry)
     return route
Esempio n. 8
0
def create_virtual_chip(machine, link_data, virtual_chip_x, virtual_chip_y):

    # If the chip already exists, return the data
    if machine.is_chip_at(virtual_chip_x, virtual_chip_y):
        if not machine.get_chip_at(virtual_chip_x, virtual_chip_y).virtual:
            raise Exception(
                "Attempting to add virtual chip in place of a real chip")
        return

    # Create link to the virtual chip from the real chip
    virtual_link_id = (link_data.connected_link + 3) % 6
    to_virtual_chip_link = Link(
        destination_x=virtual_chip_x,
        destination_y=virtual_chip_y,
        source_x=link_data.connected_chip_x,
        source_y=link_data.connected_chip_y,
        multicast_default_from=virtual_link_id,
        multicast_default_to=virtual_link_id,
        source_link_id=link_data.connected_link)

    # Create link to the real chip from the virtual chip
    from_virtual_chip_link = Link(
        destination_x=link_data.connected_chip_x,
        destination_y=link_data.connected_chip_y,
        source_x=virtual_chip_x,
        source_y=virtual_chip_y,
        multicast_default_from=link_data.connected_link,
        multicast_default_to=link_data.connected_link,
        source_link_id=virtual_link_id)

    # create the router
    links = [from_virtual_chip_link]
    router_object = Router(
        links=links, emergency_routing_enabled=False,
        clock_speed=Router.ROUTER_DEFAULT_CLOCK_SPEED,
        n_available_multicast_entries=sys.maxsize)

    # create the processors
    processors = list()
    for virtual_core_id in range(0, constants.CORES_PER_VIRTUAL_CHIP):
        processors.append(Processor.factory(virtual_core_id))

    # connect the real chip with the virtual one
    connected_chip = machine.get_chip_at(
        link_data.connected_chip_x,
        link_data.connected_chip_y)
    connected_chip.router.add_link(to_virtual_chip_link)

    machine.add_chip(Chip(
        processors=processors, router=router_object,
        sdram=SDRAM(size=0),
        x=virtual_chip_x, y=virtual_chip_y,
        virtual=True, nearest_ethernet_x=None, nearest_ethernet_y=None))
Esempio n. 9
0
    def setUp(self):
        """
        setup for all basic partitioner tests
        """
        unittest_setup()
        self.vert1 = SimpleTestVertex(10, "New AbstractConstrainedVertex 1")
        self.vert1.splitter = SplitterSliceLegacy()
        self.vert2 = SimpleTestVertex(5, "New AbstractConstrainedVertex 2")
        self.vert2.splitter = SplitterSliceLegacy()
        self.vert3 = SimpleTestVertex(3, "New AbstractConstrainedVertex 3")
        self.vert3.splitter = SplitterSliceLegacy()
        self.edge1 = ApplicationEdge(self.vert1,
                                     self.vert2,
                                     label="First edge")
        self.edge2 = ApplicationEdge(self.vert2,
                                     self.vert1,
                                     label="Second edge")
        self.edge3 = ApplicationEdge(self.vert1,
                                     self.vert3,
                                     label="Third edge")
        self.verts = [self.vert1, self.vert2, self.vert3]
        self.edges = [self.edge1, self.edge2, self.edge3]
        self.graph = ApplicationGraph("Graph")
        self.graph.add_vertices(self.verts)
        self.graph.add_edges(self.edges, "foo")

        n_processors = 18
        (e, ne, n, w, _, _) = range(6)

        links = list()
        links.append(Link(0, 0, e, 0, 1))

        _sdram = SDRAM(128 * (2**20))

        links = list()

        links.append(Link(0, 0, e, 1, 1))
        links.append(Link(0, 1, ne, 1, 0))
        links.append(Link(1, 1, n, 0, 0))
        links.append(Link(1, 0, w, 0, 1))
        r = Router(links, False, 1024)

        ip = TestBasicPartitioner.TheTestAddress
        chips = list()
        for x in range(5):
            for y in range(5):
                if x == y == 0:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0, ip))
                else:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0))

        self.machine = machine_from_chips(chips)
Esempio n. 10
0
def create_virtual_chip(machine, link_data, virtual_chip_x, virtual_chip_y):
    """ Create a virtual chip on a real machine.

    :param ~spinn_machine.Machine machine:
    :param ~spinn_machine.link_data_objects.AbstractLinkData link_data:
        Describes the link from the real machine.
    :param int virtual_chip_x: Virtual chip coordinate
    :param int virtual_chip_y: Virtual chip coordinate
    """

    # If the chip already exists, return the data
    if machine.is_chip_at(virtual_chip_x, virtual_chip_y):
        if not machine.get_chip_at(virtual_chip_x, virtual_chip_y).virtual:
            raise Exception(
                "Attempting to add virtual chip in place of a real chip")
        return

    # Create link to the virtual chip from the real chip
    virtual_link_id = (link_data.connected_link + 3) % 6
    to_virtual_chip_link = Link(destination_x=virtual_chip_x,
                                destination_y=virtual_chip_y,
                                source_x=link_data.connected_chip_x,
                                source_y=link_data.connected_chip_y,
                                source_link_id=link_data.connected_link)

    # Create link to the real chip from the virtual chip
    from_virtual_chip_link = Link(destination_x=link_data.connected_chip_x,
                                  destination_y=link_data.connected_chip_y,
                                  source_x=virtual_chip_x,
                                  source_y=virtual_chip_y,
                                  source_link_id=virtual_link_id)

    # create the router
    links = [from_virtual_chip_link]
    router_object = Router(links=links,
                           emergency_routing_enabled=False,
                           n_available_multicast_entries=sys.maxsize)

    # connect the real chip with the virtual one
    connected_chip = machine.get_chip_at(link_data.connected_chip_x,
                                         link_data.connected_chip_y)
    connected_chip.router.add_link(to_virtual_chip_link)

    machine.add_virtual_chip(
        Chip(n_processors=constants.CORES_PER_VIRTUAL_CHIP,
             router=router_object,
             sdram=SDRAM(size=0),
             x=virtual_chip_x,
             y=virtual_chip_y,
             virtual=True,
             nearest_ethernet_x=None,
             nearest_ethernet_y=None))
    def _add_routing_entry(self, route_no, offset, app_id, route, key, mask):
        # pylint: disable=too-many-arguments
        if route >= 0xFF000000:
            return
        if self._app_id is not None and self._app_id != app_id:
            return

        # Convert bit-set into list of (set) IDs
        processor_ids, link_ids = \
            Router.convert_spinnaker_route_to_routing_ids(route)

        self._entries[route_no + offset] = MulticastRoutingEntry(
            key, mask, processor_ids, link_ids, False)
    def _add_routing_entry(self, route_no, offset, app_id, route, key, mask):
        # pylint: disable=too-many-arguments
        if route >= 0xFF000000:
            return
        if self._app_id is not None and self._app_id != app_id:
            return

        # Convert bit-set into list of (set) IDs
        processor_ids, link_ids = \
            Router.convert_spinnaker_route_to_routing_ids(route)

        self._entries[route_no + offset] = MulticastRoutingEntry(
            key, mask, processor_ids, link_ids, False)
    def test_creating_new_router(self):
        links = list()
        (e, ne, n, w, sw, s) = range(6)
        links.append(Link(0, 0, 0, 1, 1, n, n))
        links.append(Link(0, 1, 1, 1, 0, s, s))
        links.append(Link(1, 1, 2, 0, 0, e, e))
        links.append(Link(1, 0, 3, 0, 1, w, w))
        r = Router(links, False, 100, 1024)

        self.assertEqual(len(r), 4)
        for i in range(4):
            self.assertTrue(r.is_link(i))
            self.assertTrue(i in r)
            self.assertEqual(r.get_link(i), links[i])
            self.assertEqual(r[i], links[i])
        self.assertEqual([l[0] for l in r], [0, 1, 2, 3])
        self.assertEqual([l[1].source_link_id for l in r], [0, 1, 2, 3])

        self.assertFalse(r.emergency_routing_enabled)
        self.assertEqual(r.clock_speed, 100)
        self.assertEqual(r.n_available_multicast_entries, 1024)

        self.assertFalse(r.is_link(-1))
        self.assertFalse(r.is_link(links.__len__() + 1))
        self.assertEqual(r.get_link(-1), None)
        self.assertEqual(r.get_link(links.__len__() + 1), None)

        self.assertEqual(r.get_neighbouring_chips_coords(),
                         [{'x': 1, 'y': 1}, {'x': 1, 'y': 0},
                          {'x': 0, 'y': 0}, {'x': 0, 'y': 1}])
        self.assertEqual(
            r.__repr__(),
            "[Router: clock_speed=0 MHz, emergency_routing=False, "
            "available_entries=1024, links=[[Link: source_x=0, source_y=0, "
            "source_link_id=0, destination_x=1, destination_y=1, "
            "default_from=2, default_to=2], [Link: source_x=0, source_y=1, "
            "source_link_id=1, destination_x=1, destination_y=0, "
            "default_from=5, default_to=5], [Link: source_x=1, source_y=1, "
            "source_link_id=2, destination_x=0, destination_y=0, "
            "default_from=0, default_to=0], [Link: source_x=1, source_y=0, "
            "source_link_id=3, destination_x=0, destination_y=1, "
            "default_from=3, default_to=3]]]")
 def load_fixed_route(self, x, y, fixed_route, app_id=0):
     """
     :param int x: The x-coordinate of the chip, between 0 and 255;
         this is not checked due to speed restrictions.
     :param int y: The y-coordinate of the chip, between 0 and 255;
         this is not checked due to speed restrictions.
     :param ~spinn_machine.FixedRouteEntry fixed_route:
         the fixed route entry
     :param int app_id: The ID of the application with which to associate
         the routes.  If not specified, defaults to 0.
     """
     route_entry = \
         Router.convert_routing_table_entry_to_spinnaker_route(fixed_route)
     self._send_request(FixedRouteInit(x, y, route_entry, app_id))
     self._finish()
     self.check_for_error()
Esempio n. 15
0
    def setup(self):
        """
        setup for all basic partitioner tests
        """
        self.vert1 = SimpleTestVertex(10, "New AbstractConstrainedVertex 1")
        self.vert2 = SimpleTestVertex(5, "New AbstractConstrainedVertex 2")
        self.vert3 = SimpleTestVertex(3, "New AbstractConstrainedVertex 3")
        self.edge1 = ApplicationEdge(self.vert1, self.vert2, None,
                                     "First edge")
        self.edge2 = ApplicationEdge(self.vert2, self.vert1, None,
                                     "Second edge")
        self.edge3 = ApplicationEdge(self.vert1, self.vert3, None,
                                     "Third edge")
        self.verts = [self.vert1, self.vert2, self.vert3]
        self.edges = [self.edge1, self.edge2, self.edge3]
        self.graph = ApplicationGraph("Graph")
        self.graph.add_vertices(self.verts)
        self.graph.add_edges(self.edges, "foo")

        flops = 200000000
        (e, _, n, w, _, s) = range(6)

        processors = list()
        for i in range(18):
            processors.append(Processor(i, flops))

        links = list()
        links.append(Link(0, 0, 0, 0, 1, s, s))

        _sdram = SDRAM(128 * (2**20))

        links = list()

        links.append(Link(0, 0, 0, 1, 1, n, n))
        links.append(Link(0, 1, 1, 1, 0, s, s))
        links.append(Link(1, 1, 2, 0, 0, e, e))
        links.append(Link(1, 0, 3, 0, 1, w, w))
        r = Router(links, False, 100, 1024)

        ip = TestBasicPartitioner.TheTestAddress
        chips = list()
        for x in range(5):
            for y in range(5):
                chips.append(Chip(x, y, processors, r, _sdram, 0, 0, ip))

        self.machine = Machine(chips, 0, 0)
        self.bp = BasicPartitioner()
Esempio n. 16
0
    def test_partition_with_barely_sufficient_space(self):
        """
        test that partitioning will work when close to filling the machine
        """
        self.setup()

        n_processors = 18
        (e, ne, n, w, _, _) = range(6)

        links = list()
        links.append(Link(0, 0, e, 0, 1))

        _sdram = SDRAM(2**12)

        links = list()

        links.append(Link(0, 0, e, 1, 1))
        links.append(Link(0, 1, ne, 1, 0))
        links.append(Link(1, 1, n, 0, 0))
        links.append(Link(1, 0, w, 0, 1))
        r = Router(links, False, 1024)

        ip = "192.162.240.253"
        chips = list()
        for x in range(5):
            for y in range(5):
                if x == y == 0:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0, ip))
                else:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0))

        self.machine = machine_from_chips(chips)
        n_neurons = 17 * 5 * 5
        singular_vertex = SimpleTestVertex(n_neurons,
                                           "Large vertex",
                                           max_atoms_per_core=1)
        singular_vertex.splitter = SplitterSliceLegacy()
        self.assertEqual(singular_vertex._model_based_max_atoms_per_core, 1)
        self.graph = ApplicationGraph("Graph with large vertex")
        self.graph.add_vertex(singular_vertex)
        graph, _ = self.bp(
            self.graph,
            self.machine,
            plan_n_time_steps=100,
            pre_allocated_resources=PreAllocatedResourceContainer())
        self.assertEqual(singular_vertex._model_based_max_atoms_per_core, 1)
        self.assertEqual(len(list(graph.vertices)), n_neurons)
    def load_routes(self, x, y, routes, app_id):
        """
        :param int x:
        :param int y:
        :param list(~spinn_machine.MulticastRoutingEntry) routes:
        :param int app_id:
        """
        # Create the routing data - 16 bytes per entry plus one for the end
        # entry
        routing_data = bytearray(16 * (len(routes) + 1))
        n_entries = 0
        for route in routes:
            route_entry = \
                Router.convert_routing_table_entry_to_spinnaker_route(route)

            _ROUTE_PATTERN.pack_into(
                routing_data, n_entries * 16, n_entries,
                route_entry, route.routing_entry_key, route.mask)
            n_entries += 1

        # Add an entry to mark the end
        _END_PATTERN.pack_into(
            routing_data, n_entries * 16,
            0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)

        # Upload the data
        process = WriteMemoryProcess(self._conn_selector)
        process.write_memory_from_bytearray(
            x, y, 0, _TABLE_ADDRESS, routing_data, 0, len(routing_data))

        # Allocate space in the router table
        self._send_request(RouterAlloc(x, y, app_id, n_entries),
                           self.__handle_router_alloc_response)
        self._finish()
        self.check_for_error()
        if self._base_address == 0:
            raise SpinnmanInvalidParameterException(
                "Allocation base address", str(self._base_address),
                "Not enough space to allocate the entries")

        # Load the entries
        self._send_request(
            RouterInit(
                x, y, n_entries, _TABLE_ADDRESS, self._base_address, app_id))
        self._finish()
        self.check_for_error()
 def test_allocate_resources_when_chip_used(self):
     router = Router([])
     sdram = SDRAM()
     empty_chip = Chip(0,
                       0,
                       1,
                       router,
                       sdram,
                       0,
                       0,
                       "127.0.0.1",
                       virtual=False,
                       tag_ids=[1])
     machine = machine_from_chips([empty_chip])
     resource_tracker = ResourceTracker(machine, plan_n_timesteps=None)
     with self.assertRaises(PacmanValueError):
         resource_tracker.allocate_resources(
             ResourceContainer(sdram=ConstantSDRAM(1024)))
Esempio n. 19
0
    def test_partition_with_insufficient_space(self):
        """
        test that if there's not enough space, the test the partitioner will
        raise an error
        """
        self.setup()
        n_processors = 18
        (e, ne, n, w, _, _) = range(6)

        links = list()
        links.append(Link(0, 0, e, 0, 1))

        _sdram = SDRAM(2**11)

        links = list()

        links.append(Link(0, 0, e, 1, 1))
        links.append(Link(0, 1, ne, 1, 0))
        links.append(Link(1, 1, n, 0, 0))
        links.append(Link(1, 0, w, 0, 1))
        r = Router(links, False, 1024)

        ip = "192.162.240.253"
        chips = list()
        for x in range(5):
            for y in range(5):
                if x == y == 0:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0, ip))
                else:
                    chips.append(Chip(x, y, n_processors, r, _sdram, 0, 0))

        self.machine = machine_from_chips(chips)
        large_vertex = SimpleTestVertex(3000,
                                        "Large vertex",
                                        max_atoms_per_core=1)
        large_vertex.splitter = SplitterSliceLegacy()
        self.assertEqual(large_vertex._model_based_max_atoms_per_core, 1)
        self.graph = ApplicationGraph("Graph with large vertex")
        self.graph.add_vertex(large_vertex)
        with self.assertRaises(PacmanValueError):
            self.bp(self.graph, self.machine, 3000,
                    PreAllocatedResourceContainer())
    def load_fixed_route(self, x, y, fixed_route, app_id=0):
        """ Load a fixed route routing entry onto a chip.

        :param x: The x-coordinate of the chip, between 0 and 255; \
            this is not checked due to speed restrictions.
        :type x: int
        :param y: The y-coordinate of the chip, between 0 and 255; \
            this is not checked due to speed restrictions.
        :type y: int
        :param fixed_route: the fixed route entry
        :param app_id: The ID of the application with which to associate the\
            routes.  If not specified, defaults to 0.
        :type app_id: int
        :rtype: None
        """
        route_entry = \
            Router.convert_routing_table_entry_to_spinnaker_route(fixed_route)
        self._send_request(FixedRouteInit(x, y, route_entry, app_id))
        self._finish()
        self.check_for_error()
Esempio n. 21
0
    def test_partition_with_insufficient_space(self):
        """
        test that if there's not enough space, the test the partitioner will
        raise an error
        """
        self.setup()
        flops = 1000
        (e, _, n, w, _, s) = range(6)

        processors = list()
        for i in range(18):
            processors.append(Processor(i, flops))

        links = list()
        links.append(Link(0, 0, 0, 0, 1, s, s))

        _sdram = SDRAM(2**11)

        links = list()

        links.append(Link(0, 0, 0, 1, 1, n, n))
        links.append(Link(0, 1, 1, 1, 0, s, s))
        links.append(Link(1, 1, 2, 0, 0, e, e))
        links.append(Link(1, 0, 3, 0, 1, w, w))
        r = Router(links, False, 100, 1024)

        ip = TestBasicPartitioner.TheTestAddress
        chips = list()
        for x in range(5):
            for y in range(5):
                chips.append(Chip(x, y, processors, r, _sdram, 0, 0, ip))

        self.machine = Machine(chips, 0, 0)
        large_vertex = SimpleTestVertex(3000,
                                        "Large vertex",
                                        max_atoms_per_core=1)
        self.assertEqual(large_vertex._model_based_max_atoms_per_core, 1)
        self.graph = ApplicationGraph("Graph with large vertex")
        self.graph.add_vertex(large_vertex)
        with self.assertRaises(PacmanPartitionException):
            self.bp(self.graph, self.machine)
Esempio n. 22
0
    def test_partition_with_barely_sufficient_space(self):
        """
        test that partitioning will work when close to filling the machine
        """
        self.setup()
        flops = 20000000
        (e, _, n, w, _, s) = range(6)

        processors = list()
        for i in range(18):
            processors.append(Processor(i, flops))

        links = list()
        links.append(Link(0, 0, 0, 0, 1, s, s))

        _sdram = SDRAM(2**12)

        links = list()

        links.append(Link(0, 0, 0, 1, 1, n, n))
        links.append(Link(0, 1, 1, 1, 0, s, s))
        links.append(Link(1, 1, 2, 0, 0, e, e))
        links.append(Link(1, 0, 3, 0, 1, w, w))
        r = Router(links, False, 100, 1024)

        ip = TestBasicPartitioner.TheTestAddress
        chips = list()
        for x in range(5):
            for y in range(5):
                chips.append(Chip(x, y, processors, r, _sdram, 0, 0, ip))

        self.machine = Machine(chips, 0, 0)
        singular_vertex = SimpleTestVertex(450,
                                           "Large vertex",
                                           max_atoms_per_core=1)
        self.assertEqual(singular_vertex._model_based_max_atoms_per_core, 1)
        self.graph = ApplicationGraph("Graph with large vertex")
        self.graph.add_vertex(singular_vertex)
        graph, _, _ = self.bp(self.graph, self.machine)
        self.assertEqual(singular_vertex._model_based_max_atoms_per_core, 1)
        self.assertEqual(len(list(graph.vertices)), 450)
    def load_routes(self, x, y, routes, app_id):
        # Create the routing data - 16 bytes per entry plus one for the end
        # entry
        routing_data = bytearray(16 * (len(routes) + 1))
        n_entries = 0
        for route in routes:
            route_entry = \
                Router.convert_routing_table_entry_to_spinnaker_route(route)

            _ROUTE_PATTERN.pack_into(
                routing_data, n_entries * 16, n_entries,
                route_entry, route.routing_entry_key, route.mask)
            n_entries += 1

        # Add an entry to mark the end
        _END_PATTERN.pack_into(
            routing_data, n_entries * 16,
            0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)

        # Upload the data
        table_address = 0x67800000
        process = WriteMemoryProcess(self._next_connection_selector)
        process.write_memory_from_bytearray(
            x, y, 0, table_address, routing_data, 0, len(routing_data))

        # Allocate space in the router table
        self._send_request(RouterAlloc(x, y, app_id, n_entries),
                           self.handle_router_alloc_response)
        self._finish()
        self.check_for_error()
        if self._base_address == 0:
            raise SpinnmanInvalidParameterException(
                "Allocation base address", str(self._base_address),
                "Not enough space to allocate the entries")

        # Load the entries
        self._send_request(
            RouterInit(
                x, y, n_entries, table_address, self._base_address, app_id))
        self._finish()
        self.check_for_error()
Esempio n. 24
0
    def _make_router(self, chip_info, machine):
        """
        :param ChipSummaryInfo chip_info:
        :param ~spinn_machine.Machine machine:
        :rtype: ~spinn_machine.Router
        """
        links = list()
        for link in chip_info.working_links:
            dest_xy = machine.xy_over_link(chip_info.x, chip_info.y, link)
            if dest_xy in self._chip_info:
                links.append(
                    Link(chip_info.x, chip_info.y, link, dest_xy[0],
                         dest_xy[1]))
            else:
                logger.warning(
                    "Link {},{}:{} points to {} but that is not included ",
                    chip_info.x, chip_info.y, link, dest_xy)

        return Router(links=links,
                      n_available_multicast_entries=(
                          chip_info.n_free_multicast_routing_entries))
    def _build_data(
            self, routing_table, app_id, compress_only_when_needed,
            compress_as_much_as_possible):
        """ Convert the router table into the data needed by the router\
            compressor c code.

        :param routing_table: the pacman router table instance
        :param app_id: the application ID to load the entries in by
        :param compress_only_when_needed:\
            If True, the compressor will only compress if the table doesn't\
            fit in the current router space, otherwise it will just load\
            the table
        :type compress_only_when_needed: bool
        :param compress_as_much_as_possible:\
            If False, the compressor will only reduce the table until it fits\
            in the router space, otherwise it will try to reduce until it\
            until it can't reduce it any more
        :type compress_as_much_as_possible: bool
        :return: The byte array of data
        """

        # write header data of the app ID to load the data, if to store
        # results in SDRAM and the router table entries

        data = b''
        data += _FOUR_WORDS.pack(
            app_id, int(compress_only_when_needed),
            int(compress_as_much_as_possible),
            # Write the size of the table
            routing_table.number_of_entries)

        for entry in routing_table.multicast_routing_entries:
            data += _FOUR_WORDS.pack(
                entry.routing_entry_key, entry.mask,
                Router.convert_routing_table_entry_to_spinnaker_route(entry),
                self._make_source_hack(entry))
        return bytearray(data)
    def _build_data(
            self, routing_table, app_id, compress_only_when_needed,
            compress_as_much_as_possible):
        """ Convert the router table into the data needed by the router\
            compressor c code.

        :param routing_table: the pacman router table instance
        :param app_id: the application ID to load the entries in by
        :param compress_only_when_needed:\
            If True, the compressor will only compress if the table doesn't\
            fit in the current router space, otherwise it will just load\
            the table
        :type compress_only_when_needed: bool
        :param compress_as_much_as_possible:\
            If False, the compressor will only reduce the table until it fits\
            in the router space, otherwise it will try to reduce until it\
            until it can't reduce it any more
        :type compress_as_much_as_possible: bool
        :return: The byte array of data
        """

        # write header data of the app ID to load the data, if to store
        # results in SDRAM and the router table entries

        data = b''
        data += _FOUR_WORDS.pack(
            app_id, int(compress_only_when_needed),
            int(compress_as_much_as_possible),
            # Write the size of the table
            routing_table.number_of_entries)

        for entry in routing_table.multicast_routing_entries:
            data += _FOUR_WORDS.pack(
                entry.routing_entry_key, entry.mask,
                Router.convert_routing_table_entry_to_spinnaker_route(entry),
                self._make_source_hack(entry))
        return bytearray(data)
 def test_convert_to_route(self):
     e = MulticastRoutingEntry(28, 60, [4, 5, 7], [1, 3, 5], True)
     r = Router.convert_routing_table_entry_to_spinnaker_route(e)
     self.assertEqual(r, 11306)
Esempio n. 28
0
    def setUp(self):
        #######################################################################
        # Setting up vertices, edges and graph                                #
        #######################################################################
        self.vert1 = T_AppVertex(100, "New AbstractConstrainedVertex 1")
        self.vert2 = T_AppVertex(5, "New AbstractConstrainedVertex 2")
        self.vert3 = T_AppVertex(3, "New AbstractConstrainedVertex 3")
        self.edge1 = ApplicationEdge(self.vert1, self.vert2, "First edge")
        self.edge2 = ApplicationEdge(self.vert2, self.vert1, "Second edge")
        self.edge3 = ApplicationEdge(self.vert1, self.vert3, "Third edge")
        self.verts = [self.vert1, self.vert2, self.vert3]
        self.edges = [self.edge1, self.edge2, self.edge3]
        self.graph = ApplicationGraph("Graph", self.verts, self.edges)

        #######################################################################
        # Setting up machine                                                  #
        #######################################################################
        flops = 1000
        (_, _, n, _, _, s) = range(6)

        processors = list()
        for i in range(18):
            processors.append(Processor(i, flops))

        _sdram = SDRAM(128 * (2**20))

        ip = "192.168.240.253"
        chips = list()
        for x in range(10):
            for y in range(10):
                links = list()

                links.append(Link(x, y, 0, (x + 1) % 10, y, n, n))
                links.append(Link(x, y, 1, (x + 1) % 10, (y + 1) % 10, s, s))
                links.append(Link(x, y, 2, x, (y + 1) % 10, n, n))
                links.append(Link(x, y, 3, (x - 1) % 10, y, s, s))
                links.append(Link(x, y, 4, (x - 1) % 10, (y - 1) % 10, n, n))
                links.append(Link(x, y, 5, x, (y - 1) % 10, s, s))

                r = Router(links, False, 100, 1024)
                chips.append(Chip(x, y, processors, r, _sdram, ip))

        self.machine = Machine(chips)
        #######################################################################
        # Setting up graph and graph_mapper                                   #
        #######################################################################
        self.vertices = list()
        self.vertex1 = T_MachineVertex(0, 1,
                                       get_resources_used_by_atoms(0, 1, []),
                                       "First vertex")
        self.vertex2 = T_MachineVertex(1, 5,
                                       get_resources_used_by_atoms(1, 5, []),
                                       "Second vertex")
        self.vertex3 = T_MachineVertex(5, 10,
                                       get_resources_used_by_atoms(5, 10, []),
                                       "Third vertex")
        self.vertex4 = T_MachineVertex(
            10, 100, get_resources_used_by_atoms(10, 100, []), "Fourth vertex")
        self.vertices.append(self.vertex1)
        self.vertices.append(self.vertex2)
        self.vertices.append(self.vertex3)
        self.vertices.append(self.vertex4)
        self.edges = list()
        self.graph = MachineGraph(self.vertices, self.edges)
        self.graph_mapper = GraphMapper()
        self.graph_mapper.add_vertices(self.vertices)
    def _build_cluster_graph(
            self, outgoing_partitions, placements, machine, routing_tables):
        """Build a graph the nodes of which represent the chips on which the
        vertices representing a single operator have been placed and the edges 
        of which represent constraints upon which of these chips may share 
        routing identifiers for the purposes of this set of vertices.

        :param outgoing_partitions : list of outgoing partitions 
        :param placements:
        :param machine:
        :param routing_tables:

        Returns
        -------
        {(x, y): {(x, y), ...}, ...}
            An adjacency list representation of the graph described above.
        """

        # Adjacency list represent of the graph
        cluster_graph = defaultdict(set)

        for outgoing_partition in outgoing_partitions:
            # Build up a dictionary which maps each chip to a mapping of the
            # routes from this chip to the source cluster of the multicast
            # nets which take these routes. This will allow us to determine
            # which clusters need to be uniquely identified.
            chips_routes_clusters = defaultdict(lambda: defaultdict(set))

            source_placement = placements.get_placement_of_vertex(
                outgoing_partition.pre_vertex)

            for edge in outgoing_partition.edges:
                dest_placement = placements.get_placement_of_vertex(
                    edge.post_vertex)
                path = self._recursive_trace_to_destination(
                    source_placement.x, source_placement.y, outgoing_partition,
                    dest_placement.x, dest_placement.y, machine, routing_tables)

                # Ensure every cluster is in the graph
                source_chip = machine.get_chip_at(
                    source_placement.x, source_placement.y)
                for (chip, entry) in path:
                    route = (
                        Router.convert_routing_table_entry_to_spinnaker_route(
                            entry))
                    # Add this cluster to the set of clusters whose net takes
                    # this route at this point.
                    chips_routes_clusters[chip][route].add(source_chip)

                    # Add constraints to the cluster graph dependent on which
                    # multicast nets take different routes at this point.
                    routes_from_chip = chips_routes_clusters[chip]
                    for other_route, clusters in iteritems(routes_from_chip):
                        # We care about different routes
                        if other_route != route:
                            for cluster in clusters:
                                # This cluster cannot share an identifier with
                                # any of the clusters whose nets take a
                                # different route at this point.
                                cluster_graph[source_chip].add(cluster)
                                cluster_graph[cluster].add(source_chip)
        return cluster_graph
 def __encode_route(self, entry):
     route = self._app_id << _BIT_SHIFT_TO_MOVE_APP_ID
     route |= Router.convert_routing_table_entry_to_spinnaker_route(entry)
     return route