SP Manager

The SPManager in NEST manages structural plasticity by dynamically creating and deleting synapses during simulations.

Overview of steps

Initialization and Finalization:

The SPManager constructor initializes the structural plasticity update interval and other parameters. The initialize and finalize methods manage the setup and cleanup of synapse builders and growth curve factories.

Status Management:

  • get_status: retrieves the current status of structural plasticity and synapse configurations.

  • set_status: updates the structural plasticity parameters and synapse configurations based on a dictionary of settings.

Delay Management:

Disconnection:

  • disconnect: handles the disconnection of synapses between nodes, considering both local and global connections. This is essential for removing specific synapses based on given rules, which can be part of the structural plasticity process or other simulation dynamics.

Structural Plasticity Updates:

  • update_structural_plasticity: Iterates over all SPBuilder instances and calls update_structural_plasticity on each. Manages the creation and deletion of synapses based on the current state of the network. updates the structural plasticity by creating and deleting synapses based on the current state of the network.

  • create_synapses: Creates synapses between pre-synaptic and post-synaptic elements. Uses helper functions like serialize_id and global_shuffle to manage the distribution of synapses.

  • delete_synapses_from_pre and delete_synapses_from_post: Deletes synapses due to the loss of pre-synaptic or post-synaptic elements. Communicates the changes to other nodes in a distributed environment.

  • enable_structural_plasticity and disable_structural_plasticity: Enable or disable structural plasticity, with checks to ensure it’s compatible with the current simulation settings.

Relationships with other managers

Manager

Role in SPManager Operations

Example Interaction

ConnectionManager

Manages synapse creation and deletion

disconnect(), get_targets(), sp_connect()

NodeManager

Provides neuron-specific data (synaptic elements)

get_synaptic_elements()

MPIManager

Synchronizes structural plasticity changes across processes

communicate()

SimulationManager

Coordinates simulation time for triggering updates

Indirect dependency during update intervals

RandomManager

Provides randomness for distributing new synapses

Random shuffling during create_synapses()

Class Diagram

        classDiagram
 class SPManager {
     +growthcurvedict: DictionaryDatum
     +sp_conn_builders: SPBuilder[]
     +growthcurve_factories: GrowthCurveFactory[]
 }

 class SPBuilder {
     +synapse_model: string
     +pre_element: string
     +post_element: string
 }

 class ConnectionManager {
     +disconnect(...)
     +get_user_set_delay_extrema()
 }

 class Node {
     +synaptic_elements: DictionaryDatum
 }

 class KernelManager {
     +vp_manager: VPManager
     +node_manager: NodeManager
 }

 class GrowthCurveFactory {
     +create(): GrowthCurve
 }

 class GrowthCurve {
     +compute_growth(...)
 }

 class DictionaryDatum {
     +parameters: map<string, any>
 }

 class MPIManager {
     +communicate(...)
 }

 SPManager "1" --> "N" SPBuilder: manages
 SPManager "1" --> "1" ConnectionManager: uses
 SPManager "1" --> "1" KernelManager: depends on
 SPManager "1" --> "N" GrowthCurveFactory: configures
 SPManager "1" --> "1" DictionaryDatum: configures
 SPManager "1" --> "1" MPIManager: communicates via

 SPBuilder --> "1" GrowthCurve: uses
 SPBuilder --> "1" Node: connects to

 KernelManager --> "1" VPManager: manages
 KernelManager --> "1" NodeManager: manages
    

Detailed operation sequence

Here’s a breakdown of the operations, especially focusing on the update_structural_plasticity and related methods, which are central to the structural plasticity mechanism:

SPManager::update_structural_plasticity() (Main Update Function)

  • This is the entry point for updating structural plasticity. It iterates through a list of SPBuilder objects (sp_conn_builders_). For each SPBuilder, it calls update_structural_plasticity(SPBuilder* sp_builder).

  • SPManager::update_structural_plasticity(SPBuilder* sp_builder) (Per-Builder Update)

    • Get Vacant and Deleted Elements:

      Calls get_synaptic_elements() for pre-synaptic elements (e.g., axons) to identify neurons with vacant synaptic elements (pre_vacant_id, pre_vacant_n) and neurons that should delete synaptic elements (pre_deleted_id, pre_deleted_n).

      Calls get_synaptic_elements() for post-synaptic elements (e.g., dendrites) to identify vacant and deleted elements in the post-synaptic population (post_vacant_id, post_vacant_n, post_deleted_id, post_deleted_n).

    • MPI Communication (Deletion of Pre-Synaptic Elements):

      kernel().mpi_manager.communicate(): Communicates the pre_deleted_id and pre_deleted_n vectors across all MPI processes. The results are stored in pre_deleted_id_global and pre_deleted_n_global. This step ensures that all processes know which pre-synaptic neurons have lost synaptic elements.

    • Delete Synapses (Based on Pre-Synaptic Element Loss):

      If any pre-synaptic elements are to be deleted (pre_deleted_id_global.size() > 0), calls delete_synapses_from_pre().

      Calls get_synaptic_elements() for pre and post synaptic elements to update the vacant and deleted elements (Important).

    • MPI Communication (Deletion of Post-Synaptic Elements):

      kernel().mpi_manager.communicate(): Communicates the post_deleted_id and post_deleted_n vectors across all MPI processes. The results are stored in post_deleted_id_global and post_deleted_n_global. This step ensures that all processes know which post-synaptic neurons have lost synaptic elements.

    • Delete Synapses (Based on Post-Synaptic Element Loss):

      If any post-synaptic elements are to be deleted (post_deleted_id_global.size() > 0), calls delete_synapses_from_post().

      Calls get_synaptic_elements() for pre and post synaptic elements to update the vacant and deleted elements (Important).

    • MPI Communication (Vacant Elements):

      kernel().mpi_manager.communicate(): Communicates the pre_vacant_id, pre_vacant_n, post_vacant_id, and post_vacant_n vectors across all MPI processes. The results are stored in pre_vacant_id_global, pre_vacant_n_global, post_vacant_id_global, and post_vacant_n_global.

    • Create Synapses:

      If there are vacant pre-synaptic and post-synaptic elements (pre_vacant_id_global.size() > 0 and post_vacant_id_global.size() > 0), calls create_synapses().

    • Flag Connection Changes:

      If any synapses were created or deleted, it calls kernel().connection_manager.set_connections_have_changed().

  • SPManager::get_synaptic_elements()

    • This function (which is not fully provided but is used to retrieve the vacant and deleted elements from global nodes) is crucial for determining which neurons are candidates for synapse creation or deletion.

  • SPManager::delete_synapses_from_pre()

    • This function deletes synapses based on the loss of pre-synaptic elements.

    • It calls kernel().connection_manager.get_targets() to determine the target neurons connected to the deleted pre-synaptic neurons.

    • It then iterates through the connectivity information and calls kernel().connection_manager.disconnect() to remove the synapses.

  • SPManager::delete_synapses_from_post()

    • This function deletes synapses based on the loss of post-synaptic elements. The logic is similar to delete_synapses_from_pre(), but it handles the deletion from the perspective of the post-synaptic neuron.

  • SPManager::create_synapses()

    • This function creates new synapses between vacant pre-synaptic and post-synaptic elements.

    • serialize_id: expands the list of ids according to the provided number of synaptic elements.

    • It shuffles the pre-synaptic and post-synaptic neuron IDs using global_shuffle().

    • It then calls sp_conn_builder->sp_connect() to actually create the new synapses.

  • SPManager::disconnect(NodeCollectionPTR sources, ...)

    • This function disconnects existing synapses based on a given rule.

Functions

class SPManager : public nest::ManagerInterface

The SPManager class is in charge of managing the dynamic creation and deletion of synapses in the simulation when structural plasticity is enabled.

Otherwise it behaves as the normal ConnectionManager.

Param :

Public Functions

SPManager()
~SPManager() override
virtual void initialize(const bool) override

Prepare manager for operation.

After this method has completed, the manager should be completely initialized and “ready for action”.

See also

finalize()

Note

Initialization of any given manager may depend on other managers having been initialized before. KernelManager::initialize() is responsible for calling the initialization routines on the specific managers in correct order.

Parameters:

adjust_number_of_threads_or_rng_only – Pass true if calling from kernel_manager::change_number_of_threads() or RandomManager::get_status() to limit operations to those necessary for thread adjustment or switch or re-seeding of RNG.

virtual void finalize(const bool) override

Take down manager after operation.

After this method has completed, all dynamic data structures created by the manager shall be deallocated and containers emptied. Plain variables need not be reset.

See also

initialize()

Note

Finalization of any given manager may depend on other managers not having been finalized yet. KernelManager::finalize() is responsible for calling the initialization routines on the specific managers in correct order, i.e., the opposite order of initialize() calls.

Parameters:

adjust_number_of_threads_or_rng_only – Pass true if calling from kernel_manager::change_number_of_threads() to limit operations to those necessary for thread adjustment.

virtual void get_status(DictionaryDatum&) override

Retrieve the status of the manager.

See also

set_status()

Note

This would ideally be a const function. However, some managers delay the update of internal variables up to the point where they are needed (e.g., before reporting their values to the user, or before simulate is called). An example for this pattern is the call to update_delay_extrema_() right at the beginning of ConnectionManager::get_status().

virtual void set_status(const DictionaryDatum&) override

Set status of synaptic plasticity variables: synaptic update interval, synapses and synaptic elements.

Parameters:

d – Dictionary containing the values to be set

inline GrowthCurve *new_growth_curve(Name name)

Create a new Growth Curve object using the GrowthCurve Factory.

Parameters:

name – which defines the type of NC to be created

Returns:

a new Growth Curve object of the type indicated by name

template<typename GrowthCurve>
void register_growth_curve(const std::string &name)

Add a growth curve for MSP.

void disconnect(NodeCollectionPTR sources, NodeCollectionPTR targets, DictionaryDatum &conn_spec, DictionaryDatum &syn_spec)

Disconnect two collections of nodes.

The connection is established on the thread/process that owns the target node.

Obtains the right connection builder and performs a synapse deletion according to the specified connection specs.

Parameters:
  • sources – Node collection of the source Nodes.

  • targets – Node collection of the target Nodes.

  • connectivity – Params connectivity Dictionary

  • synapse – Params synapse parameters Dictionary conn_spec disconnection specs. For now only all to all and one to one rules are implemented.

void disconnect(const size_t snode_id, Node *target, size_t target_thread, const size_t syn_id)

Disconnect two nodes.

The source node is defined by its global ID. The target node is defined by the node. The connection is established on the thread/process that owns the target node.

Parameters:
  • snode_id – node ID of the sending Node.

  • target – Pointer to target Node.

  • target_thread – Thread that hosts the target node.

  • syn_id – The synapse model to use.

void update_structural_plasticity()
void update_structural_plasticity(SPBuilder*)
void enable_structural_plasticity()

Enable structural plasticity.

void disable_structural_plasticity()

Disable structural plasticity.

inline bool is_structural_plasticity_enabled() const
inline double get_structural_plasticity_update_interval() const
long builder_min_delay() const

Returns the minimum delay of all SP builders.

This influences the min_delay of the kernel, as the connections are build during the simulation. Hence, the ConnectionManager::min_delay() methods have to respect this delay as well.

long builder_max_delay() const

Returns the maximum delay of all SP builders.

This influences the max_delay of the kernel, as the connections are build during the simulation. Hence, the ConnectionManager::max_delay() methods have to respect this delay as well.

bool create_synapses(std::vector<size_t> &pre_vacant_id, std::vector<int> &pre_vacant_n, std::vector<size_t> &post_vacant_id, std::vector<int> &post_vacant_n, SPBuilder *sp_conn_builder)
void delete_synapses_from_pre(const std::vector<size_t> &pre_deleted_id, std::vector<int> &pre_deleted_n, const size_t synapse_model, const std::string &se_pre_name, const std::string &se_post_name)
void delete_synapses_from_post(std::vector<size_t> &post_deleted_id, std::vector<int> &post_deleted_n, size_t synapse_model, std::string se_pre_name, std::string se_post_name)
void delete_synapse(size_t source, size_t target, long syn_id, std::string se_pre_name, std::string se_post_name)
void get_synaptic_elements(std::string se_name, std::vector<size_t> &se_vacant_id, std::vector<int> &se_vacant_n, std::vector<size_t> &se_deleted_id, std::vector<int> &se_deleted_n)
void serialize_id(std::vector<size_t> &id, std::vector<int> &n, std::vector<size_t> &res)
void global_shuffle(std::vector<size_t> &v)
void global_shuffle(std::vector<size_t> &v, size_t n)

Private Members

double structural_plasticity_update_interval_

Time interval for structural plasticity update (creation/deletion of synapses).

bool structural_plasticity_enabled_

Indicates whether the Structrual Plasticity functionality is On (True) of Off (False).

std::vector<SPBuilder*> sp_conn_builders_
std::vector<GenericGrowthCurveFactory*> growthcurve_factories_

GrowthCurve factories, indexed by growthcurvedict_ elements.

DictionaryDatum growthcurvedict_

Dictionary for growth rules.