Skip to content

Comments

Step 4 - Replace implicit neuron variable references with explicit ones#604

Merged
neworderofjamie merged 85 commits intogenn_5from
pre_post_var_references
Jan 9, 2024
Merged

Step 4 - Replace implicit neuron variable references with explicit ones#604
neworderofjamie merged 85 commits intogenn_5from
pre_post_var_references

Conversation

@neworderofjamie
Copy link
Contributor

@neworderofjamie neworderofjamie commented Nov 9, 2023

In the previous 3 stages of the great GeNN 5 updating, the ability to reference neuron variables in postsynaptic models, weight update models and current sources implicitly via $(X_post) syntax was entirely disabled but this PR adds new functionality to do this explicitly via variable references. This means models are not tied together by the names of variables so e.g. you can use the standard ExpCond model even if you have the gall to call your neuron model's voltage u or (lower-case) v.

However, this was the straw that broke the camel's back of the addSynapsePopulation function as it ended up with 17 arguments. This is annoying even when using Python where there's keyword arguments so, continuing the approach used to setup connectivity, I added weight update and postsynaptic model inititialisation functions:

excitatory_synapse_params = {"g": EXCITATORY_WEIGHT}

excitatory_post_syn_params = {"tau": 5.0}

model.add_synapse_population("EE", "SPARSE", 0,
    excitatory_pop, excitatory_pop,
    "StaticPulseConstantWeight", excitatory_synapse_params, {}, {}, {},
    "ExpCurr", excitatory_post_syn_params, {},
    init_sparse_connectivity("FixedProbabilityNoAutapse", fixed_prob))

becomes something like:

excitatory_weight_init = init_weight_update("StaticPulseConstantWeight", {"g": EXCITATORY_WEIGHT})
excitatory_postsynaptic_init = init_postsynaptic("ExpCurr", {"tau": 5.0})

model.add_synapse_population("EE", "SPARSE", 0,
    excitatory_pop, excitatory_pop,
    excitatory_weight_init, excitatory_postsynaptic_init,
    init_sparse_connectivity("FixedProbabilityNoAutapse", fixed_prob))

which I think it actually a lot nicer and lets you reuse fully-configured models much easily. To further ease the pain I have shortened and unified all of the names of the keyword arguments on the GeNNModel.add_XXX methods and given them defaults of {} so you can more complex configurations with less {}, {}, {} nonsense! Clearly this breaks backward compatibility but updating is pretty painless, to the point I was able to update all of the unit tests and feature tests with an (admittedly absolutely nightmarish) regular expression.

With that out of the way, the syntax to connect an ExpCond model back to the presynaptic neuron is simple:

model.add_synapse_population("Pop1self", "SPARSE", 10,
    pop1, pop1,
    init_weight_update("StaticPulseConstantWeight", {"g": -0.2}), 
    init_postsynaptic("ExpCond", {"tau": 1.0, "E": -80.0}, var_refs={"V": create_var_ref(pop1, "V")}),
    init_sparse_connectivity(ring_model))

Most of the bits and pieces to implement this internally were already there but some tweaks of environment classes were required to correctly setup the lazy substitutions (e.g. references to neuron variables in per-neuron weight update model code may just be aliases to local variables in the dynamics bit but, on SIMD backends, in the spike-driven bit the indices are different).

This PR also adds the ability to change which neuron input variable a current source targets (in line with postsynaptic model). Finally, this enables a whole swathe of feature tests that rely on delays (which only get applied to neuron variables if they're referenced in synaptic code) to be re-implemented in PyGeNN which led to a further wave of bug-fixing.

* Options to hide (i.e. prefix with _) variables and variable references
* Function to add local variable references i.e. to variables already exposed with _ prefixes
* Add fields to pointers to in backend (moved functionality out of custom connectivity update into environment to do this)
* Add new sort of caching environment that reads existing (pointer) fields into local variables if referenced and use this around neuron code
…omConnectivityUpdate`` direct from wrapper (and delay neuron group)

* remove python-layer implementation of ``synapse_group`` properties
…cessible from PyGeNN so delays don't need to be wrangled
* No weird _space in names of parameter and variable arguments to make kwarging easier
* All parameter and variable arguments default to {}
@tnowotny tnowotny self-requested a review November 22, 2023 20:22
@neworderofjamie neworderofjamie marked this pull request as ready for review December 5, 2023 13:41
Copy link
Member

@tnowotny tnowotny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving based on our general discussion of the aims and design decisions.

Base automatically changed from dynamic_loader to genn_5 January 9, 2024 09:41
@neworderofjamie neworderofjamie merged commit e94b1e1 into genn_5 Jan 9, 2024
@neworderofjamie neworderofjamie deleted the pre_post_var_references branch January 9, 2024 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants