nest-simulator icon indicating copy to clipboard operation
nest-simulator copied to clipboard

Resetting the network state between simulation runs (``ResetNetwork()``)

Open clinssen opened this issue 2 years ago • 5 comments

This continues the discussion from #525. Going from NEST 2 to 3, the API function ResetNetwork() was removed because it was unclear what it was supposed to do. We now propose to reintroduce the function, but with a more clearly defined semantics. Robust PyNN support for NEST 3 is a particular driver behind this proposal.

In principle, all state variables in neurons, synapses and devices, can be read from and written to via calls to SetStatus() and GetStatus(). So this is not something that ResetNetwork() necessarily has to take care of. We leave this task (of resetting, or saving and restoring the state variables) to be done "by hand" by the user, as exemplified in #1919. (Some places need some fixing of this, for example t_lastspike_ is not resettable in synapses right now.)

We propose to let ResetNetwork() take care of all the rest. This includes (partially copied from #1618):

  • Spike buffers in neuron models (in the Buffers_ member struct). These are initialised by a call to the node method init_buffers(). So, ResetNetwork() has to loop over all the nodes in the network, and call their init_buffers() method.

    Alternatively, this could also be a method of a NodeCollection.

  • Random number generators: unknown how—is there a reset() method on our RNGs? (Some seem to have it, some not.) I would propose that if this does not exist, this is not a blocking issue for the ResetNetwork() feature.

  • Resetting the clock to 0: this could potentially go via a SetKernelStatus(), for instance:

    nest.SetKernelStatus({'time': 0.})
    
  • Recording devices: @jougs is this just a matter of calling RecordingBackend::cleanup() and RecordingBackend::prepare() on each device, in that order? Is there any way we can add these to the PyNEST API for Devices? They're already public methods at the C++ level. That way, we can also make the user call them explicitly and avoid having ResetNetwork() do it.

  • OpenMP/MPI communication buffers in the NEST kernel: unknown which/what/how

  • Unknown unknowns: spike buffers in the kernel?

When much of the functionality of ResetNetwork() dissolves into individual, more specific calls, we might be left with only one kernel call, that could then perhaps be named FlushSpikes() (@heplesser, #1618).

clinssen avatar Mar 10 '22 22:03 clinssen

Thank you for this nice summary, @clinssen.

Some comments:

  • I consider t_lastspike_ an internal variable, so that should be cleared automatically by ResetNetwork().
  • Random number generators should be re-seeded by the user explicitly. The user can choose whether to run again with the same seed or a different seed.
  • For random seed and resetting time, we may want to offer convenience arguments to ResetNetwork(), something like ResetNetwork(reset_time=True, random_seed=12345).
  • All buffers in MPIManager and EventDeliveryManager should be cleared.

heplesser avatar Mar 11 '22 09:03 heplesser

I am against re-using the old name ResetNetwork() here, as it would again suggest one-function-to-rule-them-all semantics. I would rather introduce one or more functions with clear names and atomic functionality. Regarding the addition of optional convenience arguments, I am also skeptical.

I would find something along these lines much more expressive:

# 1. create nodes, connect them, and simulate a bit

# 2. outside of the Run() context
nest.clear_buffers()      # clear all node spike buffers and MPI comm buffers
nest.biological_time = 0  # reset simulation time
nest.rng_seed = 1234321
nest.GetNodes({"element_type": "neuron"}).V_m = -55.0  # reset selected node's states
nest.GetNodes({"element_type": "recorder", "record_to": "memory"}).n_events = 0  # delete events from devices

# 3. simulate some more

My proposed function clear_buffers() could also be split into clear_node_buffers() and clear_comm_buffers(), but I'm not sure if that would make any sense practically or if people then just forget about one of them regularly and get into trouble.

RecordingBackend::cleanup() is anyway called at the end of Simulate()/Cleanup(), so files or network connection should be properly closed outside of the Run() context (i.e. at position 2. above) and I don't think we need to do anything special here.

jougs avatar Mar 17 '22 18:03 jougs

Issue automatically marked stale!

github-actions[bot] avatar May 17 '22 08:05 github-actions[bot]

@heplesser and @clinssen what are the plans regarding this issue?

med-ayssar avatar Apr 06 '23 12:04 med-ayssar

Issue automatically marked stale!

github-actions[bot] avatar Aug 31 '23 08:08 github-actions[bot]