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)