Ejemplo n.º 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
Ejemplo n.º 2
0
    def create_machine_vertices(
            self, resource_tracker, machine_graph, app_graph):

        # slices
        self._post_slice = Slice(
            0, int(self._governed_app_vertex.n_atoms / self.N_VERTS))

        for count in range(1, self.N_VERTS):
            self._pre_slices.append(Slice(
                self._post_slice.n_atoms * count,
                self._post_slice.n_atoms * count + self._post_slice.n_atoms))

        # mac verts
        self._post_vertex = (
            SDRAMMachineVertex(
                vertex_slice=self._post_slice, label=None,
                constraints=None, app_vertex=self._governed_app_vertex,
                sdram_cost=self._governed_app_vertex.fixed_sdram_value))
        resource_tracker.allocate_constrained_resources(
            self._post_vertex.resources_required,
            self._governed_app_vertex.constraints,
            vertices=[self._post_vertex])
        machine_graph.add_vertex(self._post_vertex)

        for vertex_slice in self._pre_slices:
            pre_vertex = (
                SDRAMMachineVertex(
                    vertex_slice=vertex_slice, label=None,
                    constraints=None, app_vertex=self._governed_app_vertex,
                    sdram_cost=self._governed_app_vertex.fixed_sdram_value))
            self._pre_vertices.append(pre_vertex)

            # allocate res
            resource_tracker.allocate_constrained_resources(
                pre_vertex.resources_required,
                self._governed_app_vertex.constraints,
                vertices=[pre_vertex])

            # add to mac graph
            machine_graph.add_vertex(pre_vertex)

        # add outgoing edge partition to mac graph
        machine_graph.add_outgoing_edge_partition(self._partition_type(
            identifier="sdram", pre_vertices=self._pre_vertices,
            label="sdram"))

        # add edge between the two verts app and mac
        self._app_edge = ApplicationEdge(
            self._governed_app_vertex, self._governed_app_vertex)
        app_graph.add_edge(self._app_edge, "sdram_app")

        # mac add
        for pre_vertex in self._pre_vertices:
            edge = SDRAMMachineEdge(
                pre_vertex, self._post_vertex, label="sdram",
                app_edge=self._app_edge)
            machine_graph.add_edge(edge, "sdram")

        return [self._post_vertex].extend(self._pre_vertices)
Ejemplo n.º 3
0
    def create_machine_vertices(self, resource_tracker, machine_graph,
                                app_graph):
        # slices
        self._pre_slice = Slice(0, int(self._governed_app_vertex.n_atoms / 2))
        self._post_slice = Slice(
            int(self._governed_app_vertex.n_atoms / 2) + 1,
            int(self._governed_app_vertex.n_atoms - 1))

        # mac verts
        self._pre_vertex = (SDRAMMachineVertex(
            vertex_slice=self._pre_slice,
            label=None,
            constraints=None,
            app_vertex=self._governed_app_vertex,
            sdram_cost=self._governed_app_vertex.fixed_sdram_value))
        self._post_vertex = (SDRAMMachineVertex(
            vertex_slice=self._post_slice,
            label=None,
            constraints=None,
            app_vertex=self._governed_app_vertex,
            sdram_cost=self._governed_app_vertex.fixed_sdram_value))

        # allocate res
        resource_tracker.allocate_constrained_resources(
            self._pre_vertex.resources_required,
            self._governed_app_vertex.constraints,
            vertices=[self._pre_vertex])
        resource_tracker.allocate_constrained_resources(
            self._post_vertex.resources_required,
            self._governed_app_vertex.constraints,
            vertices=[self._post_vertex])

        # add to mac graph
        machine_graph.add_vertex(self._pre_vertex)
        machine_graph.add_vertex(self._post_vertex)

        # add outgoing edge partition to mac graph
        machine_graph.add_outgoing_edge_partition(
            self._partition_type(identifier="sdram",
                                 pre_vertex=self._pre_vertex,
                                 label="sdram"))

        # add edge between the two verts app and mac
        self._app_edge = ApplicationEdge(self._governed_app_vertex,
                                         self._governed_app_vertex)
        app_graph.add_edge(self._app_edge, "sdram_app")

        # mac add
        edge = SDRAMMachineEdge(self._pre_vertex,
                                self._post_vertex,
                                label="sdram",
                                app_edge=self._app_edge)
        machine_graph.add_edge(edge, "sdram")

        return [self._pre_vertex, self._post_vertex]
Ejemplo n.º 4
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
Ejemplo n.º 5
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
Ejemplo n.º 6
0
    def test_at_vertex_methods(self):
        graph = MachineGraph("foo")
        mach1 = MockMachineVertex("mach1", sdram_requirement=0)
        mach2 = MockMachineVertex("mach2", sdram_requirement=0)
        mach3 = MockMachineVertex("mach3", sdram_requirement=0)
        mach4 = SimpleMachineVertex("mach4")
        graph.add_vertices([mach1, mach2, mach3, mach4])

        # Add partition then edge
        part_m_1 = MulticastEdgePartition(mach1, "spikes")
        graph.add_outgoing_edge_partition(part_m_1)
        edge_m_11 = MachineEdge(mach1,
                                mach2,
                                traffic_type=EdgeTrafficType.MULTICAST)
        graph.add_edge(edge_m_11, "spikes")
        # check clear error it you add the edge again
        with self.assertRaises(PacmanAlreadyExistsException):
            graph.add_edge(edge_m_11, "spikes")
        self.assertIn(edge_m_11, part_m_1.edges)
        edge_m_12 = MachineEdge(mach1,
                                mach3,
                                traffic_type=EdgeTrafficType.MULTICAST)
        graph.add_edge(edge_m_12, "spikes")
        edge_m_21 = MachineEdge(mach3,
                                mach4,
                                traffic_type=EdgeTrafficType.MULTICAST)
        graph.add_edge(edge_m_21, "spikes")
        part_m_2 = graph.get_outgoing_partition_for_edge(edge_m_21)

        edge_f_1 = MachineEdge(mach1,
                               mach3,
                               traffic_type=EdgeTrafficType.FIXED_ROUTE)
        graph.add_edge(edge_f_1, "Control")
        part_f = graph.get_outgoing_partition_for_edge(edge_f_1)

        part_s_1 = ConstantSDRAMMachinePartition("ram", mach1, "ram1")
        graph.add_outgoing_edge_partition(part_s_1)
        edge_s_11 = SDRAMMachineEdge(mach1, mach2, "s1")
        graph.add_edge(edge_s_11, "ram")
        edge_s_12 = SDRAMMachineEdge(mach1, mach3, "s2")
        graph.add_edge(edge_s_12, "ram")

        starting_at_mach1 = list(
            graph.get_outgoing_edge_partitions_starting_at_vertex(mach1))
        self.assertIn(part_m_1, starting_at_mach1)
        self.assertIn(part_f, starting_at_mach1)
        self.assertIn(part_s_1, starting_at_mach1)
        self.assertEqual(3, len(starting_at_mach1))

        starting_at_mach3 = list(
            graph.get_outgoing_edge_partitions_starting_at_vertex(mach3))
        self.assertIn(part_m_2, starting_at_mach3)
        self.assertEqual(1, len(starting_at_mach3))

        starting_at_mach4 = list(
            graph.get_outgoing_edge_partitions_starting_at_vertex(mach4))
        self.assertEqual(0, len(starting_at_mach4))

        ending_at_mach2 = list(
            graph.get_edge_partitions_ending_at_vertex(mach2))
        self.assertIn(part_m_1, ending_at_mach2)
        self.assertIn(part_s_1, ending_at_mach2)
        self.assertEqual(2, len(ending_at_mach2))

        ending_at_mach3 = list(
            graph.get_edge_partitions_ending_at_vertex(mach3))
        self.assertIn(part_m_1, ending_at_mach3)
        self.assertIn(part_f, ending_at_mach3)
        self.assertIn(part_s_1, ending_at_mach3)
        self.assertEqual(3, len(ending_at_mach3))

        ending_at_mach1 = list(
            graph.get_edge_partitions_ending_at_vertex(mach1))
        self.assertEqual(0, len(ending_at_mach1))
Ejemplo n.º 7
0
    def create_machine_vertices(
            self, resource_tracker, machine_graph, app_graph):

        # slices
        self._post_slice = Slice(
            0, int(self._governed_app_vertex.n_atoms / self.N_VERTS))

        for count in range(1, self.N_VERTS):
            self._pre_slices.add(Slice(
                self._post_slice.n_atoms * count,
                self._post_slice.n_atoms * count + self._post_slice.n_atoms))

        # mac verts
        self._post_vertex = (
            SDRAMMachineVertex(
                vertex_slice=self._post_slice, label=None,
                constraints=None, app_vertex=self._governed_app_vertex,
                sdram_cost=self._governed_app_vertex.fixed_sdram_value))
        resource_tracker.allocate_constrained_resources(
            self._post_vertex.resources_required,
            self._governed_app_vertex.constraints)
        machine_graph.add_vertex(self._post_vertex)

        for vertex_slice in self._pre_slices:
            pre_vertex = (
                SDRAMMachineVertex(
                    vertex_slice=vertex_slice, label=None,
                    constraints=None, app_vertex=self._governed_app_vertex,
                    sdram_cost=self._governed_app_vertex.fixed_sdram_value))
            self._pre_vertices.add(pre_vertex)

            # allocate res
            resource_tracker.allocate_constrained_resources(
                pre_vertex.resources_required,
                self._governed_app_vertex.constraints)

            # add to mac graph
            machine_graph.add_vertex(pre_vertex)

        # add outgoing edge partition to mac graph
        if self._other_splitter is not None:
            total_pre_verts = list()
            total_pre_verts.extend(self._pre_vertices)
            for incoming_edge in app_graph.get_edges_ending_at_vertex(
                    self._governed_app_vertex):
                if (incoming_edge.pre_vertex.splitter ==
                        self._other_splitter):
                    outgoing_edge_partition = (
                        app_graph.get_outgoing_partition_for_edge(
                            incoming_edge))
                    total_pre_verts.extend(
                        self._other_splitter.get_out_going_vertices(
                            incoming_edge, outgoing_edge_partition))
            machine_graph.add_outgoing_edge_partition(self._partition_type(
                identifier="sdram", pre_vertices=total_pre_verts,
                label="sdram"))

        # add edge between the two verts app and mac
        self._app_edge = ApplicationEdge(
            self._governed_app_vertex, self._governed_app_vertex)
        app_graph.add_edge(self._app_edge, "sdram_app")

        # mac add
        for pre_vertex in self._pre_vertices:
            edge = SDRAMMachineEdge(
                pre_vertex, self._post_vertex, label="sdram",
                app_edge=self._app_edge)
            machine_graph.add_edge(edge, "sdram")

        return [self._post_vertex].extend(self._pre_vertices)
    def create_machine_vertices(self, resource_tracker, machine_graph):
        app_vertex = self._governed_app_vertex
        label = app_vertex.label
        constraints = get_remaining_constraints(app_vertex)

        # Structural plasticity can only be run on a single synapse core
        if (isinstance(app_vertex.synapse_dynamics,
                       AbstractSynapseDynamicsStructural)
                and self.__n_synapse_vertices != 1):
            raise SynapticConfigurationException(
                "The current implementation of structural plasticity can only"
                " be run on a single synapse core.  Please ensure the number"
                " of synapse cores is set to 1")

        # Do some checks to make sure everything is likely to fit
        atoms_per_core = min(app_vertex.get_max_atoms_per_core(),
                             app_vertex.n_atoms)
        n_synapse_types = app_vertex.neuron_impl.get_n_synapse_types()
        if (get_n_bits(atoms_per_core) + get_n_bits(n_synapse_types) +
                get_n_bits(self.__get_max_delay)) > MAX_RING_BUFFER_BITS:
            raise SynapticConfigurationException(
                "The combination of the number of neurons per core ({}), "
                "the number of synapse types ({}), and the maximum delay per "
                "core ({}) will require too much DTCM.  Please reduce one or "
                "more of these values.".format(atoms_per_core, n_synapse_types,
                                               self.__get_max_delay))

        self.__neuron_vertices = list()
        self.__synapse_vertices = list()
        self.__synapse_verts_by_neuron = defaultdict(list)

        incoming_direct_poisson = self.__handle_poisson_sources(
            label, machine_graph)

        # Work out the ring buffer shifts based on all incoming things
        rb_shifts = app_vertex.get_ring_buffer_shifts(
            app_vertex.incoming_projections)
        weight_scales = app_vertex.get_weight_scales(rb_shifts)

        # Get resources for synapses
        independent_synapse_sdram = self.__independent_synapse_sdram()
        proj_dependent_sdram = self.__proj_dependent_synapse_sdram(
            app_vertex.incoming_projections)

        for index, vertex_slice in enumerate(self.__get_fixed_slices()):

            # Find the maximum number of cores on any chip available
            max_crs = resource_tracker.get_maximum_cores_available_on_a_chip()
            if max_crs < (self.__n_synapse_vertices + 1):
                raise ConfigurationException(
                    "No chips remaining with enough cores for"
                    f" {self.__n_synapse_vertices} synapse cores and a neuron"
                    " core")
            max_crs -= self.__n_synapse_vertices + 1

            # Create the neuron vertex for the slice
            neuron_vertex, neuron_resources = self.__add_neuron_core(
                vertex_slice, label, index, rb_shifts, weight_scales,
                machine_graph, constraints)

            # Keep track of synapse vertices for each neuron vertex and
            # resources used by each core (neuron core is added later)
            synapse_vertices = list()
            self.__synapse_verts_by_neuron[neuron_vertex] = synapse_vertices
            all_resources = []

            # Add the first vertex
            synapse_references, syn_label = self.__add_lead_synapse_core(
                vertex_slice, independent_synapse_sdram, proj_dependent_sdram,
                label, rb_shifts, weight_scales, all_resources, machine_graph,
                synapse_vertices, neuron_vertex, constraints)

            # Do the remaining synapse cores
            for i in range(1, self.__n_synapse_vertices):
                self.__add_shared_synapse_core(syn_label, i, vertex_slice,
                                               synapse_references,
                                               all_resources, machine_graph,
                                               synapse_vertices, neuron_vertex,
                                               constraints)

            # Add resources for Poisson vertices up to core limit
            poisson_vertices = incoming_direct_poisson[vertex_slice]
            remaining_poisson_vertices = list()
            added_poisson_vertices = list()
            for poisson_vertex, poisson_edge in poisson_vertices:
                if max_crs <= 0:
                    remaining_poisson_vertices.append(poisson_vertex)
                    self.__add_poisson_multicast(poisson_vertex,
                                                 synapse_vertices,
                                                 machine_graph, poisson_edge)
                else:
                    all_resources.append(
                        (poisson_vertex.resources_required, []))
                    added_poisson_vertices.append(poisson_vertex)
                    max_crs -= 1

            if remaining_poisson_vertices:
                logger.warn(
                    f"Vertex {label} is using multicast for"
                    f" {len(remaining_poisson_vertices)} one-to-one Poisson"
                    " sources as not enough cores exist to put them on the"
                    " same chip")

            # Create an SDRAM edge partition
            sdram_label = "SDRAM {} Synapses-->Neurons:{}-{}".format(
                label, vertex_slice.lo_atom, vertex_slice.hi_atom)
            source_vertices = added_poisson_vertices + synapse_vertices
            sdram_partition = SourceSegmentedSDRAMMachinePartition(
                SYNAPSE_SDRAM_PARTITION_ID, sdram_label, source_vertices)
            machine_graph.add_outgoing_edge_partition(sdram_partition)
            neuron_vertex.set_sdram_partition(sdram_partition)

            # Add SDRAM edges for synapse vertices
            for source_vertex in source_vertices:
                edge_label = "SDRAM {}-->{}".format(source_vertex.label,
                                                    neuron_vertex.label)
                machine_graph.add_edge(
                    SDRAMMachineEdge(source_vertex, neuron_vertex, edge_label),
                    SYNAPSE_SDRAM_PARTITION_ID)
                source_vertex.set_sdram_partition(sdram_partition)

            # Add SDRAM edge requirements to the neuron SDRAM, as the resource
            # tracker will otherwise try to add another core for it
            extra_sdram = MultiRegionSDRAM()
            extra_sdram.merge(neuron_resources.sdram)
            extra_sdram.add_cost(
                len(extra_sdram.regions) + 1,
                sdram_partition.total_sdram_requirements())
            neuron_resources_plus = ResourceContainer(
                sdram=extra_sdram,
                dtcm=neuron_resources.dtcm,
                cpu_cycles=neuron_resources.cpu_cycles,
                iptags=neuron_resources.iptags,
                reverse_iptags=neuron_resources.reverse_iptags)
            all_resources.append((neuron_resources_plus, constraints))

            # Allocate all the resources to ensure they all fit
            resource_tracker.allocate_constrained_group_resources(
                all_resources)

        return True