Ejemplo n.º 1
0
    def _addDelayExtension(self, numSrcNeurons, max_delay_for_projection,
                           max_delay_per_neuron, original_connector,
                           original_synapse_list, presynaptic_population,
                           postsynaptic_population, 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).
        """
        global controller
        # 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):
            direct_edge = ProjectionEdge(presynaptic_population.vertex,
                                         postsynaptic_population.vertex,
                                         controller.dao.machineTimeStep,
                                         synapse_list=direct_synaptic_sublist,
                                         label=label)
            controller.add_edge(direct_edge)
            self.projection_edge = direct_edge

        # Create a delay extension vertex to do the extra delays
        self.delay_vertex = presynaptic_population.vertex.delay_vertex
        if self.delay_vertex is None:
            sourceName = presynaptic_population.vertex.label
            delayName = "%s_delayed" % (sourceName)
            self.delay_vertex = DelayExtension(numSrcNeurons,
                                               max_delay_per_neuron,
                                               label=delayName)
            presynaptic_population.vertex.delay_vertex = self.delay_vertex
            #controller.add_vertex(self.delay_vertex)

        # Create a connection from the source population to the delay vertex
        new_label = "%s_to_DE" % (label)
        remaining_edge = DelayAfferentEdge(presynaptic_population.vertex,
                                           self.delay_vertex,
                                           label=new_label)
        controller.add_edge(remaining_edge)

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

        # Create a special DelayEdge from the delay vertex to the outgoing
        # population, with the same set of connections
        delay_label = "DE to %s" % (label)
        num_blocks = int(
            math.ceil(
                float(max_delay_for_projection) /
                float(max_delay_per_neuron))) - 1
        self.delay_edge = DelayProjectionEdge(
            self.delay_vertex,
            postsynaptic_population.vertex,
            controller.dao.machineTimeStep,
            num_blocks,
            max_delay_per_neuron,
            synapse_list=remaining_synaptic_sublist,
            synapse_dynamics=synapse_dynamics,
            label=delay_label)
        controller.add_edge(self.delay_edge)
Ejemplo n.º 2
0
    def __init__(self,
                 presynaptic_population,
                 postsynaptic_population,
                 connector,
                 source=None,
                 target='excitatory',
                 synapse_dynamics=None,
                 label=None,
                 rng=None):
        """
        Instantiates a :py:object:`Projection`.
        """
        global controller
        self.projection_edge = None
        if issubclass(type(postsynaptic_population.vertex), PopulationVertex):
            # Check that the "target" is an acceptable value
            targets = postsynaptic_population.vertex.get_synapse_targets()
            if not target in targets:
                raise exceptions.PacmanException(
                    "Target {} is not available in " +
                    "the post-synaptic population (choices are {})".format(
                        target, targets))
            synapse_type = postsynaptic_population.vertex.get_synapse_id(
                target)
        else:
            raise exceptions.ConfigurationException(
                "postsynaptic_population is "
                "not a supposal reciever of"
                " synaptic projections")

        # Check that the edge doesn't already exist elsewhere
        # This would be a possible place for a merge at some point,
        # but this needs more thought
        for edge in controller.dao.get_edges():
            if (edge.prevertex == presynaptic_population.vertex
                    and edge.postvertex == postsynaptic_population.vertex):
                raise exceptions.PacmanException(
                    "More than one connection between the same pair of" +
                    " vertices is not currently supported")

        synapse_list = connector.generate_synapse_list(
            presynaptic_population.vertex, postsynaptic_population.vertex,
            1000.0 / controller.dao.machineTimeStep, synapse_type)
        self.read_synapse_list = None

        # If there are some negative weights
        if synapse_list.get_min_weight() < 0:

            # If there are mixed negative and positive weights,
            # raise an exception
            if synapse_list.get_max_weight() > 0:
                raise exceptions.PacmanException("Weights must be positive")

            # Otherwise, the weights are all negative, so invert them(!)
            else:
                synapse_list.flip()

        # check if all delays requested can fit into the natively supported
        # delays in the models
        min_delay, max_delay = synapse_list.get_min_max_delay()
        natively_supported_delay_for_models = MAX_SUPPORTED_DELAY_TICS

        delay_extention_max_supported_delay = \
            MAX_DELAY_BLOCKS * MAX_TIMER_TICS_SUPPORTED_PER_BLOCK

        if max_delay > (natively_supported_delay_for_models +
                        delay_extention_max_supported_delay):
            raise exceptions.ConfigurationException(
                "the max delay for projection {} is not "
                "supported by the pacman "
                "toolchain".format(max_delay))

        if conf.config.has_option("Model", "max_delay"):
            user_max_delay = conf.config.get("Model", "max_delay")
            if max_delay > user_max_delay:
                logger.warn(
                    "The end user entered a max delay to which the projection breaks"
                )

        if (max_delay > natively_supported_delay_for_models):
            source_sz = presynaptic_population.vertex.atoms
            self._addDelayExtension(source_sz, max_delay,
                                    natively_supported_delay_for_models,
                                    connector, synapse_list,
                                    presynaptic_population,
                                    postsynaptic_population, label,
                                    synapse_dynamics)

        else:
            self.projection_edge = ProjectionEdge(
                presynaptic_population.vertex,
                postsynaptic_population.vertex,
                controller.dao.machineTimeStep,
                synapse_list=synapse_list,
                synapse_dynamics=synapse_dynamics,
                label=label)
            self.delay_edge = None
            controller.add_edge(self.projection_edge)