@@ -50,7 +50,7 @@ NodeManager::NodeManager()
50
50
, node_collection_container_()
51
51
, wfr_nodes_vec_()
52
52
, wfr_is_used_( false )
53
- , wfr_network_size_ ( 0 ) // zero to force update
53
+ , size_last_local_data_update_ ( 0 ) // zero to force update
54
54
, num_active_nodes_( 0 )
55
55
, num_thread_local_devices_()
56
56
, have_nodes_changed_( true )
@@ -68,11 +68,11 @@ NodeManager::~NodeManager()
68
68
void
69
69
NodeManager::initialize ( const bool adjust_number_of_threads_or_rng_only )
70
70
{
71
- // explicitly force construction of wfr_nodes_vec_ to ensure consistent state
72
- wfr_network_size_ = 0 ;
71
+ // explicitly force construction of thread-local node data to ensure consistent state
72
+ size_last_local_data_update_ = 0 ;
73
73
local_nodes_.resize ( kernel ().vp_manager .get_num_threads () );
74
74
num_thread_local_devices_.resize ( kernel ().vp_manager .get_num_threads (), 0 );
75
- ensure_valid_thread_local_ids ();
75
+ update_thread_local_node_data ();
76
76
77
77
if ( not adjust_number_of_threads_or_rng_only )
78
78
{
@@ -523,74 +523,56 @@ NodeManager::get_thread_siblings( size_t node_id ) const
523
523
}
524
524
525
525
void
526
- NodeManager::ensure_valid_thread_local_ids ()
526
+ NodeManager::update_thread_local_node_data ()
527
527
{
528
- // Check if the network size changed, in order to not enter
529
- // the critical region if it is not necessary. Note that this
530
- // test also covers that case that nodes have been deleted
531
- // by reset.
532
- if ( size () == wfr_network_size_ )
528
+ kernel ().vp_manager .assert_single_threaded ();
529
+
530
+ if ( thread_local_data_is_up_to_date () )
533
531
{
534
532
return ;
535
533
}
536
534
537
- #pragma omp critical( update_wfr_nodes_vec )
538
- {
539
- // This code may be called from a thread-parallel context, when it is
540
- // invoked by TargetIdentifierIndex::set_target() during parallel
541
- // wiring. Nested OpenMP parallelism is problematic, therefore, we
542
- // enforce single threading here. This should be unproblematic wrt
543
- // performance, because the wfr_nodes_vec_ is rebuilt only once after
544
- // changes in network size.
545
- //
546
- // Check again, if the network size changed, since a previous thread
547
- // can have updated wfr_nodes_vec_ before.
548
- if ( size () != wfr_network_size_ )
549
- {
550
-
551
- // We clear the existing wfr_nodes_vec_ and then rebuild it.
552
- wfr_nodes_vec_.clear ();
553
- wfr_nodes_vec_.resize ( kernel ().vp_manager .get_num_threads () );
554
-
555
- for ( size_t tid = 0 ; tid < kernel ().vp_manager .get_num_threads (); ++tid )
556
- {
557
- wfr_nodes_vec_[ tid ].clear ();
558
-
559
- const size_t num_thread_local_wfr_nodes = std::count_if ( local_nodes_[ tid ].begin (),
560
- local_nodes_[ tid ].end (),
561
- []( const SparseNodeArray::NodeEntry& elem ) { return elem.get_node ()->node_uses_wfr_ ; } );
562
- wfr_nodes_vec_[ tid ].reserve ( num_thread_local_wfr_nodes );
535
+ // We clear the existing wfr_nodes_vec_ and then rebuild it.
536
+ wfr_nodes_vec_.clear ();
537
+ wfr_nodes_vec_.resize ( kernel ().vp_manager .get_num_threads () );
563
538
564
- auto node_it = local_nodes_[ tid ].begin ();
565
- size_t idx = 0 ;
566
- for ( ; node_it < local_nodes_[ tid ].end (); ++node_it, ++idx )
567
- {
568
- auto node = node_it->get_node ();
569
- node->set_thread_lid ( idx );
570
- if ( node->node_uses_wfr_ )
571
- {
572
- wfr_nodes_vec_[ tid ].push_back ( node );
573
- }
574
- }
575
- } // end of for threads
539
+ for ( size_t tid = 0 ; tid < kernel ().vp_manager .get_num_threads (); ++tid )
540
+ {
541
+ wfr_nodes_vec_[ tid ].clear ();
576
542
577
- wfr_network_size_ = size ();
543
+ const size_t num_thread_local_wfr_nodes = std::count_if ( local_nodes_[ tid ].begin (),
544
+ local_nodes_[ tid ].end (),
545
+ []( const SparseNodeArray::NodeEntry& elem ) { return elem.get_node ()->node_uses_wfr_ ; } );
546
+ wfr_nodes_vec_[ tid ].reserve ( num_thread_local_wfr_nodes );
578
547
579
- // wfr_is_used_ indicates, whether at least one
580
- // of the threads has a neuron that uses waveform relaxation
581
- // all threads then need to perform a wfr_update
582
- // step, because gather_events() has to be done in an
583
- // openmp single section
584
- wfr_is_used_ = false ;
585
- for ( size_t tid = 0 ; tid < kernel (). vp_manager . get_num_threads (); ++tid )
548
+ auto node_it = local_nodes_[ tid ]. begin ();
549
+ size_t idx = 0 ;
550
+ for ( ; node_it < local_nodes_[ tid ]. end (); ++node_it, ++idx )
551
+ {
552
+ auto node = node_it-> get_node ();
553
+ node-> set_thread_lid ( idx ) ;
554
+ if ( node-> node_uses_wfr_ )
586
555
{
587
- if ( wfr_nodes_vec_[ tid ].size () > 0 )
588
- {
589
- wfr_is_used_ = true ;
590
- }
556
+ wfr_nodes_vec_[ tid ].push_back ( node );
591
557
}
592
558
}
593
- } // omp critical
559
+ } // end of for threads
560
+
561
+ size_last_local_data_update_ = size ();
562
+
563
+ // wfr_is_used_ indicates, whether at least one
564
+ // of the threads has a neuron that uses waveform relaxation
565
+ // all threads then need to perform a wfr_update
566
+ // step, because gather_events() has to be done in an
567
+ // openmp single section
568
+ wfr_is_used_ = false ;
569
+ for ( size_t tid = 0 ; tid < kernel ().vp_manager .get_num_threads (); ++tid )
570
+ {
571
+ if ( wfr_nodes_vec_[ tid ].size () > 0 )
572
+ {
573
+ wfr_is_used_ = true ;
574
+ }
575
+ }
594
576
}
595
577
596
578
void
0 commit comments