Exemplo 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
Exemplo n.º 2
0
    def test_ip_tags(self):
        machine = virtual_machine(12, 12)
        eth_chips = machine.ethernet_connected_chips
        vertices = [
            SimpleMachineVertex(ResourceContainer(
                iptags=[IPtagResource("127.0.0.1", port=None, strip_sdp=True)
                        ]),
                                label="Vertex {}".format(i))
            for i in range(len(eth_chips))
        ]
        print("Created {} vertices".format(len(vertices)))
        placements = Placements(
            Placement(vertex, chip.x, chip.y, 1)
            for vertex, chip in zip(vertices, eth_chips))
        allocator = BasicTagAllocator()
        _, _, tags = allocator(machine,
                               plan_n_timesteps=None,
                               placements=placements)

        for vertex, chip in zip(vertices, eth_chips):
            iptags = tags.get_ip_tags_for_vertex(vertex)
            self.assertEqual(len(iptags), 1,
                             "Incorrect number of tags assigned")
            self.assertEqual(iptags[0].destination_x, chip.x,
                             "Destination of tag incorrect")
            self.assertEqual(iptags[0].destination_y, chip.y,
                             "Destination of tag incorrect")
            placement = placements.get_placement_of_vertex(vertex)
            print(placement, "has tag", iptags[0])
    def test_ip_tags(self):
        machine = VirtualMachine(12, 12, with_wrap_arounds=True)
        eth_chips = machine.ethernet_connected_chips
        vertices = [
            SimpleMachineVertex(
                ResourceContainer(iptags=[IPtagResource(
                    "127.0.0.1", port=None, strip_sdp=True)]),
                label="Vertex {}".format(i))
            for i in range(len(eth_chips))]
        print("Created {} vertices".format(len(vertices)))
        placements = Placements(
            Placement(vertex, chip.x, chip.y, 1)
            for vertex, chip in zip(vertices, eth_chips))
        allocator = BasicTagAllocator()
        _, _, tags = allocator(
            machine, plan_n_timesteps=None, placements=placements)

        for vertex, chip in zip(vertices, eth_chips):
            iptags = tags.get_ip_tags_for_vertex(vertex)
            self.assertEqual(
                len(iptags), 1, "Incorrect number of tags assigned")
            self.assertEqual(
                iptags[0].destination_x, chip.x,
                "Destination of tag incorrect")
            self.assertEqual(
                iptags[0].destination_y, chip.y,
                "Destination of tag incorrect")
            placement = placements.get_placement_of_vertex(vertex)
            print(placement, "has tag", iptags[0])
Exemplo 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)
Exemplo n.º 6
0
    def test_too_many_ip_tags_for_1_board(self):
        n_extra_vertices = 3
        machine = virtual_machine(12, 12)
        eth_chips = machine.ethernet_connected_chips
        eth_chip = eth_chips[0]
        eth_chip_2 = machine.get_chip_at(eth_chip.x + 1, eth_chip.y + 1)
        eth_procs = [
            proc.processor_id for proc in eth_chip.processors
            if not proc.is_monitor
        ]
        procs = [proc for proc in eth_chip_2.processors if not proc.is_monitor]
        eth2_procs = [proc.processor_id for proc in procs]
        proc = procs[-1]
        eth_vertices = [
            SimpleMachineVertex(ResourceContainer(
                iptags=[IPtagResource("127.0.0.1", port=tag, strip_sdp=True)]),
                                label="Ethernet Vertex {}".format(proc))
            for tag in eth_chip.tag_ids
        ]
        eth2_vertices = [
            SimpleMachineVertex(ResourceContainer(iptags=[
                IPtagResource("127.0.0.1", port=10000 + tag, strip_sdp=True)
            ]),
                                label="Ethernet 2 Vertex {}".format(proc))
            for tag in range(n_extra_vertices)
        ]
        placements = Placements(
            Placement(vertex, eth_chip.x, eth_chip.y, proc)
            for proc, vertex in zip(eth_procs, eth_vertices))
        placements.add_placements(
            Placement(vertex, eth_chip_2.x, eth_chip_2.y, proc)
            for proc, vertex in zip(eth2_procs, eth2_vertices))
        allocator = BasicTagAllocator()
        _, _, tags = allocator(machine,
                               plan_n_timesteps=None,
                               placements=placements)

        tags_by_board = defaultdict(set)
        for vertices in (eth_vertices, eth2_vertices):
            for vertex in vertices:
                iptags = tags.get_ip_tags_for_vertex(vertex)
                self.assertEqual(len(iptags), 1,
                                 "Incorrect number of tags assigned")
                placement = placements.get_placement_of_vertex(vertex)
                print(placement, "has tag", iptags[0])
                self.assertFalse(
                    iptags[0].tag in tags_by_board[iptags[0].board_address],
                    "Tag used more than once")
                tags_by_board[iptags[0].board_address].add(iptags[0].tag)

        self.assertEqual(len(tags_by_board[eth_chip.ip_address]),
                         len(eth_chip.tag_ids),
                         "Wrong number of tags assigned to first Ethernet")
Exemplo 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
    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_too_many_ip_tags_for_1_board(self):
        n_extra_vertices = 3
        machine = VirtualMachine(12, 12, with_wrap_arounds=True)
        eth_chips = machine.ethernet_connected_chips
        eth_chip = eth_chips[0]
        eth_chip_2 = machine.get_chip_at(eth_chip.x + 1, eth_chip.y + 1)
        eth_procs = [
            proc.processor_id for proc in eth_chip.processors
            if not proc.is_monitor]
        procs = [proc for proc in eth_chip_2.processors if not proc.is_monitor]
        eth2_procs = [proc.processor_id for proc in procs]
        proc = procs[-1]
        eth_vertices = [
            SimpleMachineVertex(
                ResourceContainer(iptags=[IPtagResource(
                    "127.0.0.1", port=tag, strip_sdp=True)]),
                label="Ethernet Vertex {}".format(proc))
            for tag in eth_chip.tag_ids]
        eth2_vertices = [
            SimpleMachineVertex(
                ResourceContainer(iptags=[IPtagResource(
                    "127.0.0.1", port=10000 + tag, strip_sdp=True)]),
                label="Ethernet 2 Vertex {}".format(proc))
            for tag in range(n_extra_vertices)]
        placements = Placements(
            Placement(vertex, eth_chip.x, eth_chip.y, proc)
            for proc, vertex in zip(eth_procs, eth_vertices))
        placements.add_placements(
            Placement(vertex, eth_chip_2.x, eth_chip_2.y, proc)
            for proc, vertex in zip(eth2_procs, eth2_vertices))
        allocator = BasicTagAllocator()
        _, _, tags = allocator(
            machine, plan_n_timesteps=None, placements=placements)

        tags_by_board = defaultdict(set)
        for vertices in (eth_vertices, eth2_vertices):
            for vertex in vertices:
                iptags = tags.get_ip_tags_for_vertex(vertex)
                self.assertEqual(
                    len(iptags), 1, "Incorrect number of tags assigned")
                placement = placements.get_placement_of_vertex(vertex)
                print(placement, "has tag", iptags[0])
                self.assertFalse(
                    iptags[0].tag in tags_by_board[iptags[0].board_address],
                    "Tag used more than once")
                tags_by_board[iptags[0].board_address].add(iptags[0].tag)

        self.assertEqual(
            len(tags_by_board[eth_chip.ip_address]), len(eth_chip.tag_ids),
            "Wrong number of tags assigned to first Ethernet")
    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_get_placement_of_vertex(self):
        """
        checks the placements get placement method
        """
        subv = list()
        for i in range(5):
            subv.append(SimpleMachineVertex(None, ""))

        pl = list()
        for i in range(4):
            pl.append(Placement(subv[i], 0, 0, i))

        pls = Placements(pl)
        for i in range(4):
            self.assertEqual(pls.get_placement_of_vertex(subv[i]), pl[i])
Exemplo n.º 12
0
    def test_get_placement_of_vertex(self):
        """
        checks the placements get placement method
        """
        subv = list()
        for i in range(5):
            subv.append(SimpleMachineVertex(None, ""))

        pl = list()
        for i in range(4):
            pl.append(Placement(subv[i], 0, 0, i))

        pls = Placements(pl)
        for i in range(4):
            self.assertEqual(pls.get_placement_of_vertex(subv[i]), pl[i])
Exemplo n.º 13
0
 def test_create_new_placements(self):
     """
     test creating a placements object
     """
     subv = SimpleMachineVertex(None, "")
     pl = Placement(subv, 0, 0, 1)
     Placements([pl])
Exemplo n.º 14
0
    def __call__(self, machine_graph, machine, plan_n_timesteps):
        """ Place each vertex in a machine graph on a core in the machine.

        :param MachineGraph machine_graph: The machine_graph to place
        :param ~spinn_machine.Machine machine: A SpiNNaker machine object.
        :param int plan_n_timesteps: number of timesteps to plan for
        :return placements: Placements of vertices on the machine
        :rtype: Placements
        """

        # 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(machine_graph.n_vertices,
                               "Placing graph vertices")
        resource_tracker = ResourceTracker(
            machine, plan_n_timesteps, self._generate_random_chips(machine))
        vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph)
        vertices_placed = set()
        for vertex in progress.over(vertices):
            if vertex not in vertices_placed:
                vertices_placed.update(
                    self._place_vertex(vertex, resource_tracker, machine,
                                       placements, vertices_on_same_chip))
        return placements
Exemplo n.º 15
0
    def __call__(self, machine_graph, machine, plan_n_timesteps):
        """
        :param MachineGraph machine_graph: The machine_graph to place
        :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
        :return: A set of placements
        :rtype: Placements
        :raise PacmanPlaceException:
            If something goes wrong with the placement
        """
        # check that the algorithm can handle the constraints
        self._check_constraints(machine_graph.vertices)

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

        # Iterate over vertices and generate placements
        progress = ProgressBar(machine_graph.n_vertices,
                               "Placing graph vertices")
        resource_tracker = ResourceTracker(
            machine, plan_n_timesteps, self._generate_radial_chips(machine))
        vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph)
        all_vertices_placed = set()
        for vertex in progress.over(vertices):
            if vertex not in all_vertices_placed:
                vertices_placed = self._place_vertex(vertex, resource_tracker,
                                                     machine, placements,
                                                     vertices_on_same_chip,
                                                     machine_graph)
                all_vertices_placed.update(vertices_placed)
        return placements
    def test_call(self):
        """ Test calling the binary gatherer normally
        """

        vertex_1 = _TestVertexWithBinary("test.aplx", ExecutableType.RUNNING)
        vertex_2 = _TestVertexWithBinary("test2.aplx", ExecutableType.RUNNING)
        vertex_3 = _TestVertexWithBinary("test2.aplx", ExecutableType.RUNNING)
        vertex_4 = _TestVertexWithoutBinary()

        graph = MachineGraph("Test")
        graph.add_vertices([vertex_1, vertex_2, vertex_3])

        placements = Placements(placements=[
            Placement(vertex_1, 0, 0, 0),
            Placement(vertex_2, 0, 0, 1),
            Placement(vertex_3, 0, 0, 2),
            Placement(vertex_4, 0, 0, 3)
        ])

        gatherer = GraphBinaryGatherer()
        targets = gatherer.__call__(placements, graph, _TestExecutableFinder())
        gatherer = LocateExecutableStartType()
        start_type = gatherer.__call__(graph, placements)
        self.assertEqual(next(iter(start_type)), ExecutableType.RUNNING)
        self.assertEqual(targets.total_processors, 3)

        test_cores = targets.get_cores_for_binary("test.aplx")
        test_2_cores = targets.get_cores_for_binary("test2.aplx")
        self.assertEqual(len(test_cores), 1)
        self.assertEqual(len(test_2_cores), 2)
        self.assertIn((0, 0, 0), test_cores)
        self.assertIn((0, 0, 1), test_2_cores)
        self.assertIn((0, 0, 2), test_2_cores)
Exemplo n.º 17
0
    def __call__(self, machine_graph, machine, plan_n_timesteps):
        """
        :param MachineGraph machine_graph: The machine_graph to place
        :param ~spinn_machine.Machine machine: A SpiNNaker machine object.
        :param int plan_n_timesteps: number of timesteps to plan for
        :return: Placements of vertices on the machine
        :rtype: Placements
        """
        # check that the algorithm can handle the constraints
        self._check_constraints(
            machine_graph.vertices,
            additional_placement_constraints={SameChipAsConstraint})

        # in order to test isomorphism include:
        # placements_copy = Placements()
        placements = Placements()
        vertices = sort_vertices_by_known_constraints(machine_graph.vertices)

        progress = ProgressBar(
            machine_graph.n_vertices, "Placing graph vertices")
        resource_tracker = ResourceTracker(
            machine, plan_n_timesteps, self._generate_hilbert_chips(machine))

        # get vertices which must be placed on the same chip
        vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph)

        # iterate over vertices and generate placements
        all_vertices_placed = set()
        for vertex in progress.over(vertices):
            if vertex not in all_vertices_placed:
                vertices_placed = self._place_vertex(
                    vertex, resource_tracker, machine,
                    placements, vertices_on_same_chip)
                all_vertices_placed.update(vertices_placed)
        return placements
Exemplo n.º 18
0
 def test_create_new_empty_placements(self):
     """
     checks that creating an empty placements object is valid
     """
     pls = Placements()
     self.assertEqual(pls._placements, dict())
     self.assertEqual(pls._machine_vertices, dict())
    def test_listener_creation(self):
        # Test of buffer manager listener creation problem, where multiple
        # listeners were being created for the buffer manager traffic from
        # individual boards, where it's preferred all traffic is received by
        # a single listener

        # Create two vertices
        v1 = _TestVertex(10, "v1", 256)
        v2 = _TestVertex(10, "v2", 256)

        # Create two tags - important thing is port=None
        t1 = IPTag(board_address='127.0.0.1', destination_x=0,
                   destination_y=1, tag=1, port=None, ip_address=None,
                   strip_sdp=True, traffic_identifier='BufferTraffic')
        t2 = IPTag(board_address='127.0.0.1', destination_x=0,
                   destination_y=2, tag=1, port=None, ip_address=None,
                   strip_sdp=True, traffic_identifier='BufferTraffic')

        # Create 'Tags' object and add tags
        t = Tags()
        t.add_ip_tag(t1, v1)
        t.add_ip_tag(t2, v2)

        # Create board connections
        connections = []
        connections.append(SCAMPConnection(
            remote_host=None))
        connections.append(EIEIOConnection())

        # Create two placements and 'Placements' object
        pl1 = Placement(v1, 0, 1, 1)
        pl2 = Placement(v2, 0, 2, 1)
        pl = Placements([pl1, pl2])

        # Create transceiver
        trnx = Transceiver(version=5, connections=connections)
        # Alternatively, one can register a udp listener for testing via:
        # trnx.register_udp_listener(callback=None,
        #        connection_class=EIEIOConnection)

        # Create buffer manager
        bm = BufferManager(pl, t, trnx)

        # Register two listeners, and check the second listener uses the
        # first rather than creating a new one
        bm._add_buffer_listeners(vertex=v1)
        bm._add_buffer_listeners(vertex=v2)

        number_of_listeners = 0
        for i in bm._transceiver._udp_listenable_connections_by_class[
                EIEIOConnection]:
            # Check if listener is registered on connection - we only expect
            # one listener to be registered, as all connections can use the
            # same listener for the buffer manager
            if not i[1] is None:
                number_of_listeners += 1
            print i
        self.assertEqual(number_of_listeners, 1)
Exemplo n.º 20
0
    def test_with_application_vertices(self):
        """ Test that an application vertex's data is rewritten correctly
        """
        # Create a default SDRAM to set the max to default
        SDRAM()
        reload_region_data = [(0, [0] * 10), (1, [1] * 20)]
        vertex = _TestApplicationVertex(10, reload_region_data)
        m_slice_1 = Slice(0, 4)
        m_slice_2 = Slice(5, 9)
        m_vertex_1 = vertex.create_machine_vertex(m_slice_1, None, None, None)
        m_vertex_2 = vertex.create_machine_vertex(m_slice_2, None, None, None)

        graph_mapper = GraphMapper()
        graph_mapper.add_vertex_mapping(m_vertex_1, m_slice_1, vertex)
        graph_mapper.add_vertex_mapping(m_vertex_2, m_slice_2, vertex)

        placements = Placements(
            [Placement(m_vertex_1, 0, 0, 1),
             Placement(m_vertex_2, 0, 0, 2)])

        user_0_addresses = {
            (placement.x, placement.y, placement.p): i * 1000
            for i, placement in enumerate(placements.placements)
        }
        region_addresses = [i for i in range(MAX_MEM_REGIONS)]
        transceiver = _MockTransceiver(user_0_addresses, region_addresses)

        reloader = DSGRegionReloader()
        reloader.__call__(transceiver, placements, "localhost", "test", False,
                          "test", graph_mapper)

        regions_rewritten = transceiver.regions_rewritten

        # Check that the number of times the data has been regenerated is
        # correct
        self.assertEqual(vertex.regenerate_call_count, placements.n_placements)

        # Check that the number of regions rewritten is correct
        self.assertEqual(len(transceiver.regions_rewritten),
                         placements.n_placements * len(reload_region_data))

        # Check that the data rewritten is correct
        for i, placement in enumerate(placements.placements):
            user_0_address = user_0_addresses[placement.x, placement.y,
                                              placement.p]
            for j in range(len(reload_region_data)):
                pos = (i * len(reload_region_data)) + j
                region, data = reload_region_data[j]
                address = get_region_base_address_offset(
                    user_0_address, 0) + region_addresses[region]
                data = bytearray(numpy.array(data, dtype="uint32").tobytes())

                # Check that the base address and data written is correct
                self.assertEqual(regions_rewritten[pos], (address, data))

        # Delete data files
        shutil.rmtree("test")
    def test_get_vertex_on_processor(self):
        """
        checks that from a placements object, you can get to the correct
        vertex using the get_vertex_on_processor() method
        """
        subv = list()
        for i in range(5):
            subv.append(SimpleMachineVertex(None, ""))

        pl = list()
        for i in range(4):
            pl.append(Placement(subv[i], 0, 0, i))

        pls = Placements(pl)
        for i in range(4):
            self.assertEqual(pls.get_vertex_on_processor(0, 0, i), subv[i])

        self.assertEqual(pls.get_placement_of_vertex(subv[0]), pl[0])
Exemplo n.º 22
0
    def test_get_vertex_on_processor(self):
        """
        checks that from a placements object, you can get to the correct
        vertex using the get_vertex_on_processor() method
        """
        subv = list()
        for i in range(5):
            subv.append(SimpleMachineVertex(None, ""))

        pl = list()
        for i in range(4):
            pl.append(Placement(subv[i], 0, 0, i))

        pls = Placements(pl)
        for i in range(4):
            self.assertEqual(pls.get_vertex_on_processor(0, 0, i), subv[i])

        self.assertEqual(pls.get_placement_of_vertex(subv[0]), pl[0])
Exemplo n.º 23
0
 def test_create_new_placements_duplicate_vertex(self):
     """
     check that you cant put a vertex in multiple placements
     """
     subv = SimpleMachineVertex(None, "")
     pl = list()
     for i in range(4):
         pl.append(Placement(subv, 0, 0, i))
     with self.assertRaises(PacmanAlreadyPlacedError):
         Placements(pl)
Exemplo n.º 24
0
 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)
Exemplo n.º 25
0
def test_convert_to_file_placement(tmpdir):
    v = SimpleMachineVertex(ResourceContainer())
    pl = Placement(v, 1, 2, 3)
    placements = Placements([pl])
    algo = ConvertToFilePlacement()
    fn = tmpdir.join("foo.json")
    filename, _vertex_by_id = algo(placements, str(fn))
    assert filename == str(fn)
    obj = json.loads(fn.read())
    baseline = {ident(v): [1, 2]}
    assert obj == baseline
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)
Exemplo n.º 27
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)
    def _run(self, machine_graph, machine, plan_n_timesteps):
        """
        :param MachineGraph machine_graph: The machine_graph to place
        :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
        :return: A set of placements
        :rtype: ~pacman.model.placements.Placements
        :raise PacmanPlaceException:
            If something goes wrong with the placement
        """
        # check that the algorithm can handle the constraints
        self._check_constraints(machine_graph.vertices)

        # Sort the vertices into those with and those without
        # placement constraints
        placements = Placements()
        constrained = list()
        unconstrained = set()
        for vertex in machine_graph.vertices:
            if locate_constraints_of_type(vertex.constraints,
                                          AbstractPlacerConstraint):
                constrained.append(vertex)
            else:
                unconstrained.add(vertex)

        # Iterate over constrained vertices and generate placements
        progress = ProgressBar(machine_graph.n_vertices,
                               "Placing graph vertices")
        resource_tracker = ResourceTracker(
            machine, plan_n_timesteps, self._generate_radial_chips(machine))
        constrained = sort_vertices_by_known_constraints(constrained)
        vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph)
        for vertex in progress.over(constrained, False):
            self._place_vertex(vertex, resource_tracker, machine, placements,
                               vertices_on_same_chip, machine_graph)

        while unconstrained:
            # Place the subgraph with the overall most connected vertex
            max_connected_vertex = self._find_max_connected_vertex(
                unconstrained, machine_graph)
            self._place_unconstrained_subgraph(max_connected_vertex,
                                               machine_graph, unconstrained,
                                               machine, placements,
                                               resource_tracker, progress,
                                               vertices_on_same_chip)

        # finished, so stop progress bar and return placements
        progress.end()
        return 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)
Exemplo n.º 30
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
Exemplo n.º 31
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)
    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)
Exemplo n.º 33
0
    def test_get_placements(self):
        """
        tests the placements iterator functionality.
        """
        subv = list()
        for i in range(5):
            subv.append(SimpleMachineVertex(None, ""))

        pl = list()
        for i in range(4):
            pl.append(Placement(subv[i], 0, 0, i))

        pls = Placements(pl)
        container = pls.placements
        for i in range(4):
            self.assertIn(pl[i], container)
def _check_setup(width, height):
    machine = virtual_machine(width=width, height=height)

    ethernet_chips = machine.ethernet_connected_chips
    placements = Placements(
        Placement(DestinationVertex(), ethernet_chip.x, ethernet_chip.y, 1)
        for ethernet_chip in ethernet_chips)

    fixed_route_tables = fixed_route_router(machine, placements,
                                            DestinationVertex)

    for x, y in machine.chip_coordinates:
        assert (x, y) in fixed_route_tables
        chip = machine.get_chip_at(x, y)
        destinations = _get_destinations(machine, fixed_route_tables, x, y)
        assert len(destinations) == 1
        assert ((chip.nearest_ethernet_x, chip.nearest_ethernet_y, 1)
                in destinations)
Exemplo n.º 35
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 test_mixed_binaries(self):
        """ Test calling the binary gatherer with mixed executable types
        """

        vertex_1 = _TestVertexWithBinary("test.aplx", ExecutableType.RUNNING)
        vertex_2 = _TestVertexWithBinary("test2.aplx", ExecutableType.SYNC)

        placements = Placements(placements=[
            Placement(vertex_1, 0, 0, 0),
            Placement(vertex_2, 0, 0, 1)
        ])

        graph = MachineGraph("Test")
        graph.add_vertices([vertex_1, vertex_2])

        gatherer = LocateExecutableStartType()
        results = gatherer.__call__(graph, placements=placements)
        self.assertIn(ExecutableType.RUNNING, results)
        self.assertIn(ExecutableType.SYNC, results)
        self.assertNotIn(ExecutableType.USES_SIMULATION_INTERFACE, results)
        self.assertNotIn(ExecutableType.NO_APPLICATION, results)
Exemplo n.º 37
0
    def __call__(self, machine_graph, machine):
        # check that the algorithm can handle the constraints
        self._check_constraints(machine_graph.vertices)

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

        # Iterate over vertices and generate placements
        progress = ProgressBar(machine_graph.n_vertices,
                               "Placing graph vertices")
        resource_tracker = ResourceTracker(
            machine, self._generate_radial_chips(machine))
        vertices_on_same_chip = get_same_chip_vertex_groups(machine_graph)
        all_vertices_placed = set()
        for vertex in progress.over(vertices):
            if vertex not in all_vertices_placed:
                vertices_placed = self._place_vertex(vertex, resource_tracker,
                                                     machine, placements,
                                                     vertices_on_same_chip)
                all_vertices_placed.update(vertices_placed)
        return placements
Exemplo n.º 38
0
    def __call__(self, machine_graph, machine):

        # check that the algorithm can handle the constraints
        self._check_constraints(machine_graph.vertices)

        # Sort the vertices into those with and those without
        # placement constraints
        placements = Placements()
        constrained = list()
        unconstrained = set()
        for vertex in machine_graph.vertices:
            if locate_constraints_of_type(vertex.constraints,
                                          AbstractPlacerConstraint):
                constrained.append(vertex)
            else:
                unconstrained.add(vertex)

        # Iterate over constrained vertices and generate placements
        progress = ProgressBar(machine_graph.n_vertices,
                               "Placing graph vertices")
        resource_tracker = ResourceTracker(
            machine, self._generate_radial_chips(machine))
        constrained = sort_vertices_by_known_constraints(constrained)
        for vertex in progress.over(constrained, False):
            self._place_vertex(vertex, resource_tracker, machine, placements)

        while unconstrained:
            # Place the subgraph with the overall most connected vertex
            max_connected_vertex = self._find_max_connected_vertex(
                unconstrained, machine_graph)
            self._place_unconstrained_subgraph(max_connected_vertex,
                                               machine_graph, unconstrained,
                                               machine, placements,
                                               resource_tracker, progress)

        # finished, so stop progress bar and return placements
        progress.end()
        return placements
    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])
Exemplo n.º 40
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])
    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
Exemplo n.º 42
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