Ejemplo n.º 1
0
    def __call__(self, machine_graph, machine, plan_n_timesteps):
        """ Place a machine_graph so that each vertex is placed on a core

        :param machine_graph: The machine_graph to place
        :type machine_graph:\
            :py:class:`pacman.model.graphs.machine.MachineGraph`
        :param machine:\
            The machine with respect to which to partition the application\
            graph
        :type machine: :py:class:`spinn_machine.Machine`
        :param plan_n_timesteps: number of timesteps to plan for
        :type  plan_n_timesteps: int
        :return: A set of placements
        :rtype: :py:class:`pacman.model.placements.Placements`
        :raise pacman.exceptions.PacmanPlaceException: \
            If something goes wrong with the placement
        """

        # check that the algorithm can handle the constraints
        ResourceTracker.check_constraints(machine_graph.vertices)

        placements = Placements()
        vertices = sort_vertices_by_known_constraints(machine_graph.vertices)

        # Iterate over vertices and generate placements
        progress = ProgressBar(vertices, "Placing graph vertices")
        resource_tracker = ResourceTracker(machine, plan_n_timesteps)
        for vertex in progress.over(vertices):
            # Create and store a new placement anywhere on the board
            (x, y, p, _, _) = resource_tracker.allocate_constrained_resources(
                vertex.resources_required, vertex.constraints, None)
            placement = Placement(vertex, x, y, p)
            placements.add_placement(placement)
        return placements
def test_ner_route_default():
    unittest_setup()
    graph = MachineGraph("Test")
    machine = virtual_machine(8, 8)
    placements = Placements()

    source_vertex = SimpleMachineVertex(None)
    graph.add_vertex(source_vertex)
    placements.add_placement(Placement(source_vertex, 0, 0, 1))
    target_vertex = SimpleMachineVertex(None)
    graph.add_vertex(target_vertex)
    placements.add_placement(Placement(target_vertex, 0, 2, 1))
    edge = MachineEdge(source_vertex, target_vertex)
    graph.add_edge(edge, "Test")
    partition = graph.get_outgoing_partition_for_edge(edge)

    routes = ner_route(graph, machine, placements)

    source_route = routes.get_entries_for_router(0, 0)[partition]
    assert (not source_route.defaultable)
    mid_route = routes.get_entries_for_router(0, 1)[partition]
    print(mid_route.incoming_link, mid_route.link_ids)
    assert (mid_route.defaultable)
    end_route = routes.get_entries_for_router(0, 2)[partition]
    assert (not end_route.defaultable)
Ejemplo n.º 3
0
    def test_routing(self):
        graph = MachineGraph("Test")
        machine = VirtualMachine(2, 2)
        placements = Placements()
        vertices = list()

        for x in range(machine.max_chip_x + 1):
            for y in range(machine.max_chip_y + 1):
                chip = machine.get_chip_at(x, y)
                if chip is not None:
                    for processor in chip.processors:
                        if not processor.is_monitor:
                            vertex = SimpleMachineVertex(
                                resources=ResourceContainer())
                            graph.add_vertex(vertex)
                            placements.add_placement(
                                Placement(vertex, x, y,
                                          processor.processor_id))
                            vertices.append(vertex)

        for vertex in vertices:
            for vertex_to in vertices:
                if vertex != vertex_to:
                    graph.add_edge(MachineEdge(vertex, vertex_to), "Test")

        router = BasicDijkstraRouting()
        routing_paths = router.__call__(placements, machine, graph)

        for vertex in vertices:
            vertices_reached = set()
            queue = deque()
            seen_entries = set()
            placement = placements.get_placement_of_vertex(vertex)
            partition = graph.get_outgoing_edge_partition_starting_at_vertex(
                vertex, "Test")
            entry = routing_paths.get_entry_on_coords_for_edge(
                partition, placement.x, placement.y)
            self.assertEqual(entry.incoming_processor, placement.p)
            queue.append((placement.x, placement.y))
            while len(queue) > 0:
                x, y = queue.pop()
                entry = routing_paths.get_entry_on_coords_for_edge(
                    partition, x, y)
                self.assertIsNotNone(entry)
                chip = machine.get_chip_at(x, y)
                for p in entry.out_going_processors:
                    self.assertIsNotNone(chip.get_processor_with_id(p))
                    vertex_found = placements.get_vertex_on_processor(x, y, p)
                    vertices_reached.add(vertex_found)
                seen_entries.add((x, y))
                for link_id in entry.out_going_links:
                    link = chip.router.get_link(link_id)
                    self.assertIsNotNone(link)
                    dest_x, dest_y = link.destination_x, link.destination_y
                    if (dest_x, dest_y) not in seen_entries:
                        queue.append((dest_x, dest_y))

            for vertex_to in vertices:
                if vertex != vertex_to:
                    self.assertIn(vertex_to, vertices_reached)
Ejemplo n.º 4
0
    def __call__(self, machine_graph, machine):
        """ Place a machine_graph so that each vertex is placed on a core

        :param machine_graph: The machine_graph to place
        :type machine_graph:\
            :py:class:`pacman.model.graphs.machine.MachineGraph`
        :return: A set of placements
        :rtype: :py:class:`pacman.model.placements.Placements`
        :raise pacman.exceptions.PacmanPlaceException: \
            If something goes wrong with the placement
        """

        # check that the algorithm can handle the constraints
        ResourceTracker.check_constraints(machine_graph.vertices)

        placements = Placements()
        vertices = sort_vertices_by_known_constraints(machine_graph.vertices)

        # Iterate over vertices and generate placements
        progress = ProgressBar(vertices, "Placing graph vertices")
        resource_tracker = ResourceTracker(machine)
        for vertex in progress.over(vertices):
            # Create and store a new placement anywhere on the board
            (x, y, p, _, _) = resource_tracker.allocate_constrained_resources(
                vertex.resources_required, vertex.constraints, None)
            placement = Placement(vertex, x, y, p)
            placements.add_placement(placement)
        return placements
    def test_routing(self):
        graph = MachineGraph("Test")
        machine = VirtualMachine(2, 2)
        placements = Placements()
        vertices = list()

        for x in range(machine.max_chip_x + 1):
            for y in range(machine.max_chip_y + 1):
                chip = machine.get_chip_at(x, y)
                if chip is not None:
                    for processor in chip.processors:
                        if not processor.is_monitor:
                            vertex = SimpleMachineVertex(
                                resources=ResourceContainer())
                            graph.add_vertex(vertex)
                            placements.add_placement(Placement(
                                vertex, x, y, processor.processor_id))
                            vertices.append(vertex)

        for vertex in vertices:
            for vertex_to in vertices:
                if vertex != vertex_to:
                    graph.add_edge(MachineEdge(vertex, vertex_to), "Test")

        router = BasicDijkstraRouting()
        routing_paths = router.__call__(placements, machine, graph)

        for vertex in vertices:
            vertices_reached = set()
            queue = deque()
            seen_entries = set()
            placement = placements.get_placement_of_vertex(vertex)
            partition = graph.get_outgoing_edge_partition_starting_at_vertex(
                vertex, "Test")
            entry = routing_paths.get_entry_on_coords_for_edge(
                partition, placement.x, placement.y)
            self.assertEqual(entry.incoming_processor, placement.p)
            queue.append((placement.x, placement.y))
            while len(queue) > 0:
                x, y = queue.pop()
                entry = routing_paths.get_entry_on_coords_for_edge(
                    partition, x, y)
                self.assertIsNotNone(entry)
                chip = machine.get_chip_at(x, y)
                for p in entry.processor_ids:
                    self.assertIsNotNone(chip.get_processor_with_id(p))
                    vertex_found = placements.get_vertex_on_processor(x, y, p)
                    vertices_reached.add(vertex_found)
                seen_entries.add((x, y))
                for link_id in entry.link_ids:
                    link = chip.router.get_link(link_id)
                    self.assertIsNotNone(link)
                    dest_x, dest_y = link.destination_x, link.destination_y
                    if (dest_x, dest_y) not in seen_entries:
                        queue.append((dest_x, dest_y))

            for vertex_to in vertices:
                if vertex != vertex_to:
                    self.assertIn(vertex_to, vertices_reached)
    def test_routing(self):
        graph = MachineGraph("Test")
        set_config("Machine", "down_chips", "1,2:5,4:3,3")
        machine = virtual_machine(8, 8)
        placements = Placements()
        vertices = list()

        for chip in machine.chips:
            for processor in chip.processors:
                if not processor.is_monitor:
                    vertex = SimpleMachineVertex(resources=ResourceContainer())
                    graph.add_vertex(vertex)
                    placements.add_placement(
                        Placement(vertex, chip.x, chip.y,
                                  processor.processor_id))
                    vertices.append(vertex)

        for vertex in vertices:
            graph.add_outgoing_edge_partition(
                MulticastEdgePartition(identifier="Test", pre_vertex=vertex))
            for vertex_to in vertices:
                graph.add_edge(MachineEdge(vertex, vertex_to), "Test")

        routing_paths = ner_route_traffic_aware(graph, machine, placements)

        for vertex in vertices:
            vertices_reached = set()
            queue = deque()
            seen_entries = set()
            placement = placements.get_placement_of_vertex(vertex)
            partition = graph.get_outgoing_edge_partition_starting_at_vertex(
                vertex, "Test")
            entry = routing_paths.get_entry_on_coords_for_edge(
                partition, placement.x, placement.y)
            self.assertEqual(entry.incoming_processor, placement.p)
            queue.append((placement.x, placement.y))
            while len(queue) > 0:
                x, y = queue.pop()
                entry = routing_paths.get_entry_on_coords_for_edge(
                    partition, x, y)
                self.assertIsNotNone(entry)
                chip = machine.get_chip_at(x, y)
                for p in entry.processor_ids:
                    self.assertIsNotNone(chip.get_processor_with_id(p))
                    vertex_found = placements.get_vertex_on_processor(x, y, p)
                    vertices_reached.add(vertex_found)
                seen_entries.add((x, y))
                for link_id in entry.link_ids:
                    link = chip.router.get_link(link_id)
                    self.assertIsNotNone(link)
                    dest_x, dest_y = link.destination_x, link.destination_y
                    if (dest_x, dest_y) not in seen_entries:
                        queue.append((dest_x, dest_y))

            for vertex_to in vertices:
                self.assertIn(vertex_to, vertices_reached)
Ejemplo n.º 7
0
def convert_from_rig_placements(
        rig_placements, rig_allocations, machine_graph):
    placements = Placements()
    for vertex in rig_placements:
        if isinstance(vertex, AbstractVirtualVertex):
            placements.add_placement(Placement(
                vertex, vertex.virtual_chip_x, vertex.virtual_chip_y, None))
        else:
            x, y = rig_placements[vertex]
            p = rig_allocations[vertex]["cores"].start
            placements.add_placement(Placement(vertex, x, y, p))

    return placements
Ejemplo n.º 8
0
def convert_from_rig_placements(rig_placements, rig_allocations,
                                machine_graph):
    placements = Placements()
    for vertex in rig_placements:
        if isinstance(vertex, AbstractVirtualVertex):
            placements.add_placement(
                Placement(vertex, vertex.virtual_chip_x, vertex.virtual_chip_y,
                          None))
        else:
            x, y = rig_placements[vertex]
            p = rig_allocations[vertex]["cores"].start
            placements.add_placement(Placement(vertex, x, y, p))

    return placements
    def __call__(self, extended_machine, placements, allocations, constraints,
                 vertex_by_id):
        """
        :param placements:
        :param allocations:
        :param extended_machine:
        :param constraints:
        """

        # load the json files
        file_placements, core_allocations, constraints = \
            self._load_json_files(placements, allocations, constraints)

        # validate the json files against the schemas
        self._validate_file_read_data(file_placements, core_allocations,
                                      constraints)

        memory_placements = Placements()

        # process placements
        for vertex_id in file_placements:
            if str(vertex_id) not in vertex_by_id:
                if text_type(vertex_id) not in core_allocations:
                    raise PacmanConfigurationException(
                        "I don't recognise this pattern of constraints for"
                        " a vertex which does not have a placement")
                else:
                    raise PacmanConfigurationException(
                        "Failed to locate the vertex in the "
                        "graph with id {}".format(vertex_id))

            if text_type(vertex_id) in core_allocations:
                memory_placements.add_placement(
                    Placement(x=file_placements[vertex_id][0],
                              y=file_placements[vertex_id][1],
                              p=core_allocations[vertex_id][0],
                              vertex=vertex_by_id[str(vertex_id)]))
            else:
                # virtual chip or tag chip
                external_device_constraints = \
                    self._valid_constraints_for_external_device(
                        self._locate_constraints(vertex_id, constraints))
                if external_device_constraints:
                    placements.add(
                        self._make_virtual_placement(
                            extended_machine, vertex_by_id[str(vertex_id)],
                            external_device_constraints))

        # return the file format
        return memory_placements
    def __call__(self, extended_machine, placements, allocations,
                 constraints, vertex_by_id):
        """
        :param placements:
        :param allocations:
        :param extended_machine:
        :param constraints:
        """

        # load the json files
        file_placements, core_allocations, constraints = \
            self._load_json_files(placements, allocations, constraints)

        # validate the json files against the schemas
        self._validate_file_read_data(
            file_placements, core_allocations, constraints)

        memory_placements = Placements()

        # process placements
        for vertex_id in file_placements:
            if str(vertex_id) not in vertex_by_id:
                if text_type(vertex_id) not in core_allocations:
                    raise PacmanConfigurationException(
                        "I don't recognise this pattern of constraints for"
                        " a vertex which does not have a placement")
                else:
                    raise PacmanConfigurationException(
                        "Failed to locate the vertex in the "
                        "graph with id {}".format(vertex_id))

            if text_type(vertex_id) in core_allocations:
                memory_placements.add_placement(Placement(
                    x=file_placements[vertex_id][0],
                    y=file_placements[vertex_id][1],
                    p=core_allocations[vertex_id][0],
                    vertex=vertex_by_id[str(vertex_id)]))
            else:
                # virtual chip or tag chip
                external_device_constraints = \
                    self._valid_constraints_for_external_device(
                        self._locate_constraints(vertex_id, constraints))
                if external_device_constraints:
                    placements.add(self._make_virtual_placement(
                        extended_machine, vertex_by_id[str(vertex_id)],
                        external_device_constraints))

        # return the file format
        return memory_placements
def test_memory_io():
    vertex = MyVertex()
    graph = MachineGraph("Test")
    graph.add_vertex(vertex)
    placements = Placements()
    placements.add_placement(Placement(vertex, 0, 0, 1))
    transceiver = _MockTransceiver()
    temp = tempfile.mkdtemp()
    print("ApplicationDataFolder = {}".format(temp))
    inputs = {
        "MemoryTransceiver": transceiver,
        "MemoryMachineGraph": graph,
        "MemoryPlacements": placements,
        "IPAddress": "testing",
        "ApplicationDataFolder": temp,
        "APPID": 30
    }
    algorithms = ["WriteMemoryIOData"]
    executor = PACMANAlgorithmExecutor(
        algorithms, [], inputs, [], [], [],
        xml_paths=get_front_end_common_pacman_xml_paths())
    executor.execute_mapping()
    assert(vertex._test_tag == vertex._tag)
Ejemplo n.º 12
0
    def _do_allocation(self, vertices, machine, same_chip_vertex_groups,
                       machine_graph):
        placements = Placements()

        # Iterate over vertices and generate placements
        progress = ProgressBar(machine_graph.n_vertices,
                               "Placing graph vertices")
        resource_tracker = ResourceTracker(
            machine, self._generate_radial_chips(machine))
        all_vertices_placed = set()

        # iterate over vertices
        for vertex_list in vertices:
            # if too many one to ones to fit on a chip, allocate individually
            if len(vertex_list) > machine.maximum_user_cores_on_chip:
                for vertex in progress.over(vertex_list, False):
                    self._allocate_individual(vertex, placements,
                                              resource_tracker,
                                              same_chip_vertex_groups,
                                              all_vertices_placed)
                continue
            allocations = self._get_allocations(resource_tracker, vertex_list)
            if allocations is not None:
                # allocate cores to vertices
                for vertex, (x, y, p, _,
                             _) in progress.over(zip(vertex_list, allocations),
                                                 False):
                    placements.add_placement(Placement(vertex, x, y, p))
            else:
                # Something went wrong, try to allocate each individually
                for vertex in progress.over(vertex_list, False):
                    self._allocate_individual(vertex, placements,
                                              resource_tracker,
                                              same_chip_vertex_groups,
                                              all_vertices_placed)
        progress.end()
        return placements
Ejemplo n.º 13
0
def test_memory_io():
    vertex = MyVertex()
    graph = MachineGraph("Test")
    graph.add_vertex(vertex)
    placements = Placements()
    placements.add_placement(Placement(vertex, 0, 0, 1))
    transceiver = _MockTransceiver()
    temp = tempfile.mkdtemp()
    print("ApplicationDataFolder = {}".format(temp))
    inputs = {
        "MemoryTransceiver": transceiver,
        "MemoryMachineGraph": graph,
        "MemoryPlacements": placements,
        "IPAddress": "testing",
        "ReportFolder": temp,
        "APPID": 30
    }
    algorithms = ["WriteMemoryIOData"]
    executor = PACMANAlgorithmExecutor(
        algorithms, [],
        inputs, [], [], [],
        xml_paths=get_front_end_common_pacman_xml_paths())
    executor.execute_mapping()
    assert (vertex._test_tag == vertex._tag)
Ejemplo n.º 14
0
    def _do_allocation(
            self, one_to_one_groups, same_chip_vertex_groups,
            machine, plan_n_timesteps, machine_graph, progress):
        """
        :param list(set(MachineVertex)) one_to_one_groups:
            Groups of vertexes that would be nice on same chip
        :param same_chip_vertex_groups:
            Mapping of Vertex to the Vertex that must be on the same Chip
        :type same_chip_vertex_groups:
            dict(MachineVertex, collection(MachineVertex))
        :param ~spinn_machine.Machine machine:
            The machine with respect to which to partition the application
            graph
        :param int plan_n_timesteps: number of timesteps to plan for
        :param MachineGraph machine_graph: The machine_graph to place
        :param ~spinn_utilities.progress_bar.ProgressBar progress:
        :rtype: Placements
        """

        placements = Placements()

        resource_tracker = ResourceTracker(
            machine, plan_n_timesteps, self._generate_radial_chips(machine))
        all_vertices_placed = set()

        # RadialPlacementFromChipConstraint won't work here
        for vertex in machine_graph.vertices:
            for constraint in vertex.constraints:
                if isinstance(constraint, RadialPlacementFromChipConstraint):
                    raise PacmanPlaceException(
                        "A RadialPlacementFromChipConstraint will not work "
                        "with the OneToOnePlacer algorithm; use the "
                        "RadialPlacer algorithm instead")

        # Find and place vertices with hard constraints
        for vertex in machine_graph.vertices:
            if isinstance(vertex, AbstractVirtual):
                virtual_p = 0
                while placements.is_processor_occupied(
                        vertex.virtual_chip_x, vertex.virtual_chip_y,
                        virtual_p):
                    virtual_p += 1
                placements.add_placement(Placement(
                    vertex, vertex.virtual_chip_x, vertex.virtual_chip_y,
                    virtual_p))
                all_vertices_placed.add(vertex)
            elif locate_constraints_of_type(
                    vertex.constraints, ChipAndCoreConstraint):
                self._allocate_same_chip_as_group(
                    vertex, placements, resource_tracker,
                    same_chip_vertex_groups, all_vertices_placed, progress,
                    machine_graph)

        for grouped_vertices in one_to_one_groups:
            # Get unallocated vertices and placements of allocated vertices
            unallocated = list()
            chips = list()
            for vert in grouped_vertices:
                if vert in all_vertices_placed:
                    placement = placements.get_placement_of_vertex(vert)
                    chips.append((placement.x, placement.y))
                else:
                    unallocated.append(vert)
            if not chips:
                chips = None

            if 0 < len(unallocated) <=\
                    resource_tracker.get_maximum_cores_available_on_a_chip():
                # Try to allocate all vertices to the same chip
                self._allocate_one_to_one_group(
                    resource_tracker, unallocated, progress, placements, chips,
                    all_vertices_placed, machine_graph)
            # if too big or failed go on to other groups first

        # check all have been allocated if not do so now.
        for vertex in machine_graph.vertices:
            if vertex not in all_vertices_placed:
                self._allocate_same_chip_as_group(
                    vertex, placements, resource_tracker,
                    same_chip_vertex_groups, all_vertices_placed,
                    progress, machine_graph)

        progress.end()
        return placements
    def _do_dynamic_routing(
            self, fixed_route_tables, placements, ethernet_connected_chip,
            destination_class, machine, board_version):
        """ Uses a router to route fixed routes

        :param fixed_route_tables: fixed route tables entry holder
        :param placements: placements
        :param ethernet_connected_chip: the chip to consider for this routing
        :param destination_class: the class at the Ethernet connected chip\
            for receiving all these routes.
        :param machine: SpiNNMachine instance
        :param board_version: The version of the machine
        :rtype: None
        """
        graph = MachineGraph(label="routing graph")
        fake_placements = Placements()

        # build fake setup for the routing
        eth_x = ethernet_connected_chip.x
        eth_y = ethernet_connected_chip.y
        down_links = set()
        for (chip_x, chip_y) in machine.get_chips_on_board(
                ethernet_connected_chip):
            vertex = RoutingMachineVertex()
            graph.add_vertex(vertex)
            rel_x = chip_x - eth_x
            if rel_x < 0:
                rel_x += machine.max_chip_x + 1
            rel_y = chip_y - eth_y
            if rel_y < 0:
                rel_y += machine.max_chip_y + 1

            free_processor = 0
            while ((free_processor < machine.MAX_CORES_PER_CHIP) and
                   fake_placements.is_processor_occupied(
                       self.FAKE_ETHERNET_CHIP_X,
                       y=self.FAKE_ETHERNET_CHIP_Y,
                       p=free_processor)):
                free_processor += 1

            fake_placements.add_placement(Placement(
                x=rel_x, y=rel_y, p=free_processor, vertex=vertex))
            down_links.update({
                (rel_x, rel_y, link) for link in range(
                    Router.MAX_LINKS_PER_ROUTER)
                if not machine.is_link_at(chip_x, chip_y, link)})

        # Create a fake machine consisting of only the one board that
        # the routes should go over
        fake_machine = machine
        if (board_version in machine.BOARD_VERSION_FOR_48_CHIPS and
                (machine.max_chip_x > machine.MAX_CHIP_X_ID_ON_ONE_BOARD or
                 machine.max_chip_y > machine.MAX_CHIP_Y_ID_ON_ONE_BOARD)):
            down_chips = {
                (x, y) for x, y in zip(
                    range(machine.SIZE_X_OF_ONE_BOARD),
                    range(machine.SIZE_Y_OF_ONE_BOARD))
                if not machine.is_chip_at(
                    (x + eth_x) % (machine.max_chip_x + 1),
                    (y + eth_y) % (machine.max_chip_y + 1))}

            # build a fake machine which is just one board but with the missing
            # bits of the real board
            fake_machine = VirtualMachine(
                machine.SIZE_X_OF_ONE_BOARD, machine.SIZE_Y_OF_ONE_BOARD,
                False, down_chips=down_chips, down_links=down_links)

        # build destination
        verts = graph.vertices
        vertex_dest = RoutingMachineVertex()
        graph.add_vertex(vertex_dest)
        destination_processor = self._locate_destination(
            ethernet_chip_x=ethernet_connected_chip.x,
            ethernet_chip_y=ethernet_connected_chip.y,
            destination_class=destination_class,
            placements=placements)
        fake_placements.add_placement(Placement(
            x=self.FAKE_ETHERNET_CHIP_X, y=self.FAKE_ETHERNET_CHIP_Y,
            p=destination_processor, vertex=vertex_dest))

        # deal with edges
        for vertex in verts:
            graph.add_edge(
                MachineEdge(pre_vertex=vertex, post_vertex=vertex_dest),
                self.FAKE_ROUTING_PARTITION)

        # route as if using multicast
        router = BasicDijkstraRouting()
        routing_tables_by_partition = router(
            placements=fake_placements, machine=fake_machine,
            machine_graph=graph, use_progress_bar=False)

        # convert to fixed route entries
        for (chip_x, chip_y) in routing_tables_by_partition.get_routers():
            mc_entries = routing_tables_by_partition.get_entries_for_router(
                chip_x, chip_y)
            # only want the first entry, as that will all be the same.
            mc_entry = next(itervalues(mc_entries))
            fixed_route_entry = FixedRouteEntry(
                link_ids=mc_entry.link_ids,
                processor_ids=mc_entry.processor_ids)
            x = (chip_x + eth_x) % (machine.max_chip_x + 1)
            y = (chip_y + eth_y) % (machine.max_chip_y + 1)
            key = (x, y)
            if key in fixed_route_tables:
                raise PacmanAlreadyExistsException(
                    "fixed route entry", str(key))
            fixed_route_tables[key] = fixed_route_entry
Ejemplo n.º 16
0
    def _create_fake_network(self, ethernet_connected_chip):
        """ Generate the fake network for each board

        :param ethernet_connected_chip: the ethernet chip to fire from
        :return: fake graph, fake placements, fake machine.
        """

        fake_graph = MachineGraph(label="routing fake_graph")
        fake_placements = Placements()
        destination_to_partition_id_map = dict()

        # build fake setup for the routing
        eth_x = ethernet_connected_chip.x
        eth_y = ethernet_connected_chip.y
        fake_machine = virtual_submachine(self._real_machine,
                                          ethernet_connected_chip)

        # Build a fake graph with vertices for all the monitors
        for chip in self._real_machine.get_chips_by_ethernet(eth_x, eth_y):
            # locate correct chips extra monitor placement
            placement = self._real_placements.get_placement_of_vertex(
                self._monitors[chip.x, chip.y])

            # adjust for wrap around's
            fake_x, fake_y = self._real_machine.get_local_xy(chip)

            # add destination vertex
            vertex = RoutingMachineVertex()
            fake_graph.add_vertex(vertex)

            # build fake placement
            fake_placements.add_placement(
                Placement(x=fake_x, y=fake_y, p=placement.p, vertex=vertex))

        # build source vertex, which is for the Gatherer
        vertex_source = RoutingMachineVertex()
        fake_graph.add_vertex(vertex_source)

        for free_processor in range(Machine.MAX_CORES_PER_CHIP):
            if not fake_placements.is_processor_occupied(
                    x=FAKE_ETHERNET_CHIP_X,
                    y=FAKE_ETHERNET_CHIP_Y,
                    p=free_processor):
                fake_placements.add_placement(
                    Placement(x=FAKE_ETHERNET_CHIP_X,
                              y=FAKE_ETHERNET_CHIP_Y,
                              p=free_processor,
                              vertex=vertex_source))
                break

        # deal with edges, each one being in a unique partition id, to
        # allow unique routing to each chip.
        counter = KEY_START_VALUE
        for vertex in fake_graph.vertices:
            if vertex == vertex_source:
                continue
            fake_graph.add_edge(
                MachineEdge(pre_vertex=vertex_source, post_vertex=vertex),
                counter)
            placement = fake_placements.get_placement_of_vertex(vertex)

            # adjust to real chip ids
            real_chip_xy = self._real_machine.get_global_xy(
                placement.x, placement.y, eth_x, eth_y)
            destination_to_partition_id_map[real_chip_xy] = counter
            counter += N_KEYS_PER_PARTITION_ID

        return (fake_graph, fake_placements, fake_machine,
                destination_to_partition_id_map)
Ejemplo n.º 17
0
    def __call__(self, machine_graph, machine, n_keys_map, plan_n_timesteps):
        """
        :param MachineGraph machine_graph: the machine graph
        :param ~spinn_machine.Machine machine: the SpiNNaker machine
        :param AbstractMachinePartitionNKeysMap n_keys_map:
            the n keys from partition map
        :param int plan_n_timesteps: number of timesteps to plan for
        :return: placements.
        :rtype: Placements
        """
        # create progress bar
        progress_bar = ProgressBar(
            (machine_graph.n_vertices * self.ITERATIONS) + self.STEPS,
            "Placing graph vertices via spreading over an entire machine")

        # check that the algorithm can handle the constraints
        self._check_constraints(
            machine_graph.vertices,
            additional_placement_constraints={SameChipAsConstraint})
        progress_bar.update()

        # get same chip groups
        same_chip_vertex_groups = get_same_chip_vertex_groups(machine_graph)
        progress_bar.update()
        # get chip and core placed verts
        hard_chip_constraints = self._locate_hard_placement_verts(
            machine_graph)
        progress_bar.update()
        # get one to one groups
        one_to_one_groups = create_vertices_groups(
            machine_graph.vertices,
            functools.partial(self._find_one_to_one_vertices,
                              graph=machine_graph))
        progress_bar.update()

        # sort chips so that they are radial from a given point and other
        # init data structs
        chips_in_order = self._determine_chip_list(machine)
        resource_tracker = ResourceTracker(machine,
                                           plan_n_timesteps,
                                           chips=chips_in_order)
        placements = Placements()
        placed_vertices = set()
        cost_per_chip = defaultdict(int)
        progress_bar.update()

        # allocate hard ones
        for hard_vertex in hard_chip_constraints:
            (x, y, p, _, _) = resource_tracker.allocate_constrained_resources(
                hard_vertex.resources_required, hard_vertex.constraints)
            placements.add_placement(Placement(hard_vertex, x, y, p))
            placed_vertices.add(hard_vertex)
            cost_per_chip[x, y] += self._get_cost(hard_vertex, machine_graph,
                                                  n_keys_map)

        # place groups of verts that need the same chip on the same chip,
        self._place_same_chip_verts(same_chip_vertex_groups, chips_in_order,
                                    placements, progress_bar, resource_tracker,
                                    placed_vertices, cost_per_chip,
                                    machine_graph, n_keys_map)

        # place 1 group per chip if possible on same chip as any already
        # placed verts. if not then radially from it.
        self._place_one_to_one_verts(one_to_one_groups, chips_in_order,
                                     placements, progress_bar,
                                     resource_tracker, placed_vertices,
                                     cost_per_chip, machine_graph, n_keys_map,
                                     machine)

        # place vertices which don't have annoying placement constraints.
        # spread them over the chips so that they have minimal impact on the
        # overall incoming packet cost per router.
        self._place_left_over_verts(machine_graph, chips_in_order, placements,
                                    progress_bar, resource_tracker,
                                    placed_vertices, cost_per_chip, n_keys_map)
        progress_bar.end()

        # return the built placements
        return placements
Ejemplo n.º 18
0
    def _do_allocation(
            self, one_to_one_groups, same_chip_vertex_groups,
            machine, plan_n_timesteps, machine_graph, progress):
        """

        :param one_to_one_groups:
            Groups of vertexes that would be nice on same chip
        :type one_to_one_groups:
            list(set(vertex))
        :param same_chip_vertex_groups:
            Mapping of Vertex to the Vertex that must be on the same Chip
        :type same_chip_vertex_groups:
            dict(vertex, collection(vertex))
        :param machine:\
            The machine with respect to which to partition the application\
            graph
        :type machine: :py:class:`spinn_machine.Machine`
        :param plan_n_timesteps: number of timesteps to plan for
        :type  plan_n_timesteps: int
        :param machine_graph: The machine_graph to place
        :type machine_graph:\
            :py:class:`pacman.model.graphs.machine.MachineGraph`
        :param progress:
        :return:
        """

        placements = Placements()

        resource_tracker = ResourceTracker(
            machine, plan_n_timesteps, self._generate_radial_chips(machine))
        all_vertices_placed = set()

        # RadialPlacementFromChipConstraint won't work here
        for vertex in machine_graph.vertices:
            for constraint in vertex.constraints:
                if isinstance(constraint, RadialPlacementFromChipConstraint):
                    raise PacmanPlaceException(
                        "A RadialPlacementFromChipConstraint will not work "
                        "with the OneToOnePlacer algorithm; use the "
                        "RadialPlacer algorithm instead")

        unconstrained = list()
        # Find and place vertices with hard constraints
        for vertex in machine_graph.vertices:
            if isinstance(vertex, AbstractVirtualVertex):
                virtual_p = 0
                while placements.is_processor_occupied(
                        vertex.virtual_chip_x, vertex.virtual_chip_y,
                        virtual_p):
                    virtual_p += 1
                placements.add_placement(Placement(
                    vertex, vertex.virtual_chip_x, vertex.virtual_chip_y,
                    virtual_p))
                all_vertices_placed.add(vertex)
            elif locate_constraints_of_type(
                    vertex.constraints, ChipAndCoreConstraint):
                self._allocate_same_chip_as_group(
                    vertex, placements, resource_tracker,
                    same_chip_vertex_groups,
                    all_vertices_placed, progress)
            else:
                unconstrained.append(vertex)

        for grouped_vertices in one_to_one_groups:
            # Get unallocated vertices and placements of allocated vertices
            unallocated = list()
            chips = list()
            for vert in grouped_vertices:
                if vert in all_vertices_placed:
                    placement = placements.get_placement_of_vertex(vert)
                    chips.append((placement.x, placement.y))
                else:
                    unallocated.append(vert)

            if 0 < len(unallocated) <=\
                    resource_tracker.get_maximum_cores_available_on_a_chip():
                # Try to allocate all vertices to the same chip
                self._allocate_one_to_one_group(
                    resource_tracker, unallocated, progress, placements, chips,
                    all_vertices_placed)
            # if too big or failed go on to other groups first

        # check all have been allocated if not do so now.
        for vertex in machine_graph.vertices:
            if vertex not in all_vertices_placed:
                self._allocate_same_chip_as_group(
                    vertex, placements, resource_tracker,
                    same_chip_vertex_groups, all_vertices_placed,
                    progress)

        progress.end()
        return placements
Ejemplo n.º 19
0
    def test_local_verts_go_to_local_lpgs(self):
        machine = VirtualMachine(width=12, height=12, with_wrap_arounds=True)
        graph = MachineGraph("Test")

        default_params = {
            'use_prefix': False,
            'key_prefix': None,
            'prefix_type': None,
            'message_type': EIEIOType.KEY_32_BIT,
            'right_shift': 0,
            'payload_as_time_stamps': True,
            'use_payload_prefix': True,
            'payload_prefix': None,
            'payload_right_shift': 0,
            'number_of_packets_sent_per_time_step': 0,
            'hostname': None,
            'port': None,
            'strip_sdp': None,
            'board_address': None,
            'tag': None,
            'label': "test"
        }

        # data stores needed by algorithm
        live_packet_gatherers = dict()
        extended = dict(default_params)
        extended.update({'partition_id': "EVENTS"})
        default_params_holder = LivePacketGatherParameters(**extended)
        live_packet_gatherers[default_params_holder] = list()

        live_packet_gatherers_to_vertex_mapping = dict()
        live_packet_gatherers_to_vertex_mapping[default_params_holder] = dict()

        placements = Placements()

        # add LPG's (1 for each Ethernet connected chip)
        for chip in machine.ethernet_connected_chips:
            vertex = LivePacketGatherMachineVertex(**default_params)
            graph.add_vertex(vertex)
            placements.add_placement(
                Placement(x=chip.x, y=chip.y, p=2, vertex=vertex))
            live_packet_gatherers_to_vertex_mapping[default_params_holder][
                chip.x, chip.y] = vertex

        # tracker of wirings
        verts_expected = defaultdict(list)
        positions = list()
        positions.append([0, 0, 0, 0])
        positions.append([4, 4, 0, 0])
        positions.append([1, 1, 0, 0])
        positions.append([2, 2, 0, 0])
        positions.append([8, 4, 8, 4])
        positions.append([11, 4, 8, 4])
        positions.append([4, 11, 4, 8])
        positions.append([4, 8, 4, 8])
        positions.append([0, 11, 8, 4])
        positions.append([11, 11, 4, 8])
        positions.append([8, 8, 4, 8])
        positions.append([4, 0, 0, 0])
        positions.append([7, 7, 0, 0])

        # add graph vertices which reside on areas of the machine to ensure
        #  spread over boards.
        for x, y, eth_x, eth_y in positions:
            vertex = SimpleMachineVertex(resources=ResourceContainer())
            graph.add_vertex(vertex)
            live_packet_gatherers[default_params_holder].append(vertex)
            verts_expected[eth_x, eth_y].append(vertex)
            placements.add_placement(Placement(x=x, y=y, p=5, vertex=vertex))

        # run edge inserter that should go boom
        edge_inserter = InsertEdgesToLivePacketGatherers()
        edge_inserter(live_packet_gatherer_parameters=live_packet_gatherers,
                      placements=placements,
                      live_packet_gatherers_to_vertex_mapping=(
                          live_packet_gatherers_to_vertex_mapping),
                      machine=machine,
                      machine_graph=graph,
                      application_graph=None,
                      graph_mapper=None)

        # verify edges are in the right place
        for chip in machine.ethernet_connected_chips:
            edges = graph.get_edges_ending_at_vertex(
                live_packet_gatherers_to_vertex_mapping[default_params_holder][
                    chip.x, chip.y])
            for edge in edges:
                self.assertIn(edge.pre_vertex, verts_expected[chip.x, chip.y])
Ejemplo n.º 20
0
    def _do_dynamic_routing(
            self, fixed_route_tables, placements, ethernet_connected_chip,
            destination_class, machine, board_version):
        """ Uses a router to route fixed routes

        :param fixed_route_tables: fixed route tables entry holder
        :param placements: placements
        :param ethernet_connected_chip: the chip to consider for this routing
        :param destination_class: the class at the Ethernet connected chip\
            for receiving all these routes.
        :param machine: SpiNNMachine instance
        :param board_version: The version of the machine
        :rtype: None
        """
        graph = MachineGraph(label="routing graph")
        fake_placements = Placements()

        # build fake setup for the routing
        eth_x = ethernet_connected_chip.x
        eth_y = ethernet_connected_chip.y
        down_links = set()
        for (chip_x, chip_y) in machine.get_chips_on_board(
                ethernet_connected_chip):
            vertex = RoutingMachineVertex()
            graph.add_vertex(vertex)
            rel_x = chip_x - eth_x
            if rel_x < 0:
                rel_x += machine.max_chip_x + 1
            rel_y = chip_y - eth_y
            if rel_y < 0:
                rel_y += machine.max_chip_y + 1

            free_processor = 0
            while ((free_processor < machine.MAX_CORES_PER_CHIP) and
                   fake_placements.is_processor_occupied(
                       self.FAKE_ETHERNET_CHIP_X,
                       y=self.FAKE_ETHERNET_CHIP_Y,
                       p=free_processor)):
                free_processor += 1

            fake_placements.add_placement(Placement(
                x=rel_x, y=rel_y, p=free_processor, vertex=vertex))
            down_links.update({
                (rel_x, rel_y, link) for link in range(
                    Router.MAX_LINKS_PER_ROUTER)
                if not machine.is_link_at(chip_x, chip_y, link)})

        # Create a fake machine consisting of only the one board that
        # the routes should go over
        fake_machine = machine
        if (board_version in machine.BOARD_VERSION_FOR_48_CHIPS and
                (machine.max_chip_x > machine.MAX_CHIP_X_ID_ON_ONE_BOARD or
                 machine.max_chip_y > machine.MAX_CHIP_Y_ID_ON_ONE_BOARD)):
            down_chips = {
                (x, y) for x, y in zip(
                    range(machine.SIZE_X_OF_ONE_BOARD),
                    range(machine.SIZE_Y_OF_ONE_BOARD))
                if not machine.is_chip_at(
                    (x + eth_x) % (machine.max_chip_x + 1),
                    (y + eth_y) % (machine.max_chip_y + 1))}

            # build a fake machine which is just one board but with the missing
            # bits of the real board
            fake_machine = VirtualMachine(
                machine.SIZE_X_OF_ONE_BOARD, machine.SIZE_Y_OF_ONE_BOARD,
                False, down_chips=down_chips, down_links=down_links)

        # build destination
        verts = graph.vertices
        vertex_dest = RoutingMachineVertex()
        graph.add_vertex(vertex_dest)
        destination_processor = self._locate_destination(
            ethernet_chip_x=ethernet_connected_chip.x,
            ethernet_chip_y=ethernet_connected_chip.y,
            destination_class=destination_class,
            placements=placements)
        fake_placements.add_placement(Placement(
            x=self.FAKE_ETHERNET_CHIP_X, y=self.FAKE_ETHERNET_CHIP_Y,
            p=destination_processor, vertex=vertex_dest))

        # deal with edges
        for vertex in verts:
            graph.add_edge(
                MachineEdge(pre_vertex=vertex, post_vertex=vertex_dest),
                self.FAKE_ROUTING_PARTITION)

        # route as if using multicast
        router = BasicDijkstraRouting()
        routing_tables_by_partition = router(
            placements=fake_placements, machine=fake_machine,
            machine_graph=graph, use_progress_bar=False)

        # convert to fixed route entries
        for (chip_x, chip_y) in routing_tables_by_partition.get_routers():
            mc_entries = routing_tables_by_partition.get_entries_for_router(
                chip_x, chip_y)
            # only want the first entry, as that will all be the same.
            mc_entry = next(itervalues(mc_entries))
            fixed_route_entry = FixedRouteEntry(
                link_ids=mc_entry.out_going_links,
                processor_ids=mc_entry.out_going_processors)
            x = (chip_x + eth_x) % (machine.max_chip_x + 1)
            y = (chip_y + eth_y) % (machine.max_chip_y + 1)
            key = (x, y)
            if key in fixed_route_tables:
                raise PacmanAlreadyExistsException(
                    "fixed route entry", str(key))
            fixed_route_tables[key] = fixed_route_entry
Ejemplo n.º 21
0
    def test_local_verts_go_to_local_lpgs_app_graph(self):
        machine = virtual_machine(width=12, height=12)
        app_graph = ApplicationGraph("Test")
        graph = MachineGraph("Test", app_graph)

        default_params = {
            'use_prefix': False,
            'key_prefix': None,
            'prefix_type': None,
            'message_type': EIEIOType.KEY_32_BIT,
            'right_shift': 0,
            'payload_as_time_stamps': True,
            'use_payload_prefix': True,
            'payload_prefix': None,
            'payload_right_shift': 0,
            'number_of_packets_sent_per_time_step': 0,
            'hostname': None,
            'port': None,
            'strip_sdp': None,
            'tag': None,
            'label': "Test"}

        # data stores needed by algorithm
        live_packet_gatherers = dict()
        default_params_holder = LivePacketGatherParameters(**default_params)
        live_packet_gatherers[default_params_holder] = list()

        live_packet_gatherers_to_vertex_mapping = defaultdict(dict)

        placements = Placements()

        # add LPG's (1 for each Ethernet connected chip
        for chip in machine.ethernet_connected_chips:
            new_params = dict(default_params)
            vertex = LivePacketGather(
                LivePacketGatherParameters(**new_params))
            app_graph.add_vertex(vertex)
            vertex_slice = None
            resources_required = vertex.get_resources_used_by_atoms(
                vertex_slice)
            mac_vertex = vertex.create_machine_vertex(
                vertex_slice, resources_required)
            graph.add_vertex(mac_vertex)
            placements.add_placement(
                Placement(x=chip.x, y=chip.y, p=2, vertex=mac_vertex))
            live_packet_gatherers_to_vertex_mapping[
                default_params_holder][chip.x, chip.y] = mac_vertex

        # tracker of wirings
        verts_expected = defaultdict(list)

        positions = list()
        positions.append([0, 0, 0, 0])
        positions.append([4, 4, 0, 0])
        positions.append([1, 1, 0, 0])
        positions.append([2, 2, 0, 0])
        positions.append([8, 4, 8, 4])
        positions.append([11, 4, 8, 4])
        positions.append([4, 11, 4, 8])
        positions.append([4, 8, 4, 8])
        positions.append([0, 11, 8, 4])
        positions.append([11, 11, 4, 8])
        positions.append([8, 8, 4, 8])
        positions.append([4, 0, 0, 0])
        positions.append([7, 7, 0, 0])

        # add graph vertices which reside on areas of the machine to ensure
        #  spread over boards.
        for x, y, eth_x, eth_y in positions:
            vertex = SimpleTestVertex(1)
            app_graph.add_vertex(vertex)
            vertex_slice = Slice(0, 0)
            resources_required = vertex.get_resources_used_by_atoms(
                vertex_slice)
            mac_vertex = vertex.create_machine_vertex(
                vertex_slice, resources_required)
            graph.add_vertex(mac_vertex)
            partition_ids = ["EVENTS"]
            live_packet_gatherers[default_params_holder].append(
                (vertex, partition_ids))
            verts_expected[eth_x, eth_y].append(mac_vertex)
            placements.add_placement(
                Placement(x=x, y=y, p=5, vertex=mac_vertex))

        # run edge inserter that should go boom
        edge_inserter = InsertEdgesToLivePacketGatherers()
        edge_inserter(
            live_packet_gatherer_parameters=live_packet_gatherers,
            placements=placements,
            live_packet_gatherers_to_vertex_mapping=(
                live_packet_gatherers_to_vertex_mapping),
            machine=machine, machine_graph=graph, application_graph=app_graph)

        # verify edges are in the right place
        for chip in machine.ethernet_connected_chips:
            edges = graph.get_edges_ending_at_vertex(
                live_packet_gatherers_to_vertex_mapping[
                    default_params_holder][chip.x, chip.y])
            for edge in edges:
                self.assertIn(edge.pre_vertex, verts_expected[chip.x, chip.y])

        # check app graph
        for chip in machine.ethernet_connected_chips:
            app_verts_expected = [
                vert.app_vertex for vert in verts_expected[chip.x, chip.y]]
            lpg_machine = live_packet_gatherers_to_vertex_mapping[
                default_params_holder][chip.x, chip.y]
            for edge in app_graph.get_edges_ending_at_vertex(
                    lpg_machine.app_vertex):
                self.assertIn(edge.pre_vertex, app_verts_expected)
Ejemplo n.º 22
0
    def test_local_verts_when_multiple_lpgs_are_local(self):
        machine = virtual_machine(width=12, height=12)
        graph = MachineGraph("Test")

        default_params = {
            'use_prefix': False,
            'key_prefix': None,
            'prefix_type': None,
            'message_type': EIEIOType.KEY_32_BIT,
            'right_shift': 0,
            'payload_as_time_stamps': True,
            'use_payload_prefix': True,
            'payload_prefix': None,
            'payload_right_shift': 0,
            'number_of_packets_sent_per_time_step': 0,
            'hostname': None,
            'port': None,
            'strip_sdp': None,
            'tag': None,
            'label': "Test"}

        # data stores needed by algorithm
        live_packet_gatherers = dict()
        default_params_holder = LivePacketGatherParameters(**default_params)
        live_packet_gatherers[default_params_holder] = list()

        live_packet_gatherers_to_vertex_mapping = defaultdict(dict)

        placements = Placements()

        # add LPG's (1 for each Ethernet connected chip)

        specific_data_holders = dict()
        index = 1
        for chip in machine.ethernet_connected_chips:
            extended = dict(default_params)
            vertex = LivePacketGatherMachineVertex(
                LivePacketGatherParameters(**extended), label='test')
            graph.add_vertex(vertex)
            placements.add_placement(
                Placement(x=chip.x, y=chip.y, p=2, vertex=vertex))
            live_packet_gatherers_to_vertex_mapping[
                default_params_holder][chip.x, chip.y] = vertex

            # Add another on each chip separately
            index += 1
            extended = dict(default_params)
            extended['board_address'] = chip.ip_address
            default_params_holder2 = LivePacketGatherParameters(**extended)

            extended = dict(default_params)
            extended.update({'label': "test"})
            vertex = LivePacketGatherMachineVertex(
                LivePacketGatherParameters(**extended))
            specific_data_holders[(chip.x, chip.y)] = default_params_holder2
            placements.add_placement(Placement(
                x=chip.x, y=chip.y, p=3, vertex=vertex))
            graph.add_vertex(vertex)
            live_packet_gatherers_to_vertex_mapping[
                default_params_holder2][chip.x, chip.y] = vertex
            live_packet_gatherers[default_params_holder2] = list()

        # tracker of wirings
        verts_expected = defaultdict(list)

        positions = list()
        positions.append([0, 0, 0, 0, 2, default_params_holder])
        positions.append([4, 4, 0, 0, 2, default_params_holder])
        positions.append(
            [1, 1, 0, 0, 3, specific_data_holders[(0, 0)]])
        positions.append(
            [2, 2, 0, 0, 3, specific_data_holders[(0, 0)]])
        positions.append([8, 4, 8, 4, 2, default_params_holder])
        positions.append([11, 4, 8, 4, 2, default_params_holder])
        positions.append([4, 11, 4, 8, 2, default_params_holder])
        positions.append([4, 8, 4, 8, 2, default_params_holder])
        positions.append([0, 11, 8, 4, 3, specific_data_holders[(8, 4)]])
        positions.append([11, 11, 4, 8, 3, specific_data_holders[(4, 8)]])
        positions.append([8, 8, 4, 8, 3, specific_data_holders[(4, 8)]])
        positions.append([4, 0, 0, 0, 3, specific_data_holders[(0, 0)]])
        positions.append([7, 7, 0, 0, 2, default_params_holder])

        # add graph vertices which reside on areas of the machine to ensure
        #  spread over boards.
        for x, y, eth_x, eth_y, eth_p, params in positions:
            vertex = SimpleMachineVertex(resources=ResourceContainer())
            graph.add_vertex(vertex)
            live_packet_gatherers[params].append((vertex, ["EVENTS"]))
            verts_expected[eth_x, eth_y, eth_p].append(vertex)
            placements.add_placement(Placement(x=x, y=y, p=5, vertex=vertex))

        # run edge inserter that should go boom
        edge_inserter = InsertEdgesToLivePacketGatherers()
        edge_inserter(
            live_packet_gatherer_parameters=live_packet_gatherers,
            placements=placements,
            live_packet_gatherers_to_vertex_mapping=(
                live_packet_gatherers_to_vertex_mapping),
            machine=machine, machine_graph=graph, application_graph=None)

        # verify edges are in the right place
        for chip in machine.ethernet_connected_chips:
            for params, p in zip(
                    (default_params_holder,
                     specific_data_holders[chip.x, chip.y]),
                    (2, 3)):
                edges = graph.get_edges_ending_at_vertex(
                    live_packet_gatherers_to_vertex_mapping[
                        params][chip.x, chip.y])
                for edge in edges:
                    self.assertIn(
                        edge.pre_vertex, verts_expected[chip.x, chip.y, p])
    def test_local_verts_go_to_local_lpgs(self):
        machine = VirtualMachine(width=12, height=12, with_wrap_arounds=True)
        graph = MachineGraph("Test")

        default_params = {
            'use_prefix': False,
            'key_prefix': None,
            'prefix_type': None,
            'message_type': EIEIOType.KEY_32_BIT,
            'right_shift': 0,
            'payload_as_time_stamps': True,
            'use_payload_prefix': True,
            'payload_prefix': None,
            'payload_right_shift': 0,
            'number_of_packets_sent_per_time_step': 0,
            'hostname': None,
            'port': None,
            'strip_sdp': None,
            'board_address': None,
            'tag': None}

        # data stores needed by algorithm
        live_packet_gatherers = dict()
        extended = dict(default_params)
        extended.update({'partition_id': "EVENTS"})
        default_params_holder = LivePacketGatherParameters(**extended)
        live_packet_gatherers[default_params_holder] = list()

        live_packet_gatherers_to_vertex_mapping = dict()
        live_packet_gatherers_to_vertex_mapping[default_params_holder] = dict()

        placements = Placements()

        # add LPG's (1 for each Ethernet connected chip)
        for chip in machine.ethernet_connected_chips:
            extended = dict(default_params)
            extended.update({'label': 'test'})
            vertex = LivePacketGatherMachineVertex(**extended)
            graph.add_vertex(vertex)
            placements.add_placement(
                Placement(x=chip.x, y=chip.y, p=2, vertex=vertex))
            live_packet_gatherers_to_vertex_mapping[
                default_params_holder][chip.x, chip.y] = vertex

        # tracker of wirings
        verts_expected = defaultdict(list)
        positions = list()
        positions.append([0, 0, 0, 0])
        positions.append([4, 4, 0, 0])
        positions.append([1, 1, 0, 0])
        positions.append([2, 2, 0, 0])
        positions.append([8, 4, 8, 4])
        positions.append([11, 4, 8, 4])
        positions.append([4, 11, 4, 8])
        positions.append([4, 8, 4, 8])
        positions.append([0, 11, 8, 4])
        positions.append([11, 11, 4, 8])
        positions.append([8, 8, 4, 8])
        positions.append([4, 0, 0, 0])
        positions.append([7, 7, 0, 0])

        # add graph vertices which reside on areas of the machine to ensure
        #  spread over boards.
        for x, y, eth_x, eth_y in positions:
            vertex = SimpleMachineVertex(resources=ResourceContainer())
            graph.add_vertex(vertex)
            live_packet_gatherers[default_params_holder].append(vertex)
            verts_expected[eth_x, eth_y].append(vertex)
            placements.add_placement(Placement(x=x, y=y, p=5, vertex=vertex))

        # run edge inserter that should go boom
        edge_inserter = InsertEdgesToLivePacketGatherers()
        edge_inserter(
            live_packet_gatherer_parameters=live_packet_gatherers,
            placements=placements,
            live_packet_gatherers_to_vertex_mapping=(
                live_packet_gatherers_to_vertex_mapping),
            machine=machine, machine_graph=graph, application_graph=None,
            graph_mapper=None)

        # verify edges are in the right place
        for chip in machine.ethernet_connected_chips:
            edges = graph.get_edges_ending_at_vertex(
                live_packet_gatherers_to_vertex_mapping[
                    default_params_holder][chip.x, chip.y])
            for edge in edges:
                self.assertIn(edge.pre_vertex, verts_expected[chip.x, chip.y])
Ejemplo n.º 24
0
class TestRouter(unittest.TestCase):
    def setUp(self):
        # sort out graph
        self.vert1 = Vertex(10, "New AbstractConstrainedVertex 1")
        self.vert2 = Vertex(5, "New AbstractConstrainedVertex 2")
        self.edge1 = ApplicationEdge(self.vert1, self.vert2, "First edge")
        self.verts = [self.vert1, self.vert2]
        self.edges = [self.edge1]
        self.graph = ApplicationGraph("Graph", self.verts, self.edges)
        # sort out graph
        self.graph = MachineGraph()
        self.vertex1 = SimpleMachineVertex(
            0, 10, self.vert1.get_resources_used_by_atoms(0, 10, []))
        self.vertex2 = SimpleMachineVertex(
            0, 5, self.vert2.get_resources_used_by_atoms(0, 10, []))
        self.edge = MachineEdge(self.vertex1, self.vertex2)
        self.graph.add_vertex(self.vertex1)
        self.graph.add_vertex(self.vertex2)
        self.graph.add_edge(self.edge, "TEST")

    @unittest.skip("demonstrating skipping")
    def test_router_with_same_chip_route(self):
        # sort out placements
        self.placements = Placements()
        self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=0, y=0, p=3, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_router_with_neighbour_chip(self):
        # sort out placements
        self.placements = Placements()
        self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=1, y=1, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_router_with_one_hop_route_all_default_link_0(self):
        # sort out placements
        self.placements = Placements()
        self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=2, y=0, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_router_with_one_hop_route_all_default_link_1(self):
        self.placements = Placements()
        self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=2, y=2, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_router_with_one_hop_route_all_default_link_2(self):
        self.placements = Placements()
        self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=0, y=2, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_router_with_one_hop_route_all_default_link_3(self):
        self.placements = Placements()
        self.placement1 = Placement(x=2, y=0, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=0, y=0, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_router_with_one_hop_route_all_default_link_4(self):
        self.placements = Placements()
        self.placement1 = Placement(x=2, y=2, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=0, y=0, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_router_with_one_hop_route_all_default_link_5(self):
        self.placements = Placements()
        self.placement1 = Placement(x=0, y=2, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=0, y=0, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_router_with_one_hop_route_not_default(self):
        # sort out placements
        self.placements = Placements()
        self.placement1 = Placement(x=2, y=1, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=0, y=0, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_router_with_multi_hop_route_across_board(self):
        # sort out placements
        self.placements = Placements()
        self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=8, y=7, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)

    @unittest.skip("demonstrating skipping")
    def test_new_router(self):
        report_folder = "..\reports"
        self.routing = BasicDijkstraRouting()
        self.assertEqual(self.routing._report_folder, report_folder)
        self.assertEqual(self.routing._graph, None)
        self.assertEqual(self.routing.report_states, None)
        self.assertEqual(self.routing._hostname, None)
        self.assertIsInstance(self.routing._router_algorithm,
                              BasicDijkstraRouting)
        self.assertEqual(self.routing._graph_mappings, None)

    @unittest.skip("demonstrating skipping")
    def test_new_router_set_non_default_routing_algorithm(self):
        report_folder = "..\reports"
        self.routing = BasicDijkstraRouting()
        self.assertEqual(self.routing._report_folder, report_folder)
        self.assertEqual(self.routing._graph, None)
        self.assertEqual(self.routing.report_states, None)
        self.assertEqual(self.routing._hostname, None)
        self.assertEqual(self.routing._graph_mappings, None)

    @unittest.skip("demonstrating skipping")
    def test_run_router(self):
        # sort out placements
        self.placements = Placements()
        self.placement1 = Placement(x=0, y=0, p=2, vertex=self.vertex1)
        self.placement2 = Placement(x=1, y=1, p=2, vertex=self.vertex2)
        self.placements.add_placement(self.placement1)
        self.placements.add_placement(self.placement2)
        # sort out routing infos
        self.routing_info = RoutingInfo()
        self.edge_routing_info1 = PartitionRoutingInfo(key=2 << 11,
                                                       mask=DEFAULT_MASK,
                                                       edge=self.edge)
        self.routing_info.add_partition_info(self.edge_routing_info1)
        # create machine
        self.machine = VirtualMachine(10, 10, False)
        self.routing = BasicDijkstraRouting()
        self.routing.route(machine=self.machine,
                           placements=self.placements,
                           machine_graph=self.graph,
                           routing_info_allocation=self.routing_info)