@@ -65,7 +65,7 @@ class ThirdOutBuilder;
65
65
* the connect interface. Derived classes implement the connect
66
66
* method.
67
67
*
68
- * @note Naming classes *Builder to avoid name confusion with Connector classes .
68
+ * @note This class is also the base class for all components of a TripartiteConnBuilder .
69
69
*/
70
70
class BipartiteConnBuilder
71
71
{
@@ -76,6 +76,16 @@ class BipartiteConnBuilder
76
76
// ! Delete synapses with or without structural plasticity
77
77
virtual void disconnect ();
78
78
79
+ /* *
80
+ * Create new bipartite builder.
81
+ *
82
+ * @param sources Source population to connect from
83
+ * @param targets Target population to connect to
84
+ * @param third_out `nullptr` if pure bipartite connection, pointer to \class ThirdOutBuilder object if this builder
85
+ * creates the primary connection of a tripartite connectivity
86
+ * @param conn_spec Connection specification (if part of tripartite, spec for the specific part)
87
+ * @param syn_specs Collection of synapse specifications (usually single element, several for collocated synapses)
88
+ */
79
89
BipartiteConnBuilder ( NodeCollectionPTR sources,
80
90
NodeCollectionPTR targets,
81
91
ThirdOutBuilder* third_out,
@@ -105,8 +115,6 @@ class BipartiteConnBuilder
105
115
106
116
void set_synaptic_element_names ( const std::string& pre_name, const std::string& post_name );
107
117
108
- bool all_parameters_scalar_ () const ;
109
-
110
118
/* *
111
119
* Updates the number of connected synaptic elements in the target and the source.
112
120
*
@@ -118,12 +126,14 @@ class BipartiteConnBuilder
118
126
*/
119
127
bool change_connected_synaptic_elements ( size_t snode_id, size_t tnode_id, const size_t tid, int update );
120
128
129
+ // ! Return true if rule allows creation of symmetric connectivity
121
130
virtual bool
122
131
supports_symmetric () const
123
132
{
124
133
return false ;
125
134
}
126
135
136
+ // ! Return true if rule automatically creates symmetric connectivity
127
137
virtual bool
128
138
is_symmetric () const
129
139
{
@@ -153,6 +163,8 @@ class BipartiteConnBuilder
153
163
// ! Implements the actual connection algorithm
154
164
virtual void connect_ () = 0;
155
165
166
+ bool all_parameters_scalar_ () const ;
167
+
156
168
virtual void
157
169
sp_connect_ ()
158
170
{
@@ -204,17 +216,17 @@ class BipartiteConnBuilder
204
216
*/
205
217
bool loop_over_targets_ () const ;
206
218
207
- NodeCollectionPTR sources_;
208
- NodeCollectionPTR targets_;
219
+ NodeCollectionPTR sources_; // !< Population to connect from
220
+ NodeCollectionPTR targets_; // !< Population to connect to
209
221
210
- ThirdOutBuilder* third_out_; // !< to be triggered when primary connection is created
222
+ ThirdOutBuilder* third_out_; // !< To be triggered when primary connection is created
211
223
212
224
bool allow_autapses_;
213
225
bool allow_multapses_;
214
226
bool make_symmetric_;
215
227
bool creates_symmetric_connections_;
216
228
217
- // ! buffer for exceptions raised in threads
229
+ // ! Buffer for exceptions raised in threads
218
230
std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_;
219
231
220
232
// Name of the pre synaptic and postsynaptic elements for this connection builder
@@ -223,12 +235,18 @@ class BipartiteConnBuilder
223
235
224
236
bool use_structural_plasticity_;
225
237
226
- // ! pointers to connection parameters specified as arrays
238
+ // ! Pointers to connection parameters specified as arrays
227
239
std::vector< ConnParameter* > parameters_requiring_skipping_;
228
240
229
241
std::vector< size_t > synapse_model_id_;
230
242
231
- // ! dictionaries to pass to connect function, one per thread for every syn_spec
243
+ /* *
244
+ * Dictionaries to pass to connect function, one per thread for every syn_spec
245
+ *
246
+ * Outer dim: syn_spec, inner dim: thread
247
+ *
248
+ * @note Each thread can independently modify its dictionary to pass parameters on
249
+ */
232
250
std::vector< std::vector< DictionaryDatum > > param_dicts_;
233
251
234
252
private:
@@ -300,20 +318,47 @@ class BipartiteConnBuilder
300
318
* This builder creates the actual connections from primary sources to third-factor nodes
301
319
* based on the source-third lists generated by the third-out builder.
302
320
*
321
+ * The `ThirdOutBuilder::third_connect()` method calls `register_connection()`
322
+ * for each source node to third-factor node connection that needs to be created to store this
323
+ * information in the `ThirdIn` builder.
324
+ *
325
+ * The `connect_()` method of this class needs to be called after all primary connections
326
+ * and third-factor to target connections have been created. It then exchanges information
327
+ * about required source-third connections with the other MPI ranks and creates required
328
+ * connections locally.
329
+ *
303
330
* The class is final because there is no freedom of choice of connection rule at this stage.
304
331
*/
305
332
class ThirdInBuilder final : public BipartiteConnBuilder
306
333
{
307
334
public:
308
- ThirdInBuilder ( NodeCollectionPTR,
309
- NodeCollectionPTR,
310
- const DictionaryDatum&, // only for compatibility with BipartiteConnBuilder
311
- const std::vector< DictionaryDatum >& );
335
+ /* *
336
+ * Create ThirdInBuilder
337
+ *
338
+ * @param sources Source population of primary connection
339
+ * @param third Third-factor population
340
+ * @param third_conn_spec is ignored by this builder but required to make base class happy
341
+ * @param syn_specs Collection of synapse specification for connection from primary source to third factor
342
+ *
343
+ * @todo Once DictionaryDatums are gone, see if we can remove `third_conn_spec` and just pass empty conn spec
344
+ * container to base-class constructor, since \class ThirdInBuilder has no connection rule properties to set.
345
+ */
346
+ ThirdInBuilder ( NodeCollectionPTR sources,
347
+ NodeCollectionPTR third,
348
+ const DictionaryDatum& third_conn_spec,
349
+ const std::vector< DictionaryDatum >& syn_specs );
312
350
~ThirdInBuilder ();
313
351
314
- void register_connection ( size_t primary_source_id, size_t primary_target_id );
352
+ /* *
353
+ * Register required source node to third-factor node connection.
354
+ *
355
+ * @param primary_source_id GID of source node to connect from
356
+ * @param third_node_id GID of target node to connect to
357
+ */
358
+ void register_connection ( size_t primary_source_id, size_t third_node_id );
315
359
316
360
private:
361
+ // ! Exchange required connection info via MPI and create needed connections locally
317
362
void connect_ () override ;
318
363
319
364
/* *
@@ -336,15 +381,16 @@ class ThirdInBuilder final : public BipartiteConnBuilder
336
381
{
337
382
}
338
383
339
- size_t source_gid;
340
- size_t third_gid;
341
- size_t third_rank;
384
+ size_t source_gid; // !< GID of source node to connect from
385
+ size_t third_gid; // !< GID of third-factor node to connect to
386
+ size_t third_rank; // !< Rank of third-factor node (stored locally as it is needed multiple times)
342
387
};
343
388
344
- // ! source-thirdparty GID pairs to be communicated; one per thread
389
+ // ! Container for register source-third connections, one per thread via pointer for collision free operation in
390
+ // ! thread-local storage
345
391
std::vector< BlockVector< SourceThirdInfo_ >* > source_third_gids_;
346
392
347
- // ! number of source-third pairs to send. Outer dimension writing thread, inner dimension rank to send to
393
+ // ! Number of source-third pairs to send. Outer dimension is writing thread, inner dimension MPI rank to send to
348
394
std::vector< std::vector< size_t >* > source_third_counts_;
349
395
};
350
396
@@ -361,14 +407,33 @@ class ThirdInBuilder final : public BipartiteConnBuilder
361
407
class ThirdOutBuilder : public BipartiteConnBuilder
362
408
{
363
409
public:
364
- ThirdOutBuilder ( NodeCollectionPTR,
365
- NodeCollectionPTR,
366
- ThirdInBuilder*,
367
- const DictionaryDatum&, // only for compatibility with BipartiteConnBuilder
368
- const std::vector< DictionaryDatum >& );
410
+ /* *
411
+ * Create ThirdOutBuilder.
412
+ *
413
+ * @param third Third-factor population
414
+ * @param targets Target population of primary connection
415
+ * @param third_in ThirdInBuilder which will create source-third connections later
416
+ * @param third_conn_spec Specification for third-factor connectivity
417
+ * @param syn_specs Collection of synapse specifications for third-target connections
418
+ */
419
+ ThirdOutBuilder ( const NodeCollectionPTR third,
420
+ const NodeCollectionPTR targets,
421
+ ThirdInBuilder* third_in,
422
+ const DictionaryDatum& third_conn_spec,
423
+ const std::vector< DictionaryDatum >& syn_specs );
369
424
370
- void connect () override ;
425
+ void
426
+ connect () override final
427
+ {
428
+ assert ( false );
429
+ } // !< only call third_connect() on ThirdOutBuilder
371
430
431
+ /* *
432
+ * Create third-factor connection for given primary connection.
433
+ *
434
+ * @param source_gid GID of source of primary connection
435
+ * @param target Target node of primary connection
436
+ */
372
437
virtual void third_connect ( size_t source_gid, Node& target ) = 0;
373
438
374
439
protected:
@@ -392,7 +457,7 @@ class ConnBuilder
392
457
* @param sources Source population for primary connection
393
458
* @param targets Target population for primary connection
394
459
* @param conn_spec Connection specification dictionary for tripartite bernoulli rule
395
- * @param syn_spec Dictionary of synapse specification
460
+ * @param syn_spec Collection of dictionaries with synapse specifications
396
461
*/
397
462
ConnBuilder ( const std::string& primary_rule,
398
463
NodeCollectionPTR sources,
@@ -410,7 +475,8 @@ class ConnBuilder
410
475
* @param third Third-party population
411
476
* @param conn_spec Connection specification dictionary for tripartite bernoulli rule
412
477
* @param syn_specs Dictionary of synapse specifications for the three connections that may be created. Allowed keys
413
- * are `"primary"`, `"third_in"`, `"third_out"`
478
+ * are `"primary"`, `"third_in"`, `"third_out"`, and for each of these the value must be a collection of dictionaries
479
+ * with synapse specifications as for bipartite connectivity.
414
480
*/
415
481
ConnBuilder ( const std::string& primary_rule,
416
482
const std::string& third_rule,
@@ -430,20 +496,23 @@ class ConnBuilder
430
496
void disconnect ();
431
497
432
498
private:
433
- // order of declarations based on dependencies
499
+ // Order of declarations based on dependencies, do not change.
434
500
ThirdInBuilder* third_in_builder_;
435
501
ThirdOutBuilder* third_out_builder_;
436
502
BipartiteConnBuilder* primary_builder_;
437
503
};
438
504
439
-
505
+ /* *
506
+ * Build third-factor connectivity based on Bernoulli trials, selecting third factor nodes from a fixed pool per target
507
+ * node.
508
+ */
440
509
class ThirdBernoulliWithPoolBuilder : public ThirdOutBuilder
441
510
{
442
511
public:
443
512
ThirdBernoulliWithPoolBuilder ( NodeCollectionPTR,
444
513
NodeCollectionPTR,
445
- ThirdInBuilder* third_in ,
446
- const DictionaryDatum&, // only for compatibility with BCB
514
+ ThirdInBuilder*,
515
+ const DictionaryDatum&,
447
516
const std::vector< DictionaryDatum >& );
448
517
~ThirdBernoulliWithPoolBuilder ();
449
518
@@ -454,16 +523,39 @@ class ThirdBernoulliWithPoolBuilder : public ThirdOutBuilder
454
523
connect_ () override
455
524
{
456
525
assert ( false );
457
- }
526
+ } // !< only call third_connect()
527
+
528
+ /* *
529
+ * For block pool, return index of first pool element for given target node.
530
+ *
531
+ * @param targe_index
532
+ */
458
533
size_t get_first_pool_index_ ( const size_t target_index ) const ;
459
534
460
- double p_;
461
- bool random_pool_;
462
- size_t pool_size_;
463
- size_t targets_per_third_;
535
+ double p_; // !< probability of creating a third-factor connection
536
+ bool random_pool_; // !< random or block pool?
537
+ size_t pool_size_; // !< number of nodes per pool
538
+ size_t targets_per_third_; // !< number of target nodes per third-factor node
464
539
540
+ /* *
541
+ * Type for single pool of third-factor nodes
542
+ *
543
+ * @todo Could probably be BlockVector, but currently some problem with back_inserter when sampling pool.
544
+ */
465
545
typedef std::vector< NodeIDTriple > PoolType_;
546
+
547
+ // ! Type mapping target GID to pool for this target
466
548
typedef std::map< size_t , PoolType_ > TgtPoolMap_;
549
+
550
+ /* *
551
+ * Thread-specific pools of third-factor nodes.
552
+ *
553
+ * Each thread maintains a map from target node IDs to the third-factor node pool for that target node.
554
+ * Since each target lives on exactly one thread, there will be no overlap. For each node, the pool is
555
+ * created when a third-factor connection needs to be made to that node for the first time.
556
+ * The pools are deleted when the ConnBuilder is destroyed at the end of the connect call.
557
+ * We store a pointer instead of the map itself to ensure that the map is in thread-local memory.
558
+ */
467
559
std::vector< TgtPoolMap_* > pools_; // outer: threads
468
560
};
469
561
0 commit comments