예제 #1
0
def test_sdram_links():
    """ Test sdram edges which should explode
        """

    # Create a graph
    machine_graph = MachineGraph("Test")

    # Connect a set of vertices in a chain of length 3
    last_vertex = None
    for x in range(20):
        vertex = SimpleMachineVertex(
            resources=ResourceContainer(),
            label="Vertex_{}".format(x), sdram_cost=20)
        machine_graph.add_vertex(vertex)
        last_vertex = vertex

    for vertex in machine_graph.vertices:
        machine_graph.add_outgoing_edge_partition(
            ConstantSDRAMMachinePartition(
                identifier="SDRAM", pre_vertex=vertex, label="bacon"))
        edge = SDRAMMachineEdge(vertex, last_vertex, "bacon", app_edge=None)
        machine_graph.add_edge(edge, "SDRAM")
    n_keys_map = DictBasedMachinePartitionNKeysMap()

    # Do placements
    machine = virtual_machine(width=8, height=8)
    try:
        SpreaderPlacer()(machine_graph, machine, n_keys_map,
                         plan_n_timesteps=1000)
        raise Exception("should blow up here")
    except PacmanException:
        pass
예제 #2
0
def test_virtual_placement(placer):
    machine = virtual_machine(width=8, height=8)
    graph = MachineGraph("Test")
    virtual_vertex = MachineSpiNNakerLinkVertex(spinnaker_link_id=0)
    graph.add_vertex(virtual_vertex)
    extended_machine = MallocBasedChipIdAllocator()(machine, graph)
    n_keys_map = DictBasedMachinePartitionNKeysMap()

    inputs = {
        "MemoryExtendedMachine": machine,
        "MemoryMachine": machine,
        "MemoryMachineGraph": graph,
        "PlanNTimeSteps": 1000,
        "MemoryMachinePartitionNKeysMap": n_keys_map
    }
    algorithms = [placer]
    xml_paths = []
    executor = PACMANAlgorithmExecutor(algorithms, [], inputs, [], [], [],
                                       xml_paths)
    executor.execute_mapping()
    placements = executor.get_item("MemoryPlacements")

    placement = placements.get_placement_of_vertex(virtual_vertex)
    chip = extended_machine.get_chip_at(placement.x, placement.y)
    assert chip.virtual
    def _integration_setup(self):
        machine_graph = MachineGraph(label="test me you git")
        n_keys_map = DictBasedMachinePartitionNKeysMap()
        v1 = SimpleMachineVertex(ResourceContainer())
        v2 = SimpleMachineVertex(ResourceContainer())
        v3 = SimpleMachineVertex(ResourceContainer())
        v4 = SimpleMachineVertex(ResourceContainer())
        machine_graph.add_vertex(v1)
        machine_graph.add_vertex(v2)
        machine_graph.add_vertex(v3)
        machine_graph.add_vertex(v4)

        e1 = MachineEdge(v1, v2, label="e1")
        e2 = MachineEdge(v1, v3, label="e2")
        e3 = MachineEdge(v2, v3, label="e3")
        e4 = MachineEdge(v1, v4, label="e4")

        machine_graph.add_outgoing_edge_partition(
            MulticastEdgePartition(identifier="part1", pre_vertex=v1))
        machine_graph.add_outgoing_edge_partition(
            MulticastEdgePartition(identifier="part2", pre_vertex=v2))
        machine_graph.add_outgoing_edge_partition(
            MulticastEdgePartition(identifier="part2", pre_vertex=v1))

        machine_graph.add_edge(e1, "part1")
        machine_graph.add_edge(e2, "part1")
        machine_graph.add_edge(e3, "part2")
        machine_graph.add_edge(e4, "part2")

        for partition in machine_graph.outgoing_edge_partitions:
            n_keys_map.set_n_keys_for_partition(partition, 24)

        return machine_graph, n_keys_map, v1, v2, v3, v4, e1, e2, e3, e4
예제 #4
0
    def test_get_vertices_from_vertex(self):
        """
        test getting the vertex from a graph mapper via the vertex
        """
        vertices = list()
        app_graph = ApplicationGraph("bacon")
        vert = SimpleTestVertex(10, "Some testing vertex")
        app_graph.add_vertex(vert)
        vertices.append(SimpleMachineVertex(None, ""))
        vertices.append(SimpleMachineVertex(None, ""))
        mac_graph = MachineGraph("cooked bacon", application_graph=app_graph)
        vertex1 = SimpleMachineVertex(None,
                                      "",
                                      vertex_slice=Slice(0, 1),
                                      app_vertex=vert)
        vertex2 = SimpleMachineVertex(None,
                                      "",
                                      vertex_slice=Slice(2, 3),
                                      app_vertex=vert)
        mac_graph.add_vertex(vertex1)
        mac_graph.add_vertex(vertex2)

        returned_vertices = vert.machine_vertices

        self.assertIn(vertex1, returned_vertices)
        self.assertIn(vertex2, returned_vertices)
        for v in vertices:
            self.assertNotIn(v, returned_vertices)
def test_sdram_links():
    """ Test sdram edges which should explode
        """

    # Create a graph
    machine_graph = MachineGraph("Test")

    # Connect a set of vertices in a chain of length 3
    last_vertex = None
    for x in range(20):
        vertex = SimpleMachineVertex(
            resources=ResourceContainer(),
            label="Vertex_{}".format(x))
        machine_graph.add_vertex(vertex)
        last_vertex = vertex

    for vertex in machine_graph.vertices:
        edge = MachineEdge(vertex, last_vertex,
                           traffic_type=EdgeTrafficType.SDRAM)
        machine_graph.add_edge(edge, "SDRAM")

    # Do placements
    machine = VirtualMachine(version=5)
    try:
        OneToOnePlacer()(machine_graph, machine, plan_n_timesteps=1000)
        raise Exception("should blow up here")
    except PacmanException:
        pass
    def _do_test(self, placer):
        machine = VirtualMachine(width=8, height=8)
        graph = MachineGraph("Test")
        plan_n_timesteps = 100

        vertices = [
            SimpleMachineVertex(ResourceContainer(), label="v{}".format(i))
            for i in range(100)
        ]
        for vertex in vertices:
            graph.add_vertex(vertex)

        same_vertices = [
            SimpleMachineVertex(ResourceContainer(), label="same{}".format(i))
            for i in range(10)
        ]
        random.seed(12345)
        sdram_edges = list()
        for vertex in same_vertices:
            graph.add_vertex(vertex)
            for i in range(0, random.randint(1, 5)):
                sdram_edge = MachineEdge(
                    vertex, vertices[random.randint(0, 99)],
                    traffic_type=EdgeTrafficType.SDRAM)
                sdram_edges.append(sdram_edge)
                graph.add_edge(sdram_edge, "Test")

        placements = placer(graph, machine, plan_n_timesteps)
        for edge in sdram_edges:
            pre_place = placements.get_placement_of_vertex(edge.pre_vertex)
            post_place = placements.get_placement_of_vertex(edge.post_vertex)
            assert pre_place.x == post_place.x
            assert pre_place.y == post_place.y
    def _integration_setup(self):
        machine_graph = MachineGraph(label="test me you git")
        n_keys_map = DictBasedMachinePartitionNKeysMap()
        v1 = SimpleMachineVertex(ResourceContainer())
        v2 = SimpleMachineVertex(ResourceContainer())
        v3 = SimpleMachineVertex(ResourceContainer())
        v4 = SimpleMachineVertex(ResourceContainer())
        machine_graph.add_vertex(v1)
        machine_graph.add_vertex(v2)
        machine_graph.add_vertex(v3)
        machine_graph.add_vertex(v4)

        e1 = MachineEdge(v1, v2, label="e1")
        e2 = MachineEdge(v1, v3, label="e2")
        e3 = MachineEdge(v2, v3, label="e3")
        e4 = MachineEdge(v1, v4, label="e4")

        machine_graph.add_edge(e1, "part1")
        machine_graph.add_edge(e2, "part1")
        machine_graph.add_edge(e3, "part2")
        machine_graph.add_edge(e4, "part2")

        for partition in machine_graph.outgoing_edge_partitions:
            n_keys_map.set_n_keys_for_partition(partition, 24)

        return machine_graph, n_keys_map, v1, v2, v3, v4, e1, e2, e3, e4
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)
예제 #9
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)
예제 #10
0
    def _do_test(self, placer):
        machine = VirtualMachine(width=8, height=8)
        graph = MachineGraph("Test")

        vertices = [
            SimpleMachineVertex(ResourceContainer(), label="v{}".format(i))
            for i in range(100)
        ]
        for vertex in vertices:
            graph.add_vertex(vertex)

        same_vertices = [
            SimpleMachineVertex(ResourceContainer(), label="same{}".format(i))
            for i in range(10)
        ]
        random.seed(12345)
        sdram_edges = list()
        for vertex in same_vertices:
            graph.add_vertex(vertex)
            for i in range(0, random.randint(1, 5)):
                sdram_edge = MachineEdge(
                    vertex, vertices[random.randint(0, 99)],
                    traffic_type=EdgeTrafficType.SDRAM)
                sdram_edges.append(sdram_edge)
                graph.add_edge(sdram_edge, "Test")

        placements = placer(graph, machine)
        for edge in sdram_edges:
            pre_place = placements.get_placement_of_vertex(edge.pre_vertex)
            post_place = placements.get_placement_of_vertex(edge.post_vertex)
            self.assert_(pre_place.x == post_place.x)
            self.assert_(pre_place.y == post_place.y)
    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)
예제 #12
0
def test_one_to_one():
    """ Test normal 1-1 placement
    """

    # Create a graph
    machine_graph = MachineGraph("Test")

    # Connect a set of vertices in a chain of length 3
    one_to_one_chains = list()
    for i in range(10):
        last_vertex = None
        chain = list()
        for j in range(3):
            vertex = SimpleMachineVertex(resources=ResourceContainer(),
                                         label="Vertex_{}_{}".format(i, j))
            machine_graph.add_vertex(vertex)
            if last_vertex is not None:
                edge = MachineEdge(last_vertex, vertex)
                machine_graph.add_edge(edge, "SPIKES")
            last_vertex = vertex
            chain.append(vertex)
        one_to_one_chains.append(chain)

    # Connect a set of 20 vertices in a chain
    too_many_vertices = list()
    last_vertex = None
    for i in range(20):
        vertex = SimpleMachineVertex(resources=ResourceContainer(),
                                     label="Vertex_{}".format(i))
        machine_graph.add_vertex(vertex)
        if last_vertex is not None:
            edge = MachineEdge(last_vertex, vertex)
            machine_graph.add_edge(edge, "SPIKES")
        too_many_vertices.append(vertex)
        last_vertex = vertex

    # Do placements
    machine = virtual_machine(width=8, height=8)
    placements = OneToOnePlacer()(machine_graph,
                                  machine,
                                  plan_n_timesteps=1000)

    # The 1-1 connected vertices should be on the same chip
    for chain in one_to_one_chains:
        first_placement = placements.get_placement_of_vertex(chain[0])
        for i in range(1, 3):
            placement = placements.get_placement_of_vertex(chain[i])
            assert placement.x == first_placement.x
            assert placement.y == first_placement.y

    # The other vertices should be on more than one chip
    too_many_chips = set()
    for vertex in too_many_vertices:
        placement = placements.get_placement_of_vertex(vertex)
        too_many_chips.add((placement.x, placement.y))
    assert len(too_many_chips) > 1
def test_one_to_one():
    """ Test normal 1-1 placement
    """

    # Create a graph
    machine_graph = MachineGraph("Test")

    # Connect a set of vertices in a chain of length 3
    one_to_one_chains = list()
    for i in range(10):
        last_vertex = None
        chain = list()
        for j in range(3):
            vertex = SimpleMachineVertex(
                resources=ResourceContainer(),
                label="Vertex_{}_{}".format(i, j))
            machine_graph.add_vertex(vertex)
            if last_vertex is not None:
                edge = MachineEdge(last_vertex, vertex)
                machine_graph.add_edge(edge, "SPIKES")
            last_vertex = vertex
            chain.append(vertex)
        one_to_one_chains.append(chain)

    # Connect a set of 20 vertices in a chain
    too_many_vertices = list()
    last_vertex = None
    for i in range(20):
        vertex = SimpleMachineVertex(
            resources=ResourceContainer(), label="Vertex_{}".format(i))
        machine_graph.add_vertex(vertex)
        if last_vertex is not None:
            edge = MachineEdge(last_vertex, vertex)
            machine_graph.add_edge(edge, "SPIKES")
        too_many_vertices.append(vertex)
        last_vertex = vertex

    # Do placements
    machine = VirtualMachine(version=5)
    placements = OneToOnePlacer()(
        machine_graph, machine, plan_n_timesteps=1000)

    # The 1-1 connected vertices should be on the same chip
    for chain in one_to_one_chains:
        first_placement = placements.get_placement_of_vertex(chain[0])
        for i in range(1, 3):
            placement = placements.get_placement_of_vertex(chain[i])
            assert placement.x == first_placement.x
            assert placement.y == first_placement.y

    # The other vertices should be on more than one chip
    too_many_chips = set()
    for vertex in too_many_vertices:
        placement = placements.get_placement_of_vertex(vertex)
        too_many_chips.add((placement.x, placement.y))
    assert len(too_many_chips) > 1
    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)
예제 #15
0
 def test_none_have_app_vertex(self):
     app_graph = ApplicationGraph("Test")
     graph = MachineGraph("foo", app_graph)
     app1 = SimpleTestVertex(12, "app1")
     mach1 = SimpleMachineVertex("mach1", app_vertex=None)
     mach2 = SimpleMachineVertex("mach2", app_vertex=None)
     mach3 = SimpleMachineVertex("mach3", app_vertex=app1)
     graph.add_vertices([mach1, mach2])
     with self.assertRaises(PacmanInvalidParameterException):
         graph.add_vertex(mach3)
예제 #16
0
    def _do_test(self, placer):
        machine = virtual_machine(width=8, height=8)
        graph = MachineGraph("Test")

        vertices = [
            SimpleMachineVertex(ResourceContainer(), label="v{}".format(i))
            for i in range(100)
        ]
        for vertex in vertices:
            graph.add_vertex(vertex)

        same_vertices = [
            SimpleMachineVertex(ResourceContainer(), label="same{}".format(i))
            for i in range(10)
        ]
        random.seed(12345)
        for vertex in same_vertices:
            graph.add_vertex(vertex)
            for _i in range(0, random.randint(1, 5)):
                vertex.add_constraint(
                    SameChipAsConstraint(
                        vertices[random.randint(0, 99)]))

        n_keys_map = DictBasedMachinePartitionNKeysMap()

        inputs = {
            "MemoryExtendedMachine": machine,
            "MemoryMachine": machine,
            "MemoryMachineGraph": graph,
            "PlanNTimeSteps": None,
            "MemoryMachinePartitionNKeysMap": n_keys_map
        }
        algorithms = [placer]
        xml_paths = []
        executor = PACMANAlgorithmExecutor(
            algorithms, [], inputs, [], [], [], xml_paths)
        executor.execute_mapping()

        placements = executor.get_item("MemoryPlacements")
        for same in same_vertices:
            print("{0.vertex.label}, {0.x}, {0.y}, {0.p}: {1}".format(
                placements.get_placement_of_vertex(same),
                ["{0.vertex.label}, {0.x}, {0.y}, {0.p}".format(
                    placements.get_placement_of_vertex(constraint.vertex))
                 for constraint in same.constraints]))
            placement = placements.get_placement_of_vertex(same)
            for constraint in same.constraints:
                if isinstance(constraint, SameChipAsConstraint):
                    other_placement = placements.get_placement_of_vertex(
                        constraint.vertex)
                    self.assertTrue(
                        other_placement.x == placement.x and
                        other_placement.y == placement.y,
                        "Vertex was not placed on the same chip as requested")
예제 #17
0
    def _do_test(self, placer):
        machine = virtual_machine(width=8, height=8)
        graph = MachineGraph("Test")
        plan_n_timesteps = 100

        vertices = [
            SimpleMachineVertex(ResourceContainer(),
                                label="v{}".format(i),
                                sdram_cost=20) for i in range(100)
        ]
        for vertex in vertices:
            graph.add_vertex(vertex)

        same_vertices = [
            SimpleMachineVertex(ResourceContainer(),
                                label="same{}".format(i),
                                sdram_cost=20) for i in range(10)
        ]
        random.seed(12345)
        sdram_edges = list()
        for vertex in same_vertices:
            graph.add_vertex(vertex)
            graph.add_outgoing_edge_partition(
                ConstantSDRAMMachinePartition(identifier="Test",
                                              pre_vertex=vertex,
                                              label="bacon"))
            for _i in range(0, random.randint(1, 5)):
                sdram_edge = SDRAMMachineEdge(vertex,
                                              vertices[random.randint(0, 99)],
                                              label="bacon",
                                              app_edge=None)
                sdram_edges.append(sdram_edge)
                graph.add_edge(sdram_edge, "Test")
        n_keys_map = DictBasedMachinePartitionNKeysMap()

        inputs = {
            "MemoryExtendedMachine": machine,
            "MemoryMachine": machine,
            "MemoryMachineGraph": graph,
            "PlanNTimeSteps": plan_n_timesteps,
            "MemoryMachinePartitionNKeysMap": n_keys_map
        }
        algorithms = [placer]
        xml_paths = []
        executor = PACMANAlgorithmExecutor(algorithms, [], inputs, [], [], [],
                                           xml_paths)
        executor.execute_mapping()
        placements = executor.get_item("MemoryPlacements")
        for edge in sdram_edges:
            pre_place = placements.get_placement_of_vertex(edge.pre_vertex)
            post_place = placements.get_placement_of_vertex(edge.post_vertex)
            assert pre_place.x == post_place.x
            assert pre_place.y == post_place.y
예제 #18
0
 def test_fill_machine(self):
     graph = MachineGraph("machine")
     cores = sum(chip.n_user_processors for chip in self.machine.chips)
     for i in range(cores):  # 50 atoms per each processor on 20 chips
         graph.add_vertex(
             get_resourced_machine_vertex(0, 50, "vertex " + str(i)))
     placements = connective_based_placer(graph, self.machine, 100)
     self.assertEqual(len(placements), cores)
     # One more vertex should be too many
     graph.add_vertex(get_resourced_machine_vertex(0, 50, "toomany"))
     with self.assertRaises(PacmanValueError):
         connective_based_placer(graph, self.machine, 100)
예제 #19
0
def graph_from_json(json_dict):
    json_dict = json_to_object(json_dict)
    graph = MachineGraph(json_dict.get("label"))
    for j_vertex in json_dict["vertices"]:
        graph.add_vertex(vertex_from_json(j_vertex, convert_constraints=False))
    # Only do constraints when we have all the vertexes to link to
    for j_vertex in json_dict["vertices"]:
        vertex_add_contstraints_from_json(j_vertex, graph)
    for j_edge in json_dict["edges"]:
        edge = edge_from_json(j_edge, graph)
        graph.add_edge(edge, "JSON_MOCK")
    return graph
예제 #20
0
    def _do_test(self, placer):
        machine = virtual_machine(width=8, height=8)
        graph = MachineGraph("Test")

        vertices = [
            SimpleMachineVertex(ResourceContainer(), label="v{}".format(i))
            for i in range(100)
        ]
        for vertex in vertices:
            graph.add_vertex(vertex)

        same_vertices = [
            SimpleMachineVertex(ResourceContainer(), label="same{}".format(i))
            for i in range(10)
        ]
        random.seed(12345)
        for vertex in same_vertices:
            graph.add_vertex(vertex)
            for _i in range(0, random.randint(1, 5)):
                vertex.add_constraint(
                    SameChipAsConstraint(vertices[random.randint(0, 99)]))

        n_keys_map = DictBasedMachinePartitionNKeysMap()

        if placer == "ConnectiveBasedPlacer":
            placements = connective_based_placer(graph, machine, None)
        elif placer == "OneToOnePlacer":
            placements = one_to_one_placer(graph, machine, None)
        elif placer == "RadialPlacer":
            placements = radial_placer(graph, machine, None)
        elif placer == "SpreaderPlacer":
            placements = spreader_placer(graph, machine, n_keys_map, None)
        else:
            raise NotImplementedError(placer)

        for same in same_vertices:
            print("{0.vertex.label}, {0.x}, {0.y}, {0.p}: {1}".format(
                placements.get_placement_of_vertex(same), [
                    "{0.vertex.label}, {0.x}, {0.y}, {0.p}".format(
                        placements.get_placement_of_vertex(constraint.vertex))
                    for constraint in same.constraints
                ]))
            placement = placements.get_placement_of_vertex(same)
            for constraint in same.constraints:
                if isinstance(constraint, SameChipAsConstraint):
                    other_placement = placements.get_placement_of_vertex(
                        constraint.vertex)
                    self.assertTrue(
                        other_placement.x == placement.x
                        and other_placement.y == placement.y,
                        "Vertex was not placed on the same chip as requested")
예제 #21
0
 def test_machine_vertices(self):
     app_graph = ApplicationGraph("super bacon")
     machine_graph = MachineGraph("bacon", application_graph=app_graph)
     vert = SimpleTestVertex(12, "New AbstractConstrainedVertex", 256)
     sub1 = vert.create_machine_vertex(
         Slice(0, 7), vert.get_resources_used_by_atoms(Slice(0, 7)), "M1")
     sub2 = vert.create_machine_vertex(
         Slice(7, 11), vert.get_resources_used_by_atoms(Slice(7, 11)), "M2")
     machine_graph.add_vertex(sub1)
     machine_graph.add_vertex(sub2)
     self.assertIn(sub1, vert.machine_vertices)
     self.assertIn(sub2, vert.machine_vertices)
     self.assertIn(Slice(0, 7), vert.vertex_slices)
     self.assertIn(Slice(7, 11), vert.vertex_slices)
예제 #22
0
    def _do_test(self, placer):
        machine = virtual_machine(width=8, height=8)
        graph = MachineGraph("Test")

        vertices = [
            MockMachineVertex(ResourceContainer(),
                              label="v{}".format(i),
                              sdram_requirement=20) for i in range(100)
        ]
        for vertex in vertices:
            graph.add_vertex(vertex)

        same_vertices = [
            MockMachineVertex(ResourceContainer(),
                              label="same{}".format(i),
                              sdram_requirement=20) for i in range(10)
        ]
        random.seed(12345)
        sdram_edges = list()
        for vertex in same_vertices:
            graph.add_vertex(vertex)
            graph.add_outgoing_edge_partition(
                ConstantSDRAMMachinePartition(identifier="Test",
                                              pre_vertex=vertex,
                                              label="bacon"))
            for _i in range(0, random.randint(1, 5)):
                sdram_edge = SDRAMMachineEdge(vertex,
                                              vertices[random.randint(0, 99)],
                                              label="bacon",
                                              app_edge=None)
                sdram_edges.append(sdram_edge)
                graph.add_edge(sdram_edge, "Test")
        n_keys_map = DictBasedMachinePartitionNKeysMap()

        if placer == "ConnectiveBasedPlacer":
            placements = connective_based_placer(graph, machine, None)
        elif placer == "OneToOnePlacer":
            placements = one_to_one_placer(graph, machine, None)
        elif placer == "RadialPlacer":
            placements = radial_placer(graph, machine, None)
        elif placer == "SpreaderPlacer":
            placements = spreader_placer(graph, machine, n_keys_map, None)
        else:
            raise NotImplementedError(placer)
        for edge in sdram_edges:
            pre_place = placements.get_placement_of_vertex(edge.pre_vertex)
            post_place = placements.get_placement_of_vertex(edge.post_vertex)
            assert pre_place.x == post_place.x
            assert pre_place.y == post_place.y
예제 #23
0
    def __call__(self, machine_graph, graph_mapper):
        """
        :param machine_graph: the machine_graph whose edges are to be filtered
        :param graph_mapper: the graph mapper between graphs
        :return: a new graph mapper and machine graph
        """
        new_machine_graph = MachineGraph(label=machine_graph.label)
        new_graph_mapper = GraphMapper()

        # create progress bar
        progress_bar = ProgressBar(
            machine_graph.n_vertices +
            machine_graph.n_outgoing_edge_partitions, "Filtering edges")

        # add the vertices directly, as they wont be pruned.
        for vertex in machine_graph.vertices:
            new_machine_graph.add_vertex(vertex)
            associated_vertex = graph_mapper.get_application_vertex(vertex)
            vertex_slice = graph_mapper.get_slice(vertex)
            new_graph_mapper.add_vertex_mapping(
                machine_vertex=vertex,
                vertex_slice=vertex_slice,
                application_vertex=associated_vertex)
            progress_bar.update()

        # start checking edges to decide which ones need pruning....
        for partition in machine_graph.outgoing_edge_partitions:
            for edge in partition.edges:
                if not self._is_filterable(edge, graph_mapper):
                    logger.debug("this edge was not pruned {}".format(edge))
                    new_machine_graph.add_edge(edge, partition.identifier)
                    app_edge = graph_mapper.get_application_edge(edge)
                    new_graph_mapper.add_edge_mapping(edge, app_edge)

                    # add partition constraints from the original graph to
                    # the new graph
                    # add constraints from the application partition
                    new_machine_graph_partition = new_machine_graph.\
                        get_outgoing_edge_partition_starting_at_vertex(
                            edge.pre_vertex, partition.identifier)
                    new_machine_graph_partition.add_constraints(
                        partition.constraints)
                else:
                    logger.debug("this edge was pruned {}".format(edge))
            progress_bar.update()
        progress_bar.end()

        # returned the pruned graph and graph_mapper
        return new_machine_graph, new_graph_mapper
def test_create_constraints_to_file(tmpdir):
    # Construct the sample machine and graph
    machine = VirtualMachine(version=3, with_wrap_arounds=None)
    # TODO: define some extra monitor cores (how?)
    graph = MachineGraph("foo")
    tag1 = IPtagResource("1.2.3.4", 5, False, tag="footag")
    tag2 = ReverseIPtagResource(tag="bartag")
    v0 = SimpleMachineVertex(ResourceContainer(
        iptags=[tag1], reverse_iptags=[tag2]), constraints=[
        ChipAndCoreConstraint(1, 1, 3)])
    graph.add_vertex(v0)
    v0_id = ident(v0)
    v1 = MachineSpiNNakerLinkVertex(0)
    v1.set_virtual_chip_coordinates(0, 2)
    graph.add_vertex(v1)
    v1_id = ident(v1)

    machine = MallocBasedChipIdAllocator()(machine, graph)
    algo = CreateConstraintsToFile()
    fn = tmpdir.join("foo.json")
    filename, mapping = algo(graph, machine, str(fn))
    assert filename == str(fn)
    for vid in mapping:
        assert vid in [v0_id, v1_id]
        assert vid == ident(mapping[vid])
    obj = json.loads(fn.read())
    baseline = [
        {
            "type": "reserve_resource",
            "location": None, "reservation": [0, 1], "resource": "cores"},
        {
            "type": "location",
            "location": [1, 1], "vertex": v0_id},
        {
            "type": "resource",
            "resource": "cores", "range": [3, 4], "vertex": v0_id},
        {
            "type": "resource",
            "resource": "iptag", "range": [0, 1], "vertex": v0_id},
        {
            "type": "resource",
            "resource": "reverse_iptag", "range": [0, 1], "vertex": v0_id},
        {
            "type": "route_endpoint",
            "direction": "west", "vertex": v1_id},
        {
            "type": "location",
            "location": [0, 0], "vertex": v1_id}]
    assert obj == baseline
    def test_get_vertex_from_vertex(self):
        """
        test that the graph mapper can retrieve a vertex from a given vertex
        """
        app_graph = ApplicationGraph("bacon")
        vert = SimpleTestVertex(10, "Some testing vertex")
        app_graph.add_vertex(vert)
        vertex1 = SimpleMachineVertex(None, "", app_vertex=vert,
                                      vertex_slice=Slice(0, 1))
        vertex2 = SimpleMachineVertex(None, "", app_vertex=vert,
                                      vertex_slice=Slice(2, 3))
        machine_graph = MachineGraph(
            application_graph=app_graph, label="cooked_bacon")
        machine_graph.add_vertex(vertex1)
        machine_graph.add_vertex(vertex2)

        self.assertEqual(vert, vertex1.app_vertex)
        self.assertEqual(vert, vertex2.app_vertex)
        self.assertEqual([vertex1, vertex2], list(vert.machine_vertices))
예제 #26
0
 def test_remember_machine_vertex(self):
     app_graph = ApplicationGraph("Test")
     graph = MachineGraph("foo", app_graph)
     app1 = SimpleTestVertex(12, "app1")
     app2 = SimpleTestVertex(12, "app2")
     mach1 = SimpleMachineVertex("mach1", app_vertex=app1)
     mach2 = SimpleMachineVertex("mach2", app_vertex=app1)
     mach3 = SimpleMachineVertex("mach3", app_vertex=app1)
     mach4 = SimpleMachineVertex("mach4", app_vertex=app2)
     self.assertEquals(0, len(app1.machine_vertices))
     self.assertEquals(0, len(app2.machine_vertices))
     graph.add_vertices([mach1, mach2])
     graph.add_vertex(mach3)
     graph.add_vertex(mach4)
     self.assertEquals(3, len(app1.machine_vertices))
     self.assertEquals(1, len(app2.machine_vertices))
     self.assertIn(mach1, app1.machine_vertices)
     self.assertIn(mach2, app1.machine_vertices)
     self.assertIn(mach3, app1.machine_vertices)
     self.assertIn(mach4, app2.machine_vertices)
예제 #27
0
    def __call__(self, app_graph, machine_graph):
        """
        :param app_graph: The application graph
        :type app_graph:
            ~pacman.model.graphs.application.ApplicationGraph or None
        :param .MachineGraph machine_graph:
             The machine_graph whose edges are to be filtered
        :return: a new, filtered machine graph
        """
        new_machine_graph = MachineGraph(label=machine_graph.label,
                                         application_graph=app_graph)

        # create progress bar
        progress = ProgressBar(
            machine_graph.n_vertices +
            machine_graph.n_outgoing_edge_partitions, "Filtering edges")

        # add the vertices directly, as they won't be pruned.
        for vertex in progress.over(machine_graph.vertices, False):
            new_machine_graph.add_vertex(vertex)
            vertex.associate_application_vertex()

        # start checking edges to decide which ones need pruning....
        prune_count = 0
        no_prune_count = 0
        for partition in progress.over(machine_graph.outgoing_edge_partitions):
            for edge in partition.edges:
                if self._is_filterable(edge):
                    logger.debug("this edge was pruned {}", edge)
                    prune_count += 1
                    continue
                logger.debug("this edge was not pruned {}", edge)
                no_prune_count += 1
                self._add_edge_to_new_graph(edge, partition, new_machine_graph)

        # return the pruned graph after remembering that it is the graph that
        # the application graph maps to now
        logger.debug("prune_count:{} no_prune_count:{}", prune_count,
                     no_prune_count)
        return new_machine_graph
    def _do_test(self, placer):
        machine = VirtualMachine(width=8, height=8)
        graph = MachineGraph("Test")

        vertices = [
            SimpleMachineVertex(ResourceContainer(), label="v{}".format(i))
            for i in range(100)
        ]
        for vertex in vertices:
            graph.add_vertex(vertex)

        same_vertices = [
            SimpleMachineVertex(ResourceContainer(), label="same{}".format(i))
            for i in range(10)
        ]
        random.seed(12345)
        for vertex in same_vertices:
            graph.add_vertex(vertex)
            for i in range(0, random.randint(1, 5)):
                vertex.add_constraint(
                    SameChipAsConstraint(
                        vertices[random.randint(0, 99)]))

        placements = placer(graph, machine, plan_n_timesteps=None)
        for same in same_vertices:
            print("{0.vertex.label}, {0.x}, {0.y}, {0.p}: {1}".format(
                placements.get_placement_of_vertex(same),
                ["{0.vertex.label}, {0.x}, {0.y}, {0.p}".format(
                    placements.get_placement_of_vertex(constraint.vertex))
                 for constraint in same.constraints]))
            placement = placements.get_placement_of_vertex(same)
            for constraint in same.constraints:
                if isinstance(constraint, SameChipAsConstraint):
                    other_placement = placements.get_placement_of_vertex(
                        constraint.vertex)
                    self.assert_(
                        other_placement.x == placement.x and
                        other_placement.y == placement.y,
                        "Vertex was not placed on the same chip as requested")
예제 #29
0
    def _do_test(self, placer):
        machine = VirtualMachine(width=8, height=8)
        graph = MachineGraph("Test")

        vertices = [
            SimpleMachineVertex(ResourceContainer(), label="v{}".format(i))
            for i in range(100)
        ]
        for vertex in vertices:
            graph.add_vertex(vertex)

        same_vertices = [
            SimpleMachineVertex(ResourceContainer(), label="same{}".format(i))
            for i in range(10)
        ]
        random.seed(12345)
        for vertex in same_vertices:
            graph.add_vertex(vertex)
            for i in range(0, random.randint(1, 5)):
                vertex.add_constraint(
                    SameChipAsConstraint(vertices[random.randint(0, 99)]))

        placements = placer(graph, machine)
        for same in same_vertices:
            print("{0.vertex.label}, {0.x}, {0.y}, {0.p}: {1}".format(
                placements.get_placement_of_vertex(same), [
                    "{0.vertex.label}, {0.x}, {0.y}, {0.p}".format(
                        placements.get_placement_of_vertex(constraint.vertex))
                    for constraint in same.constraints
                ]))
            placement = placements.get_placement_of_vertex(same)
            for constraint in same.constraints:
                if isinstance(constraint, SameChipAsConstraint):
                    other_placement = placements.get_placement_of_vertex(
                        constraint.vertex)
                    self.assert_(
                        other_placement.x == placement.x
                        and other_placement.y == placement.y,
                        "Vertex was not placed on the same chip as requested")
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)
def test_virtual_placement(placer):
    unittest_setup()
    machine = virtual_machine(width=8, height=8)
    graph = MachineGraph("Test")
    virtual_vertex = MachineSpiNNakerLinkVertex(spinnaker_link_id=0)
    graph.add_vertex(virtual_vertex)
    extended_machine = malloc_based_chip_id_allocator(machine, graph)
    n_keys_map = DictBasedMachinePartitionNKeysMap()

    if placer == "ConnectiveBasedPlacer":
        placements = connective_based_placer(graph, machine, None)
    elif placer == "OneToOnePlacer":
        placements = one_to_one_placer(graph, machine, None)
    elif placer == "RadialPlacer":
        placements = radial_placer(graph, machine, None)
    elif placer == "SpreaderPlacer":
        placements = spreader_placer(graph, machine, n_keys_map, None)
    else:
        raise NotImplementedError(placer)

    placement = placements.get_placement_of_vertex(virtual_vertex)
    chip = extended_machine.get_chip_at(placement.x, placement.y)
    assert chip.virtual
예제 #32
0
def test_virtual_vertices_spreader():
    """ Test that the placer works with a virtual vertex
    """

    # Create a graph with a virtual vertex
    machine_graph = MachineGraph("Test")
    virtual_vertex = MachineSpiNNakerLinkVertex(
        spinnaker_link_id=0, label="Virtual")
    machine_graph.add_vertex(virtual_vertex)

    # These vertices are fixed on 0, 0
    misc_vertices = list()
    for i in range(3):
        misc_vertex = SimpleMachineVertex(
            resources=ResourceContainer(), constraints=[
                ChipAndCoreConstraint(0, 0)],
            label="Fixed_0_0_{}".format(i))
        machine_graph.add_vertex(misc_vertex)
        misc_vertices.append(misc_vertex)

    # These vertices are 1-1 connected to the virtual vertex
    one_to_one_vertices = list()
    for i in range(16):
        one_to_one_vertex = SimpleMachineVertex(
            resources=ResourceContainer(),
            label="Vertex_{}".format(i))
        machine_graph.add_vertex(one_to_one_vertex)
        edge = MachineEdge(virtual_vertex, one_to_one_vertex)
        machine_graph.add_edge(edge, "SPIKES")
        one_to_one_vertices.append(one_to_one_vertex)

    n_keys_map = DictBasedMachinePartitionNKeysMap()
    partition = machine_graph.get_outgoing_edge_partition_starting_at_vertex(
        virtual_vertex, "SPIKES")
    n_keys_map.set_n_keys_for_partition(partition, 1)

    # Get and extend the machine for the virtual chip
    machine = virtual_machine(width=8, height=8)
    extended_machine = MallocBasedChipIdAllocator()(machine, machine_graph)

    # Do placements
    placements = SpreaderPlacer()(
        machine_graph, extended_machine, n_keys_map, plan_n_timesteps=1000)

    # The virtual vertex should be on a virtual chip
    placement = placements.get_placement_of_vertex(virtual_vertex)
    assert machine.get_chip_at(placement.x, placement.y).virtual

    # The 0, 0 vertices should be on 0, 0
    for vertex in misc_vertices:
        placement = placements.get_placement_of_vertex(vertex)
        assert placement.x == placement.y == 0

    # The other vertices should *not* be on a virtual chip
    for vertex in one_to_one_vertices:
        placement = placements.get_placement_of_vertex(vertex)
        assert not machine.get_chip_at(placement.x, placement.y).virtual
예제 #33
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)
예제 #34
0
 def test_no_app_graph_no_app_vertex(self):
     graph = MachineGraph("foo")
     app1 = SimpleTestVertex(12, "app1")
     mach1 = SimpleMachineVertex("mach1", app_vertex=app1)
     mach2 = SimpleMachineVertex("mach2", app_vertex=None)
     mach3 = SimpleMachineVertex("mach3", app_vertex=app1)
     with self.assertRaises(PacmanInvalidParameterException):
         graph.add_vertex(mach1)
     graph.add_vertex(mach2)
     with self.assertRaises(PacmanInvalidParameterException):
         graph.add_vertex(mach3)
def test_virtual_vertices_one_to_one():
    """ Test that the placer works with a virtual vertex
    """

    # Create a graph with a virtual vertex
    machine_graph = MachineGraph("Test")
    virtual_vertex = MachineSpiNNakerLinkVertex(
        spinnaker_link_id=0, label="Virtual")
    machine_graph.add_vertex(virtual_vertex)

    # These vertices are fixed on 0, 0
    misc_vertices = list()
    for i in range(3):
        misc_vertex = SimpleMachineVertex(
            resources=ResourceContainer(), constraints=[
                ChipAndCoreConstraint(0, 0)],
            label="Fixed_0_0_{}".format(i))
        machine_graph.add_vertex(misc_vertex)
        misc_vertices.append(misc_vertex)

    # These vertices are 1-1 connected to the virtual vertex
    one_to_one_vertices = list()
    for i in range(16):
        one_to_one_vertex = SimpleMachineVertex(
            resources=ResourceContainer(),
            label="Vertex_{}".format(i))
        machine_graph.add_vertex(one_to_one_vertex)
        edge = MachineEdge(virtual_vertex, one_to_one_vertex)
        machine_graph.add_edge(edge, "SPIKES")
        one_to_one_vertices.append(one_to_one_vertex)

    # Get and extend the machine for the virtual chip
    machine = VirtualMachine(version=5)
    extended_machine = MallocBasedChipIdAllocator()(machine, machine_graph)

    # Do placements
    placements = OneToOnePlacer()(
        machine_graph, extended_machine, plan_n_timesteps=1000)

    # The virtual vertex should be on a virtual chip
    placement = placements.get_placement_of_vertex(virtual_vertex)
    assert machine.get_chip_at(placement.x, placement.y).virtual

    # The 0, 0 vertices should be on 0, 0
    for vertex in misc_vertices:
        placement = placements.get_placement_of_vertex(vertex)
        assert placement.x == placement.y == 0

    # The other vertices should *not* be on a virtual chip
    for vertex in one_to_one_vertices:
        placement = placements.get_placement_of_vertex(vertex)
        assert not machine.get_chip_at(placement.x, placement.y).virtual
def test_convert_to_file_machine_graph(tmpdir):
    # Construct the sample graph
    graph = MachineGraph("foo")
    v0 = SimpleMachineVertex(ResourceContainer())
    graph.add_vertex(v0)
    tag = IPtagResource("1.2.3.4", 5, False, tag="footag")
    v1 = SimpleMachineVertex(ResourceContainer(iptags=[tag]))
    graph.add_vertex(v1)
    t1id = md5("%s_tag" % ident(v1))
    tag = ReverseIPtagResource(tag="bartag")
    v2 = SimpleMachineVertex(ResourceContainer(reverse_iptags=[tag]))
    graph.add_vertex(v2)
    t2id = md5("%s_tag" % ident(v2))
    graph.add_edge(MachineEdge(v1, v0), "part1")
    p1 = graph.get_outgoing_edge_partition_starting_at_vertex(v1, "part1")
    graph.add_edge(MachineEdge(v0, v2, label="foobar"), "part2")
    p2 = graph.get_outgoing_edge_partition_starting_at_vertex(v0, "part2")

    # Convert it to JSON
    algo = ConvertToFileMachineGraph()
    fn = tmpdir.join("foo.json")
    filename, _vertex_by_id, _partition_by_id = algo(
        graph, plan_n_timesteps=None, file_path=str(fn))
    assert filename == str(fn)

    # Rebuild and compare; simplest way of checking given that order is not
    # preserved in the underlying string and altering that is hard
    obj = json.loads(fn.read())
    baseline = {
        "vertices_resources": {
            ident(v0): {"cores": 1, "sdram": 0},
            ident(v1): {"cores": 1, "sdram": 0},
            t1id:      {"cores": 0, "sdram": 0},
            ident(v2): {"cores": 1, "sdram": 0},
            t2id:      {"cores": 0, "sdram": 0}},
        "edges": {
            ident(p1): {
                "source": ident(v1), "sinks": [ident(v0)],
                "type": "multicast", "weight": 1},
            ident(p2): {
                "source": ident(v0), "sinks": [ident(v2)],
                "type": "multicast", "weight": 1},
            t1id: {
                "source": ident(v1), "sinks": [t1id],
                "weight": 1.0, "type": "FAKE_TAG_EDGE"},
            t2id: {
                "source": ident(v2), "sinks": [t2id],
                "weight": 1.0, "type": "FAKE_TAG_EDGE"}}}
    assert obj == baseline
    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])
예제 #38
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])
예제 #39
0
class TestConnectivePlacer(unittest.TestCase):
    def setUp(self):
        unittest_setup()
        self.machine = virtual_machine(8, 8)
        self.mach_graph = MachineGraph("machine")
        self.vertices = list()
        self.vertex1 = get_resourced_machine_vertex(0, 1, "First vertex")
        self.vertex2 = get_resourced_machine_vertex(1, 5, "Second vertex")
        self.vertex3 = get_resourced_machine_vertex(5, 10, "Third vertex")
        self.vertex4 = get_resourced_machine_vertex(10, 100, "Fourth vertex")
        self.vertices.append(self.vertex1)
        self.mach_graph.add_vertex(self.vertex1)
        self.vertices.append(self.vertex2)
        self.mach_graph.add_vertex(self.vertex2)
        self.vertices.append(self.vertex3)
        self.mach_graph.add_vertex(self.vertex3)
        self.vertices.append(self.vertex4)
        self.mach_graph.add_vertex(self.vertex4)
        self.edges = list()
        edge1 = MachineEdge(self.vertex2, self.vertex3)
        self.edges.append(edge1)
        self.mach_graph.add_edge(edge1, "packet")
        edge2 = MachineEdge(self.vertex2, self.vertex4)
        self.edges.append(edge2)
        self.mach_graph.add_edge(edge2, "packet")
        edge3 = MachineEdge(self.vertex3, self.vertex4)
        self.edges.append(edge3)
        self.mach_graph.add_edge(edge3, "packet")
        edge4 = MachineEdge(self.vertex3, self.vertex1)
        self.edges.append(edge4)

        self.plan_n_timesteps = 100

    def test_simple(self):
        placements = connective_based_placer(self.mach_graph, self.machine,
                                             100)
        self.assertEqual(len(self.vertices), len(placements))

    def test_place_vertex_too_big_with_vertex(self):
        cpu_cycles = 1000
        dtcm_requirement = 1000
        sdram_requirement = self.machine.get_chip_at(0, 0).sdram.size * 20
        rc = ResourceContainer(cpu_cycles=CPUCyclesPerTickResource(cpu_cycles),
                               dtcm=DTCMResource(dtcm_requirement),
                               sdram=ConstantSDRAM(sdram_requirement))

        large_machine_vertex = SimpleMachineVertex(rc,
                                                   vertex_slice=Slice(0, 499),
                                                   label="Second vertex")
        self.mach_graph.add_vertex(large_machine_vertex)
        with self.assertRaises(PacmanValueError):
            connective_based_placer(self.mach_graph, self.machine, 100)

    def test_deal_with_constraint_placement_vertices_dont_have_vertex(self):
        self.vertex2.add_constraint(ChipAndCoreConstraint(3, 5, 7))
        self.vertex3.add_constraint(RadialPlacementFromChipConstraint(2, 4))
        placements = connective_based_placer(self.mach_graph, self.machine,
                                             100)
        for placement in placements.placements:
            if placement.vertex == self.vertex2:
                self.assertEqual(placement.x, 3)
                self.assertEqual(placement.y, 5)
                self.assertEqual(placement.p, 7)
            if placement.vertex == self.vertex3:
                self.assertEqual(placement.x, 2)
                self.assertEqual(placement.y, 4)
        self.assertEqual(len(self.vertices), len(placements))

    def test_fill_machine(self):
        graph = MachineGraph("machine")
        cores = sum(chip.n_user_processors for chip in self.machine.chips)
        for i in range(cores):  # 50 atoms per each processor on 20 chips
            graph.add_vertex(
                get_resourced_machine_vertex(0, 50, "vertex " + str(i)))
        placements = connective_based_placer(graph, self.machine, 100)
        self.assertEqual(len(placements), cores)
        # One more vertex should be too many
        graph.add_vertex(get_resourced_machine_vertex(0, 50, "toomany"))
        with self.assertRaises(PacmanValueError):
            connective_based_placer(graph, self.machine, 100)
    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
    def test_write_synaptic_matrix_and_master_population_table(self):
        MockSimulator.setup()
        # Add an sdram so maxsdram is high enough
        SDRAM(10000)

        default_config_paths = os.path.join(
            os.path.dirname(abstract_spinnaker_common.__file__),
            AbstractSpiNNakerCommon.CONFIG_FILE_NAME)

        config = conf_loader.load_config(
            AbstractSpiNNakerCommon.CONFIG_FILE_NAME, default_config_paths)
        config.set("Simulation", "one_to_one_connection_dtcm_max_bytes", 40)

        machine_time_step = 1000.0

        pre_app_vertex = SimpleApplicationVertex(10)
        pre_vertex = SimpleMachineVertex(resources=None)
        pre_vertex_slice = Slice(0, 9)
        post_app_vertex = SimpleApplicationVertex(10)
        post_vertex = SimpleMachineVertex(resources=None)
        post_vertex_slice = Slice(0, 9)
        post_slice_index = 0
        one_to_one_connector_1 = OneToOneConnector(None)
        one_to_one_connector_1.set_projection_information(
            pre_app_vertex, post_app_vertex, None, machine_time_step)
        one_to_one_connector_2 = OneToOneConnector(None)
        one_to_one_connector_2.set_projection_information(
            pre_app_vertex, post_app_vertex, None, machine_time_step)
        all_to_all_connector = AllToAllConnector(None)
        all_to_all_connector.set_projection_information(
            pre_app_vertex, post_app_vertex, None, machine_time_step)
        direct_synapse_information_1 = SynapseInformation(
            one_to_one_connector_1, SynapseDynamicsStatic(), 0, 1.5, 1.0)
        direct_synapse_information_2 = SynapseInformation(
            one_to_one_connector_2, SynapseDynamicsStatic(), 1, 2.5, 2.0)
        all_to_all_synapse_information = SynapseInformation(
            all_to_all_connector, SynapseDynamicsStatic(), 0, 4.5, 4.0)
        app_edge = ProjectionApplicationEdge(
            pre_app_vertex, post_app_vertex, direct_synapse_information_1)
        app_edge.add_synapse_information(direct_synapse_information_2)
        app_edge.add_synapse_information(all_to_all_synapse_information)
        machine_edge = ProjectionMachineEdge(
            app_edge.synapse_information, pre_vertex, post_vertex)
        partition_name = "TestPartition"

        graph = MachineGraph("Test")
        graph.add_vertex(pre_vertex)
        graph.add_vertex(post_vertex)
        graph.add_edge(machine_edge, partition_name)

        graph_mapper = GraphMapper()
        graph_mapper.add_vertex_mapping(
            pre_vertex, pre_vertex_slice, pre_app_vertex)
        graph_mapper.add_vertex_mapping(
            post_vertex, post_vertex_slice, post_app_vertex)
        graph_mapper.add_edge_mapping(machine_edge, app_edge)

        weight_scales = [4096.0, 4096.0]

        key = 0
        routing_info = RoutingInfo()
        routing_info.add_partition_info(PartitionRoutingInfo(
            [BaseKeyAndMask(key, 0xFFFFFFF0)],
            graph.get_outgoing_edge_partition_starting_at_vertex(
                pre_vertex, partition_name)))

        temp_spec = tempfile.mktemp()
        spec_writer = FileDataWriter(temp_spec)
        spec = DataSpecificationGenerator(spec_writer, None)
        master_pop_sz = 1000
        master_pop_region = 0
        all_syn_block_sz = 2000
        synapse_region = 1
        direct_region = 2
        spec.reserve_memory_region(master_pop_region, master_pop_sz)
        spec.reserve_memory_region(synapse_region, all_syn_block_sz)

        synaptic_manager = SynapticManager(
            n_synapse_types=2, ring_buffer_sigma=5.0,
            spikes_per_second=100.0, config=config)
        # UGLY but the mock transceiver NEED generate_on_machine be False
        abstract_generate_connector_on_machine.IS_PYNN_8 = False
        synaptic_manager._write_synaptic_matrix_and_master_population_table(
            spec, [post_vertex_slice], post_slice_index, post_vertex,
            post_vertex_slice, all_syn_block_sz, weight_scales,
            master_pop_region, synapse_region, direct_region, routing_info,
            graph_mapper, graph, machine_time_step)
        spec.end_specification()
        spec_writer.close()

        spec_reader = FileDataReader(temp_spec)
        executor = DataSpecificationExecutor(
            spec_reader, master_pop_sz + all_syn_block_sz)
        executor.execute()

        master_pop_table = executor.get_region(0)
        synaptic_matrix = executor.get_region(1)
        direct_matrix = executor.get_region(2)

        all_data = bytearray()
        all_data.extend(master_pop_table.region_data[
            :master_pop_table.max_write_pointer])
        all_data.extend(synaptic_matrix.region_data[
            :synaptic_matrix.max_write_pointer])
        all_data.extend(direct_matrix.region_data[
            :direct_matrix.max_write_pointer])
        master_pop_table_address = 0
        synaptic_matrix_address = master_pop_table.max_write_pointer
        direct_synapses_address = (
            synaptic_matrix_address + synaptic_matrix.max_write_pointer)
        direct_synapses_address += 4
        indirect_synapses_address = synaptic_matrix_address
        placement = Placement(None, 0, 0, 1)
        transceiver = MockTransceiverRawData(all_data)

        # Get the master population table details
        items = synaptic_manager._poptable_type\
            .extract_synaptic_matrix_data_location(
                key, master_pop_table_address, transceiver,
                placement.x, placement.y)

        # The first entry should be direct, but the rest should be indirect;
        # the second is potentially direct, but has been restricted by the
        # restriction on the size of the direct matrix
        assert len(items) == 3
        assert items[0][2]
        assert not items[1][2]
        assert not items[2][2]

        data_1, row_len_1 = synaptic_manager._retrieve_synaptic_block(
            transceiver=transceiver, placement=placement,
            master_pop_table_address=master_pop_table_address,
            indirect_synapses_address=indirect_synapses_address,
            direct_synapses_address=direct_synapses_address, key=key,
            n_rows=pre_vertex_slice.n_atoms, index=0,
            using_extra_monitor_cores=False)
        connections_1 = synaptic_manager._synapse_io.read_synapses(
            direct_synapse_information_1, pre_vertex_slice, post_vertex_slice,
            row_len_1, 0, 2, weight_scales, data_1, None,
            app_edge.n_delay_stages, machine_time_step)

        # The first matrix is a 1-1 matrix, so row length is 1
        assert row_len_1 == 1

        # Check that all the connections have the right weight and delay
        assert len(connections_1) == post_vertex_slice.n_atoms
        assert all([conn["weight"] == 1.5 for conn in connections_1])
        assert all([conn["delay"] == 1.0 for conn in connections_1])

        data_2, row_len_2 = synaptic_manager._retrieve_synaptic_block(
            transceiver=transceiver, placement=placement,
            master_pop_table_address=master_pop_table_address,
            indirect_synapses_address=indirect_synapses_address,
            direct_synapses_address=direct_synapses_address, key=key,
            n_rows=pre_vertex_slice.n_atoms, index=1,
            using_extra_monitor_cores=False)
        connections_2 = synaptic_manager._synapse_io.read_synapses(
            direct_synapse_information_2, pre_vertex_slice, post_vertex_slice,
            row_len_2, 0, 2, weight_scales, data_2, None,
            app_edge.n_delay_stages, machine_time_step)

        # The second matrix is a 1-1 matrix, so row length is 1
        assert row_len_2 == 1

        # Check that all the connections have the right weight and delay
        assert len(connections_2) == post_vertex_slice.n_atoms
        assert all([conn["weight"] == 2.5 for conn in connections_2])
        assert all([conn["delay"] == 2.0 for conn in connections_2])

        data_3, row_len_3 = synaptic_manager._retrieve_synaptic_block(
            transceiver=transceiver, placement=placement,
            master_pop_table_address=master_pop_table_address,
            indirect_synapses_address=indirect_synapses_address,
            direct_synapses_address=direct_synapses_address, key=key,
            n_rows=pre_vertex_slice.n_atoms, index=2,
            using_extra_monitor_cores=False)
        connections_3 = synaptic_manager._synapse_io.read_synapses(
            all_to_all_synapse_information, pre_vertex_slice,
            post_vertex_slice, row_len_3, 0, 2, weight_scales, data_3, None,
            app_edge.n_delay_stages, machine_time_step)

        # The third matrix is an all-to-all matrix, so length is n_atoms
        assert row_len_3 == post_vertex_slice.n_atoms

        # Check that all the connections have the right weight and delay
        assert len(connections_3) == \
            post_vertex_slice.n_atoms * pre_vertex_slice.n_atoms
        assert all([conn["weight"] == 4.5 for conn in connections_3])
        assert all([conn["delay"] == 4.0 for conn in connections_3])
예제 #42
0
    def test_write_synaptic_matrix_and_master_population_table(self):
        MockSimulator.setup()

        default_config_paths = os.path.join(
            os.path.dirname(abstract_spinnaker_common.__file__),
            AbstractSpiNNakerCommon.CONFIG_FILE_NAME)

        config = conf_loader.load_config(
            AbstractSpiNNakerCommon.CONFIG_FILE_NAME, default_config_paths)
        config.set("Simulation", "one_to_one_connection_dtcm_max_bytes", 40)

        machine_time_step = 1000.0

        pre_app_vertex = SimpleApplicationVertex(10)
        pre_vertex = SimpleMachineVertex(resources=None)
        pre_vertex_slice = Slice(0, 9)
        post_app_vertex = SimpleApplicationVertex(10)
        post_vertex = SimpleMachineVertex(resources=None)
        post_vertex_slice = Slice(0, 9)
        post_slice_index = 0
        one_to_one_connector_1 = OneToOneConnector(None)
        one_to_one_connector_1.set_projection_information(
            pre_app_vertex, post_app_vertex, None, machine_time_step)
        one_to_one_connector_1.set_weights_and_delays(1.5, 1.0)
        one_to_one_connector_2 = OneToOneConnector(None)
        one_to_one_connector_2.set_projection_information(
            pre_app_vertex, post_app_vertex, None, machine_time_step)
        one_to_one_connector_2.set_weights_and_delays(2.5, 2.0)
        all_to_all_connector = AllToAllConnector(None)
        all_to_all_connector.set_projection_information(
            pre_app_vertex, post_app_vertex, None, machine_time_step)
        all_to_all_connector.set_weights_and_delays(4.5, 4.0)
        direct_synapse_information_1 = SynapseInformation(
            one_to_one_connector_1, SynapseDynamicsStatic(), 0)
        direct_synapse_information_2 = SynapseInformation(
            one_to_one_connector_2, SynapseDynamicsStatic(), 1)
        all_to_all_synapse_information = SynapseInformation(
            all_to_all_connector, SynapseDynamicsStatic(), 0)
        app_edge = ProjectionApplicationEdge(pre_app_vertex, post_app_vertex,
                                             direct_synapse_information_1)
        app_edge.add_synapse_information(direct_synapse_information_2)
        app_edge.add_synapse_information(all_to_all_synapse_information)
        machine_edge = ProjectionMachineEdge(app_edge.synapse_information,
                                             pre_vertex, post_vertex)
        partition_name = "TestPartition"

        graph = MachineGraph("Test")
        graph.add_vertex(pre_vertex)
        graph.add_vertex(post_vertex)
        graph.add_edge(machine_edge, partition_name)

        graph_mapper = GraphMapper()
        graph_mapper.add_vertex_mapping(pre_vertex, pre_vertex_slice,
                                        pre_app_vertex)
        graph_mapper.add_vertex_mapping(post_vertex, post_vertex_slice,
                                        post_app_vertex)
        graph_mapper.add_edge_mapping(machine_edge, app_edge)

        weight_scales = [4096.0, 4096.0]

        key = 0
        routing_info = RoutingInfo()
        routing_info.add_partition_info(
            PartitionRoutingInfo(
                [BaseKeyAndMask(key, 0xFFFFFFF0)],
                graph.get_outgoing_edge_partition_starting_at_vertex(
                    pre_vertex, partition_name)))

        temp_spec = tempfile.mktemp()
        spec_writer = FileDataWriter(temp_spec)
        spec = DataSpecificationGenerator(spec_writer, None)
        master_pop_sz = 1000
        master_pop_region = 0
        all_syn_block_sz = 2000
        synapse_region = 1
        spec.reserve_memory_region(master_pop_region, master_pop_sz)
        spec.reserve_memory_region(synapse_region, all_syn_block_sz)

        synapse_type = MockSynapseType()

        synaptic_manager = SynapticManager(synapse_type=synapse_type,
                                           ring_buffer_sigma=5.0,
                                           spikes_per_second=100.0,
                                           config=config)
        synaptic_manager._write_synaptic_matrix_and_master_population_table(
            spec, [post_vertex_slice], post_slice_index, post_vertex,
            post_vertex_slice, all_syn_block_sz, weight_scales,
            master_pop_region, synapse_region, routing_info, graph_mapper,
            graph, machine_time_step)
        spec.end_specification()
        spec_writer.close()

        spec_reader = FileDataReader(temp_spec)
        executor = DataSpecificationExecutor(spec_reader,
                                             master_pop_sz + all_syn_block_sz)
        executor.execute()

        master_pop_table = executor.get_region(0)
        synaptic_matrix = executor.get_region(1)

        all_data = bytearray()
        all_data.extend(
            master_pop_table.region_data[:master_pop_table.max_write_pointer])
        all_data.extend(
            synaptic_matrix.region_data[:synaptic_matrix.max_write_pointer])
        master_pop_table_address = 0
        synaptic_matrix_address = master_pop_table.max_write_pointer
        direct_synapses_address = struct.unpack_from(
            "<I", synaptic_matrix.region_data)[0]
        direct_synapses_address += synaptic_matrix_address + 8
        indirect_synapses_address = synaptic_matrix_address + 4
        placement = Placement(None, 0, 0, 1)
        transceiver = MockTransceiverRawData(all_data)

        # Get the master population table details
        items = synaptic_manager._poptable_type\
            .extract_synaptic_matrix_data_location(
                key, master_pop_table_address, transceiver,
                placement.x, placement.y)

        # The first entry should be direct, but the rest should be indirect;
        # the second is potentially direct, but has been restricted by the
        # restriction on the size of the direct matrix
        assert len(items) == 3

        # TODO: This has been changed because direct matrices are disabled!
        assert not items[0][2]
        assert not items[1][2]
        assert not items[2][2]

        data_1, row_len_1 = synaptic_manager._retrieve_synaptic_block(
            transceiver=transceiver,
            placement=placement,
            master_pop_table_address=master_pop_table_address,
            indirect_synapses_address=indirect_synapses_address,
            direct_synapses_address=direct_synapses_address,
            key=key,
            n_rows=pre_vertex_slice.n_atoms,
            index=0,
            using_extra_monitor_cores=False)
        connections_1 = synaptic_manager._synapse_io.read_synapses(
            direct_synapse_information_1, pre_vertex_slice, post_vertex_slice,
            row_len_1, 0, 2, weight_scales, data_1, None,
            app_edge.n_delay_stages, machine_time_step)

        # The first matrix is a 1-1 matrix, so row length is 1
        assert row_len_1 == 1

        # Check that all the connections have the right weight and delay
        assert len(connections_1) == post_vertex_slice.n_atoms
        assert all([conn["weight"] == 1.5 for conn in connections_1])
        assert all([conn["delay"] == 1.0 for conn in connections_1])

        data_2, row_len_2 = synaptic_manager._retrieve_synaptic_block(
            transceiver=transceiver,
            placement=placement,
            master_pop_table_address=master_pop_table_address,
            indirect_synapses_address=indirect_synapses_address,
            direct_synapses_address=direct_synapses_address,
            key=key,
            n_rows=pre_vertex_slice.n_atoms,
            index=1,
            using_extra_monitor_cores=False)
        connections_2 = synaptic_manager._synapse_io.read_synapses(
            direct_synapse_information_2, pre_vertex_slice, post_vertex_slice,
            row_len_2, 0, 2, weight_scales, data_2, None,
            app_edge.n_delay_stages, machine_time_step)

        # The second matrix is a 1-1 matrix, so row length is 1
        assert row_len_2 == 1

        # Check that all the connections have the right weight and delay
        assert len(connections_2) == post_vertex_slice.n_atoms
        assert all([conn["weight"] == 2.5 for conn in connections_2])
        assert all([conn["delay"] == 2.0 for conn in connections_2])

        data_3, row_len_3 = synaptic_manager._retrieve_synaptic_block(
            transceiver=transceiver,
            placement=placement,
            master_pop_table_address=master_pop_table_address,
            indirect_synapses_address=indirect_synapses_address,
            direct_synapses_address=direct_synapses_address,
            key=key,
            n_rows=pre_vertex_slice.n_atoms,
            index=2,
            using_extra_monitor_cores=False)
        connections_3 = synaptic_manager._synapse_io.read_synapses(
            all_to_all_synapse_information, pre_vertex_slice,
            post_vertex_slice, row_len_3, 0, 2, weight_scales, data_3, None,
            app_edge.n_delay_stages, machine_time_step)

        # The third matrix is an all-to-all matrix, so length is n_atoms
        assert row_len_3 == post_vertex_slice.n_atoms

        # Check that all the connections have the right weight and delay
        assert len(connections_3) == \
            post_vertex_slice.n_atoms * pre_vertex_slice.n_atoms
        assert all([conn["weight"] == 4.5 for conn in connections_3])
        assert all([conn["delay"] == 4.0 for conn in connections_3])
class TestRadialPlacer(unittest.TestCase):
    def setUp(self):
        #######################################################################
        # Setting up vertices, edges and graph                                #
        #######################################################################
        self.vert1 = T_AppVertex(100, "New AbstractConstrainedVertex 1")
        self.vert2 = T_AppVertex(5, "New AbstractConstrainedVertex 2")
        self.vert3 = T_AppVertex(3, "New AbstractConstrainedVertex 3")
        self.edge1 = ApplicationEdge(self.vert1, self.vert2, "First edge")
        self.edge2 = ApplicationEdge(self.vert2, self.vert1, "Second edge")
        self.edge3 = ApplicationEdge(self.vert1, self.vert3, "Third edge")
        self.verts = [self.vert1, self.vert2, self.vert3]
        self.edges = [self.edge1, self.edge2, self.edge3]
        self.graph = ApplicationGraph("Graph", self.verts, self.edges)

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

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

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

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

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

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

        self.machine = Machine(chips)
        #######################################################################
        # Setting up graph and graph_mapper                                   #
        #######################################################################
        self.vertices = list()
        self.vertex1 = T_MachineVertex(
            0, 1, get_resources_used_by_atoms(0, 1, []), "First vertex")
        self.vertex2 = T_MachineVertex(
            1, 5, get_resources_used_by_atoms(1, 5, []), "Second vertex")
        self.vertex3 = T_MachineVertex(
            5, 10, get_resources_used_by_atoms(5, 10, []), "Third vertex")
        self.vertex4 = T_MachineVertex(
            10, 100, get_resources_used_by_atoms(10, 100, []),
            "Fourth vertex")
        self.vertices.append(self.vertex1)
        self.vertices.append(self.vertex2)
        self.vertices.append(self.vertex3)
        self.vertices.append(self.vertex4)
        self.edges = list()
        self.graph = MachineGraph(self.vertices, self.edges)
        self.graph_mapper = GraphMapper()
        self.graph_mapper.add_vertices(self.vertices)

    @unittest.skip("demonstrating skipping")
    def test_new_basic_placer(self):
        self.bp = RadialPlacer(self.machine, self.graph)
        self.assertEqual(self.bp._machine, self.machine)
        self.assertEqual(self.bp._graph, self.graph)

    @unittest.skip("demonstrating skipping")
    def test_place_where_vertices_dont_have_vertex(self):
        self.bp = RadialPlacer(self.machine, self.graph)
        placements = self.bp.place(self.graph, self.graph_mapper)
        for placement in placements.placements:
            print(placement.vertex.label, placement.vertex.n_atoms,
                  'x:', placement.x, 'y:', placement.y, 'p:', placement.p)

    @unittest.skip("demonstrating skipping")
    def test_place_where_vertices_have_vertices(self):
        self.bp = RadialPlacer(self.machine, self.graph)
        self.graph_mapper = GraphMapper()
        self.graph_mapper.add_vertices(self.vertices, self.vert1)
        placements = self.bp.place(self.graph, self.graph_mapper)
        for placement in placements.placements:
            print(placement.vertex.label, placement.vertex.n_atoms,
                  'x:', placement.x, 'y:', placement.y, 'p:', placement.p)

    @unittest.skip("demonstrating skipping")
    def test_place_vertex_too_big_with_vertex(self):
        large_vertex = T_AppVertex(500, "Large vertex 500")
        large_machine_vertex = large_vertex.create_machine_vertex(
            0, 499, get_resources_used_by_atoms(0, 499, []))
        self.graph.add_vertex(large_vertex)
        self.graph = ApplicationGraph("Graph", [large_vertex])
        self.graph_mapper = GraphMapper()
        self.graph_mapper.add_vertices([large_machine_vertex], large_vertex)
        self.bp = RadialPlacer(self.machine, self.graph)
        self.graph = MachineGraph(vertices=[large_machine_vertex])
        with self.assertRaises(PacmanPlaceException):
            self.bp.place(self.graph, self.graph_mapper)

    @unittest.skip("demonstrating skipping")
    def test_try_to_place(self):
        self.assertEqual(True, False, "Test not implemented yet")

    @unittest.skip("demonstrating skipping")
    def test_deal_with_constraint_placement_vertices_dont_have_vertex(self):
        self.bp = RadialPlacer(self.machine, self.graph)
        self.vertex1.add_constraint(ChipAndCoreConstraint(8, 3, 2))
        self.assertIsInstance(self.vertex1.constraints[0],
                              ChipAndCoreConstraint)
        self.vertex2.add_constraint(ChipAndCoreConstraint(3, 5, 7))
        self.vertex3.add_constraint(ChipAndCoreConstraint(2, 4, 6))
        self.vertex4.add_constraint(ChipAndCoreConstraint(6, 4, 16))
        self.vertices = list()
        self.vertices.append(self.vertex1)
        self.vertices.append(self.vertex2)
        self.vertices.append(self.vertex3)
        self.vertices.append(self.vertex4)
        self.edges = list()
        self.graph = MachineGraph(self.vertices, self.edges)
        self.graph_mapper = GraphMapper()
        self.graph_mapper.add_vertices(self.vertices)
        placements = self.bp.place(self.graph, self.graph_mapper)
        for placement in placements.placements:
            print(placement.vertex.label, placement.vertex.n_atoms,
                  'x:', placement.x, 'y:', placement.y, 'p:', placement.p)

    @unittest.skip("demonstrating skipping")
    def test_deal_with_constraint_placement_vertices_have_vertices(self):
        self.bp = RadialPlacer(self.machine, self.graph)
        self.vertex1.add_constraint(ChipAndCoreConstraint(1, 5, 2))
        self.assertIsInstance(self.vertex1.constraints[0],
                              ChipAndCoreConstraint)
        self.vertex2.add_constraint(ChipAndCoreConstraint(3, 5, 7))
        self.vertex3.add_constraint(ChipAndCoreConstraint(2, 4, 6))
        self.vertex4.add_constraint(ChipAndCoreConstraint(6, 7, 16))
        self.vertices = list()
        self.vertices.append(self.vertex1)
        self.vertices.append(self.vertex2)
        self.vertices.append(self.vertex3)
        self.vertices.append(self.vertex4)
        self.edges = list()
        self.graph = MachineGraph(self.vertices, self.edges)
        self.graph_mapper = GraphMapper()
        self.graph_mapper.add_vertices(self.vertices, self.vert1)
        placements = self.bp.place(self.graph, self.graph_mapper)
        for placement in placements.placements:
            print(placement.vertex.label, placement.vertex.n_atoms,
                  'x:', placement.x, 'y:', placement.y, 'p:', placement.p)

    @unittest.skip("demonstrating skipping")
    def test_unsupported_non_placer_constraint(self):
        self.assertEqual(True, False, "Test not implemented yet")

    @unittest.skip("demonstrating skipping")
    def test_unsupported_placer_constraint(self):
        self.assertEqual(True, False, "Test not implemented yet")

    @unittest.skip("demonstrating skipping")
    def test_unsupported_placer_constraints(self):
        self.assertEqual(True, False, "Test not implemented yet")

    @unittest.skip("demonstrating skipping")
    def test_many_vertices(self):
        vertices = list()
        for i in range(20 * 17):  # 51 atoms per each processor on 20 chips
            vertices.append(SimpleMachineVertex(
                0, 50, get_resources_used_by_atoms(0, 50, []),
                "vertex " + str(i)))

        self.graph = ApplicationGraph("Graph", vertices)
        self.graph_mapper = GraphMapper()
        self.graph_mapper.add_vertices(vertices)
        self.bp = RadialPlacer(self.machine, self.graph)
        self.graph = MachineGraph(vertices=vertices)
        placements = self.bp.place(self.graph, self.graph_mapper)

        unorderdered_info = list()
        for placement in placements.placements:
            unorderdered_info.append(
                (placement.vertex.label.split(" ")[0],
                 "{:<4}".format(placement.vertex.label.split(" ")[1]),
                 placement.vertex.n_atoms, 'x: ',
                 placement.x, 'y: ', placement.y, 'p: ', placement.p))

        sorted_info = sorted(unorderdered_info, key=itemgetter(4, 6, 8))
        pp(sorted_info)

        pp("{}".format("=" * 50))
        sorted_info = sorted(unorderdered_info, key=lambda x: int(x[1]))
        pp(sorted_info)

    @unittest.skip("demonstrating skipping")
    def test_too_many_vertices(self):
        vertices = list()
        for i in range(100 * 17):  # 50 atoms per each processor on 20 chips
            vertices.append(SimpleMachineVertex(
                0, 50, get_resources_used_by_atoms(0, 50, []),
                "vertex " + str(i)))

        self.graph = ApplicationGraph("Graph", vertices)
        self.graph_mapper = GraphMapper()
        self.graph_mapper.add_vertices(vertices)
        self.bp = RadialPlacer(self.machine, self.graph)
        self.graph = MachineGraph(vertices=vertices)
        with self.assertRaises(PacmanPlaceException):
            self.bp.place(self.graph, self.graph_mapper)

    @unittest.skip("demonstrating skipping")
    def test_fill_machine(self):
        vertices = list()
        for i in range(99 * 17):  # 50 atoms per each processor on 20 chips
            vertices.append(SimpleMachineVertex(
                0, 50, get_resources_used_by_atoms(0, 50, []),
                "vertex " + str(i)))

        self.graph = ApplicationGraph("Graph", vertices)
        self.graph_mapper = GraphMapper()
        self.graph_mapper.add_vertices(vertices)
        self.bp = RadialPlacer(self.machine, self.graph)
        self.graph = MachineGraph(vertices=vertices)
        self.bp.place(self.graph, self.graph_mapper)
예제 #44
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