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

Re-organise tripartite connectivity generation to support multiple primary connection rules #3204

Merged
merged 53 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
72c7b88
Experimental work on new tripartite implementation; does not yet compile
heplesser Feb 22, 2024
4f34121
Code now compiles, not complete
heplesser Feb 23, 2024
3f6f7e9
All tests not related to disconnect, structural plasticity or tripart…
heplesser Feb 23, 2024
0dab76e
First minimal example works
heplesser Feb 23, 2024
4e1d0d9
Version working for single MPI process, random pool, no disconnect/st…
heplesser Feb 25, 2024
7376c6b
Adapted tripartite tests to new syntax
heplesser Feb 26, 2024
dce1ef1
Structural plasticity and disconnect work
heplesser Feb 26, 2024
240f553
Block pools now supported again
heplesser Feb 26, 2024
9adaf6f
Add MPI support for new tripartite scheme
heplesser Feb 26, 2024
a403765
Fix formatting and pylint problems; improve example names
heplesser Feb 26, 2024
a16cbea
Fix conngen builder
heplesser Feb 26, 2024
a883317
Prohibit 'make_symmetric' in for tripartite connectivity and extend t…
heplesser Feb 27, 2024
4a3396b
Merge branch 'master' of github.com:nest/nest-simulator into new_trip…
heplesser May 6, 2024
6fd3995
Unregister third-factor conn factories on ResetKernel
heplesser May 6, 2024
3e78a18
Merge branch 'master' of github.com:nest/nest-simulator into new_trip…
heplesser Jun 20, 2024
1eaa37a
Remove superfluous checks
heplesser Jun 20, 2024
95299f0
Make ThirdInBuilder final and improve class doc
heplesser Jun 20, 2024
9a862e6
Fix typo.
heplesser Jun 20, 2024
a8a9373
Add comment
heplesser Jun 20, 2024
636b865
Merge branch 'new_tripartite' of github.com:heplesser/nest-simulator …
heplesser Jun 20, 2024
4dce0b4
Fix links to examples
heplesser Jun 26, 2024
bdf6bc6
Merge branch 'master' into new_tripartite
heplesser Aug 8, 2024
92ff702
Ensure script also works for networks with single neuron per layer.
heplesser Aug 8, 2024
725725d
Updated example documentation to new tripartite scheme
heplesser Aug 8, 2024
a49f97b
Update pynest/examples/astrocytes/astrocyte_brunel_fixed_indegree.py
heplesser Aug 8, 2024
39d86d7
Update pynest/examples/astrocytes/astrocyte_brunel_fixed_indegree.py
heplesser Aug 8, 2024
11e67ba
Update pynest/examples/astrocytes/astrocyte_brunel_fixed_indegree.py
heplesser Aug 8, 2024
c67b1ad
Merging suggestions from Github.
heplesser Aug 8, 2024
8229ddb
Merge branch 'new_tripartite' of github.com:heplesser/nest-simulator …
heplesser Aug 8, 2024
0290888
Update connectivity_concepts documentation to new tripartite scheme
heplesser Aug 8, 2024
7f5c12e
Fix typos
heplesser Aug 8, 2024
6a819fe
Stop timer for gather secondary correctly
heplesser Aug 9, 2024
2756180
Revised pool caching to support connection rules with arbitrary targe…
heplesser Aug 12, 2024
a8c30d2
Add detailed timers for third_inner connect
heplesser Aug 14, 2024
1f39884
Add stopwatch for SyncProcesses
heplesser Aug 17, 2024
f833675
Remove detailed timers for third_in and sync
heplesser Aug 23, 2024
ead840a
Merge branch 'master' into new_tripartite_nc
heplesser Aug 26, 2024
742c36f
Fill ThirdIn buffers more efficiently
heplesser Aug 26, 2024
c5a22fb
Parse ThirdIn receive buffer more efficiently
heplesser Aug 26, 2024
7c5cd28
Change parameter values in astrocyte example scripts according to Iir…
HanjiaJiang Aug 26, 2024
2e65b02
Replace astrocyte_interaction.png with new version
HanjiaJiang Aug 26, 2024
a53ce91
Change astrocyte_lr_1994 parameter default value for delta_IP3 to phy…
HanjiaJiang Aug 26, 2024
f62ddac
Update test_astrocyte.dat and astrocyte_model_implementation.ipynb du…
HanjiaJiang Aug 26, 2024
a3f9536
Merge pull request #28 from HanjiaJiang/new_tripartite_hj
heplesser Aug 27, 2024
0f981d4
Fix wording in comment
heplesser Aug 27, 2024
ca73b3e
Remove dead code
heplesser Aug 27, 2024
672008e
Improved naming and comments for conn builder factories
heplesser Aug 27, 2024
518f964
Minor fixes to examples based on code review
heplesser Aug 27, 2024
a2eee24
Extended comments on and some code improvements for conn builders
heplesser Aug 27, 2024
4291be7
Merge branch 'new_tripartite' of github.com:heplesser/nest-simulator …
heplesser Aug 27, 2024
6744b09
Fix formatting
heplesser Aug 27, 2024
5dda6c6
Correct pool type in small network example
heplesser Aug 27, 2024
1233e08
Fixed formatting
heplesser Sep 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
632 changes: 401 additions & 231 deletions nestkernel/conn_builder.cpp

Large diffs are not rendered by default.

291 changes: 216 additions & 75 deletions nestkernel/conn_builder.h

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion nestkernel/conn_builder_conngen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@ namespace nest

ConnectionGeneratorBuilder::ConnectionGeneratorBuilder( NodeCollectionPTR sources,
NodeCollectionPTR targets,
ThirdOutBuilder* third_out,
const DictionaryDatum& conn_spec,
const std::vector< DictionaryDatum >& syn_specs )
: ConnBuilder( sources, targets, conn_spec, syn_specs )
: BipartiteConnBuilder( sources, targets, third_out, conn_spec, syn_specs )
, cg_( ConnectionGeneratorDatum() )
, params_map_()
{
assert( third_out == nullptr );

updateValue< ConnectionGeneratorDatum >( conn_spec, "cg", cg_ );
if ( cg_->arity() != 0 )
{
Expand Down
3 changes: 2 additions & 1 deletion nestkernel/conn_builder_conngen.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,15 @@ namespace nest
* interface MPI aware and communicating the masks during connection
* setup.
*/
class ConnectionGeneratorBuilder : public ConnBuilder
class ConnectionGeneratorBuilder : public BipartiteConnBuilder
{
typedef std::vector< ConnectionGenerator::ClosedInterval > RangeSet;
typedef ConnectionGenerator::ClosedInterval Range;

public:
ConnectionGeneratorBuilder( NodeCollectionPTR,
NodeCollectionPTR,
ThirdOutBuilder*,
const DictionaryDatum&,
const std::vector< DictionaryDatum >& );

Expand Down
92 changes: 27 additions & 65 deletions nestkernel/conn_builder_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,105 +53,67 @@ class GenericConnBuilderFactory
/**
* Factory method for builders for bipartite connection rules (the default).
*/
virtual ConnBuilder* create( NodeCollectionPTR,
virtual BipartiteConnBuilder* create( NodeCollectionPTR,
NodeCollectionPTR,
ThirdOutBuilder*,
const DictionaryDatum&,
const std::vector< DictionaryDatum >& ) const = 0;

/**
* Factory method for builders for tripartite connection rules.
*/
virtual ConnBuilder* create( NodeCollectionPTR,
NodeCollectionPTR,
NodeCollectionPTR,
const DictionaryDatum&,
const std::map< Name, std::vector< DictionaryDatum > >& ) const = 0;
};

/**
* Factory class for ConnBuilders
*
* This template class provides an interface with bipartite and tripartite `create()` methods.
* Implementation is delegated to explicit template specialisations below, which only implement
* the `create()` method with the proper arity depending on the `is_tripartite` flag of
* the pertaining conn builder.
*/
template < typename ConnBuilderType, bool is_tripartite = ConnBuilderType::is_tripartite >
template < typename ConnBuilderType >
class ConnBuilderFactory : public GenericConnBuilderFactory
{
public:
ConnBuilder*
BipartiteConnBuilder*
create( NodeCollectionPTR sources,
NodeCollectionPTR targets,
ThirdOutBuilder* third_out,
const DictionaryDatum& conn_spec,
const std::vector< DictionaryDatum >& syn_specs ) const override
{
assert( false ); // only specialisations should be called
}

//! create tripartite builder
ConnBuilder*
create( NodeCollectionPTR sources,
NodeCollectionPTR targets,
NodeCollectionPTR third,
const DictionaryDatum& conn_spec,
const std::map< Name, std::vector< DictionaryDatum > >& syn_specs ) const override
{
assert( false ); // only specialisations should be called
return new ConnBuilderType( sources, targets, third_out, conn_spec, syn_specs );
}
};


// Specialisation for bipartite ConnBuilders
template < typename ConnBuilderType >
class ConnBuilderFactory< ConnBuilderType, false > : public GenericConnBuilderFactory
class GenericThirdConnBuilderFactory
{
ConnBuilder*
create( NodeCollectionPTR sources,
NodeCollectionPTR targets,
const DictionaryDatum& conn_spec,
const std::vector< DictionaryDatum >& syn_specs ) const override
public:
virtual ~GenericThirdConnBuilderFactory()
{
return new ConnBuilderType( sources, targets, conn_spec, syn_specs );
}

ConnBuilder*
create( NodeCollectionPTR sources,
NodeCollectionPTR targets,
NodeCollectionPTR third,
const DictionaryDatum& conn_spec,
const std::map< Name, std::vector< DictionaryDatum > >& syn_specs ) const override
{
throw IllegalConnection( String::compose(
"Connection rule '%1' does not support tripartite connections.", ( *conn_spec )[ names::rule ] ) );
}
/**
* Factory method for builders for bipartite connection rules (the default).
heplesser marked this conversation as resolved.
Show resolved Hide resolved
*/
virtual ThirdOutBuilder* create( NodeCollectionPTR,
NodeCollectionPTR,
ThirdInBuilder*,
const DictionaryDatum&,
const std::vector< DictionaryDatum >& ) const = 0;
};

// Specialisation for tripartite ConnBuilders
template < typename ConnBuilderType >
class ConnBuilderFactory< ConnBuilderType, true > : public GenericConnBuilderFactory
/**
* Factory class for Third-factor ConnBuilders
*/
template < typename ThirdConnBuilderType >
class ThirdConnBuilderFactory : public GenericThirdConnBuilderFactory
{
ConnBuilder*
public:
ThirdOutBuilder*
create( NodeCollectionPTR sources,
NodeCollectionPTR targets,
ThirdInBuilder* third_in,
const DictionaryDatum& conn_spec,
const std::vector< DictionaryDatum >& syn_specs ) const override
{
throw BadProperty(
String::compose( "Connection rule %1 only supports tripartite connections.", ( *conn_spec )[ names::rule ] ) );
}

ConnBuilder*
create( NodeCollectionPTR sources,
NodeCollectionPTR targets,
NodeCollectionPTR third,
const DictionaryDatum& conn_spec,
const std::map< Name, std::vector< DictionaryDatum > >& syn_specs ) const override
{
return new ConnBuilderType( sources, targets, third, conn_spec, syn_specs );
return new ThirdConnBuilderType( sources, targets, third_in, conn_spec, syn_specs );
}
};


} // namespace nest

#endif
2 changes: 1 addition & 1 deletion nestkernel/conn_builder_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace nest
{

inline void
ConnBuilder::single_disconnect_( size_t snode_id, Node& target, size_t target_thread )
BipartiteConnBuilder::single_disconnect_( size_t snode_id, Node& target, size_t target_thread )
{
// index tnode_id = target.get_node_id();
// This is the most simple case in which only the synapse_model_ has been
Expand Down
66 changes: 44 additions & 22 deletions nestkernel/connection_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
nest::ConnectionManager::ConnectionManager()
: connruledict_( new Dictionary() )
, connbuilder_factories_()
, thirdconnruledict_( new Dictionary() )
, thirdconnbuilder_factories_()
, min_delay_( 1 )
, max_delay_( 1 )
, keep_source_table_( true )
Expand Down Expand Up @@ -104,9 +106,9 @@
register_conn_builder< FixedOutDegreeBuilder >( "fixed_outdegree" );
register_conn_builder< BernoulliBuilder >( "pairwise_bernoulli" );
register_conn_builder< PoissonBuilder >( "pairwise_poisson" );
register_conn_builder< TripartiteBernoulliWithPoolBuilder >( "tripartite_bernoulli_with_pool" );
register_conn_builder< SymmetricBernoulliBuilder >( "symmetric_pairwise_bernoulli" );
register_conn_builder< FixedTotalNumberBuilder >( "fixed_total_number" );
register_third_conn_builder< ThirdBernoulliWithPoolBuilder >( "third_factor_bernoulli_with_pool" );
#ifdef HAVE_LIBNEUROSIM
register_conn_builder< ConnectionGeneratorBuilder >( "conngen" );
#endif
Expand Down Expand Up @@ -171,6 +173,13 @@
}
connbuilder_factories_.clear();
connruledict_->clear();

for ( auto tcbf : thirdconnbuilder_factories_ )
{
delete tcbf;
}
thirdconnbuilder_factories_.clear();
thirdconnruledict_->clear();
}
}

Expand Down Expand Up @@ -376,29 +385,42 @@
return user_set_delay_extrema;
}

nest::ConnBuilder*
nest::BipartiteConnBuilder*
nest::ConnectionManager::get_conn_builder( const std::string& name,
NodeCollectionPTR sources,
NodeCollectionPTR targets,
ThirdOutBuilder* third_out,
clinssen marked this conversation as resolved.
Show resolved Hide resolved
const DictionaryDatum& conn_spec,
const std::vector< DictionaryDatum >& syn_specs )
{
if ( not connruledict_->known( name ) )
{
throw IllegalConnection( String::compose( "Unknown connection rule '%1'.", name ) );
}

const size_t rule_id = connruledict_->lookup( name );
ConnBuilder* cb = connbuilder_factories_.at( rule_id )->create( sources, targets, conn_spec, syn_specs );
BipartiteConnBuilder* cb =
connbuilder_factories_.at( rule_id )->create( sources, targets, third_out, conn_spec, syn_specs );
assert( cb );
return cb;
}

nest::ConnBuilder*
nest::ConnectionManager::get_conn_builder( const std::string& name,
nest::ThirdOutBuilder*
nest::ConnectionManager::get_third_conn_builder( const std::string& name,
NodeCollectionPTR sources,
NodeCollectionPTR targets,
NodeCollectionPTR third,
ThirdInBuilder* third_in,
const DictionaryDatum& conn_spec,
const std::map< Name, std::vector< DictionaryDatum > >& syn_specs )
const std::vector< DictionaryDatum >& syn_specs )
{
const size_t rule_id = connruledict_->lookup( name );
ConnBuilder* cb = connbuilder_factories_.at( rule_id )->create( sources, targets, third, conn_spec, syn_specs );
if ( not thirdconnruledict_->known( name ) )
{
throw IllegalConnection( String::compose( "Unknown third-factor connection rule '%1'.", name ) );
}

const size_t rule_id = thirdconnruledict_->lookup( name );
ThirdOutBuilder* cb =
thirdconnbuilder_factories_.at( rule_id )->create( sources, targets, third_in, conn_spec, syn_specs );
assert( cb );
return cb;
}
Expand Down Expand Up @@ -438,14 +460,14 @@
{
throw BadProperty( "The connection specification must contain a connection rule." );
}
const std::string rule_name = static_cast< const std::string >( ( *conn_spec )[ names::rule ] );
const std::string rule = static_cast< const std::string >( ( *conn_spec )[ names::rule ] );

if ( not connruledict_->known( rule_name ) )
if ( not connruledict_->known( rule ) )
{
throw BadProperty( String::compose( "Unknown connection rule: %1", rule_name ) );
throw BadProperty( String::compose( "Unknown connection rule: %1", rule ) );
}

ConnBuilder* cb = get_conn_builder( rule_name, sources, targets, conn_spec, syn_specs );
ConnBuilder cb( rule, sources, targets, conn_spec, syn_specs );

// at this point, all entries in conn_spec and syn_spec have been checked
ALL_ENTRIES_ACCESSED( *conn_spec, "Connect", "Unread dictionary entries in conn_spec: " );
Expand All @@ -457,8 +479,7 @@
// Set flag before calling cb->connect() in case exception is thrown after some connections have been created.
set_connections_have_changed();

cb->connect();
delete cb;
cb.connect();
}


Expand Down Expand Up @@ -784,7 +805,7 @@
}

void
nest::ConnectionManager::connect_sonata( const DictionaryDatum& graph_specs, const long hyberslab_size )

Check warning on line 808 in nestkernel/connection_manager.cpp

View workflow job for this annotation

GitHub Actions / build_linux (ubuntu-20.04, gcc, openmp, python, gsl, ltdl, boost, optimize, warning)

unused parameter ‘graph_specs’ [-Wunused-parameter]

Check warning on line 808 in nestkernel/connection_manager.cpp

View workflow job for this annotation

GitHub Actions / build_linux (ubuntu-20.04, gcc, openmp, python, gsl, ltdl, boost, optimize, warning)

unused parameter ‘hyberslab_size’ [-Wunused-parameter]
{
#ifdef HAVE_HDF5
SonataConnector sonata_connector( graph_specs, hyberslab_size );
Expand All @@ -803,6 +824,7 @@
NodeCollectionPTR targets,
NodeCollectionPTR third,
const DictionaryDatum& conn_spec,
const DictionaryDatum& third_conn_spec,
const std::map< Name, std::vector< DictionaryDatum > >& syn_specs )
{
if ( sources->empty() )
Expand Down Expand Up @@ -831,14 +853,15 @@
{
throw BadProperty( "The connection specification must contain a connection rule." );
}
const std::string rule_name = static_cast< const std::string >( ( *conn_spec )[ names::rule ] );

if ( not connruledict_->known( rule_name ) )
if ( not third_conn_spec->known( names::rule ) )
{
throw BadProperty( String::compose( "Unknown connection rule: %1", rule_name ) );
throw BadProperty( "The third-factor connection specification must contain a connection rule." );
}

ConnBuilder* cb = get_conn_builder( rule_name, sources, targets, third, conn_spec, syn_specs );
const std::string primary_rule = static_cast< const std::string >( ( *conn_spec )[ names::rule ] );
const std::string third_rule = static_cast< const std::string >( ( *third_conn_spec )[ names::rule ] );

ConnBuilder cb( primary_rule, third_rule, sources, targets, third, conn_spec, third_conn_spec, syn_specs );

// at this point, all entries in conn_spec and syn_spec have been checked
ALL_ENTRIES_ACCESSED( *conn_spec, "Connect", "Unread dictionary entries in conn_spec: " );
Expand All @@ -853,8 +876,7 @@
// Set flag before calling cb->connect() in case exception is thrown after some connections have been created.
set_connections_have_changed();

cb->connect();
delete cb;
clinssen marked this conversation as resolved.
Show resolved Hide resolved
cb.connect();
}


Expand Down
24 changes: 19 additions & 5 deletions nestkernel/connection_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
namespace nest
{
class GenericConnBuilderFactory;
class GenericThirdConnBuilderFactory;
class spikecounter;
class Node;
class Event;
Expand Down Expand Up @@ -94,20 +95,27 @@ class ConnectionManager : public ManagerInterface
template < typename ConnBuilder >
void register_conn_builder( const std::string& name );

/**
* Add a connectivity rule, i.e. the respective ConnBuilderFactory.
*/
template < typename ThirdConnBuilder >
void register_third_conn_builder( const std::string& name );

//! Obtain builder for bipartite connections
ConnBuilder* get_conn_builder( const std::string& name,
BipartiteConnBuilder* get_conn_builder( const std::string& name,
NodeCollectionPTR sources,
NodeCollectionPTR targets,
ThirdOutBuilder* third_out,
const DictionaryDatum& conn_spec,
const std::vector< DictionaryDatum >& syn_specs );

//! Obtain builder for tripartite connections
ConnBuilder* get_conn_builder( const std::string& name,
//! Obtain builder for bipartite connections
ThirdOutBuilder* get_third_conn_builder( const std::string& name,
NodeCollectionPTR sources,
NodeCollectionPTR targets,
NodeCollectionPTR third,
ThirdInBuilder* third_in,
const DictionaryDatum& conn_spec,
const std::map< Name, std::vector< DictionaryDatum > >& syn_specs );
const std::vector< DictionaryDatum >& syn_specs );

/**
* Create connections.
Expand Down Expand Up @@ -192,6 +200,7 @@ class ConnectionManager : public ManagerInterface
NodeCollectionPTR targets,
NodeCollectionPTR third,
const DictionaryDatum& connectivity,
const DictionaryDatum& third_connectivity,
const std::map< Name, std::vector< DictionaryDatum > >& synapse_specs );

size_t find_connection( const size_t tid, const synindex syn_id, const size_t snode_id, const size_t tnode_id );
Expand Down Expand Up @@ -640,6 +649,11 @@ class ConnectionManager : public ManagerInterface
//! ConnBuilder factories, indexed by connruledict_ elements.
std::vector< GenericConnBuilderFactory* > connbuilder_factories_;

DictionaryDatum thirdconnruledict_; //!< Dictionary for third-factor connection rules.

//! Third-factor ConnBuilder factories, indexed by thirdconnruledict_ elements.
std::vector< GenericThirdConnBuilderFactory* > thirdconnbuilder_factories_;

long min_delay_; //!< Value of the smallest delay in the network.

long max_delay_; //!< Value of the largest delay in the network in steps.
Expand Down
Loading
Loading