Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move code generator options into NESTML model #721

Closed
clinssen opened this issue Jan 17, 2022 · 2 comments
Closed

Move code generator options into NESTML model #721

clinssen opened this issue Jan 17, 2022 · 2 comments

Comments

@clinssen
Copy link
Contributor

In the synapse, input ports are currently defined agnostic to whether they will connect to a pre- or postsynaptic partner:

  input:
    pre_spikes nS <- spike
    post_spikes nS <- spike
  end

They are only assigned during code generation, via the code generator options:

generate_target(...,
                codegen_opts={"neuron_synapse_pairs": [...,
                                                       "post_ports": ["post_spikes"]}]})

This works fine and is a flexible mechanism that was also adapted to map postsynaptic variables (like V_m) onto synaptic continuous-valued input ports with a potentially different name (like post_V_m), where they can be used as third factors for synaptic plasticity rules.

The difficulty is, that this information cannot be extracted from the NEST simulation script, which means it is incompatible with the proposed JIT workflow.

For this reason, we suggest to move the "meaning" of input ports into the NESTML synapse model itself, using keywords such as "pre" and "post" (and "modulatory"):

  input:
    pre_spikes nS <- pre spike
    post_spikes nS <- post spike
  end

This would be compatible with multisynapses, as there would just be more than one "pre" port.

The most general case, of mapping neuronal variables onto differently-named input ports, could be done by passing the code generator options by explicit call to the JIT mechanism, for instance

import nest_JIT as nest
nest.set_codegen_opts(...)

The disadvantage of this is that this is very far removed (in terms of lines of code) from the place in the script where the neurons and synapses actually get instantiated.

An external (my_network_codegen_opts.json) file would of course do the same trick.

@clinssen
Copy link
Contributor Author

clinssen commented Feb 17, 2022

In general, it would be preferred to specify the ports mapping during the connection setup, that is, when Connect() is called to set up the connection; we also specify the synapse type there, so it's logical for these to go together. (This is preferred over setting "global options" of the code generator.)

This would mean that we need a new argument to Connect(), or to the syn_spec, which we name "post_syn_port_map".

Some proposals for syntax would be the following. Note the complication that synapse_models can be specified as a list, with the same size as the postsynaptic population (this only works for the "one_to_one" and "fixed_total_number" connection patterns).

Assuming we have

neuron a:
    state:
        x real = ..
        p real = ..
    end
end

neuron b:
    state:
        foo real = ..
    end
end
nest.Connect(presyn_neuron, homoge_post_neuron,
             syn_spec={"synapse_model": "stdp_synapse",
                       "post_syn_port_map": ["x:y", "p:q"]})

We can use the compacted "neuron_variable_name:synapse_variable_name" format, or something more expressive (equivalently):

"post_syn_port_map": ["x:y", "p:q"]

"post_syn_port_map": [("x", "y"), ("p", "q")]

"post_syn_port_map": [{"neuron": "x",
                       "synapse": "y"},
                      {"neuron": "p",
                       "synapse": "q"}

Note the internal renaming:

  • neuron contains specified variable (here, "x") --> internally, "x__with__y"
  • synapse contains specified variable (here, "y") --> internally, JIT checks for "y__for__x" and checks unit type

Simplifications:

  • if postsyn population is homogeneous, AND single synapse type in connect call, then only have to specify a single list for the postsyn port map
  • if additionally, only a single variable needs to be mapped, a single string would be sufficient

Notes:

  • What if repeated calls to Connect() with same synapse and neuron models, but different ports mapping?

    nest.Connect(presyn_neuron, homoge_post_neuron,
              syn_spec={"synapse_model": "stdp_synapse",
                        "post_syn_port_map": {"neuron": "x",
                        "synapse": "y"}})
    nest.Connect(presyn_neuron, homoge_post_neuron,
              syn_spec={"synapse_model": "stdp_synapse",
                        "post_syn_port_map": {"neuron": "p",
                        "synapse": "y"}})

@jougs
Copy link
Contributor

jougs commented Feb 18, 2022

One additional thought: Maybe we should provide a list of such mappings for the models shipped with NEST(ML). I assume that users would not like it that much, if they had to provide such a list even for standard situations like connecting iaf_psc_alphas with stdp_synapses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants