示例#1
0
    def _add_delay_extension(self, num_src_neurons, max_delay_for_projection,
                             max_delay_per_neuron, original_synapse_list,
                             presynaptic_population, postsynaptic_population,
                             machine_time_step, timescale_factor, label,
                             synapse_dynamics):
        """
        Instantiate new delay extension component, connecting a new edge from
        the source vertex to it and new edges from it to the target (given
        by numBlocks).
        The outgoing edges cover each required block of delays, in groups of
        MAX_DELAYS_PER_NEURON delay slots (currently 16).
        """
        # If there are any connections with a delay of less than the maximum,
        # create a direct connection between the two populations only
        # containing these connections
        direct_synaptic_sublist = original_synapse_list.create_delay_sublist(
            0, max_delay_per_neuron)
        if direct_synaptic_sublist.get_max_n_connections() != 0:
            edge_to_merge = self._find_existing_edge(
                presynaptic_population._get_vertex,
                postsynaptic_population._get_vertex)
            if edge_to_merge is not None:
                self._projection_list_ranges = \
                    edge_to_merge.synapse_list.merge(direct_synaptic_sublist)
                self._projection_edge = edge_to_merge
            else:
                direct_edge = ProjectionPartitionableEdge(
                    presynaptic_population,
                    postsynaptic_population,
                    self._spinnaker.machine_time_step,
                    synapse_list=direct_synaptic_sublist,
                    label=label)
                self._spinnaker.add_edge(direct_edge)
                self._projection_edge = direct_edge
                self._projection_list_ranges = direct_synaptic_sublist.ranges()

        # Create a delay extension vertex to do the extra delays
        delay_vertex = presynaptic_population._internal_delay_vertex
        if delay_vertex is None:
            source_name = presynaptic_population._get_vertex.label
            delay_name = "{}_delayed".format(source_name)
            delay_vertex = DelayExtensionVertex(
                n_neurons=num_src_neurons,
                source_vertex=presynaptic_population._get_vertex,
                max_delay_per_neuron=max_delay_per_neuron,
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                label=delay_name)
            presynaptic_population._internal_delay_vertex = delay_vertex
            presynaptic_population._get_vertex.add_constraint(
                PartitionerSameSizeAsVertexConstraint(delay_vertex))
            self._spinnaker.add_vertex(delay_vertex)

        # Create a connection from the source pynn_population.py to the
        # delay vertex
        existing_remaining_edge = self._find_existing_edge(
            presynaptic_population._get_vertex, delay_vertex)
        if existing_remaining_edge is None:
            new_label = "{}_to_DE".format(label)
            remaining_edge = DelayAfferentPartitionableEdge(
                presynaptic_population._get_vertex,
                delay_vertex,
                label=new_label)

            # add to graph
            self._spinnaker.add_edge(remaining_edge)

        # Create a list of the connections with delay larger than that which
        # can be handled by the neuron itself
        remaining_sublist = original_synapse_list.create_delay_sublist(
            max_delay_per_neuron + 1, max_delay_for_projection)

        # Create a special DelayEdge from the delay vertex to the outgoing
        # pynn_population.py, with the same set of connections
        delay_label = "DE to {}".format(label)
        num_blocks = int(
            math.floor(
                float(max_delay_for_projection - 1) /
                float(max_delay_per_neuron)))
        if num_blocks > delay_vertex.max_stages:
            delay_vertex.max_stages = num_blocks

        # Create the delay edge
        existing_delay_edge = self._find_existing_edge(
            delay_vertex, postsynaptic_population._get_vertex)
        if existing_delay_edge is not None:
            self._delay_list_ranges = existing_delay_edge.synapse_list.merge(
                remaining_sublist)
            self._delay_edge = existing_delay_edge
        else:
            self._delay_edge = DelayPartitionableEdge(
                presynaptic_population,
                postsynaptic_population,
                self._spinnaker.machine_time_step,
                num_blocks,
                max_delay_per_neuron,
                synapse_list=remaining_sublist,
                synapse_dynamics=synapse_dynamics,
                label=delay_label)
            self._delay_list_ranges = remaining_sublist.ranges()

            # add to graph
            self._spinnaker.add_edge(self._delay_edge)