diff --git a/CMakeLists.txt b/CMakeLists.txt index 137a952507..d486f04cb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,6 +118,9 @@ include( CheckExtraCompilerFeatures ) include( ConfigureSummary ) include( GetTriple ) +# enable link-time optimizations +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + # get triples arch-vendor-os get_host_triple( NEST_HOST_TRIPLE NEST_HOST_ARCH NEST_HOST_VENDOR NEST_HOST_OS ) get_target_triple( NEST_TARGET_TRIPLE NEST_TARGET_ARCH NEST_TARGET_VENDOR NEST_TARGET_OS ) diff --git a/doc/htmldoc/developer_space/guidelines/coding_guidelines_cpp.rst b/doc/htmldoc/developer_space/guidelines/coding_guidelines_cpp.rst index f6dceba360..2308936a61 100644 --- a/doc/htmldoc/developer_space/guidelines/coding_guidelines_cpp.rst +++ b/doc/htmldoc/developer_space/guidelines/coding_guidelines_cpp.rst @@ -371,171 +371,175 @@ For example, the ``stopwatch.h`` file could look like: #ifndef STOPWATCH_H #define STOPWATCH_H - // C includes: - #include - // C++ includes: - #include + #include #include + #include + + // Includes from nestkernel: + #include "arraydatum.h" + #include "dictdatum.h" + #include "dictutils.h" + #include "exceptions.h" + #include "kernel_manager.h" + #include "vp_manager.h" namespace nest { - /*********************************************************************** - * Stopwatch * - * Accumulates time between start and stop, and provides * - * the elapsed time with different time units. * - * * - * Partly inspired by com.google.common.base.Stopwatch.java * - * Not thread-safe: - Do not share stopwatches among threads. * - * - Let each thread have its own stopwatch. * - * * - * Usage example: * - * Stopwatch x; * - * x.start(); * - * // ... do computations for 15.34 sec * - * x.stop(); // only pauses stopwatch * - * x.print("Time needed "); // > Time needed 15.34 sec. * - * x.start(); // resumes stopwatch * - * // ... next computations for 11.22 sec * - * x.stop(); * - * x.print("Time needed "); // > Time needed 26,56 sec. * - * x.reset(); // reset to default values * - * x.start(); // starts the stopwatch from 0 * - * // ... computation 5.7 sec * - * x.print("Time "); // > Time 5.7 sec. * - * // ^ intermediate timing without stopping the stopwatch * - * // ... more computations 1.7643 min * - * x.stop(); * - * x.print("Time needed ", Stopwatch::MINUTES, std::cerr); * - * // > Time needed 1,8593 min. (on cerr) * - * // other units and output streams possible * - ***********************************************************************/ - class Stopwatch + #ifdef TIMER_DETAILED + constexpr bool use_detailed_timers = true; + #else + constexpr bool use_detailed_timers = false; + #endif + #ifdef THREADED_TIMERS + constexpr bool use_threaded_timers = true; + #else + constexpr bool use_threaded_timers = false; + #endif + + enum class StopwatchGranularity { - public: - typedef size_t timestamp_t; - typedef size_t timeunit_t; + Normal, // + class Stopwatch; + + /******************************************************************************** + * Stopwatch * + * Accumulates time between start and stop, and provides the elapsed time * + * with different time units. Either runs multi-threaded or only on master. * + * * + * Usage example: * + * Stopwatch< StopwatchGranularity::Normal, StopwatchParallelism::MasterOnly > x; * + * x.start(); * + * // ... do computations for 15.34 sec * + * x.stop(); // only pauses stopwatch * + * x.print("Time needed "); // > Time needed 15.34 sec. * + * x.start(); // resumes stopwatch * + * // ... next computations for 11.22 sec * + * x.stop(); * + * x.print("Time needed "); // > Time needed 26,56 sec. * + * x.reset(); // reset to default values * + * x.start(); // starts the stopwatch from 0 * + * // ... computation 5.7 sec * + * x.print("Time "); // > Time 5.7 sec. * + * // ^ intermediate timing without stopping the stopwatch * + * // ... more computations 1.7643 min * + * x.stop(); * + * x.print("Time needed ", timeunit_t::MINUTES, std::cerr); * + * // > Time needed 1,8593 min. (on cerr) * + * // other units and output streams possible * + ********************************************************************************/ + namespace timers + { + enum class timeunit_t : size_t + { + NANOSEC = 1, + MICROSEC = NANOSEC * 1000, + MILLISEC = MICROSEC * 1000, + SECONDS = MILLISEC * 1000, + MINUTES = SECONDS * 60, + HOURS = MINUTES * 60, + DAYS = HOURS * 24 + }; - /** - * Creates a stopwatch that is not running. - */ - Stopwatch() + /** This class represents a single timer which measures the execution time of a single thread for a given clock type. + * Typical clocks are monotonic wall-time clocks or clocks just measuring cpu time. + */ + template < clockid_t clock_type > + class StopwatchTimer + { + template < StopwatchGranularity, StopwatchParallelism, typename > + friend class nest::Stopwatch; + + public: + typedef size_t timestamp_t; + + //! Creates a stopwatch that is not running. + StopwatchTimer() { reset(); } - /** - * Starts or resumes the stopwatch, if it is not running already. - */ + //! Starts or resumes the stopwatch, if it is not running already. void start(); - /** - * Stops the stopwatch, if it is not stopped already. - */ + //! Stops the stopwatch, if it is not stopped already. void stop(); /** - * Returns, whether the stopwatch is running. - */ - bool isRunning() const; - - /** - * Returns the time elapsed between the start and stop of the - * stopwatch. If it is running, it returns the time from start - * until now. If the stopwatch is run previously, the previous - * runtime is added. If you want only the last measurment, you - * have to reset the timer, before stating the measurment. - * Does not change the running state. - */ - double elapsed( timeunit_t timeunit = SECONDS ) const; - - /** - * Returns the time elapsed between the start and stop of the - * stopwatch. If it is running, it returns the time from start - * until now. If the stopwatch is run previously, the previous - * runtime is added. If you want only the last measurment, you - * have to reset the timer, before stating the measurment. + * Returns the time elapsed between the start and stop of the stopwatch in the given unit. If it is running, it + * returns the time from start until now. If the stopwatch is run previously, the previous runtime is added. If you + * want only the last measurement, you have to reset the timer, before stating the measurement. * Does not change the running state. - * In contrast to Stopwatch::elapsed(), only the timestamp is returned, - * that is the number if microseconds as an integer. */ - timestamp_t elapsed_timestamp() const; + double elapsed( timeunit_t timeunit = timeunit_t::SECONDS ) const; - /** - * Resets the stopwatch. - */ + //! Resets the stopwatch. void reset(); - /** - * This method prints out the currently elapsed time. - */ - void print( const char* msg = "", timeunit_t timeunit = SECONDS, std::ostream& os = std::cout ) const; - - /** - * Convenient method for writing time in seconds - * to some ostream. - */ - friend std::ostream& operator<<( std::ostream& os, const Stopwatch& stopwatch ); + //! This method prints out the currently elapsed time. + void + print( const std::string& msg = "", timeunit_t timeunit = timeunit_t::SECONDS, std::ostream& os = std::cout ) const; private: + //! Returns, whether the stopwatch is running. + bool is_running_() const; + #ifndef DISABLE_TIMING timestamp_t _beg, _end; size_t _prev_elapsed; bool _running; #endif - /** - * Returns current time in microseconds since EPOCH. - */ - static timestamp_t get_timestamp(); + //! Returns current time in microseconds since EPOCH. + static size_t get_current_time(); }; - inline bool - Stopwatch::correct_timeunit( timeunit_t t ) - { - return t == MICROSEC || t == MILLISEC || t == SECONDS || t == MINUTES || t == HOURS || t == DAYS; - } - + template < clockid_t clock_type > inline void - nest::Stopwatch::start() + StopwatchTimer< clock_type >::start() { #ifndef DISABLE_TIMING - if ( not isRunning() ) + if ( not is_running_() ) { - _prev_elapsed += _end - _beg; // store prev. time, if we resume - _end = _beg = get_timestamp(); // invariant: _end >= _beg - _running = true; // we start running + _prev_elapsed += _end - _beg; // store prev. time, if we resume + _end = _beg = get_current_time(); // invariant: _end >= _beg + _running = true; // we start running } #endif } + template < clockid_t clock_type > inline void - nest::Stopwatch::stop() + StopwatchTimer< clock_type >::stop() { #ifndef DISABLE_TIMING - if ( isRunning() ) + if ( is_running_() ) { - _end = get_timestamp(); // invariant: _end >= _beg - _running = false; // we stopped running + _end = get_current_time(); // invariant: _end >= _beg + _running = false; // we stopped running } #endif } + template < clockid_t clock_type > inline bool - nest::Stopwatch::isRunning() const + StopwatchTimer< clock_type >::is_running_() const { #ifndef DISABLE_TIMING return _running; @@ -544,38 +548,31 @@ For example, the ``stopwatch.h`` file could look like: #endif } + template < clockid_t clock_type > inline double - nest::Stopwatch::elapsed( timeunit_t timeunit ) const - { - #ifndef DISABLE_TIMING - assert( correct_timeunit( timeunit ) ); - return 1.0 * elapsed_timestamp() / timeunit; - #else - return 0.0; - #endif - } - - inline nest::Stopwatch::timestamp_t - nest::Stopwatch::elapsed_us() const + StopwatchTimer< clock_type >::elapsed( timeunit_t timeunit ) const { #ifndef DISABLE_TIMING - if ( isRunning() ) + size_t time_elapsed; + if ( is_running_() ) { // get intermediate elapsed time; do not change _end, to be const - return get_timestamp() - _beg + _prev_elapsed; + time_elapsed = get_current_time() - _beg + _prev_elapsed; } else { // stopped before, get time of current measurement + last measurements - return _end - _beg + _prev_elapsed; + time_elapsed = _end - _beg + _prev_elapsed; } + return static_cast< double >( time_elapsed ) / static_cast< double >( timeunit ); #else - return ( timestamp_t ) 0; + return 0.; #endif } + template < clockid_t clock_type > inline void - nest::Stopwatch::reset() + StopwatchTimer< clock_type >::reset() { #ifndef DISABLE_TIMING _beg = 0; // invariant: _end >= _beg @@ -585,33 +582,37 @@ For example, the ``stopwatch.h`` file could look like: #endif } + template < clockid_t clock_type > inline void - nest::Stopwatch::print( const char* msg, timeunit_t timeunit, std::ostream& os ) const + StopwatchTimer< clock_type >::print( const std::string& msg, timeunit_t timeunit, std::ostream& os ) const { #ifndef DISABLE_TIMING - assert( correct_timeunit( timeunit ) ); double e = elapsed( timeunit ); os << msg << e; switch ( timeunit ) { - case MICROSEC: + case timeunit_t::NANOSEC: + os << " nanosec."; + case timeunit_t::MICROSEC: os << " microsec."; break; - case MILLISEC: + case timeunit_t::MILLISEC: os << " millisec."; break; - case SECONDS: + case timeunit_t::SECONDS: os << " sec."; break; - case MINUTES: + case timeunit_t::MINUTES: os << " min."; break; - case HOURS: + case timeunit_t::HOURS: os << " h."; break; - case DAYS: + case timeunit_t::DAYS: os << " days."; break; + default: + throw BadParameter( "Invalid timeunit provided to stopwatch." ); } #ifdef DEBUG os << " (running: " << ( _running ? "true" : "false" ) << ", begin: " << _beg << ", end: " << _end @@ -621,55 +622,336 @@ For example, the ``stopwatch.h`` file could look like: #endif } - inline nest::Stopwatch::timestamp_t - nest::Stopwatch::get_current_time() + template < clockid_t clock_type > + inline size_t + StopwatchTimer< clock_type >::get_current_time() { - // works with: - // * hambach (Linux 2.6.32 x86_64) - // * JuQueen (BG/Q) - // * MacOS 10.9 - struct timeval now; - gettimeofday( &now, ( struct timezone* ) 0 ); - return ( nest::Stopwatch::timestamp_t ) now.tv_usec - + ( nest::Stopwatch::timestamp_t ) now.tv_sec * nest::Stopwatch::SECONDS; + timespec now; + clock_gettime( clock_type, &now ); + return now.tv_nsec + now.tv_sec * static_cast< long >( timeunit_t::SECONDS ); } - } /* namespace timer */ - #endif /* STOPWATCH_H */ + template < clockid_t clock_type > + inline std::ostream& + operator<<( std::ostream& os, const StopwatchTimer< clock_type >& stopwatch ) + { + stopwatch.print( "", timeunit_t::SECONDS, os ); + return os; + } -And the corresponding ``stopwatch_impl.h``: + } // namespace timers -.. code:: cpp - /* - * stopwatch_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. + /** This is the base template for all Stopwatch specializations. * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This template will be specialized in case detailed timers are deactivated or the timer is supposed to be run by + * multiple threads. If the timer should be deactivated, because detailed timers are disabled, the template + * specialization will be empty and optimized away by the compiler. + * This base template only measures a single timer, owned by the master thread, which applies for both detailed and + * regular timers. Detailed, master-only timers that are deactivated when detailed timers are turned off are handled + * by one of the template specializations below. * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . + * The template has three template arguments of which two act as actual parameters that need to be specified for each + * stopwatch instance. The first one "detailed_timer" controls the granularity of the stopwatch, i.e., if the timer is + * considered a normal or detailed timer. The second one "threaded_timer" defines if the timer is supposed to be + * measured by each thread individually. In case a timer is specified as threaded, but threaded timers are turned off + * globally, the stopwatch will run in master-only mode instead. The third template argument is used to enable or + * disable certain template specializations based on compiler flags (i.e., detailed timers and threaded timers). * + * In all cases, both the (monotonic) wall-time and cpu time are measured. */ + template < StopwatchGranularity detailed_timer, StopwatchParallelism threaded_timer, typename = void > + class Stopwatch + { + public: + void + start() + { + #pragma omp master + { + walltime_timer_.start(); + cputime_timer_.start(); + } + } - #include "stopwatch.h" + void + stop() + { + #pragma omp master + { + walltime_timer_.stop(); + cputime_timer_.stop(); + } + } - namespace nest + double + elapsed( timers::timeunit_t timeunit = timers::timeunit_t::SECONDS ) const + { + double elapsed = 0.; + #pragma omp master + { + elapsed = walltime_timer_.elapsed( timeunit ); + }; + return elapsed; + } + + void + reset() + { + #pragma omp master + { + walltime_timer_.reset(); + cputime_timer_.reset(); + } + } + + void + print( const std::string& msg = "", + timers::timeunit_t timeunit = timers::timeunit_t::SECONDS, + std::ostream& os = std::cout ) const + { + #pragma omp master + walltime_timer_.print( msg, timeunit, os ); + } + + void + get_status( DictionaryDatum& d, const Name& walltime_name, const Name& cputime_name ) const + { + def< double >( d, walltime_name, walltime_timer_.elapsed() ); + def< double >( d, cputime_name, cputime_timer_.elapsed() ); + } + + private: + bool + is_running_() const + { + bool is_running_ = false; + #pragma omp master + { + is_running_ = walltime_timer_.is_running_(); + }; + return is_running_; + } + + // We use a monotonic timer to make sure the stopwatch is not influenced by time jumps (e.g. summer/winter time). + timers::StopwatchTimer< CLOCK_MONOTONIC > walltime_timer_; + timers::StopwatchTimer< CLOCK_THREAD_CPUTIME_ID > cputime_timer_; + }; + + //! Stopwatch template specialization for detailed, master-only timer instances if detailed timers are deactivated. + template <> + class Stopwatch< StopwatchGranularity::Detailed, + StopwatchParallelism::MasterOnly, + std::enable_if< not use_detailed_timers > > { - std::ostream& operator<<( std::ostream& os, const Stopwatch& stopwatch ) + public: + void + start() + { + } + void + stop() + { + } + double + elapsed( timers::timeunit_t = timers::timeunit_t::SECONDS ) const + { + return 0; + } + void + reset() + { + } + void + print( const std::string& = "", timers::timeunit_t = timers::timeunit_t::SECONDS, std::ostream& = std::cout ) const + { + } + void + get_status( DictionaryDatum&, const Name&, const Name& ) const + { + } + + private: + bool + is_running_() const + { + return false; + } + }; + + //! Stopwatch template specialization for detailed, threaded timer instances if detailed timers are deactivated. + template < StopwatchGranularity detailed_timer > + class Stopwatch< detailed_timer, + StopwatchParallelism::Threaded, + std::enable_if_t< use_threaded_timers + and ( detailed_timer == StopwatchGranularity::Detailed and not use_detailed_timers ) > > { - stopwatch.print( "", Stopwatch::SECONDS, os ); - return os; + public: + void + start() + { + } + void + stop() + { + } + double + elapsed( timers::timeunit_t = timers::timeunit_t::SECONDS ) const + { + return 0; + } + void + reset() + { + } + void + print( const std::string& = "", timers::timeunit_t = timers::timeunit_t::SECONDS, std::ostream& = std::cout ) const + { + } + void + get_status( DictionaryDatum&, const Name&, const Name& ) const + { + } + + private: + bool + is_running_() const + { + return false; + } + }; + + /** Stopwatch template specialization for threaded timer instances if the timer is a detailed one and detailed timers + * are activated or the timer is not a detailed one in the first place. + */ + template < StopwatchGranularity detailed_timer > + class Stopwatch< detailed_timer, + StopwatchParallelism::Threaded, + std::enable_if_t< use_threaded_timers + and ( detailed_timer == StopwatchGranularity::Normal or use_detailed_timers ) > > + { + public: + void start(); + + void stop(); + + double elapsed( timers::timeunit_t timeunit = timers::timeunit_t::SECONDS ) const; + + void reset(); + + void print( const std::string& msg = "", + timers::timeunit_t timeunit = timers::timeunit_t::SECONDS, + std::ostream& os = std::cout ) const; + + void + get_status( DictionaryDatum& d, const Name& walltime_name, const Name& cputime_name ) const + { + std::vector< double > wall_times( walltime_timers_.size() ); + std::transform( walltime_timers_.begin(), + walltime_timers_.end(), + wall_times.begin(), + []( const timers::StopwatchTimer< CLOCK_MONOTONIC >& timer ) { return timer.elapsed(); } ); + def< ArrayDatum >( d, walltime_name, ArrayDatum( wall_times ) ); + + std::vector< double > cpu_times( cputime_timers_.size() ); + std::transform( cputime_timers_.begin(), + cputime_timers_.end(), + cpu_times.begin(), + []( const timers::StopwatchTimer< CLOCK_THREAD_CPUTIME_ID >& timer ) { return timer.elapsed(); } ); + def< ArrayDatum >( d, cputime_name, ArrayDatum( cpu_times ) ); + } + + private: + bool is_running_() const; + + // We use a monotonic timer to make sure the stopwatch is not influenced by time jumps (e.g. summer/winter time). + std::vector< timers::StopwatchTimer< CLOCK_MONOTONIC > > walltime_timers_; + std::vector< timers::StopwatchTimer< CLOCK_THREAD_CPUTIME_ID > > cputime_timers_; + }; + + template < StopwatchGranularity detailed_timer > + void + Stopwatch< detailed_timer, + StopwatchParallelism::Threaded, + std::enable_if_t< use_threaded_timers + and ( detailed_timer == StopwatchGranularity::Normal or use_detailed_timers ) > >::start() + { + kernel::manager().assert_thread_parallel(); + + walltime_timers_[ kernel::manager().get_thread_id() ].start(); + cputime_timers_[ kernel::manager().get_thread_id() ].start(); } + + template < StopwatchGranularity detailed_timer > + void + Stopwatch< detailed_timer, + StopwatchParallelism::Threaded, + std::enable_if_t< use_threaded_timers + and ( detailed_timer == StopwatchGranularity::Normal or use_detailed_timers ) > >::stop() + { + kernel::manager().assert_thread_parallel(); + + walltime_timers_[ kernel::manager().get_thread_id() ].stop(); + cputime_timers_[ kernel::manager().get_thread_id() ].stop(); + } + + template < StopwatchGranularity detailed_timer > + bool + Stopwatch< detailed_timer, + StopwatchParallelism::Threaded, + std::enable_if_t< use_threaded_timers + and ( detailed_timer == StopwatchGranularity::Normal or use_detailed_timers ) > >::is_running_() const + { + kernel::manager().assert_thread_parallel(); + + return walltime_timers_[ kernel::manager().get_thread_id() ].is_running_(); + } + + template < StopwatchGranularity detailed_timer > + double + Stopwatch< detailed_timer, + StopwatchParallelism::Threaded, + std::enable_if_t< use_threaded_timers + and ( detailed_timer == StopwatchGranularity::Normal or use_detailed_timers ) > >::elapsed( timers::timeunit_t + timeunit ) const + { + kernel::manager().assert_thread_parallel(); + + return walltime_timers_[ kernel::manager().get_thread_id() ].elapsed( timeunit ); } + + template < StopwatchGranularity detailed_timer > + void + Stopwatch< detailed_timer, + StopwatchParallelism::Threaded, + std::enable_if_t< use_threaded_timers + and ( detailed_timer == StopwatchGranularity::Normal or use_detailed_timers ) > >::print( const std::string& msg, + timers::timeunit_t timeunit, + std::ostream& os ) const + { + kernel::manager().assert_thread_parallel(); + + walltime_timers_[ kernel::manager().get_thread_id() ].print( msg, timeunit, os ); + } + + template < StopwatchGranularity detailed_timer > + void + Stopwatch< detailed_timer, + StopwatchParallelism::Threaded, + std::enable_if_t< use_threaded_timers + and ( detailed_timer == StopwatchGranularity::Normal or use_detailed_timers ) > >::reset() + { + kernel::manager().assert_single_threaded(); + + const size_t num_threads = kernel::manager().get_num_threads(); + walltime_timers_.resize( num_threads ); + cputime_timers_.resize( num_threads ); + for ( size_t i = 0; i < num_threads; ++i ) + { + walltime_timers_[ i ].reset(); + cputime_timers_[ i ].reset(); + } + } + + } /* namespace nest */ + #endif /* STOPWATCH_H */ diff --git a/doc/htmldoc/installation/cmake_options.rst b/doc/htmldoc/installation/cmake_options.rst index 323d3c6127..8f6191a4c4 100644 --- a/doc/htmldoc/installation/cmake_options.rst +++ b/doc/htmldoc/installation/cmake_options.rst @@ -213,7 +213,7 @@ NEST properties +-----------------------------------------------+----------------------------------------------------------------+ | ``-Dwith-full-logging=[OFF|ON]`` | Write debug output to file ``dump__.log`` | | | [default=OFF]. Developers should wrap debugging output in | -| | macro ``FULL_LOGGING_ONLY()`` and call kernel().write_dump()` | +| | macro ``FULL_LOGGING_ONLY()`` and call kernel::manager().write_dump()` | | | from inside it. The macro can contain almost any valid code. | +-----------------------------------------------+----------------------------------------------------------------+ diff --git a/doc/htmldoc/networks/spatially_structured_networks.rst b/doc/htmldoc/networks/spatially_structured_networks.rst index c982239e53..198378b9c9 100644 --- a/doc/htmldoc/networks/spatially_structured_networks.rst +++ b/doc/htmldoc/networks/spatially_structured_networks.rst @@ -1516,7 +1516,6 @@ files for the ``Mask`` parent class: .. code:: c #include "mask.h" - #include "mask_impl.h" The ``Mask`` class has a few methods that must be overridden: diff --git a/doc/htmldoc/sg_execution_times.rst b/doc/htmldoc/sg_execution_times.rst new file mode 100644 index 0000000000..a414a4e7b4 --- /dev/null +++ b/doc/htmldoc/sg_execution_times.rst @@ -0,0 +1,355 @@ + +:orphan: + +.. _sphx_glr_sg_execution_times: + + +Computation times +================= +**00:00.000** total execution time for 107 files **from all galleries**: + +.. container:: + + .. raw:: html + + + + + + + + .. list-table:: + :header-rows: 1 + :class: table table-striped sg-datatable + + * - Example + - Time + - Mem (MB) + * - :ref:`sphx_glr_auto_examples_BrodyHopfield.py` (``../../pynest/examples/BrodyHopfield.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_CampbellSiegert.py` (``../../pynest/examples/CampbellSiegert.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_EI_clustered_network_helper.py` (``../../pynest/examples/EI_clustered_network/helper.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_EI_clustered_network_network.py` (``../../pynest/examples/EI_clustered_network/network.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_EI_clustered_network_network_params.py` (``../../pynest/examples/EI_clustered_network/network_params.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_EI_clustered_network_run_simulation.py` (``../../pynest/examples/EI_clustered_network/run_simulation.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_EI_clustered_network_sim_params.py` (``../../pynest/examples/EI_clustered_network/sim_params.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_EI_clustered_network_stimulus_params.py` (``../../pynest/examples/EI_clustered_network/stimulus_params.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_Potjans_2014_helpers.py` (``../../pynest/examples/Potjans_2014/helpers.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_Potjans_2014_network.py` (``../../pynest/examples/Potjans_2014/network.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_Potjans_2014_network_params.py` (``../../pynest/examples/Potjans_2014/network_params.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_Potjans_2014_run_microcircuit.py` (``../../pynest/examples/Potjans_2014/run_microcircuit.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_Potjans_2014_sim_params.py` (``../../pynest/examples/Potjans_2014/sim_params.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_Potjans_2014_stimulus_params.py` (``../../pynest/examples/Potjans_2014/stimulus_params.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_aeif_cond_beta_multisynapse.py` (``../../pynest/examples/aeif_cond_beta_multisynapse.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_astrocytes_astrocyte_brunel_bernoulli.py` (``../../pynest/examples/astrocytes/astrocyte_brunel_bernoulli.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_astrocytes_astrocyte_brunel_fixed_indegree.py` (``../../pynest/examples/astrocytes/astrocyte_brunel_fixed_indegree.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_astrocytes_astrocyte_interaction.py` (``../../pynest/examples/astrocytes/astrocyte_interaction.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_astrocytes_astrocyte_single.py` (``../../pynest/examples/astrocytes/astrocyte_single.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_astrocytes_astrocyte_small_network.py` (``../../pynest/examples/astrocytes/astrocyte_small_network.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_balancedneuron.py` (``../../pynest/examples/balancedneuron.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_brette_gerstner_fig_2c.py` (``../../pynest/examples/brette_gerstner_fig_2c.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_brette_gerstner_fig_3d.py` (``../../pynest/examples/brette_gerstner_fig_3d.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_brunel_alpha_evolution_strategies.py` (``../../pynest/examples/brunel_alpha_evolution_strategies.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_brunel_alpha_nest.py` (``../../pynest/examples/brunel_alpha_nest.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_brunel_delta_nest.py` (``../../pynest/examples/brunel_delta_nest.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_brunel_exp_multisynapse_nest.py` (``../../pynest/examples/brunel_exp_multisynapse_nest.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_brunel_siegert_nest.py` (``../../pynest/examples/brunel_siegert_nest.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_clopath_synapse_small_network.py` (``../../pynest/examples/clopath_synapse_small_network.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_clopath_synapse_spike_pairing.py` (``../../pynest/examples/clopath_synapse_spike_pairing.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_compartmental_model_receptors_and_current.py` (``../../pynest/examples/compartmental_model/receptors_and_current.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_compartmental_model_two_comps.py` (``../../pynest/examples/compartmental_model/two_comps.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_correlospinmatrix_detector_two_neuron.py` (``../../pynest/examples/correlospinmatrix_detector_two_neuron.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_cross_check_mip_corrdet.py` (``../../pynest/examples/cross_check_mip_corrdet.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_csa_example.py` (``../../pynest/examples/csa_example.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_csa_spatial_example.py` (``../../pynest/examples/csa_spatial_example.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_eprop_plasticity_eprop_supervised_classification_evidence-accumulation_bsshslm_2020.py` (``../../pynest/examples/eprop_plasticity/eprop_supervised_classification_evidence-accumulation_bsshslm_2020.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_eprop_plasticity_eprop_supervised_classification_neuromorphic_mnist.py` (``../../pynest/examples/eprop_plasticity/eprop_supervised_classification_neuromorphic_mnist.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_eprop_plasticity_eprop_supervised_regression_handwriting_bsshslm_2020.py` (``../../pynest/examples/eprop_plasticity/eprop_supervised_regression_handwriting_bsshslm_2020.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_eprop_plasticity_eprop_supervised_regression_lemniscate_bsshslm_2020.py` (``../../pynest/examples/eprop_plasticity/eprop_supervised_regression_lemniscate_bsshslm_2020.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_eprop_plasticity_eprop_supervised_regression_sine-waves.py` (``../../pynest/examples/eprop_plasticity/eprop_supervised_regression_sine-waves.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_eprop_plasticity_eprop_supervised_regression_sine-waves_bsshslm_2020.py` (``../../pynest/examples/eprop_plasticity/eprop_supervised_regression_sine-waves_bsshslm_2020.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_evaluate_quantal_stp_synapse.py` (``../../pynest/examples/evaluate_quantal_stp_synapse.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_evaluate_tsodyks2_synapse.py` (``../../pynest/examples/evaluate_tsodyks2_synapse.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_gap_junctions_inhibitory_network.py` (``../../pynest/examples/gap_junctions_inhibitory_network.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_gap_junctions_two_neurons.py` (``../../pynest/examples/gap_junctions_two_neurons.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_gif_cond_exp_multisynapse.py` (``../../pynest/examples/gif_cond_exp_multisynapse.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_gif_pop_psc_exp.py` (``../../pynest/examples/gif_pop_psc_exp.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_gif_population.py` (``../../pynest/examples/gif_population.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_glif_cond_neuron.py` (``../../pynest/examples/glif_cond_neuron.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_glif_psc_double_alpha_neuron.py` (``../../pynest/examples/glif_psc_double_alpha_neuron.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_glif_psc_neuron.py` (``../../pynest/examples/glif_psc_neuron.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_hh_phaseplane.py` (``../../pynest/examples/hh_phaseplane.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_hh_psc_alpha.py` (``../../pynest/examples/hh_psc_alpha.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_hpc_benchmark.py` (``../../pynest/examples/hpc_benchmark.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_iaf_tum_2000_short_term_depression.py` (``../../pynest/examples/iaf_tum_2000_short_term_depression.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_iaf_tum_2000_short_term_facilitation.py` (``../../pynest/examples/iaf_tum_2000_short_term_facilitation.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_if_curve.py` (``../../pynest/examples/if_curve.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_intrinsic_currents_spiking.py` (``../../pynest/examples/intrinsic_currents_spiking.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_intrinsic_currents_subthreshold.py` (``../../pynest/examples/intrinsic_currents_subthreshold.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_lin_rate_ipn_network.py` (``../../pynest/examples/lin_rate_ipn_network.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_mc_neuron.py` (``../../pynest/examples/mc_neuron.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_multimeter_file.py` (``../../pynest/examples/multimeter_file.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_music_cont_out_proxy_example_nest_script.py` (``../../pynest/examples/music_cont_out_proxy_example/nest_script.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_music_cont_out_proxy_example_receiver_script.py` (``../../pynest/examples/music_cont_out_proxy_example/receiver_script.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_one_neuron.py` (``../../pynest/examples/one_neuron.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_one_neuron_with_noise.py` (``../../pynest/examples/one_neuron_with_noise.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_plot_weight_matrices.py` (``../../pynest/examples/plot_weight_matrices.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_pong_generate_gif.py` (``../../pynest/examples/pong/generate_gif.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_pong_networks.py` (``../../pynest/examples/pong/networks.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_pong_pong.py` (``../../pynest/examples/pong/pong.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_pong_run_simulations.py` (``../../pynest/examples/pong/run_simulations.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_precise_spiking.py` (``../../pynest/examples/precise_spiking.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_pulsepacket.py` (``../../pynest/examples/pulsepacket.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_rate_neuron_dm.py` (``../../pynest/examples/rate_neuron_dm.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_recording_demo.py` (``../../pynest/examples/recording_demo.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_repeated_stimulation.py` (``../../pynest/examples/repeated_stimulation.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_sensitivity_to_perturbation.py` (``../../pynest/examples/sensitivity_to_perturbation.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_sinusoidal_gamma_generator.py` (``../../pynest/examples/sinusoidal_gamma_generator.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_sinusoidal_poisson_generator.py` (``../../pynest/examples/sinusoidal_poisson_generator.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_sonata_example_sonata_network.py` (``../../pynest/examples/sonata_example/sonata_network.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_conncomp.py` (``../../pynest/examples/spatial/conncomp.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_conncon_sources.py` (``../../pynest/examples/spatial/conncon_sources.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_conncon_targets.py` (``../../pynest/examples/spatial/conncon_targets.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_connex.py` (``../../pynest/examples/spatial/connex.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_connex_ew.py` (``../../pynest/examples/spatial/connex_ew.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_ctx_2n.py` (``../../pynest/examples/spatial/ctx_2n.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_gaussex.py` (``../../pynest/examples/spatial/gaussex.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_grid_iaf.py` (``../../pynest/examples/spatial/grid_iaf.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_grid_iaf_irr.py` (``../../pynest/examples/spatial/grid_iaf_irr.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_grid_iaf_oc.py` (``../../pynest/examples/spatial/grid_iaf_oc.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_nodes_source_target.py` (``../../pynest/examples/spatial/nodes_source_target.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_test_3d.py` (``../../pynest/examples/spatial/test_3d.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_test_3d_exp.py` (``../../pynest/examples/spatial/test_3d_exp.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_spatial_test_3d_gauss.py` (``../../pynest/examples/spatial/test_3d_gauss.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_store_restore_network.py` (``../../pynest/examples/store_restore_network.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_structural_plasticity.py` (``../../pynest/examples/structural_plasticity.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_sudoku_helpers_sudoku.py` (``../../pynest/examples/sudoku/helpers_sudoku.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_sudoku_plot_progress.py` (``../../pynest/examples/sudoku/plot_progress.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_sudoku_sudoku_net.py` (``../../pynest/examples/sudoku/sudoku_net.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_sudoku_sudoku_solver.py` (``../../pynest/examples/sudoku/sudoku_solver.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_synapsecollection.py` (``../../pynest/examples/synapsecollection.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_testiaf.py` (``../../pynest/examples/testiaf.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_twoneurons.py` (``../../pynest/examples/twoneurons.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_urbanczik_synapse_example.py` (``../../pynest/examples/urbanczik_synapse_example.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_vinit_example.py` (``../../pynest/examples/vinit_example.py``) + - 00:00.000 + - 0.0 + * - :ref:`sphx_glr_auto_examples_wang_decision_making.py` (``../../pynest/examples/wang_decision_making.py``) + - 00:00.000 + - 0.0 diff --git a/libnestutil/dict_util.h b/libnestutil/dict_util.h index eeb954b5f9..fcf1bc1116 100644 --- a/libnestutil/dict_util.h +++ b/libnestutil/dict_util.h @@ -25,8 +25,9 @@ // Includes from nestkernel: #include "kernel_manager.h" +#include "nest.h" #include "nest_datums.h" -#include "vp_manager_impl.h" +#include "node.h" // Includes from sli: #include "dictdatum.h" @@ -53,8 +54,8 @@ updateValueParam( DictionaryDatum const& d, Name const n, VT& value, nest::Node* { throw BadParameter( "Cannot use Parameter with this model." ); } - auto vp = kernel().vp_manager.node_id_to_vp( node->get_node_id() ); - auto tid = kernel().vp_manager.vp_to_thread( vp ); + auto vp = kernel::manager< VPManager >.node_id_to_vp( node->get_node_id() ); + auto tid = kernel::manager< VPManager >.vp_to_thread( vp ); auto rng = get_vp_specific_rng( tid ); value = pd->get()->value( rng, node ); return true; diff --git a/libnestutil/logging.h b/libnestutil/logging.h index 61284b71cc..3fe6911404 100644 --- a/libnestutil/logging.h +++ b/libnestutil/logging.h @@ -23,22 +23,25 @@ #ifndef LOGGING_H #define LOGGING_H + /** * */ -#define LOG( s, fctn, msg ) nest::kernel().logging_manager.publish_log( ( s ), ( fctn ), ( msg ), __FILE__, __LINE__ ) +#define LOG( s, fctn, msg ) \ + nest::kernel::manager< LoggingManager >.publish_log( ( s ), ( fctn ), ( msg ), __FILE__, __LINE__ ) /** * */ #define ALL_ENTRIES_ACCESSED( d, fctn, msg ) \ - nest::kernel().logging_manager.all_entries_accessed( ( d ), ( fctn ), ( msg ), __FILE__, __LINE__ ) + nest::kernel::manager< LoggingManager >.all_entries_accessed( ( d ), ( fctn ), ( msg ), __FILE__, __LINE__ ) /** * */ -#define ALL_ENTRIES_ACCESSED2( d, fctn, msg1, msg2 ) \ - nest::kernel().logging_manager.all_entries_accessed( ( d ), ( fctn ), ( msg1 ), ( msg2 ), __FILE__, __LINE__ ) +#define ALL_ENTRIES_ACCESSED2( d, fctn, msg1, msg2 ) \ + nest::kernel::manager< LoggingManager >.all_entries_accessed( \ + ( d ), ( fctn ), ( msg1 ), ( msg2 ), __FILE__, __LINE__ ) namespace nest { diff --git a/models/CMakeLists.txt b/models/CMakeLists.txt index 4b861b13f3..5da8995e4e 100644 --- a/models/CMakeLists.txt +++ b/models/CMakeLists.txt @@ -23,9 +23,9 @@ set(models_sources weight_recorder.h weight_recorder.cpp # Required by CommonSynapseProperties cm_compartmentcurrents.h cm_compartmentcurrents.cpp cm_tree.h cm_tree.cpp - rate_neuron_ipn.h rate_neuron_ipn_impl.h - rate_neuron_opn.h rate_neuron_opn_impl.h - rate_transformer_node.h rate_transformer_node_impl.h + rate_neuron_ipn.h + rate_neuron_opn.h + rate_transformer_node.h weight_optimizer.h weight_optimizer.cpp ${MODELS_SOURCES_GENERATED} ) diff --git a/models/ac_generator.cpp b/models/ac_generator.cpp index d7c5ea7751..a22de62ca6 100644 --- a/models/ac_generator.cpp +++ b/models/ac_generator.cpp @@ -31,6 +31,8 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -188,7 +190,7 @@ nest::ac_generator::pre_run_hook() StimulationDevice::pre_run_hook(); const double h = Time::get_resolution().get_ms(); - const double t = kernel().simulation_manager.get_time().get_ms(); + const double t = kernel::manager< SimulationManager >.get_time().get_ms(); // scale Hz to ms const double omega = 2.0 * numerics::pi * P_.freq_ / 1000.0; @@ -224,7 +226,7 @@ nest::ac_generator::update( Time const& origin, const long from, const long to ) { S_.I_ = S_.y_1_ + P_.offset_; ce.set_current( S_.I_ ); - kernel().event_delivery_manager.send( *this, ce, lag ); + kernel::manager< EventDeliveryManager >.send( *this, ce, lag ); } B_.logger_.record_data( origin.get_steps() + lag ); } diff --git a/models/ac_generator.h b/models/ac_generator.h index 8f53ac5d7e..1cb5fecd77 100644 --- a/models/ac_generator.h +++ b/models/ac_generator.h @@ -29,7 +29,7 @@ #include "event.h" #include "nest_types.h" #include "stimulation_device.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" /* BeginUserDocs: device, generator diff --git a/models/aeif_cond_alpha.cpp b/models/aeif_cond_alpha.cpp index dc8298bc3e..a7fa97c0fb 100644 --- a/models/aeif_cond_alpha.cpp +++ b/models/aeif_cond_alpha.cpp @@ -27,7 +27,6 @@ // C++ includes: #include #include -#include #include // Includes from libnestutil: @@ -35,7 +34,9 @@ #include "numerics.h" // Includes from nestkernel: +#include "event_delivery_manager.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "nest_names.h" @@ -512,7 +513,7 @@ nest::aeif_cond_alpha::update( Time const& origin, const long from, const long t set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -541,12 +542,12 @@ nest::aeif_cond_alpha::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -559,7 +560,7 @@ nest::aeif_cond_alpha::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/aeif_cond_alpha.h b/models/aeif_cond_alpha.h index 1b4a3dbcac..235146f067 100644 --- a/models/aeif_cond_alpha.h +++ b/models/aeif_cond_alpha.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/aeif_cond_alpha_astro.cpp b/models/aeif_cond_alpha_astro.cpp index 9b073b5487..319e80f2b2 100644 --- a/models/aeif_cond_alpha_astro.cpp +++ b/models/aeif_cond_alpha_astro.cpp @@ -27,7 +27,6 @@ // C++ includes: #include #include -#include #include // Includes from libnestutil: @@ -35,7 +34,9 @@ #include "numerics.h" // Includes from nestkernel: +#include "event_delivery_manager.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "nest_names.h" @@ -515,7 +516,7 @@ nest::aeif_cond_alpha_astro::update( Time const& origin, const long from, const set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -545,12 +546,12 @@ nest::aeif_cond_alpha_astro::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -563,14 +564,14 @@ nest::aeif_cond_alpha_astro::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void nest::aeif_cond_alpha_astro::handle( SICEvent& e ) { const double weight = e.get_weight(); - const long delay = e.get_delay_steps() - kernel().connection_manager.get_min_delay(); + const long delay = e.get_delay_steps() - kernel::manager< ConnectionManager >.get_min_delay(); size_t i = 0; std::vector< unsigned int >::iterator it = e.begin(); diff --git a/models/aeif_cond_alpha_astro.h b/models/aeif_cond_alpha_astro.h index ca8f63e845..8d07ebf6dd 100644 --- a/models/aeif_cond_alpha_astro.h +++ b/models/aeif_cond_alpha_astro.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/aeif_cond_alpha_multisynapse.cpp b/models/aeif_cond_alpha_multisynapse.cpp index f027713973..f4acbfdbeb 100644 --- a/models/aeif_cond_alpha_multisynapse.cpp +++ b/models/aeif_cond_alpha_multisynapse.cpp @@ -32,7 +32,9 @@ #include "numerics.h" // Includes from nestkernel: +#include "event_delivery_manager.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -551,7 +553,7 @@ aeif_cond_alpha_multisynapse::update( Time const& origin, const long from, const set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -598,7 +600,8 @@ aeif_cond_alpha_multisynapse::handle( SpikeEvent& e ) assert( ( e.get_rport() > 0 ) and ( ( size_t ) e.get_rport() <= P_.n_receptors() ) ); B_.spikes_[ e.get_rport() - 1 ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -610,7 +613,7 @@ aeif_cond_alpha_multisynapse::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * I ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * I ); } void diff --git a/models/aeif_cond_alpha_multisynapse.h b/models/aeif_cond_alpha_multisynapse.h index ad46eaad82..deb0d726fb 100644 --- a/models/aeif_cond_alpha_multisynapse.h +++ b/models/aeif_cond_alpha_multisynapse.h @@ -40,7 +40,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" /* BeginUserDocs: neuron, integrate-and-fire, adaptation, conductance-based, soft threshold diff --git a/models/aeif_cond_beta_multisynapse.cpp b/models/aeif_cond_beta_multisynapse.cpp index 5ef7e10717..58c26ab65e 100644 --- a/models/aeif_cond_beta_multisynapse.cpp +++ b/models/aeif_cond_beta_multisynapse.cpp @@ -30,10 +30,11 @@ // Includes from libnestutil: #include "beta_normalization_factor.h" #include "dict_util.h" -#include "numerics.h" // Includes from nestkernel: +#include "event_delivery_manager.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -560,7 +561,7 @@ aeif_cond_beta_multisynapse::update( Time const& origin, const long from, const set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -607,7 +608,8 @@ aeif_cond_beta_multisynapse::handle( SpikeEvent& e ) assert( ( e.get_rport() > 0 ) and ( ( size_t ) e.get_rport() <= P_.n_receptors() ) ); B_.spikes_[ e.get_rport() - 1 ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -619,7 +621,7 @@ aeif_cond_beta_multisynapse::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * I ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * I ); } void diff --git a/models/aeif_cond_beta_multisynapse.h b/models/aeif_cond_beta_multisynapse.h index dd0c34bd3b..3425d0873d 100644 --- a/models/aeif_cond_beta_multisynapse.h +++ b/models/aeif_cond_beta_multisynapse.h @@ -40,7 +40,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/aeif_cond_exp.cpp b/models/aeif_cond_exp.cpp index cb0eb86d0c..cf8f3fe5c7 100644 --- a/models/aeif_cond_exp.cpp +++ b/models/aeif_cond_exp.cpp @@ -27,15 +27,15 @@ // C++ includes: #include #include -#include #include // Includes from libnestutil: #include "dict_util.h" -#include "numerics.h" // Includes from nestkernel: +#include "event_delivery_manager.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "nest_names.h" @@ -502,7 +502,7 @@ nest::aeif_cond_exp::update( const Time& origin, const long from, const long to set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -531,12 +531,12 @@ nest::aeif_cond_exp::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -549,7 +549,7 @@ nest::aeif_cond_exp::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/aeif_cond_exp.h b/models/aeif_cond_exp.h index bf040a664a..fad923ee00 100644 --- a/models/aeif_cond_exp.h +++ b/models/aeif_cond_exp.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/aeif_psc_alpha.cpp b/models/aeif_psc_alpha.cpp index b4a1b9c86e..373695e96f 100644 --- a/models/aeif_psc_alpha.cpp +++ b/models/aeif_psc_alpha.cpp @@ -36,6 +36,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "nest_names.h" @@ -502,7 +503,7 @@ nest::aeif_psc_alpha::update( Time const& origin, const long from, const long to set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -531,12 +532,12 @@ nest::aeif_psc_alpha::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -549,7 +550,7 @@ nest::aeif_psc_alpha::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/aeif_psc_alpha.h b/models/aeif_psc_alpha.h index 96149eefb6..e6330969f4 100644 --- a/models/aeif_psc_alpha.h +++ b/models/aeif_psc_alpha.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest diff --git a/models/aeif_psc_delta.cpp b/models/aeif_psc_delta.cpp index 7cafe3ad64..70badbea7a 100644 --- a/models/aeif_psc_delta.cpp +++ b/models/aeif_psc_delta.cpp @@ -36,6 +36,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "nest_names.h" @@ -502,7 +503,7 @@ nest::aeif_psc_delta::update( const Time& origin, const long from, const long to set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -524,8 +525,8 @@ nest::aeif_psc_delta::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -537,7 +538,7 @@ nest::aeif_psc_delta::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/aeif_psc_delta.h b/models/aeif_psc_delta.h index b055e1db95..940c18b5b2 100644 --- a/models/aeif_psc_delta.h +++ b/models/aeif_psc_delta.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest diff --git a/models/aeif_psc_delta_clopath.cpp b/models/aeif_psc_delta_clopath.cpp index c45158ee77..ee48874486 100644 --- a/models/aeif_psc_delta_clopath.cpp +++ b/models/aeif_psc_delta_clopath.cpp @@ -36,6 +36,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "nest_names.h" @@ -550,7 +551,7 @@ nest::aeif_psc_delta_clopath::update( const Time& origin, const long from, const set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } else if ( S_.clamp_r_ == 1 ) { @@ -603,8 +604,8 @@ nest::aeif_psc_delta_clopath::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -616,7 +617,7 @@ nest::aeif_psc_delta_clopath::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/aeif_psc_delta_clopath.h b/models/aeif_psc_delta_clopath.h index 505ccb6da0..8a0e84ef8c 100644 --- a/models/aeif_psc_delta_clopath.h +++ b/models/aeif_psc_delta_clopath.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest diff --git a/models/aeif_psc_exp.cpp b/models/aeif_psc_exp.cpp index 6b8aec869c..166b3ecab5 100644 --- a/models/aeif_psc_exp.cpp +++ b/models/aeif_psc_exp.cpp @@ -36,6 +36,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "nest_names.h" @@ -492,7 +493,7 @@ nest::aeif_psc_exp::update( const Time& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -520,12 +521,12 @@ nest::aeif_psc_exp::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -538,7 +539,7 @@ nest::aeif_psc_exp::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/aeif_psc_exp.h b/models/aeif_psc_exp.h index 540d6db015..fcb04a318b 100644 --- a/models/aeif_psc_exp.h +++ b/models/aeif_psc_exp.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest diff --git a/models/amat2_psc_exp.cpp b/models/amat2_psc_exp.cpp index 06bce3bd22..a115de568f 100644 --- a/models/amat2_psc_exp.cpp +++ b/models/amat2_psc_exp.cpp @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -408,7 +409,7 @@ nest::amat2_psc_exp::update( Time const& origin, const long from, const long to set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } else @@ -433,12 +434,12 @@ nest::amat2_psc_exp::handle( SpikeEvent& e ) if ( e.get_weight() >= 0.0 ) { - B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spikes_in_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spikes_in_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } } @@ -452,7 +453,7 @@ nest::amat2_psc_exp::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/amat2_psc_exp.h b/models/amat2_psc_exp.h index 3a7b0deecf..ef57d6c6b5 100644 --- a/models/amat2_psc_exp.h +++ b/models/amat2_psc_exp.h @@ -31,7 +31,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/astrocyte_lr_1994.cpp b/models/astrocyte_lr_1994.cpp index cd32bf5bc5..bcb5829064 100644 --- a/models/astrocyte_lr_1994.cpp +++ b/models/astrocyte_lr_1994.cpp @@ -36,6 +36,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -371,7 +372,7 @@ nest::astrocyte_lr_1994::init_buffers_() B_.spike_exc_.clear(); // includes resize B_.currents_.clear(); B_.sic_values.resize( - kernel().connection_manager.get_min_delay(), 0.0 ); // set size of SIC buffer according to min_delay + kernel::manager< ConnectionManager >.get_min_delay(), 0.0 ); // set size of SIC buffer according to min_delay B_.logger_.reset(); @@ -487,7 +488,7 @@ nest::astrocyte_lr_1994::update( Time const& origin, const long from, const long // send SIC event SICEvent sic; sic.set_coeffarray( B_.sic_values ); - kernel().event_delivery_manager.send_secondary( *this, sic ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, sic ); } void @@ -497,7 +498,7 @@ nest::astrocyte_lr_1994::handle( SpikeEvent& e ) if ( e.get_weight() >= 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else @@ -514,7 +515,7 @@ nest::astrocyte_lr_1994::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/astrocyte_lr_1994.h b/models/astrocyte_lr_1994.h index 8262f7c679..4e9768a15a 100644 --- a/models/astrocyte_lr_1994.h +++ b/models/astrocyte_lr_1994.h @@ -41,7 +41,7 @@ #include "node.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/bernoulli_synapse.cpp b/models/bernoulli_synapse.cpp index 95174cf2ef..06f354f196 100644 --- a/models/bernoulli_synapse.cpp +++ b/models/bernoulli_synapse.cpp @@ -22,9 +22,6 @@ #include "bernoulli_synapse.h" -// Includes from nestkernel: -#include "nest_impl.h" - void nest::register_bernoulli_synapse( const std::string& name ) { diff --git a/models/bernoulli_synapse.h b/models/bernoulli_synapse.h index 78a6faa963..741b2c05cd 100644 --- a/models/bernoulli_synapse.h +++ b/models/bernoulli_synapse.h @@ -28,6 +28,8 @@ #include "connection.h" #include "kernel_manager.h" +#include "nest_impl.h" + namespace nest { diff --git a/models/binary_neuron.h b/models/binary_neuron.h index d3854d650e..e920dba514 100644 --- a/models/binary_neuron.h +++ b/models/binary_neuron.h @@ -23,33 +23,27 @@ #ifndef BINARY_NEURON_H #define BINARY_NEURON_H -// C++ includes: -#include -#include - // Includes from libnestutil: #include "dict_util.h" -#include "numerics.h" // Includes from nestkernel: #include "archiving_node.h" #include "connection.h" #include "event.h" -#include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "nest_impl.h" #include "nest_timeconverter.h" #include "nest_types.h" #include "random_generators.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" // Includes from sli: #include "dict.h" #include "dictutils.h" -#include "doubledatum.h" -#include "integerdatum.h" namespace nest { @@ -481,7 +475,7 @@ binary_neuron< TGainfunction >::update( Time const& origin, const long from, con // use multiplicity 2 to signal transition to 1 state // use multiplicity 1 to signal transition to 0 state se.set_multiplicity( new_y ? 2 : 1 ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); // As multiplicity is used only to signal internal information // to other binary neurons, we only set spiketime once, independent @@ -537,20 +531,21 @@ binary_neuron< TGainfunction >::handle( SpikeEvent& e ) // received twice the same node ID, so transition 0->1 // take double weight to compensate for subtracting first event B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), 2.0 * e.get_weight() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), 2.0 * e.get_weight() ); } else { // count this event negatively, assuming it comes as single event // transition 1->0 B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), -e.get_weight() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() ); } } else if ( m == 2 ) { // count this event positively, transition 0->1 - B_.spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() ); + B_.spikes_.add_value( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() ); } S_.last_in_node_id_ = node_id; @@ -569,7 +564,7 @@ binary_neuron< TGainfunction >::handle( CurrentEvent& e ) // we use the spike buffer to receive the binary events // but also to handle the incoming current events added // both contributions are directly added to the variable h - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } diff --git a/models/clopath_synapse.cpp b/models/clopath_synapse.cpp index 73a2cbd1fc..07af3f894d 100644 --- a/models/clopath_synapse.cpp +++ b/models/clopath_synapse.cpp @@ -22,9 +22,6 @@ #include "clopath_synapse.h" -// Includes from nestkernel: -#include "nest_impl.h" - void nest::register_clopath_synapse( const std::string& name ) { diff --git a/models/clopath_synapse.h b/models/clopath_synapse.h index 331907f0b2..f3b101bb1e 100644 --- a/models/clopath_synapse.h +++ b/models/clopath_synapse.h @@ -31,7 +31,7 @@ #include "connection.h" #include "connector_model.h" #include "event.h" -#include "nest.h" +#include "nest_impl.h" #include "ring_buffer.h" // Includes from sli: diff --git a/models/cm_compartmentcurrents.h b/models/cm_compartmentcurrents.h index 87135ffe07..8153f1b290 100644 --- a/models/cm_compartmentcurrents.h +++ b/models/cm_compartmentcurrents.h @@ -24,6 +24,8 @@ #include +#include "logging.h" +#include "logging_manager.h" #include "ring_buffer.h" namespace nest diff --git a/models/cm_default.cpp b/models/cm_default.cpp index 37b714929b..c7137b77d2 100644 --- a/models/cm_default.cpp +++ b/models/cm_default.cpp @@ -22,9 +22,6 @@ #include "cm_default.h" -// Includes from nestkernel: -#include "nest_impl.h" - namespace nest { void @@ -334,7 +331,7 @@ nest::cm_default::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } logger_.record_data( origin.get_steps() + lag ); @@ -353,7 +350,8 @@ nest::cm_default::handle( SpikeEvent& e ) assert( e.get_rport() < syn_buffers_.size() ); syn_buffers_[ e.get_rport() ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -365,7 +363,8 @@ nest::cm_default::handle( CurrentEvent& e ) const double w = e.get_weight(); Compartment* compartment = c_tree_.get_compartment_opt( e.get_rport() ); - compartment->currents.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + compartment->currents.add_value( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/cm_default.h b/models/cm_default.h index d65544cb04..d3aed107bf 100644 --- a/models/cm_default.h +++ b/models/cm_default.h @@ -27,7 +27,7 @@ #include "archiving_node.h" #include "event.h" #include "nest_types.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" #include "cm_compartmentcurrents.h" #include "cm_tree.h" diff --git a/models/cm_tree.cpp b/models/cm_tree.cpp index 52121ca2fe..dc85163687 100644 --- a/models/cm_tree.cpp +++ b/models/cm_tree.cpp @@ -21,6 +21,9 @@ */ #include "cm_tree.h" +#include "logging.h" +#include "logging_manager.h" + nest::Compartment::Compartment( const long compartment_index, const long parent_index ) : xx_( 0.0 ) diff --git a/models/cm_tree.h b/models/cm_tree.h index 6f5898729e..2529df6942 100644 --- a/models/cm_tree.h +++ b/models/cm_tree.h @@ -37,7 +37,9 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "nest_impl.h" #include "universal_data_logger_impl.h" // Includes from sli: diff --git a/models/cont_delay_synapse.cpp b/models/cont_delay_synapse.cpp index a0a3e7afb7..253d05316f 100644 --- a/models/cont_delay_synapse.cpp +++ b/models/cont_delay_synapse.cpp @@ -21,9 +21,7 @@ */ #include "cont_delay_synapse.h" -#include "cont_delay_synapse_impl.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/cont_delay_synapse.h b/models/cont_delay_synapse.h index a5759c2622..0aaa4ef39a 100644 --- a/models/cont_delay_synapse.h +++ b/models/cont_delay_synapse.h @@ -29,6 +29,11 @@ // Includes from nestkernel: #include "connection.h" +#include "logging_manager.h" + +#include "connection_manager.h" +#include "delay_checker.h" +#include "logging.h" namespace nest { @@ -248,6 +253,75 @@ cont_delay_synapse< targetidentifierT >::send( Event& e, size_t t, const CommonS template < typename targetidentifierT > constexpr ConnectionModelProperties cont_delay_synapse< targetidentifierT >::properties; +template < typename targetidentifierT > +cont_delay_synapse< targetidentifierT >::cont_delay_synapse() + : ConnectionBase() + , weight_( 1.0 ) + , delay_offset_( 0.0 ) +{ +} + +template < typename targetidentifierT > +void +cont_delay_synapse< targetidentifierT >::get_status( DictionaryDatum& d ) const +{ + ConnectionBase::get_status( d ); + + def< double >( d, names::weight, weight_ ); + def< double >( d, names::delay, Time( Time::step( get_delay_steps() ) ).get_ms() - delay_offset_ ); + def< long >( d, names::size_of, sizeof( *this ) ); +} + +template < typename targetidentifierT > +void +cont_delay_synapse< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) +{ + ConnectionBase::set_status( d, cm ); + + updateValue< double >( d, names::weight, weight_ ); + + // set delay if mentioned + double delay; + + if ( updateValue< double >( d, names::delay, delay ) ) + { + + const double h = Time::get_resolution().get_ms(); + + double int_delay; + const double frac_delay = std::modf( delay / h, &int_delay ); + + if ( frac_delay == 0 ) + { + kernel::manager< ConnectionManager >.get_delay_checker().assert_valid_delay_ms( delay ); + set_delay_steps( Time::delay_ms_to_steps( delay ) ); + delay_offset_ = 0.0; + } + else + { + const long lowerbound = static_cast< long >( int_delay ); + kernel::manager< ConnectionManager >.get_delay_checker().assert_two_valid_delays_steps( + lowerbound, lowerbound + 1 ); + set_delay_steps( lowerbound + 1 ); + delay_offset_ = h * ( 1.0 - frac_delay ); + } + } +} + +template < typename targetidentifierT > +void +cont_delay_synapse< targetidentifierT >::check_synapse_params( const DictionaryDatum& syn_spec ) const +{ + if ( syn_spec->known( names::delay ) ) + { + LOG( M_WARNING, + "Connect", + "The delay will be rounded to the next multiple of the time step. " + "To use a more precise time delay it needs to be defined within " + "the synapse, e.g. with CopyModel()." ); + } +} + } // of namespace nest #endif // of #ifndef CONT_DELAY_SYNAPSE_H diff --git a/models/cont_delay_synapse_impl.h b/models/cont_delay_synapse_impl.h deleted file mode 100644 index 4a029b82a8..0000000000 --- a/models/cont_delay_synapse_impl.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * cont_delay_synapse_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - */ - -#ifndef CONT_DELAY_SYNAPSE_IMPL_H -#define CONT_DELAY_SYNAPSE_IMPL_H - -#include "cont_delay_synapse.h" - -// Includes from nestkernel: -#include "common_synapse_properties.h" -#include "connector_model.h" -#include "event.h" - -// Includes from sli: -#include "dictdatum.h" - -namespace nest -{ - -template < typename targetidentifierT > -cont_delay_synapse< targetidentifierT >::cont_delay_synapse() - : ConnectionBase() - , weight_( 1.0 ) - , delay_offset_( 0.0 ) -{ -} - -template < typename targetidentifierT > -void -cont_delay_synapse< targetidentifierT >::get_status( DictionaryDatum& d ) const -{ - ConnectionBase::get_status( d ); - - def< double >( d, names::weight, weight_ ); - def< double >( d, names::delay, Time( Time::step( get_delay_steps() ) ).get_ms() - delay_offset_ ); - def< long >( d, names::size_of, sizeof( *this ) ); -} - -template < typename targetidentifierT > -void -cont_delay_synapse< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) -{ - ConnectionBase::set_status( d, cm ); - - updateValue< double >( d, names::weight, weight_ ); - - // set delay if mentioned - double delay; - - if ( updateValue< double >( d, names::delay, delay ) ) - { - - const double h = Time::get_resolution().get_ms(); - - double int_delay; - const double frac_delay = std::modf( delay / h, &int_delay ); - - if ( frac_delay == 0 ) - { - kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( delay ); - set_delay_steps( Time::delay_ms_to_steps( delay ) ); - delay_offset_ = 0.0; - } - else - { - const long lowerbound = static_cast< long >( int_delay ); - kernel().connection_manager.get_delay_checker().assert_two_valid_delays_steps( lowerbound, lowerbound + 1 ); - set_delay_steps( lowerbound + 1 ); - delay_offset_ = h * ( 1.0 - frac_delay ); - } - } -} - -template < typename targetidentifierT > -void -cont_delay_synapse< targetidentifierT >::check_synapse_params( const DictionaryDatum& syn_spec ) const -{ - if ( syn_spec->known( names::delay ) ) - { - LOG( M_WARNING, - "Connect", - "The delay will be rounded to the next multiple of the time step. " - "To use a more precise time delay it needs to be defined within " - "the synapse, e.g. with CopyModel()." ); - } -} - -} // of namespace nest - -#endif // #ifndef CONT_DELAY_SYNAPSE_IMPL_H diff --git a/models/correlation_detector.cpp b/models/correlation_detector.cpp index 3d7b09b8ae..a629faa79f 100644 --- a/models/correlation_detector.cpp +++ b/models/correlation_detector.cpp @@ -29,16 +29,15 @@ // Includes from libnestutil: #include "compose.hpp" #include "dict_util.h" +#include "genericmodel_impl.h" #include "logging.h" - -// Includes from nestkernel: -#include "model_manager_impl.h" #include "nest_impl.h" // Includes from sli: #include "arraydatum.h" #include "dict.h" #include "dictutils.h" +#include "nest_timeconverter.h" void nest::register_correlation_detector( const std::string& name ) diff --git a/models/correlation_detector.h b/models/correlation_detector.h index 4e1318853b..8e0341b193 100644 --- a/models/correlation_detector.h +++ b/models/correlation_detector.h @@ -30,11 +30,11 @@ // Includes from nestkernel: #include "event.h" -#include "nest_timeconverter.h" -#include "nest_types.h" #include "node.h" #include "pseudo_recording_device.h" +#include "nest_names.h" + namespace nest { diff --git a/models/correlomatrix_detector.cpp b/models/correlomatrix_detector.cpp index 607009eedf..d20104cfe8 100644 --- a/models/correlomatrix_detector.cpp +++ b/models/correlomatrix_detector.cpp @@ -32,14 +32,16 @@ #include "logging.h" // Includes from nestkernel: +#include "connection_manager.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" -#include "model_manager_impl.h" #include "nest_impl.h" // Includes from sli: #include "arraydatum.h" #include "dict.h" #include "dictutils.h" +#include "nest_timeconverter.h" void nest::register_correlomatrix_detector( const std::string& name ) @@ -228,11 +230,11 @@ nest::correlomatrix_detector::State_::reset( const Parameters_& p ) count_covariance_.clear(); count_covariance_.resize( p.N_channels_ ); - for ( auto i = 0; i < p.N_channels_; ++i ) + for ( size_t i = 0; i < p.N_channels_; ++i ) { covariance_[ i ].resize( p.N_channels_ ); count_covariance_[ i ].resize( p.N_channels_ ); - for ( auto j = 0; j < p.N_channels_; ++j ) + for ( size_t j = 0; j < p.N_channels_; ++j ) { covariance_[ i ][ j ].resize( 1 + p.tau_max_.get_steps() / p.delta_tau_.get_steps(), 0 ); count_covariance_[ i ][ j ].resize( 1 + p.tau_max_.get_steps() / p.delta_tau_.get_steps(), 0 ); @@ -327,7 +329,7 @@ nest::correlomatrix_detector::handle( SpikeEvent& e ) // throw away all spikes which are too old to // enter the correlation window - const long min_delay = kernel().connection_manager.get_min_delay(); + const long min_delay = kernel::manager< ConnectionManager >.get_min_delay(); while ( not otherSpikes.empty() and ( spike_i - otherSpikes.front().timestep_ ) >= tau_edge + min_delay ) { otherSpikes.pop_front(); diff --git a/models/correlomatrix_detector.h b/models/correlomatrix_detector.h index ef3fbb0506..e37c66ac11 100644 --- a/models/correlomatrix_detector.h +++ b/models/correlomatrix_detector.h @@ -30,11 +30,11 @@ // Includes from nestkernel: #include "event.h" -#include "nest_timeconverter.h" -#include "nest_types.h" #include "node.h" #include "pseudo_recording_device.h" +#include "nest_names.h" + namespace nest { @@ -211,9 +211,9 @@ class correlomatrix_detector : public Node { long timestep_; double weight_; - long receptor_channel_; + size_t receptor_channel_; - Spike_( long timestep, double weight, long receptorchannel ) + Spike_( long timestep, double weight, size_t receptorchannel ) : timestep_( timestep ) , weight_( weight ) , receptor_channel_( receptorchannel ) diff --git a/models/correlospinmatrix_detector.cpp b/models/correlospinmatrix_detector.cpp index e68656ceb1..bc384d5720 100644 --- a/models/correlospinmatrix_detector.cpp +++ b/models/correlospinmatrix_detector.cpp @@ -29,17 +29,19 @@ // Includes from libnestutil: #include "compose.hpp" #include "dict_util.h" +#include "genericmodel_impl.h" #include "logging.h" // Includes from nestkernel: +#include "connection_manager.h" #include "kernel_manager.h" -#include "model_manager_impl.h" #include "nest_impl.h" // Includes from sli: #include "arraydatum.h" #include "dict.h" #include "dictutils.h" +#include "nest_timeconverter.h" void nest::register_correlospinmatrix_detector( const std::string& name ) @@ -392,7 +394,7 @@ nest::correlospinmatrix_detector::handle( SpikeEvent& e ) // yet every impulse in the queue that is further in the past than // this minimum - tau_max cannot contribute to the count covariance long t_min_on = t_i_on; - for ( auto n = 0; n < P_.N_channels_; n++ ) + for ( size_t n = 0; n < P_.N_channels_; n++ ) { if ( S_.curr_state_[ n ] ) { @@ -404,7 +406,7 @@ nest::correlospinmatrix_detector::handle( SpikeEvent& e ) } const double tau_edge = P_.tau_max_.get_steps() + P_.delta_tau_.get_steps(); - const long min_delay = kernel().connection_manager.get_min_delay(); + const long min_delay = kernel::manager< ConnectionManager >.get_min_delay(); while ( not otherPulses.empty() and ( t_min_on - otherPulses.front().t_off_ ) >= tau_edge + min_delay ) { otherPulses.pop_front(); diff --git a/models/correlospinmatrix_detector.h b/models/correlospinmatrix_detector.h index 7087454df4..461e6094a0 100644 --- a/models/correlospinmatrix_detector.h +++ b/models/correlospinmatrix_detector.h @@ -30,11 +30,12 @@ // Includes from nestkernel: #include "event.h" -#include "nest_timeconverter.h" #include "nest_types.h" #include "node.h" #include "pseudo_recording_device.h" +#include "nest_names.h" + namespace nest { diff --git a/models/dc_generator.cpp b/models/dc_generator.cpp index 7c5389914f..4cef8560f3 100644 --- a/models/dc_generator.cpp +++ b/models/dc_generator.cpp @@ -24,6 +24,8 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -178,7 +180,7 @@ nest::dc_generator::update( Time const& origin, const long from, const long to ) if ( StimulationDevice::is_active( Time::step( start + offs ) ) ) { S_.I_ = P_.amp_; - kernel().event_delivery_manager.send( *this, ce, offs ); + kernel::manager< EventDeliveryManager >.send( *this, ce, offs ); } B_.logger_.record_data( origin.get_steps() + offs ); } diff --git a/models/dc_generator.h b/models/dc_generator.h index dd8bafabd7..895c6c88a3 100644 --- a/models/dc_generator.h +++ b/models/dc_generator.h @@ -34,7 +34,7 @@ #include "nest_types.h" #include "ring_buffer.h" #include "stimulation_device.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/diffusion_connection.cpp b/models/diffusion_connection.cpp index bd23f5dfe1..ec934b6e85 100644 --- a/models/diffusion_connection.cpp +++ b/models/diffusion_connection.cpp @@ -22,7 +22,6 @@ #include "diffusion_connection.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/eprop_iaf.cpp b/models/eprop_iaf.cpp index fb336a40f4..b362fa51e2 100644 --- a/models/eprop_iaf.cpp +++ b/models/eprop_iaf.cpp @@ -31,11 +31,12 @@ #include "numerics.h" // nestkernel +#include "eprop_archiving_node_readout_impl.h" #include "eprop_archiving_node_recurrent_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // sli #include "dictutils.h" @@ -309,7 +310,7 @@ eprop_iaf::update( Time const& origin, const long from, const long to ) if ( S_.v_m_ >= P_.V_th_ and S_.r_ == 0 ) { SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); S_.z_ = 1.0; S_.v_m_ -= P_.V_th_ * S_.z_; @@ -337,8 +338,8 @@ eprop_iaf::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -346,8 +347,8 @@ eprop_iaf::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/eprop_iaf.h b/models/eprop_iaf.h index 225de65333..85911958b8 100644 --- a/models/eprop_iaf.h +++ b/models/eprop_iaf.h @@ -25,13 +25,12 @@ // nestkernel #include "connection.h" -#include "eprop_archiving_node_impl.h" #include "eprop_archiving_node_recurrent.h" #include "eprop_synapse.h" #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/eprop_iaf_adapt.cpp b/models/eprop_iaf_adapt.cpp index 10cb9ff224..1b5b3a0919 100644 --- a/models/eprop_iaf_adapt.cpp +++ b/models/eprop_iaf_adapt.cpp @@ -31,11 +31,12 @@ #include "numerics.h" // nestkernel +#include "eprop_archiving_node_readout_impl.h" #include "eprop_archiving_node_recurrent_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // sli #include "dictutils.h" @@ -348,7 +349,7 @@ eprop_iaf_adapt::update( Time const& origin, const long from, const long to ) if ( S_.v_m_ >= S_.v_th_adapt_ and S_.r_ == 0 ) { SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); S_.z_ = 1.0; S_.v_m_ -= P_.V_th_ * S_.z_; @@ -376,8 +377,8 @@ eprop_iaf_adapt::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -385,8 +386,8 @@ eprop_iaf_adapt::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/eprop_iaf_adapt.h b/models/eprop_iaf_adapt.h index d404dcbd69..6d41e18d94 100644 --- a/models/eprop_iaf_adapt.h +++ b/models/eprop_iaf_adapt.h @@ -25,13 +25,12 @@ // nestkernel #include "connection.h" -#include "eprop_archiving_node_impl.h" #include "eprop_archiving_node_recurrent.h" #include "eprop_synapse.h" #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/eprop_iaf_adapt_bsshslm_2020.cpp b/models/eprop_iaf_adapt_bsshslm_2020.cpp index f37f2203a0..7845937194 100644 --- a/models/eprop_iaf_adapt_bsshslm_2020.cpp +++ b/models/eprop_iaf_adapt_bsshslm_2020.cpp @@ -32,10 +32,11 @@ // nestkernel #include "eprop_archiving_node_recurrent_impl.h" +#include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // sli #include "dictutils.h" @@ -302,8 +303,8 @@ eprop_iaf_adapt_bsshslm_2020::pre_run_hook() void eprop_iaf_adapt_bsshslm_2020::update( Time const& origin, const long from, const long to ) { - const long update_interval = kernel().simulation_manager.get_eprop_update_interval().get_steps(); - const bool with_reset = kernel().simulation_manager.get_eprop_reset_neurons_on_update(); + const long update_interval = kernel::manager< SimulationManager >.get_eprop_update_interval().get_steps(); + const bool with_reset = kernel::manager< SimulationManager >.get_eprop_reset_neurons_on_update(); const long shift = get_shift(); for ( long lag = from; lag < to; ++lag ) @@ -349,7 +350,7 @@ eprop_iaf_adapt_bsshslm_2020::update( Time const& origin, const long from, const count_spike(); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); S_.z_ = 1.0; S_.r_ = V_.RefractoryCounts_; @@ -381,8 +382,8 @@ eprop_iaf_adapt_bsshslm_2020::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -390,8 +391,8 @@ eprop_iaf_adapt_bsshslm_2020::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void @@ -457,8 +458,8 @@ eprop_iaf_adapt_bsshslm_2020::compute_gradient( std::vector< long >& presyn_isis } presyn_isis.clear(); - const long update_interval = kernel().simulation_manager.get_eprop_update_interval().get_steps(); - const long learning_window = kernel().simulation_manager.get_eprop_learning_window().get_steps(); + const long update_interval = kernel::manager< SimulationManager >.get_eprop_update_interval().get_steps(); + const long learning_window = kernel::manager< SimulationManager >.get_eprop_learning_window().get_steps(); const auto firing_rate_reg = get_firing_rate_reg_history( t_previous_update + get_shift() + update_interval ); grad += firing_rate_reg * sum_e; diff --git a/models/eprop_iaf_adapt_bsshslm_2020.h b/models/eprop_iaf_adapt_bsshslm_2020.h index f8d8009ba2..eb37991022 100644 --- a/models/eprop_iaf_adapt_bsshslm_2020.h +++ b/models/eprop_iaf_adapt_bsshslm_2020.h @@ -25,12 +25,11 @@ // nestkernel #include "connection.h" -#include "eprop_archiving_node_impl.h" #include "eprop_archiving_node_recurrent.h" #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/eprop_iaf_bsshslm_2020.cpp b/models/eprop_iaf_bsshslm_2020.cpp index a4c52557ff..d886ec29c9 100644 --- a/models/eprop_iaf_bsshslm_2020.cpp +++ b/models/eprop_iaf_bsshslm_2020.cpp @@ -32,10 +32,11 @@ // nestkernel #include "eprop_archiving_node_recurrent_impl.h" +#include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // sli #include "dictutils.h" @@ -267,8 +268,8 @@ eprop_iaf_bsshslm_2020::pre_run_hook() void eprop_iaf_bsshslm_2020::update( Time const& origin, const long from, const long to ) { - const long update_interval = kernel().simulation_manager.get_eprop_update_interval().get_steps(); - const bool with_reset = kernel().simulation_manager.get_eprop_reset_neurons_on_update(); + const long update_interval = kernel::manager< SimulationManager >.get_eprop_update_interval().get_steps(); + const bool with_reset = kernel::manager< SimulationManager >.get_eprop_reset_neurons_on_update(); const long shift = get_shift(); for ( long lag = from; lag < to; ++lag ) @@ -309,7 +310,7 @@ eprop_iaf_bsshslm_2020::update( Time const& origin, const long from, const long count_spike(); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); S_.z_ = 1.0; S_.r_ = V_.RefractoryCounts_; @@ -341,8 +342,8 @@ eprop_iaf_bsshslm_2020::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -350,8 +351,8 @@ eprop_iaf_bsshslm_2020::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void @@ -415,8 +416,8 @@ eprop_iaf_bsshslm_2020::compute_gradient( std::vector< long >& presyn_isis, } presyn_isis.clear(); - const long update_interval = kernel().simulation_manager.get_eprop_update_interval().get_steps(); - const long learning_window = kernel().simulation_manager.get_eprop_learning_window().get_steps(); + const long update_interval = kernel::manager< SimulationManager >.get_eprop_update_interval().get_steps(); + const long learning_window = kernel::manager< SimulationManager >.get_eprop_learning_window().get_steps(); const auto firing_rate_reg = get_firing_rate_reg_history( t_previous_update + get_shift() + update_interval ); grad += firing_rate_reg * sum_e; diff --git a/models/eprop_iaf_bsshslm_2020.h b/models/eprop_iaf_bsshslm_2020.h index 34cc9a575d..5fa2414397 100644 --- a/models/eprop_iaf_bsshslm_2020.h +++ b/models/eprop_iaf_bsshslm_2020.h @@ -25,12 +25,11 @@ // nestkernel #include "connection.h" -#include "eprop_archiving_node_impl.h" #include "eprop_archiving_node_recurrent.h" #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/eprop_iaf_psc_delta.cpp b/models/eprop_iaf_psc_delta.cpp index a8b13ac4e4..4ace66ca65 100644 --- a/models/eprop_iaf_psc_delta.cpp +++ b/models/eprop_iaf_psc_delta.cpp @@ -31,11 +31,12 @@ #include "numerics.h" // nestkernel +#include "eprop_archiving_node_readout_impl.h" #include "eprop_archiving_node_recurrent_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // sli #include "dictutils.h" @@ -344,7 +345,7 @@ eprop_iaf_psc_delta::update( Time const& origin, const long from, const long to S_.v_m_ = P_.V_reset_; SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); z = 1.0; } @@ -370,8 +371,8 @@ eprop_iaf_psc_delta::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -379,8 +380,8 @@ eprop_iaf_psc_delta::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/eprop_iaf_psc_delta.h b/models/eprop_iaf_psc_delta.h index c36066a984..ed579e3ff1 100644 --- a/models/eprop_iaf_psc_delta.h +++ b/models/eprop_iaf_psc_delta.h @@ -25,13 +25,12 @@ // nestkernel #include "connection.h" -#include "eprop_archiving_node_impl.h" #include "eprop_archiving_node_recurrent.h" #include "eprop_synapse.h" #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/eprop_iaf_psc_delta_adapt.cpp b/models/eprop_iaf_psc_delta_adapt.cpp index 9ffe2a8b69..48b4d2600f 100644 --- a/models/eprop_iaf_psc_delta_adapt.cpp +++ b/models/eprop_iaf_psc_delta_adapt.cpp @@ -31,11 +31,12 @@ #include "numerics.h" // nestkernel +#include "eprop_archiving_node_readout_impl.h" #include "eprop_archiving_node_recurrent_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // sli #include "dictutils.h" @@ -383,7 +384,7 @@ eprop_iaf_psc_delta_adapt::update( Time const& origin, const long from, const lo S_.v_m_ = P_.V_reset_; SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); S_.z_ = 1.0; } @@ -409,8 +410,8 @@ eprop_iaf_psc_delta_adapt::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -418,8 +419,8 @@ eprop_iaf_psc_delta_adapt::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/eprop_iaf_psc_delta_adapt.h b/models/eprop_iaf_psc_delta_adapt.h index 3c0949de3a..1d8acec73b 100644 --- a/models/eprop_iaf_psc_delta_adapt.h +++ b/models/eprop_iaf_psc_delta_adapt.h @@ -25,13 +25,12 @@ // nestkernel #include "connection.h" -#include "eprop_archiving_node_impl.h" #include "eprop_archiving_node_recurrent.h" #include "eprop_synapse.h" #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/eprop_learning_signal_connection.cpp b/models/eprop_learning_signal_connection.cpp index 7e537ed5c0..337977a1bb 100644 --- a/models/eprop_learning_signal_connection.cpp +++ b/models/eprop_learning_signal_connection.cpp @@ -22,9 +22,10 @@ #include "eprop_learning_signal_connection.h" -// nestkernel #include "nest_impl.h" +// nestkernel + void nest::register_eprop_learning_signal_connection( const std::string& name ) { diff --git a/models/eprop_learning_signal_connection_bsshslm_2020.cpp b/models/eprop_learning_signal_connection_bsshslm_2020.cpp index fe29c2a84c..c4dfc80af9 100644 --- a/models/eprop_learning_signal_connection_bsshslm_2020.cpp +++ b/models/eprop_learning_signal_connection_bsshslm_2020.cpp @@ -22,9 +22,10 @@ #include "eprop_learning_signal_connection_bsshslm_2020.h" -// nestkernel #include "nest_impl.h" +// nestkernel + void nest::register_eprop_learning_signal_connection_bsshslm_2020( const std::string& name ) { diff --git a/models/eprop_readout.cpp b/models/eprop_readout.cpp index b2f740d70e..72d043061f 100644 --- a/models/eprop_readout.cpp +++ b/models/eprop_readout.cpp @@ -31,10 +31,12 @@ #include "numerics.h" // nestkernel +#include "eprop_archiving_node_readout_impl.h" +#include "eprop_archiving_node_recurrent_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // sli #include "dictutils.h" @@ -217,7 +219,7 @@ eprop_readout::pre_run_hook() void eprop_readout::update( Time const& origin, const long from, const long to ) { - const size_t buffer_size = kernel().connection_manager.get_min_delay(); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); std::vector< double > error_signal_buffer( buffer_size, 0.0 ); @@ -249,7 +251,7 @@ eprop_readout::update( Time const& origin, const long from, const long to ) LearningSignalConnectionEvent error_signal_event; error_signal_event.set_coeffarray( error_signal_buffer ); - kernel().event_delivery_manager.send_secondary( *this, error_signal_event ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, error_signal_event ); return; } @@ -285,8 +287,8 @@ eprop_readout::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -294,8 +296,8 @@ eprop_readout::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/eprop_readout.h b/models/eprop_readout.h index b96c007542..ea748bb0ad 100644 --- a/models/eprop_readout.h +++ b/models/eprop_readout.h @@ -25,13 +25,14 @@ // nestkernel #include "connection.h" -#include "eprop_archiving_node_impl.h" #include "eprop_archiving_node_readout.h" #include "eprop_synapse.h" #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" + +#include namespace nest { @@ -518,7 +519,7 @@ eprop_readout::handles_test_event( CurrentEvent&, size_t receptor_type ) inline size_t eprop_readout::handles_test_event( DelayedRateConnectionEvent& e, size_t receptor_type ) { - size_t step_rate_model_id = kernel().model_manager.get_node_model_id( "step_rate_generator" ); + size_t step_rate_model_id = kernel::manager< ModelManager >.get_node_model_id( "step_rate_generator" ); size_t model_id = e.get_sender().get_model_id(); if ( step_rate_model_id == model_id and receptor_type != TARGET_SIG and receptor_type != LEARNING_WINDOW_SIG ) diff --git a/models/eprop_readout_bsshslm_2020.cpp b/models/eprop_readout_bsshslm_2020.cpp index 79f059fb59..de3015a0bc 100644 --- a/models/eprop_readout_bsshslm_2020.cpp +++ b/models/eprop_readout_bsshslm_2020.cpp @@ -31,10 +31,12 @@ #include "numerics.h" // nestkernel +#include "eprop_archiving_node_readout_impl.h" +#include "eprop_archiving_node_recurrent_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // sli #include "dictutils.h" @@ -233,12 +235,12 @@ eprop_readout_bsshslm_2020::pre_run_hook() void eprop_readout_bsshslm_2020::update( Time const& origin, const long from, const long to ) { - const long update_interval = kernel().simulation_manager.get_eprop_update_interval().get_steps(); - const long learning_window = kernel().simulation_manager.get_eprop_learning_window().get_steps(); - const bool with_reset = kernel().simulation_manager.get_eprop_reset_neurons_on_update(); + const long update_interval = kernel::manager< SimulationManager >.get_eprop_update_interval().get_steps(); + const long learning_window = kernel::manager< SimulationManager >.get_eprop_learning_window().get_steps(); + const bool with_reset = kernel::manager< SimulationManager >.get_eprop_reset_neurons_on_update(); const long shift = get_shift(); - const size_t buffer_size = kernel().connection_manager.get_min_delay(); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); std::vector< double > error_signal_buffer( buffer_size, 0.0 ); std::vector< double > readout_signal_unnorm_buffer( buffer_size, 0.0 ); @@ -292,7 +294,7 @@ eprop_readout_bsshslm_2020::update( Time const& origin, const long from, const l LearningSignalConnectionEvent error_signal_event; error_signal_event.set_coeffarray( error_signal_buffer ); - kernel().event_delivery_manager.send_secondary( *this, error_signal_event ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, error_signal_event ); if ( V_.signal_to_other_readouts_ ) { @@ -301,7 +303,7 @@ eprop_readout_bsshslm_2020::update( Time const& origin, const long from, const l // in the next times step for computing the normalized readout signal DelayedRateConnectionEvent readout_signal_unnorm_event; readout_signal_unnorm_event.set_coeffarray( readout_signal_unnorm_buffer ); - kernel().event_delivery_manager.send_secondary( *this, readout_signal_unnorm_event ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, readout_signal_unnorm_event ); } return; } @@ -358,8 +360,8 @@ eprop_readout_bsshslm_2020::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -367,8 +369,8 @@ eprop_readout_bsshslm_2020::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void @@ -410,7 +412,7 @@ eprop_readout_bsshslm_2020::compute_gradient( std::vector< long >& presyn_isis, } presyn_isis.clear(); - const long learning_window = kernel().simulation_manager.get_eprop_learning_window().get_steps(); + const long learning_window = kernel::manager< SimulationManager >.get_eprop_learning_window().get_steps(); if ( average_gradient ) { grad /= learning_window; diff --git a/models/eprop_readout_bsshslm_2020.h b/models/eprop_readout_bsshslm_2020.h index 36ae6e7134..1ba93f02d7 100644 --- a/models/eprop_readout_bsshslm_2020.h +++ b/models/eprop_readout_bsshslm_2020.h @@ -25,12 +25,12 @@ // nestkernel #include "connection.h" -#include "eprop_archiving_node_impl.h" #include "eprop_archiving_node_readout.h" #include "event.h" -#include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" + +#include "model_manager.h" namespace nest { @@ -526,7 +526,7 @@ eprop_readout_bsshslm_2020::handles_test_event( CurrentEvent&, size_t receptor_t inline size_t eprop_readout_bsshslm_2020::handles_test_event( DelayedRateConnectionEvent& e, size_t receptor_type ) { - size_t step_rate_model_id = kernel().model_manager.get_node_model_id( "step_rate_generator" ); + size_t step_rate_model_id = kernel::manager< ModelManager >.get_node_model_id( "step_rate_generator" ); size_t model_id = e.get_sender().get_model_id(); if ( step_rate_model_id == model_id and receptor_type != TARGET_SIG ) diff --git a/models/eprop_synapse.cpp b/models/eprop_synapse.cpp index 3c196ee49e..0f56cfe37e 100644 --- a/models/eprop_synapse.cpp +++ b/models/eprop_synapse.cpp @@ -22,9 +22,11 @@ #include "eprop_synapse.h" -// nestkernel +#include "connection_manager.h" #include "nest_impl.h" +// nestkernel + namespace nest { @@ -74,7 +76,7 @@ EpropSynapseCommonProperties::set_status( const DictionaryDatum& d, ConnectorMod const bool set_optimizer = updateValue< std::string >( optimizer_dict, names::type, new_optimizer ); if ( set_optimizer and new_optimizer != optimizer_cp_->get_name() ) { - if ( kernel().connection_manager.get_num_connections( cm.get_syn_id() ) > 0 ) + if ( kernel::manager< ConnectionManager >.get_num_connections( cm.get_syn_id() ) > 0 ) { throw BadParameter( "The optimizer cannot be changed because synapses have been created." ); } diff --git a/models/eprop_synapse.h b/models/eprop_synapse.h index 5509019296..75e6f4e6c0 100644 --- a/models/eprop_synapse.h +++ b/models/eprop_synapse.h @@ -26,7 +26,7 @@ // nestkernel #include "connection.h" #include "connector_base.h" -#include "eprop_archiving_node.h" +#include "eprop_archiving_node_impl.h" #include "target_identifier.h" #include "weight_optimizer.h" diff --git a/models/eprop_synapse_bsshslm_2020.cpp b/models/eprop_synapse_bsshslm_2020.cpp index 0603b652f0..df280a2fd9 100644 --- a/models/eprop_synapse_bsshslm_2020.cpp +++ b/models/eprop_synapse_bsshslm_2020.cpp @@ -22,9 +22,11 @@ #include "eprop_synapse_bsshslm_2020.h" -// nestkernel +#include "connection_manager.h" #include "nest_impl.h" +// nestkernel + namespace nest { @@ -79,7 +81,7 @@ EpropSynapseBSSHSLM2020CommonProperties::set_status( const DictionaryDatum& d, C const bool set_optimizer = updateValue< std::string >( optimizer_dict, names::type, new_optimizer ); if ( set_optimizer and new_optimizer != optimizer_cp_->get_name() ) { - if ( kernel().connection_manager.get_num_connections( cm.get_syn_id() ) > 0 ) + if ( kernel::manager< ConnectionManager >.get_num_connections( cm.get_syn_id() ) > 0 ) { throw BadParameter( "The optimizer cannot be changed because synapses have been created." ); } diff --git a/models/eprop_synapse_bsshslm_2020.h b/models/eprop_synapse_bsshslm_2020.h index 3ac9144827..427bdd90ae 100644 --- a/models/eprop_synapse_bsshslm_2020.h +++ b/models/eprop_synapse_bsshslm_2020.h @@ -26,7 +26,7 @@ // nestkernel #include "connection.h" #include "connector_base.h" -#include "eprop_archiving_node.h" +#include "eprop_archiving_node_impl.h" #include "target_identifier.h" #include "weight_optimizer.h" @@ -408,7 +408,7 @@ eprop_synapse_bsshslm_2020< targetidentifierT >::eprop_synapse_bsshslm_2020( con , weight_( es.weight_ ) , t_spike_previous_( 0 ) , t_previous_update_( 0 ) - , t_next_update_( kernel().simulation_manager.get_eprop_update_interval().get_steps() ) + , t_next_update_( kernel::manager< SimulationManager >.get_eprop_update_interval().get_steps() ) , t_previous_trigger_spike_( 0 ) , tau_m_readout_( es.tau_m_readout_ ) , kappa_( std::exp( -Time::get_resolution().get_ms() / tau_m_readout_ ) ) @@ -524,7 +524,7 @@ eprop_synapse_bsshslm_2020< targetidentifierT >::send( Event& e, assert( target ); const long t_spike = e.get_stamp().get_steps(); - const long update_interval = kernel().simulation_manager.get_eprop_update_interval().get_steps(); + const long update_interval = kernel::manager< SimulationManager >.get_eprop_update_interval().get_steps(); const long shift = target->get_shift(); const long interval_step = ( t_spike - shift ) % update_interval; diff --git a/models/erfc_neuron.cpp b/models/erfc_neuron.cpp index 891a7cfc1f..4ba38127f7 100644 --- a/models/erfc_neuron.cpp +++ b/models/erfc_neuron.cpp @@ -22,12 +22,6 @@ #include "erfc_neuron.h" -// Includes from nestkernel -#include "kernel_manager.h" -#include "model_manager_impl.h" -#include "nest_impl.h" -#include "universal_data_logger_impl.h" - namespace nest { void diff --git a/models/gamma_sup_generator.cpp b/models/gamma_sup_generator.cpp index 5817c36f7f..2f16ad8c08 100644 --- a/models/gamma_sup_generator.cpp +++ b/models/gamma_sup_generator.cpp @@ -22,17 +22,16 @@ #include "gamma_sup_generator.h" -// C++ includes: -#include - // Includes from libnestutil: #include "dict_util.h" -#include "numerics.h" // Includes from nestkernel: #include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" // Includes from sli: #include "dict.h" @@ -251,7 +250,7 @@ nest::gamma_sup_generator::update( Time const& T, const long from, const long to } DSSpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } diff --git a/models/gap_junction.cpp b/models/gap_junction.cpp index 4dd0886c6c..7c01f7eb2e 100644 --- a/models/gap_junction.cpp +++ b/models/gap_junction.cpp @@ -22,7 +22,6 @@ #include "gap_junction.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/gauss_rate.cpp b/models/gauss_rate.cpp index 520f0228e9..6a68d8357a 100644 --- a/models/gauss_rate.cpp +++ b/models/gauss_rate.cpp @@ -24,8 +24,6 @@ // Includes from nestkernel #include "kernel_manager.h" -#include "model_manager_impl.h" -#include "nest_impl.h" namespace nest { diff --git a/models/gauss_rate.h b/models/gauss_rate.h index 8d51447775..71cdee6f50 100644 --- a/models/gauss_rate.h +++ b/models/gauss_rate.h @@ -28,9 +28,7 @@ // Includes from models: #include "rate_neuron_ipn.h" -#include "rate_neuron_ipn_impl.h" #include "rate_transformer_node.h" -#include "rate_transformer_node_impl.h" // Includes from libnestutil: #include "dict_util.h" diff --git a/models/gif_cond_exp.cpp b/models/gif_cond_exp.cpp index 43e7d96d19..5759608b37 100644 --- a/models/gif_cond_exp.cpp +++ b/models/gif_cond_exp.cpp @@ -34,6 +34,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -558,7 +559,7 @@ nest::gif_cond_exp::update( Time const& origin, const long from, const long to ) // And send the spike event set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } } @@ -587,12 +588,12 @@ nest::gif_cond_exp::handle( SpikeEvent& e ) // is clumsy and should be improved. if ( e.get_weight() >= 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } // keep conductance positive } @@ -606,7 +607,7 @@ nest::gif_cond_exp::handle( CurrentEvent& e ) const double w = e.get_weight(); // Add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/gif_cond_exp.h b/models/gif_cond_exp.h index 077a4b453f..dae5388af0 100644 --- a/models/gif_cond_exp.h +++ b/models/gif_cond_exp.h @@ -38,9 +38,9 @@ #include "event.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" -#include "nest.h" +#include "nest_impl.h" namespace nest diff --git a/models/gif_cond_exp_multisynapse.cpp b/models/gif_cond_exp_multisynapse.cpp index 5a31ba490f..354a79c573 100644 --- a/models/gif_cond_exp_multisynapse.cpp +++ b/models/gif_cond_exp_multisynapse.cpp @@ -35,6 +35,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -565,7 +566,7 @@ nest::gif_cond_exp_multisynapse::update( Time const& origin, const long from, co // And send the spike event set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } } @@ -597,7 +598,8 @@ nest::gif_cond_exp_multisynapse::handle( SpikeEvent& e ) assert( ( e.get_rport() > 0 ) and ( ( size_t ) e.get_rport() <= P_.n_receptors() ) ); B_.spikes_[ e.get_rport() - 1 ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -609,7 +611,7 @@ nest::gif_cond_exp_multisynapse::handle( CurrentEvent& e ) const double w = e.get_weight(); // Add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * I ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * I ); } void diff --git a/models/gif_cond_exp_multisynapse.h b/models/gif_cond_exp_multisynapse.h index 1fd6c9a516..e157ee6a1e 100644 --- a/models/gif_cond_exp_multisynapse.h +++ b/models/gif_cond_exp_multisynapse.h @@ -37,9 +37,9 @@ #include "connection.h" #include "event.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" -#include "nest.h" +#include "nest_impl.h" namespace nest { diff --git a/models/gif_pop_psc_exp.cpp b/models/gif_pop_psc_exp.cpp index 43299c877f..2bb53cea04 100644 --- a/models/gif_pop_psc_exp.cpp +++ b/models/gif_pop_psc_exp.cpp @@ -36,12 +36,7 @@ // Includes from libnestutil: #include "compose.hpp" #include "dict_util.h" - -// Includes from nestkernel: -#include "model_manager_impl.h" -#include "nest_impl.h" -#include "universal_data_logger_impl.h" - +#include "genericmodel_impl.h" #ifdef HAVE_GSL @@ -646,7 +641,7 @@ nest::gif_pop_psc_exp::update( Time const& origin, const long from, const long t SpikeEvent* se; se = new SpikeEvent; se->set_multiplicity( S_.n_spikes_ ); - kernel().event_delivery_manager.send( *this, *se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, *se, lag ); } } } @@ -660,11 +655,11 @@ gif_pop_psc_exp::handle( SpikeEvent& e ) if ( s > 0.0 ) { - B_.ex_spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), s ); + B_.ex_spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), s ); } else { - B_.in_spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), s ); + B_.in_spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), s ); } } @@ -677,7 +672,7 @@ nest::gif_pop_psc_exp::handle( CurrentEvent& e ) const double w = e.get_weight(); // Add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/gif_pop_psc_exp.h b/models/gif_pop_psc_exp.h index ed18a07d65..07dd87e0bf 100644 --- a/models/gif_pop_psc_exp.h +++ b/models/gif_pop_psc_exp.h @@ -25,11 +25,11 @@ // Includes from nestkernel: -#include "nest.h" +#include "nest_impl.h" #include "node.h" #include "random_generators.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" #ifdef HAVE_GSL diff --git a/models/gif_psc_exp.cpp b/models/gif_psc_exp.cpp index 0731dc8175..022fcf09ad 100644 --- a/models/gif_psc_exp.cpp +++ b/models/gif_psc_exp.cpp @@ -23,22 +23,20 @@ #include "gif_psc_exp.h" // Includes from nestkernel: +#include "compose.hpp" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" +#include "numerics.h" // Includes from libnestutil: #include "dict_util.h" #include "iaf_propagator.h" // Includes from sli: -#include "dict.h" #include "dictutils.h" -#include "compose.hpp" -#include "numerics.h" - namespace nest { void @@ -381,7 +379,7 @@ nest::gif_psc_exp::update( Time const& origin, const long from, const long to ) // And send the spike event set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } } @@ -411,12 +409,12 @@ nest::gif_psc_exp::handle( SpikeEvent& e ) // is clumsy and should be improved. if ( e.get_weight() >= 0.0 ) { - B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spikes_in_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spikes_in_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } } @@ -430,7 +428,7 @@ nest::gif_psc_exp::handle( CurrentEvent& e ) const double w = e.get_weight(); // Add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/gif_psc_exp.h b/models/gif_psc_exp.h index dfc667d850..7900d737d2 100644 --- a/models/gif_psc_exp.h +++ b/models/gif_psc_exp.h @@ -28,9 +28,9 @@ #include "connection.h" #include "event.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" -#include "nest.h" +#include "nest_impl.h" namespace nest { diff --git a/models/gif_psc_exp_multisynapse.cpp b/models/gif_psc_exp_multisynapse.cpp index cfeca96ea4..6a45c35c49 100644 --- a/models/gif_psc_exp_multisynapse.cpp +++ b/models/gif_psc_exp_multisynapse.cpp @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -407,7 +408,7 @@ nest::gif_psc_exp_multisynapse::update( Time const& origin, const long from, con // And send the spike event set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } } @@ -433,7 +434,8 @@ gif_psc_exp_multisynapse::handle( SpikeEvent& e ) assert( ( e.get_rport() > 0 ) and ( ( size_t ) e.get_rport() <= P_.n_receptors_() ) ); B_.spikes_[ e.get_rport() - 1 ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -445,7 +447,7 @@ nest::gif_psc_exp_multisynapse::handle( CurrentEvent& e ) const double w = e.get_weight(); // Add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/gif_psc_exp_multisynapse.h b/models/gif_psc_exp_multisynapse.h index 1011a87818..e2c65d923c 100644 --- a/models/gif_psc_exp_multisynapse.h +++ b/models/gif_psc_exp_multisynapse.h @@ -28,9 +28,9 @@ #include "connection.h" #include "event.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" -#include "nest.h" +#include "nest_impl.h" namespace nest { diff --git a/models/ginzburg_neuron.cpp b/models/ginzburg_neuron.cpp index 36b94176cb..0c331630f4 100644 --- a/models/ginzburg_neuron.cpp +++ b/models/ginzburg_neuron.cpp @@ -24,9 +24,6 @@ // Includes from nestkernel #include "kernel_manager.h" -#include "model_manager_impl.h" -#include "nest_impl.h" -#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/glif_cond.cpp b/models/glif_cond.cpp index a1434786b9..e5a1252bd8 100644 --- a/models/glif_cond.cpp +++ b/models/glif_cond.cpp @@ -34,6 +34,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "name.h" #include "nest_impl.h" @@ -739,7 +740,7 @@ nest::glif_cond::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } else @@ -790,7 +791,8 @@ nest::glif_cond::handle( SpikeEvent& e ) assert( e.get_delay_steps() > 0 ); B_.spikes_[ e.get_rport() - 1 ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -798,16 +800,8 @@ nest::glif_cond::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); -} - -// Do not move this function as inline to h-file. It depends on -// universal_data_logger_impl.h being included here. -void -nest::glif_cond::handle( DataLoggingRequest& e ) -{ - B_.logger_.handle( e ); // the logger does this for us + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } #endif // HAVE_GSL diff --git a/models/glif_cond.h b/models/glif_cond.h index acfbffef2b..dc3279cc15 100644 --- a/models/glif_cond.h +++ b/models/glif_cond.h @@ -38,7 +38,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" #include "dictdatum.h" @@ -527,6 +527,12 @@ glif_cond::set_status( const DictionaryDatum& d ) S_ = stmp; } +inline void +nest::glif_cond::handle( DataLoggingRequest& e ) +{ + B_.logger_.handle( e ); // the logger does this for us +} + } // namespace nest #endif // HAVE_GSL diff --git a/models/glif_psc.cpp b/models/glif_psc.cpp index b60dafc0ec..4329a3bd3f 100644 --- a/models/glif_psc.cpp +++ b/models/glif_psc.cpp @@ -23,27 +23,28 @@ #include "glif_psc.h" // C++ includes: -#include #include // Includes from libnestutil: #include "dict_util.h" -#include "exceptions.h" #include "iaf_propagator.h" + +// Includes from nestkernel: +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" // Includes from sli: -#include "dict.h" #include "dictutils.h" using namespace nest; -nest::RecordablesMap< nest::glif_psc > nest::glif_psc::recordablesMap_; - namespace nest { +RecordablesMap< glif_psc > glif_psc::recordablesMap_; + void register_glif_psc( const std::string& name ) { @@ -54,23 +55,22 @@ register_glif_psc( const std::string& name ) // for each quantity to be recorded. template <> void -RecordablesMap< nest::glif_psc >::create() +RecordablesMap< glif_psc >::create() { - insert_( names::V_m, &nest::glif_psc::get_V_m_ ); - insert_( names::ASCurrents_sum, &nest::glif_psc::get_ASCurrents_sum_ ); - insert_( names::I, &nest::glif_psc::get_I_ ); - insert_( names::I_syn, &nest::glif_psc::get_I_syn_ ); - insert_( names::threshold, &nest::glif_psc::get_threshold_ ); - insert_( names::threshold_spike, &nest::glif_psc::get_threshold_spike_ ); - insert_( names::threshold_voltage, &nest::glif_psc::get_threshold_voltage_ ); -} + insert_( names::V_m, &glif_psc::get_V_m_ ); + insert_( names::ASCurrents_sum, &glif_psc::get_ASCurrents_sum_ ); + insert_( names::I, &glif_psc::get_I_ ); + insert_( names::I_syn, &glif_psc::get_I_syn_ ); + insert_( names::threshold, &glif_psc::get_threshold_ ); + insert_( names::threshold_spike, &glif_psc::get_threshold_spike_ ); + insert_( names::threshold_voltage, &glif_psc::get_threshold_voltage_ ); } /* ---------------------------------------------------------------- * Default constructors defining default parameters and state * ---------------------------------------------------------------- */ -nest::glif_psc::Parameters_::Parameters_() +glif_psc::Parameters_::Parameters_() : G_( 9.43 ) // in nS , E_L_( -78.85 ) // in mV , th_inf_( -51.68 - E_L_ ) // in mv, rel to E_L_, - 51.68 - E_L_, i.e., 27.17 @@ -95,7 +95,7 @@ nest::glif_psc::Parameters_::Parameters_() { } -nest::glif_psc::State_::State_( const Parameters_& p ) +glif_psc::State_::State_( const Parameters_& p ) : U_( 0.0 ) // in mV , threshold_( p.th_inf_ ) // in mV , threshold_spike_( 0.0 ) // in mV @@ -119,7 +119,7 @@ nest::glif_psc::State_::State_( const Parameters_& p ) * ---------------------------------------------------------------- */ void -nest::glif_psc::Parameters_::get( DictionaryDatum& d ) const +glif_psc::Parameters_::get( DictionaryDatum& d ) const { def< double >( d, names::V_th, th_inf_ + E_L_ ); def< double >( d, names::g, G_ ); @@ -149,7 +149,7 @@ nest::glif_psc::Parameters_::get( DictionaryDatum& d ) const } double -nest::glif_psc::Parameters_::set( const DictionaryDatum& d, Node* node ) +glif_psc::Parameters_::set( const DictionaryDatum& d, Node* node ) { // if E_L_ is changed, we need to adjust all variables defined relative to // E_L_ @@ -303,7 +303,7 @@ nest::glif_psc::Parameters_::set( const DictionaryDatum& d, Node* node ) } void -nest::glif_psc::State_::get( DictionaryDatum& d, const Parameters_& p ) const +glif_psc::State_::get( DictionaryDatum& d, const Parameters_& p ) const { def< double >( d, names::V_m, U_ + p.E_L_ ); def< std::vector< double > >( d, names::ASCurrents, ASCurrents_ ); @@ -312,7 +312,7 @@ nest::glif_psc::State_::get( DictionaryDatum& d, const Parameters_& p ) const } void -nest::glif_psc::State_::set( const DictionaryDatum& d, const Parameters_& p, double delta_EL, Node* node ) +glif_psc::State_::set( const DictionaryDatum& d, const Parameters_& p, double delta_EL, Node* node ) { if ( updateValueParam< double >( d, names::V_m, U_, node ) ) { @@ -351,12 +351,12 @@ nest::glif_psc::State_::set( const DictionaryDatum& d, const Parameters_& p, dou } } -nest::glif_psc::Buffers_::Buffers_( glif_psc& n ) +glif_psc::Buffers_::Buffers_( glif_psc& n ) : logger_( n ) { } -nest::glif_psc::Buffers_::Buffers_( const Buffers_&, glif_psc& n ) +glif_psc::Buffers_::Buffers_( const Buffers_&, glif_psc& n ) : logger_( n ) { } @@ -365,7 +365,7 @@ nest::glif_psc::Buffers_::Buffers_( const Buffers_&, glif_psc& n ) * Default and copy constructor for node * ---------------------------------------------------------------- */ -nest::glif_psc::glif_psc() +glif_psc::glif_psc() : ArchivingNode() , P_() , S_( P_ ) @@ -374,7 +374,7 @@ nest::glif_psc::glif_psc() recordablesMap_.create(); } -nest::glif_psc::glif_psc( const glif_psc& n ) +glif_psc::glif_psc( const glif_psc& n ) : ArchivingNode( n ) , P_( n.P_ ) , S_( n.S_ ) @@ -387,7 +387,7 @@ nest::glif_psc::glif_psc( const glif_psc& n ) * ---------------------------------------------------------------- */ void -nest::glif_psc::init_buffers_() +glif_psc::init_buffers_() { B_.spikes_.clear(); // includes resize B_.currents_.clear(); // include resize @@ -395,7 +395,7 @@ nest::glif_psc::init_buffers_() } void -nest::glif_psc::pre_run_hook() +glif_psc::pre_run_hook() { B_.logger_.init(); @@ -469,7 +469,7 @@ nest::glif_psc::pre_run_hook() * ---------------------------------------------------------------- */ void -nest::glif_psc::update( Time const& origin, const long from, const long to ) +glif_psc::update( Time const& origin, const long from, const long to ) { double v_old = S_.U_; @@ -564,7 +564,7 @@ nest::glif_psc::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } else @@ -598,40 +598,4 @@ nest::glif_psc::update( Time const& origin, const long from, const long to ) } } -size_t -nest::glif_psc::handles_test_event( SpikeEvent&, size_t receptor_type ) -{ - if ( receptor_type <= 0 or receptor_type > P_.n_receptors_() ) - { - throw IncompatibleReceptorType( receptor_type, get_name(), "SpikeEvent" ); - } - - P_.has_connections_ = true; - return receptor_type; -} - -void -nest::glif_psc::handle( SpikeEvent& e ) -{ - assert( e.get_delay_steps() > 0 ); - - B_.spikes_[ e.get_rport() - 1 ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); -} - -void -nest::glif_psc::handle( CurrentEvent& e ) -{ - assert( e.get_delay_steps() > 0 ); - - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); -} - -// Do not move this function as inline to h-file. It depends on -// universal_data_logger_impl.h being included here. -void -nest::glif_psc::handle( DataLoggingRequest& e ) -{ - B_.logger_.handle( e ); // the logger does this for us -} +} // namespace nest diff --git a/models/glif_psc.h b/models/glif_psc.h index 63d51b93e8..2eb0e3d9ca 100644 --- a/models/glif_psc.h +++ b/models/glif_psc.h @@ -28,7 +28,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" #include "dictdatum.h" @@ -461,6 +461,43 @@ glif_psc::set_status( const DictionaryDatum& d ) S_ = stmp; } +inline size_t +glif_psc::handles_test_event( SpikeEvent&, size_t receptor_type ) +{ + if ( receptor_type <= 0 or receptor_type > P_.n_receptors_() ) + { + throw IncompatibleReceptorType( receptor_type, get_name(), "SpikeEvent" ); + } + + P_.has_connections_ = true; + return receptor_type; +} + +inline void +glif_psc::handle( DataLoggingRequest& e ) +{ + B_.logger_.handle( e ); // the logger does this for us +} + +inline void +glif_psc::handle( SpikeEvent& e ) +{ + assert( e.get_delay_steps() > 0 ); + + B_.spikes_[ e.get_rport() - 1 ].add_value( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); +} + +inline void +glif_psc::handle( CurrentEvent& e ) +{ + assert( e.get_delay_steps() > 0 ); + + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); +} + } // namespace nest #endif diff --git a/models/glif_psc_double_alpha.cpp b/models/glif_psc_double_alpha.cpp index f79de012d3..efe8a1873e 100644 --- a/models/glif_psc_double_alpha.cpp +++ b/models/glif_psc_double_alpha.cpp @@ -29,10 +29,10 @@ // Includes from libnestutil: #include "dict_util.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "iaf_propagator.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "dict.h" @@ -628,7 +628,7 @@ nest::glif_psc_double_alpha::update( Time const& origin, const long from, const set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } else @@ -686,7 +686,8 @@ nest::glif_psc_double_alpha::handle( SpikeEvent& e ) assert( e.get_delay_steps() > 0 ); B_.spikes_[ e.get_rport() - 1 ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -694,14 +695,6 @@ nest::glif_psc_double_alpha::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); -} - -// Do not move this function as inline to h-file. It depends on -// universal_data_logger_impl.h being included here. -void -nest::glif_psc_double_alpha::handle( DataLoggingRequest& e ) -{ - B_.logger_.handle( e ); // the logger does this for us + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } diff --git a/models/glif_psc_double_alpha.h b/models/glif_psc_double_alpha.h index 69a51a98b0..7632571e52 100644 --- a/models/glif_psc_double_alpha.h +++ b/models/glif_psc_double_alpha.h @@ -28,7 +28,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" #include "dictdatum.h" @@ -493,6 +493,12 @@ glif_psc_double_alpha::set_status( const DictionaryDatum& d ) S_ = stmp; } +inline void +glif_psc_double_alpha::handle( DataLoggingRequest& e ) +{ + B_.logger_.handle( e ); // the logger does this for us +} + } // namespace nest #endif diff --git a/models/hh_cond_beta_gap_traub.cpp b/models/hh_cond_beta_gap_traub.cpp index 7907b051c8..8a363e37a5 100644 --- a/models/hh_cond_beta_gap_traub.cpp +++ b/models/hh_cond_beta_gap_traub.cpp @@ -40,6 +40,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -106,7 +107,7 @@ hh_cond_beta_gap_traub_dynamics( double time, const double y[], double f[], void const double t = time / node.B_.step_; - switch ( kernel().simulation_manager.get_wfr_interpolation_order() ) + switch ( kernel::manager< SimulationManager >.get_wfr_interpolation_order() ) { case 0: gap = -node.B_.sumj_g_ij_ * y[ S::V_M ] + node.B_.interpolation_coefficients[ node.B_.lag_ ]; @@ -344,7 +345,7 @@ nest::hh_cond_beta_gap_traub::hh_cond_beta_gap_traub() , B_( *this ) { recordablesMap_.create(); - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); } nest::hh_cond_beta_gap_traub::hh_cond_beta_gap_traub( const hh_cond_beta_gap_traub& n ) @@ -353,7 +354,7 @@ nest::hh_cond_beta_gap_traub::hh_cond_beta_gap_traub( const hh_cond_beta_gap_tra , S_( n.S_ ) , B_( n.B_, *this ) { - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); } nest::hh_cond_beta_gap_traub::~hh_cond_beta_gap_traub() @@ -394,12 +395,12 @@ nest::hh_cond_beta_gap_traub::init_buffers_() // per min_delay step) // resize interpolation_coefficients depending on interpolation order - const size_t buffer_size = - kernel().connection_manager.get_min_delay() * ( kernel().simulation_manager.get_wfr_interpolation_order() + 1 ); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay() + * ( kernel::manager< SimulationManager >.get_wfr_interpolation_order() + 1 ); B_.interpolation_coefficients.resize( buffer_size, 0.0 ); - B_.last_y_values.resize( kernel().connection_manager.get_min_delay(), 0.0 ); + B_.last_y_values.resize( kernel::manager< ConnectionManager >.get_min_delay(), 0.0 ); B_.sumj_g_ij_ = 0.0; @@ -477,13 +478,13 @@ nest::hh_cond_beta_gap_traub::update_( Time const& origin, const long to, const bool called_from_wfr_update ) { - const size_t interpolation_order = kernel().simulation_manager.get_wfr_interpolation_order(); - const double wfr_tol = kernel().simulation_manager.get_wfr_tol(); + const size_t interpolation_order = kernel::manager< SimulationManager >.get_wfr_interpolation_order(); + const double wfr_tol = kernel::manager< SimulationManager >.get_wfr_tol(); bool wfr_tol_exceeded = false; // allocate memory to store the new interpolation coefficients // to be sent by gap event - const size_t buffer_size = kernel().connection_manager.get_min_delay() * ( interpolation_order + 1 ); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay() * ( interpolation_order + 1 ); std::vector< double > new_coefficients( buffer_size, 0.0 ); // parameters needed for piecewise interpolation @@ -556,7 +557,7 @@ nest::hh_cond_beta_gap_traub::update_( Time const& origin, set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // log state data @@ -616,13 +617,13 @@ nest::hh_cond_beta_gap_traub::update_( Time const& origin, new_coefficients[ temp * ( interpolation_order + 1 ) + 0 ] = S_.y_[ State_::V_M ]; } - std::vector< double >( kernel().connection_manager.get_min_delay(), 0.0 ).swap( B_.last_y_values ); + std::vector< double >( kernel::manager< ConnectionManager >.get_min_delay(), 0.0 ).swap( B_.last_y_values ); } // Send gap-event GapJunctionEvent ge; ge.set_coeffarray( new_coefficients ); - kernel().event_delivery_manager.send_secondary( *this, ge ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, ge ); // Reset variables B_.sumj_g_ij_ = 0.0; @@ -638,14 +639,14 @@ nest::hh_cond_beta_gap_traub::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { // add with negative weight, ie positive value, since we are changing a // conductance - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -659,7 +660,7 @@ nest::hh_cond_beta_gap_traub::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/hh_cond_beta_gap_traub.h b/models/hh_cond_beta_gap_traub.h index fd63783789..8d4ff3a02a 100644 --- a/models/hh_cond_beta_gap_traub.h +++ b/models/hh_cond_beta_gap_traub.h @@ -42,7 +42,7 @@ #include "node.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/hh_cond_exp_traub.cpp b/models/hh_cond_exp_traub.cpp index 5aa908a15d..bf70c76eef 100644 --- a/models/hh_cond_exp_traub.cpp +++ b/models/hh_cond_exp_traub.cpp @@ -37,6 +37,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -430,7 +431,7 @@ nest::hh_cond_exp_traub::update( Time const& origin, const long from, const long set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -449,14 +450,14 @@ nest::hh_cond_exp_traub::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { // add with negative weight, ie positive value, since we are changing a // conductance - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -470,7 +471,7 @@ nest::hh_cond_exp_traub::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/hh_cond_exp_traub.h b/models/hh_cond_exp_traub.h index 1d2075ba43..904d850f14 100644 --- a/models/hh_cond_exp_traub.h +++ b/models/hh_cond_exp_traub.h @@ -38,7 +38,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/hh_psc_alpha.cpp b/models/hh_psc_alpha.cpp index 29e953b810..8fae8e9ad7 100644 --- a/models/hh_psc_alpha.cpp +++ b/models/hh_psc_alpha.cpp @@ -33,8 +33,8 @@ #include "numerics.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -440,7 +440,7 @@ nest::hh_psc_alpha::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // log state data @@ -458,12 +458,12 @@ nest::hh_psc_alpha::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } } @@ -476,7 +476,7 @@ nest::hh_psc_alpha::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/hh_psc_alpha.h b/models/hh_psc_alpha.h index cdc63e89b3..4950ef58c6 100644 --- a/models/hh_psc_alpha.h +++ b/models/hh_psc_alpha.h @@ -41,7 +41,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/hh_psc_alpha_clopath.cpp b/models/hh_psc_alpha_clopath.cpp index e0c35e830f..b5540b0d91 100644 --- a/models/hh_psc_alpha_clopath.cpp +++ b/models/hh_psc_alpha_clopath.cpp @@ -33,8 +33,8 @@ #include "numerics.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -477,7 +477,7 @@ nest::hh_psc_alpha_clopath::update( Time const& origin, const long from, const l set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // log state data @@ -495,12 +495,12 @@ nest::hh_psc_alpha_clopath::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } // current input, keep negative weight } @@ -514,7 +514,7 @@ nest::hh_psc_alpha_clopath::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/hh_psc_alpha_clopath.h b/models/hh_psc_alpha_clopath.h index b1b3649b2a..cff76dd82d 100644 --- a/models/hh_psc_alpha_clopath.h +++ b/models/hh_psc_alpha_clopath.h @@ -41,7 +41,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/hh_psc_alpha_gap.cpp b/models/hh_psc_alpha_gap.cpp index b26176784f..b68dcde288 100644 --- a/models/hh_psc_alpha_gap.cpp +++ b/models/hh_psc_alpha_gap.cpp @@ -36,6 +36,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -114,7 +115,7 @@ hh_psc_alpha_gap_dynamics( double time, const double y[], double f[], void* pnod const double t = time / node.B_.step_; - switch ( kernel().simulation_manager.get_wfr_interpolation_order() ) + switch ( kernel::manager< SimulationManager >.get_wfr_interpolation_order() ) { case 0: gap = -node.B_.sumj_g_ij_ * V + node.B_.interpolation_coefficients[ node.B_.lag_ ]; @@ -335,7 +336,7 @@ nest::hh_psc_alpha_gap::hh_psc_alpha_gap() , B_( *this ) { recordablesMap_.create(); - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); } nest::hh_psc_alpha_gap::hh_psc_alpha_gap( const hh_psc_alpha_gap& n ) @@ -344,7 +345,7 @@ nest::hh_psc_alpha_gap::hh_psc_alpha_gap( const hh_psc_alpha_gap& n ) , S_( n.S_ ) , B_( n.B_, *this ) { - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); } nest::hh_psc_alpha_gap::~hh_psc_alpha_gap() @@ -385,12 +386,12 @@ nest::hh_psc_alpha_gap::init_buffers_() // per min_delay step) // resize interpolation_coefficients depending on interpolation order - const size_t buffer_size = - kernel().connection_manager.get_min_delay() * ( kernel().simulation_manager.get_wfr_interpolation_order() + 1 ); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay() + * ( kernel::manager< SimulationManager >.get_wfr_interpolation_order() + 1 ); B_.interpolation_coefficients.resize( buffer_size, 0.0 ); - B_.last_y_values.resize( kernel().connection_manager.get_min_delay(), 0.0 ); + B_.last_y_values.resize( kernel::manager< ConnectionManager >.get_min_delay(), 0.0 ); B_.sumj_g_ij_ = 0.0; @@ -456,13 +457,13 @@ nest::hh_psc_alpha_gap::pre_run_hook() bool nest::hh_psc_alpha_gap::update_( Time const& origin, const long from, const long to, const bool called_from_wfr_update ) { - const size_t interpolation_order = kernel().simulation_manager.get_wfr_interpolation_order(); - const double wfr_tol = kernel().simulation_manager.get_wfr_tol(); + const size_t interpolation_order = kernel::manager< SimulationManager >.get_wfr_interpolation_order(); + const double wfr_tol = kernel::manager< SimulationManager >.get_wfr_tol(); bool wfr_tol_exceeded = false; // allocate memory to store the new interpolation coefficients // to be sent by gap event - const size_t buffer_size = kernel().connection_manager.get_min_delay() * ( interpolation_order + 1 ); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay() * ( interpolation_order + 1 ); std::vector< double > new_coefficients( buffer_size, 0.0 ); // parameters needed for piecewise interpolation @@ -537,7 +538,7 @@ nest::hh_psc_alpha_gap::update_( Time const& origin, const long from, const long set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // log state data @@ -597,13 +598,13 @@ nest::hh_psc_alpha_gap::update_( Time const& origin, const long from, const long new_coefficients[ temp * ( interpolation_order + 1 ) + 0 ] = S_.y_[ State_::V_M ]; } - std::vector< double >( kernel().connection_manager.get_min_delay(), 0.0 ).swap( B_.last_y_values ); + std::vector< double >( kernel::manager< ConnectionManager >.get_min_delay(), 0.0 ).swap( B_.last_y_values ); } // Send gap-event GapJunctionEvent ge; ge.set_coeffarray( new_coefficients ); - kernel().event_delivery_manager.send_secondary( *this, ge ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, ge ); // Reset variables B_.sumj_g_ij_ = 0.0; @@ -619,12 +620,12 @@ nest::hh_psc_alpha_gap::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } } @@ -637,7 +638,7 @@ nest::hh_psc_alpha_gap::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/hh_psc_alpha_gap.h b/models/hh_psc_alpha_gap.h index cbeca72139..a6b40d92dd 100644 --- a/models/hh_psc_alpha_gap.h +++ b/models/hh_psc_alpha_gap.h @@ -41,7 +41,7 @@ #include "node.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/ht_neuron.cpp b/models/ht_neuron.cpp index 047ca61fa3..40aab642c4 100644 --- a/models/ht_neuron.cpp +++ b/models/ht_neuron.cpp @@ -32,9 +32,9 @@ #include "dict_util.h" // Includes from nestkernel: +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" namespace nest { @@ -824,7 +824,7 @@ ht_neuron::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } @@ -857,7 +857,8 @@ nest::ht_neuron::handle( SpikeEvent& e ) assert( e.get_rport() < B_.spike_inputs_.size() ); B_.spike_inputs_[ e.get_rport() ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -869,7 +870,7 @@ nest::ht_neuron::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * I ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * I ); } void diff --git a/models/ht_neuron.h b/models/ht_neuron.h index 6b33b29cdd..635361079b 100644 --- a/models/ht_neuron.h +++ b/models/ht_neuron.h @@ -42,7 +42,7 @@ #include "connection.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" // Includes from diff --git a/models/ht_synapse.cpp b/models/ht_synapse.cpp index b92c297138..f3560c4a07 100644 --- a/models/ht_synapse.cpp +++ b/models/ht_synapse.cpp @@ -22,7 +22,6 @@ #include "ht_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/ht_synapse.h b/models/ht_synapse.h index 1221e89116..1ebbb96f07 100644 --- a/models/ht_synapse.h +++ b/models/ht_synapse.h @@ -131,22 +131,15 @@ class ht_synapse : public Connection< targetidentifierT > using ConnectionBase::get_rport; using ConnectionBase::get_target; - /** - * Default Destructor. - */ - virtual ~ht_synapse() - { - } - /** * Get all properties of this connection and put them into a dictionary. */ - virtual void get_status( DictionaryDatum& d ) const; + void get_status( DictionaryDatum& d ) const; /** * Set properties of this connection from the values given in dictionary. */ - virtual void set_status( const DictionaryDatum& d, ConnectorModel& cm ); + void set_status( const DictionaryDatum& d, ConnectorModel& cm ); /** * Send an event to the receiver of this connection. diff --git a/models/iaf_bw_2001.cpp b/models/iaf_bw_2001.cpp index e030579183..206b5b32d0 100644 --- a/models/iaf_bw_2001.cpp +++ b/models/iaf_bw_2001.cpp @@ -28,25 +28,19 @@ // Includes from libnestutil: #include "dict_util.h" #include "dictdatum.h" -#include "numerics.h" // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" // Includes from sli: -#include "dict.h" #include "dictutils.h" -#include "doubledatum.h" -#include "integerdatum.h" -#include "lockptrdatum.h" // Includes from standard library -#include #include -#include /* --------------------------------------------------------------------------- * Recordables map @@ -409,7 +403,7 @@ nest::iaf_bw_2001::pre_run_hook() void nest::iaf_bw_2001::update( Time const& origin, const long from, const long to ) { - std::vector< double > s_vals( kernel().connection_manager.get_min_delay(), 0.0 ); + std::vector< double > s_vals( kernel::manager< ConnectionManager >.get_min_delay(), 0.0 ); for ( long lag = from; lag < to; ++lag ) { double t = 0.0; @@ -475,7 +469,7 @@ nest::iaf_bw_2001::update( Time const& origin, const long from, const long to ) SpikeEvent se; se.set_offset( s_NMDA_delta ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -486,41 +480,5 @@ nest::iaf_bw_2001::update( Time const& origin, const long from, const long to ) } } -// Do not move this function as inline to h-file. It depends on -// universal_data_logger_impl.h being included here. -void -nest::iaf_bw_2001::handle( DataLoggingRequest& e ) -{ - B_.logger_.handle( e ); -} - -void -nest::iaf_bw_2001::handle( SpikeEvent& e ) -{ - assert( e.get_delay_steps() > 0 ); - - const double steps = e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ); - - const auto rport = e.get_rport(); - - if ( rport < NMDA ) - { - B_.spikes_[ rport - 1 ].add_value( steps, e.get_weight() * e.get_multiplicity() ); - } - else - { - B_.spikes_[ rport - 1 ].add_value( steps, e.get_weight() * e.get_multiplicity() * e.get_offset() ); - } -} - -void -nest::iaf_bw_2001::handle( CurrentEvent& e ) -{ - assert( e.get_delay_steps() > 0 ); - - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); -} - #endif // HAVE_BOOST #endif // HAVE_GSL diff --git a/models/iaf_bw_2001.h b/models/iaf_bw_2001.h index 3efbace816..3319c35352 100644 --- a/models/iaf_bw_2001.h +++ b/models/iaf_bw_2001.h @@ -40,7 +40,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { @@ -523,6 +523,41 @@ iaf_bw_2001::set_status( const DictionaryDatum& d ) P_ = ptmp; S_ = stmp; }; + +inline void +iaf_bw_2001::handle( DataLoggingRequest& e ) +{ + B_.logger_.handle( e ); +} + +inline void +iaf_bw_2001::handle( SpikeEvent& e ) +{ + assert( e.get_delay_steps() > 0 ); + + const double steps = e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ); + + const auto rport = e.get_rport(); + + if ( rport < NMDA ) + { + B_.spikes_[ rport - 1 ].add_value( steps, e.get_weight() * e.get_multiplicity() ); + } + else + { + B_.spikes_[ rport - 1 ].add_value( steps, e.get_weight() * e.get_multiplicity() * e.get_offset() ); + } +} + +inline void +iaf_bw_2001::handle( CurrentEvent& e ) +{ + assert( e.get_delay_steps() > 0 ); + + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); +} + } // namespace #endif // HAVE_BOOST diff --git a/models/iaf_bw_2001_exact.cpp b/models/iaf_bw_2001_exact.cpp index 3855c27a53..da6f54c0a2 100644 --- a/models/iaf_bw_2001_exact.cpp +++ b/models/iaf_bw_2001_exact.cpp @@ -31,6 +31,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -506,7 +507,7 @@ nest::iaf_bw_2001_exact::update( Time const& origin, const long from, const long set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -517,53 +518,4 @@ nest::iaf_bw_2001_exact::update( Time const& origin, const long from, const long } } -// Do not move this function as inline to h-file. It depends on -// universal_data_logger_impl.h being included here. -void -nest::iaf_bw_2001_exact::handle( DataLoggingRequest& e ) -{ - B_.logger_.handle( e ); -} - -void -nest::iaf_bw_2001_exact::handle( SpikeEvent& e ) -{ - assert( e.get_delay_steps() > 0 ); - assert( e.get_rport() <= static_cast< int >( B_.spikes_.size() ) ); - - const double steps = e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ); - const auto rport = e.get_rport(); - - if ( rport < NMDA ) - { - B_.spikes_[ rport - 1 ].add_value( steps, e.get_weight() * e.get_multiplicity() ); - } - else - // we need to scale each individual S_j variable by its weight, - // so we store them - { - B_.spikes_[ rport - 1 ].add_value( steps, e.get_multiplicity() ); - // since we scale entire S_j variable by the weight it also affects previous spikes. - // we therefore require them to be constant. - const size_t w_idx = rport - NMDA; - if ( B_.weights_[ w_idx ] == 0 ) - { - B_.weights_[ w_idx ] = e.get_weight(); - } - else if ( B_.weights_[ w_idx ] != e.get_weight() ) - { - throw KernelException( "iaf_bw_2001_exact requires constant weights." ); - } - } -} - -void -nest::iaf_bw_2001_exact::handle( CurrentEvent& e ) -{ - assert( e.get_delay_steps() > 0 ); - - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); -} - #endif // HAVE_GSL diff --git a/models/iaf_bw_2001_exact.h b/models/iaf_bw_2001_exact.h index cf650afefe..cd067ec2f3 100644 --- a/models/iaf_bw_2001_exact.h +++ b/models/iaf_bw_2001_exact.h @@ -39,7 +39,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { @@ -540,6 +540,54 @@ iaf_bw_2001_exact::set_status( const DictionaryDatum& d ) P_ = ptmp; S_ = stmp; }; + +inline void +nest::iaf_bw_2001_exact::handle( DataLoggingRequest& e ) +{ + B_.logger_.handle( e ); +} + +inline void +nest::iaf_bw_2001_exact::handle( SpikeEvent& e ) +{ + assert( e.get_delay_steps() > 0 ); + assert( e.get_rport() <= static_cast< int >( B_.spikes_.size() ) ); + + const double steps = e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ); + const auto rport = e.get_rport(); + + if ( rport < NMDA ) + { + B_.spikes_[ rport - 1 ].add_value( steps, e.get_weight() * e.get_multiplicity() ); + } + else + // we need to scale each individual S_j variable by its weight, + // so we store them + { + B_.spikes_[ rport - 1 ].add_value( steps, e.get_multiplicity() ); + // since we scale entire S_j variable by the weight it also affects previous spikes. + // we therefore require them to be constant. + const size_t w_idx = rport - NMDA; + if ( B_.weights_[ w_idx ] == 0 ) + { + B_.weights_[ w_idx ] = e.get_weight(); + } + else if ( B_.weights_[ w_idx ] != e.get_weight() ) + { + throw KernelException( "iaf_bw_2001_exact requires constant weights." ); + } + } +} + +inline void +nest::iaf_bw_2001_exact::handle( CurrentEvent& e ) +{ + assert( e.get_delay_steps() > 0 ); + + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); +} + } // namespace #endif // HAVE_GSL diff --git a/models/iaf_chs_2007.cpp b/models/iaf_chs_2007.cpp index b5c183d7b0..e81f527b42 100644 --- a/models/iaf_chs_2007.cpp +++ b/models/iaf_chs_2007.cpp @@ -28,6 +28,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -253,7 +254,7 @@ nest::iaf_chs_2007::update( const Time& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // log state data @@ -268,7 +269,7 @@ nest::iaf_chs_2007::handle( SpikeEvent& e ) if ( e.get_weight() >= 0.0 ) { - B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } } diff --git a/models/iaf_chs_2007.h b/models/iaf_chs_2007.h index df3bb48efd..42764d414e 100644 --- a/models/iaf_chs_2007.h +++ b/models/iaf_chs_2007.h @@ -31,7 +31,7 @@ #include "random_generators.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_chxk_2008.cpp b/models/iaf_chxk_2008.cpp index 62559536ae..060be81ba7 100644 --- a/models/iaf_chxk_2008.cpp +++ b/models/iaf_chxk_2008.cpp @@ -33,6 +33,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -426,7 +427,7 @@ nest::iaf_chxk_2008::update( Time const& origin, const long from, const long to SpikeEvent se; se.set_offset( dt ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // add incoming spikes @@ -448,12 +449,12 @@ nest::iaf_chxk_2008::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -463,8 +464,8 @@ nest::iaf_chxk_2008::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/iaf_chxk_2008.h b/models/iaf_chxk_2008.h index 20e3fed269..57950ed56b 100644 --- a/models/iaf_chxk_2008.h +++ b/models/iaf_chxk_2008.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_cond_alpha.cpp b/models/iaf_cond_alpha.cpp index 7cbff968ee..a3aaa51d1a 100644 --- a/models/iaf_cond_alpha.cpp +++ b/models/iaf_cond_alpha.cpp @@ -35,6 +35,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -426,7 +427,7 @@ nest::iaf_cond_alpha::update( Time const& origin, const long from, const long to set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // add incoming spikes @@ -448,12 +449,12 @@ nest::iaf_cond_alpha::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -463,8 +464,8 @@ nest::iaf_cond_alpha::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/iaf_cond_alpha.h b/models/iaf_cond_alpha.h index 4d67e2c52f..2b1b6d68d4 100644 --- a/models/iaf_cond_alpha.h +++ b/models/iaf_cond_alpha.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_cond_alpha_mc.cpp b/models/iaf_cond_alpha_mc.cpp index 2b99b81025..b3e22a5761 100644 --- a/models/iaf_cond_alpha_mc.cpp +++ b/models/iaf_cond_alpha_mc.cpp @@ -35,6 +35,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -640,7 +641,7 @@ nest::iaf_cond_alpha_mc::update( Time const& origin, const long from, const long set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input currents @@ -661,7 +662,8 @@ nest::iaf_cond_alpha_mc::handle( SpikeEvent& e ) assert( e.get_rport() < 2 * NCOMP ); B_.spikes_[ e.get_rport() ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -673,7 +675,8 @@ nest::iaf_cond_alpha_mc::handle( CurrentEvent& e ) // add weighted current; HEP 2002-10-04 B_.currents_[ e.get_rport() ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/iaf_cond_alpha_mc.h b/models/iaf_cond_alpha_mc.h index fe9052ee40..247517bf73 100644 --- a/models/iaf_cond_alpha_mc.h +++ b/models/iaf_cond_alpha_mc.h @@ -43,7 +43,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" // Includes from sli: #include "dictdatum.h" diff --git a/models/iaf_cond_beta.cpp b/models/iaf_cond_beta.cpp index a0f5d59c2e..b1dc4200db 100644 --- a/models/iaf_cond_beta.cpp +++ b/models/iaf_cond_beta.cpp @@ -36,6 +36,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -439,7 +440,7 @@ nest::iaf_cond_beta::update( Time const& origin, const long from, const long to set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // add incoming spikes @@ -461,12 +462,12 @@ nest::iaf_cond_beta::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } // ensure conductance is positive } @@ -477,8 +478,8 @@ nest::iaf_cond_beta::handle( CurrentEvent& e ) assert( e.get_delay_steps() > 0 ); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/iaf_cond_beta.h b/models/iaf_cond_beta.h index 56f6510556..098977100b 100644 --- a/models/iaf_cond_beta.h +++ b/models/iaf_cond_beta.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_cond_exp.cpp b/models/iaf_cond_exp.cpp index c777d686fd..e631d0bc76 100644 --- a/models/iaf_cond_exp.cpp +++ b/models/iaf_cond_exp.cpp @@ -35,9 +35,9 @@ // Includes from nestkernel: #include "event.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "dictutils.h" @@ -403,7 +403,7 @@ nest::iaf_cond_exp::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -421,12 +421,12 @@ nest::iaf_cond_exp::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -439,7 +439,7 @@ nest::iaf_cond_exp::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/iaf_cond_exp.h b/models/iaf_cond_exp.h index 926831195f..28908e383a 100644 --- a/models/iaf_cond_exp.h +++ b/models/iaf_cond_exp.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_cond_exp_sfa_rr.cpp b/models/iaf_cond_exp_sfa_rr.cpp index d37b461e06..91b8ae6d69 100644 --- a/models/iaf_cond_exp_sfa_rr.cpp +++ b/models/iaf_cond_exp_sfa_rr.cpp @@ -35,6 +35,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -442,7 +443,7 @@ nest::iaf_cond_exp_sfa_rr::update( Time const& origin, const long from, const lo S_.y_[ State_::G_RR ] += P_.q_rr; SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -460,12 +461,12 @@ nest::iaf_cond_exp_sfa_rr::handle( SpikeEvent& e ) if ( e.get_weight() > 0.0 ) { - B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_exc_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spike_inh_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), -e.get_weight() * e.get_multiplicity() ); } } @@ -478,7 +479,7 @@ nest::iaf_cond_exp_sfa_rr::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/iaf_cond_exp_sfa_rr.h b/models/iaf_cond_exp_sfa_rr.h index 12c156f5a6..98d34d478b 100644 --- a/models/iaf_cond_exp_sfa_rr.h +++ b/models/iaf_cond_exp_sfa_rr.h @@ -40,7 +40,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_alpha.cpp b/models/iaf_psc_alpha.cpp index 053a30a22c..431dfb3280 100644 --- a/models/iaf_psc_alpha.cpp +++ b/models/iaf_psc_alpha.cpp @@ -28,12 +28,12 @@ // Includes from libnestutil: #include "dict_util.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "iaf_propagator.h" #include "kernel_manager.h" #include "nest_impl.h" #include "numerics.h" #include "ring_buffer_impl.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "dictutils.h" @@ -328,7 +328,7 @@ iaf_psc_alpha::update( Time const& origin, const long from, const long to ) S_.dI_ex_ *= V_.P11_ex_; // get read access to the correct input-buffer slot - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( lag ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( lag ); auto& input = B_.input_buffer_.get_values_all_channels( input_buffer_slot ); // Apply spikes delivered in this step; spikes arriving at T+1 have @@ -357,7 +357,7 @@ iaf_psc_alpha::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -376,8 +376,8 @@ iaf_psc_alpha::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ) ); const double s = e.get_weight() * e.get_multiplicity(); @@ -390,8 +390,8 @@ iaf_psc_alpha::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ) ); const double I = e.get_current(); const double w = e.get_weight(); diff --git a/models/iaf_psc_alpha.h b/models/iaf_psc_alpha.h index a13b58e7e0..b557599bbb 100644 --- a/models/iaf_psc_alpha.h +++ b/models/iaf_psc_alpha.h @@ -30,7 +30,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_alpha_multisynapse.cpp b/models/iaf_psc_alpha_multisynapse.cpp index cee69d2889..7a0e1648f2 100644 --- a/models/iaf_psc_alpha_multisynapse.cpp +++ b/models/iaf_psc_alpha_multisynapse.cpp @@ -28,11 +28,11 @@ // Includes from libnestutil: #include "dict_util.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "iaf_propagator.h" #include "kernel_manager.h" #include "nest_impl.h" #include "numerics.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "dict.h" @@ -371,7 +371,7 @@ iaf_psc_alpha_multisynapse::update( Time const& origin, const long from, const l set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -400,7 +400,8 @@ iaf_psc_alpha_multisynapse::handle( SpikeEvent& e ) assert( e.get_delay_steps() > 0 ); B_.spikes_[ e.get_rport() - 1 ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -412,7 +413,7 @@ iaf_psc_alpha_multisynapse::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * I ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * I ); } void diff --git a/models/iaf_psc_alpha_multisynapse.h b/models/iaf_psc_alpha_multisynapse.h index 61852db6ef..0af4e63a62 100644 --- a/models/iaf_psc_alpha_multisynapse.h +++ b/models/iaf_psc_alpha_multisynapse.h @@ -33,7 +33,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_alpha_ps.cpp b/models/iaf_psc_alpha_ps.cpp index 885d1f2051..16ba02266b 100644 --- a/models/iaf_psc_alpha_ps.cpp +++ b/models/iaf_psc_alpha_ps.cpp @@ -33,6 +33,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -474,7 +475,7 @@ nest::iaf_psc_alpha_ps::handle( SpikeEvent& e ) */ const long Tdeliver = e.get_stamp().get_steps() + e.get_delay_steps() - 1; - B_.events_.add_spike( e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), + B_.events_.add_spike( e.get_rel_delivery_steps( nest::kernel::manager< SimulationManager >.get_slice_origin() ), Tdeliver, e.get_offset(), e.get_weight() * e.get_multiplicity() ); @@ -489,7 +490,8 @@ nest::iaf_psc_alpha_ps::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( + e.get_rel_delivery_steps( nest::kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void @@ -554,7 +556,7 @@ nest::iaf_psc_alpha_ps::emit_spike_( Time const& origin, const long lag, const d set_spiketime( Time::step( S_.last_spike_step_ ), S_.last_spike_offset_ ); SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); return; } @@ -576,7 +578,7 @@ nest::iaf_psc_alpha_ps::emit_instant_spike_( Time const& origin, const long lag, set_spiketime( Time::step( S_.last_spike_step_ ), S_.last_spike_offset_ ); SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); return; } diff --git a/models/iaf_psc_alpha_ps.h b/models/iaf_psc_alpha_ps.h index 7e1ac8190c..72c015a9ba 100644 --- a/models/iaf_psc_alpha_ps.h +++ b/models/iaf_psc_alpha_ps.h @@ -37,7 +37,7 @@ #include "nest_types.h" #include "ring_buffer.h" #include "slice_ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_delta.cpp b/models/iaf_psc_delta.cpp index 4de329ed60..a69fd5362d 100644 --- a/models/iaf_psc_delta.cpp +++ b/models/iaf_psc_delta.cpp @@ -33,6 +33,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -320,7 +321,7 @@ nest::iaf_psc_delta::update( Time const& origin, const long from, const long to set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -340,8 +341,8 @@ nest::iaf_psc_delta::handle( SpikeEvent& e ) // explicity, since it depends on delay and offset within // the update cycle. The way it is done here works, but // is clumsy and should be improved. - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -353,7 +354,7 @@ nest::iaf_psc_delta::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/iaf_psc_delta.h b/models/iaf_psc_delta.h index fde397dc15..9a30ff7909 100644 --- a/models/iaf_psc_delta.h +++ b/models/iaf_psc_delta.h @@ -29,7 +29,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_delta_ps.cpp b/models/iaf_psc_delta_ps.cpp index 1da42f3dcc..21a261795e 100644 --- a/models/iaf_psc_delta_ps.cpp +++ b/models/iaf_psc_delta_ps.cpp @@ -34,6 +34,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -481,7 +482,7 @@ nest::iaf_psc_delta_ps::emit_spike_( Time const& origin, const long lag, const d set_spiketime( Time::step( S_.last_spike_step_ ), S_.last_spike_offset_ ); SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } void @@ -501,7 +502,7 @@ nest::iaf_psc_delta_ps::emit_instant_spike_( Time const& origin, const long lag, set_spiketime( Time::step( S_.last_spike_step_ ), S_.last_spike_offset_ ); SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } void @@ -514,7 +515,7 @@ iaf_psc_delta_ps::handle( SpikeEvent& e ) in the queue. The time is computed according to Time Memo, Rule 3. */ const long Tdeliver = e.get_stamp().get_steps() + e.get_delay_steps() - 1; - B_.events_.add_spike( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.events_.add_spike( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), Tdeliver, e.get_offset(), e.get_weight() * e.get_multiplicity() ); @@ -529,7 +530,7 @@ iaf_psc_delta_ps::handle( CurrentEvent& e ) const double w = e.get_weight(); // add stepwise constant current; MH 2009-10-14 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } diff --git a/models/iaf_psc_delta_ps.h b/models/iaf_psc_delta_ps.h index 67c913fb1e..cd32db5f88 100644 --- a/models/iaf_psc_delta_ps.h +++ b/models/iaf_psc_delta_ps.h @@ -33,7 +33,7 @@ #include "nest_types.h" #include "ring_buffer.h" #include "slice_ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_exp.cpp b/models/iaf_psc_exp.cpp index 48385040db..3afc005ab8 100644 --- a/models/iaf_psc_exp.cpp +++ b/models/iaf_psc_exp.cpp @@ -26,16 +26,13 @@ // Includes from libnestutil: #include "dict_util.h" #include "iaf_propagator.h" -#include "numerics.h" // Includes from nestkernel: #include "exceptions.h" -#include "iaf_propagator.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "numerics.h" #include "ring_buffer_impl.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "dictutils.h" @@ -314,7 +311,7 @@ nest::iaf_psc_exp::update( const Time& origin, const long from, const long to ) S_.i_syn_ex_ += ( 1. - V_.P11ex_ ) * S_.i_1_; // get read access to the correct input-buffer slot - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( lag ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( lag ); auto& input = B_.input_buffer_.get_values_all_channels( input_buffer_slot ); // the spikes arriving at T+1 have an immediate effect on the state of the @@ -335,7 +332,7 @@ nest::iaf_psc_exp::update( const Time& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -355,8 +352,8 @@ nest::iaf_psc_exp::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ) ); const double s = e.get_weight() * e.get_multiplicity(); @@ -372,8 +369,8 @@ nest::iaf_psc_exp::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ) ); if ( 0 == e.get_rport() ) { diff --git a/models/iaf_psc_exp.h b/models/iaf_psc_exp.h index 37b9a08d26..9db264eb79 100644 --- a/models/iaf_psc_exp.h +++ b/models/iaf_psc_exp.h @@ -30,7 +30,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_exp_htum.cpp b/models/iaf_psc_exp_htum.cpp index dd38c565cd..71d0f13d6a 100644 --- a/models/iaf_psc_exp_htum.cpp +++ b/models/iaf_psc_exp_htum.cpp @@ -26,11 +26,10 @@ // Includes from libnestutil: #include "dict_util.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "iaf_propagator.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "numerics.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "dictutils.h" @@ -332,7 +331,7 @@ nest::iaf_psc_exp_htum::update( Time const& origin, const long from, const long set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } else @@ -357,12 +356,12 @@ nest::iaf_psc_exp_htum::handle( SpikeEvent& e ) if ( e.get_weight() >= 0.0 ) { - B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spikes_in_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spikes_in_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } } @@ -376,7 +375,7 @@ nest::iaf_psc_exp_htum::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/iaf_psc_exp_htum.h b/models/iaf_psc_exp_htum.h index 62b349bd21..ed6c54eed2 100644 --- a/models/iaf_psc_exp_htum.h +++ b/models/iaf_psc_exp_htum.h @@ -30,7 +30,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_exp_multisynapse.cpp b/models/iaf_psc_exp_multisynapse.cpp index 7c53921537..ccc75160ac 100644 --- a/models/iaf_psc_exp_multisynapse.cpp +++ b/models/iaf_psc_exp_multisynapse.cpp @@ -25,11 +25,10 @@ // Includes from libnestutil: #include "dict_util.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "iaf_propagator.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "numerics.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "dict.h" @@ -337,7 +336,7 @@ iaf_psc_exp_multisynapse::update( const Time& origin, const long from, const lon set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -366,7 +365,8 @@ iaf_psc_exp_multisynapse::handle( SpikeEvent& e ) assert( e.get_delay_steps() > 0 ); B_.spikes_[ e.get_rport() - 1 ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -378,7 +378,7 @@ iaf_psc_exp_multisynapse::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * I ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * I ); } void diff --git a/models/iaf_psc_exp_multisynapse.h b/models/iaf_psc_exp_multisynapse.h index bebb073071..956aa0eacb 100644 --- a/models/iaf_psc_exp_multisynapse.h +++ b/models/iaf_psc_exp_multisynapse.h @@ -33,7 +33,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_exp_ps.cpp b/models/iaf_psc_exp_ps.cpp index 71f83acc78..fda97283e5 100644 --- a/models/iaf_psc_exp_ps.cpp +++ b/models/iaf_psc_exp_ps.cpp @@ -33,6 +33,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -443,7 +444,7 @@ nest::iaf_psc_exp_ps::handle( SpikeEvent& e ) */ const long Tdeliver = e.get_stamp().get_steps() + e.get_delay_steps() - 1; - B_.events_.add_spike( e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), + B_.events_.add_spike( e.get_rel_delivery_steps( nest::kernel::manager< SimulationManager >.get_slice_origin() ), Tdeliver, e.get_offset(), e.get_weight() * e.get_multiplicity() ); @@ -458,7 +459,8 @@ nest::iaf_psc_exp_ps::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( + e.get_rel_delivery_steps( nest::kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void @@ -517,7 +519,7 @@ nest::iaf_psc_exp_ps::emit_spike_( const Time& origin, const long lag, const dou SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } void @@ -538,7 +540,7 @@ nest::iaf_psc_exp_ps::emit_instant_spike_( const Time& origin, const long lag, c SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } double diff --git a/models/iaf_psc_exp_ps.h b/models/iaf_psc_exp_ps.h index 953bef593a..51b8647885 100644 --- a/models/iaf_psc_exp_ps.h +++ b/models/iaf_psc_exp_ps.h @@ -38,7 +38,7 @@ #include "recordables_map.h" #include "ring_buffer.h" #include "slice_ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/iaf_psc_exp_ps_lossless.cpp b/models/iaf_psc_exp_ps_lossless.cpp index dcbf6435bf..cc60989ccd 100644 --- a/models/iaf_psc_exp_ps_lossless.cpp +++ b/models/iaf_psc_exp_ps_lossless.cpp @@ -27,16 +27,15 @@ // Includes from nestkernel: #include "exceptions.h" -#include "nest_impl.h" -#include "universal_data_logger_impl.h" // Includes from libnestutil: #include "dict_util.h" +#include "genericmodel_impl.h" #include "iaf_propagator.h" +#include "nest_impl.h" #include "regula_falsi.h" // Includes from sli: -#include "dict.h" #include "dictutils.h" @@ -487,7 +486,7 @@ nest::iaf_psc_exp_ps_lossless::handle( SpikeEvent& e ) */ const long Tdeliver = e.get_stamp().get_steps() + e.get_delay_steps() - 1; - B_.events_.add_spike( e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), + B_.events_.add_spike( e.get_rel_delivery_steps( nest::kernel::manager< SimulationManager >.get_slice_origin() ), Tdeliver, e.get_offset(), e.get_weight() * e.get_multiplicity() ); @@ -502,7 +501,8 @@ nest::iaf_psc_exp_ps_lossless::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( + e.get_rel_delivery_steps( nest::kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void @@ -560,7 +560,7 @@ nest::iaf_psc_exp_ps_lossless::emit_spike_( const Time& origin, const long lag, SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } void @@ -581,7 +581,7 @@ nest::iaf_psc_exp_ps_lossless::emit_instant_spike_( const Time& origin, const lo SpikeEvent se; se.set_offset( S_.last_spike_offset_ ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } double diff --git a/models/iaf_psc_exp_ps_lossless.h b/models/iaf_psc_exp_ps_lossless.h index 95f3becabc..7407c5580b 100644 --- a/models/iaf_psc_exp_ps_lossless.h +++ b/models/iaf_psc_exp_ps_lossless.h @@ -38,7 +38,7 @@ #include "recordables_map.h" #include "ring_buffer.h" #include "slice_ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest diff --git a/models/iaf_tum_2000.cpp b/models/iaf_tum_2000.cpp index 29ae084558..a721f99d2b 100644 --- a/models/iaf_tum_2000.cpp +++ b/models/iaf_tum_2000.cpp @@ -25,16 +25,13 @@ // Includes from libnestutil: #include "dict_util.h" #include "iaf_propagator.h" -#include "numerics.h" // Includes from nestkernel: #include "exceptions.h" -#include "iaf_propagator.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "numerics.h" #include "ring_buffer_impl.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "dictutils.h" @@ -367,7 +364,7 @@ nest::iaf_tum_2000::update( const Time& origin, const long from, const long to ) S_.i_syn_ex_ += ( 1. - V_.P11ex_ ) * S_.i_1_; // get read access to the correct input-buffer slot - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( lag ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( lag ); auto& input = B_.input_buffer_.get_values_all_channels( input_buffer_slot ); // the spikes arriving at T+1 have an immediate effect on the state of the @@ -430,7 +427,7 @@ nest::iaf_tum_2000::update( const Time& origin, const long from, const long to ) // send spike with datafield SpikeEvent se; se.set_offset( delta_y_tsp ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -450,8 +447,8 @@ nest::iaf_tum_2000::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ) ); // Multiply with datafield from SpikeEvent to apply depression/facilitation computed by presynaptic neuron double s = e.get_weight() * e.get_multiplicity(); @@ -473,8 +470,8 @@ nest::iaf_tum_2000::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ) ); if ( 0 == e.get_rport() ) { diff --git a/models/iaf_tum_2000.h b/models/iaf_tum_2000.h index 76d2402010..5ce5a35fc3 100644 --- a/models/iaf_tum_2000.h +++ b/models/iaf_tum_2000.h @@ -30,7 +30,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/ignore_and_fire.cpp b/models/ignore_and_fire.cpp index 82b61785da..4a56a41e64 100644 --- a/models/ignore_and_fire.cpp +++ b/models/ignore_and_fire.cpp @@ -22,20 +22,16 @@ #include "ignore_and_fire.h" -// C++ includes: -#include - // Includes from nestkernel: #include "exceptions.h" -#include "nest_impl.h" -#include "universal_data_logger_impl.h" // Includes from libnestutil: #include "dict_util.h" -#include "iaf_propagator.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" -#include "numerics.h" +#include "nest_impl.h" #include "ring_buffer_impl.h" +#include "universal_data_logger_impl.h" // Includes from sli: #include "dictutils.h" @@ -185,7 +181,7 @@ ignore_and_fire::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } else { @@ -202,8 +198,8 @@ ignore_and_fire::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ) ); const double s = e.get_weight() * e.get_multiplicity(); // separate buffer channels for excitatory and inhibitory inputs @@ -215,8 +211,8 @@ ignore_and_fire::handle( CurrentEvent& e ) { assert( e.get_delay_steps() > 0 ); - const size_t input_buffer_slot = kernel().event_delivery_manager.get_modulo( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ) ); + const size_t input_buffer_slot = kernel::manager< EventDeliveryManager >.get_modulo( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ) ); const double I = e.get_current(); const double w = e.get_weight(); diff --git a/models/ignore_and_fire.h b/models/ignore_and_fire.h index 857e596ce9..f3f8fdbbd7 100644 --- a/models/ignore_and_fire.h +++ b/models/ignore_and_fire.h @@ -29,7 +29,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { @@ -116,24 +116,24 @@ class ignore_and_fire : public ArchivingNode using Node::handle; using Node::handles_test_event; - size_t send_test_event( Node&, size_t, synindex, bool ); + size_t send_test_event( Node&, size_t, synindex, bool ) override; - void handle( SpikeEvent& ); - void handle( CurrentEvent& ); - void handle( DataLoggingRequest& ); + void handle( SpikeEvent& ) override; + void handle( CurrentEvent& ) override; + void handle( DataLoggingRequest& ) override; - size_t handles_test_event( SpikeEvent&, size_t ); - size_t handles_test_event( CurrentEvent&, size_t ); - size_t handles_test_event( DataLoggingRequest&, size_t ); + size_t handles_test_event( SpikeEvent&, size_t ) override; + size_t handles_test_event( CurrentEvent&, size_t ) override; + size_t handles_test_event( DataLoggingRequest&, size_t ) override; - void get_status( DictionaryDatum& ) const; - void set_status( const DictionaryDatum& ); + void get_status( DictionaryDatum& ) const override; + void set_status( const DictionaryDatum& ) override; private: - void init_buffers_(); - void pre_run_hook(); + void init_buffers_() override; + void pre_run_hook() override; - void update( Time const&, const long, const long ); + void update( Time const&, const long, const long ) override; // The next two classes need to be friends to access the State_ class/member friend class RecordablesMap< ignore_and_fire >; diff --git a/models/inhomogeneous_poisson_generator.cpp b/models/inhomogeneous_poisson_generator.cpp index 8f0b5f58ba..e411ad570c 100644 --- a/models/inhomogeneous_poisson_generator.cpp +++ b/models/inhomogeneous_poisson_generator.cpp @@ -22,15 +22,11 @@ #include "inhomogeneous_poisson_generator.h" -// C++ includes: -#include - -// Includes from libnestutil: -#include "numerics.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" +#include "event_delivery_manager.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -85,7 +81,7 @@ nest::inhomogeneous_poisson_generator::Parameters_::assert_valid_rate_time_and_i { Time t_rate; - if ( t <= kernel().simulation_manager.get_time().get_ms() ) + if ( t <= kernel::manager< SimulationManager >.get_time().get_ms() ) { throw BadProperty( "Time points must lie strictly in the future." ); } @@ -272,7 +268,7 @@ nest::inhomogeneous_poisson_generator::update( Time const& origin, const long fr if ( B_.rate_ > 0 and StimulationDevice::is_active( Time::step( curr_time ) ) ) { DSSpikeEvent se; - kernel().event_delivery_manager.send( *this, se, offs ); + kernel::manager< EventDeliveryManager >.send( *this, se, offs ); } } } diff --git a/models/inhomogeneous_poisson_generator.h b/models/inhomogeneous_poisson_generator.h index 40efca5aa3..f081568e78 100644 --- a/models/inhomogeneous_poisson_generator.h +++ b/models/inhomogeneous_poisson_generator.h @@ -30,7 +30,7 @@ #include "connection.h" #include "device_node.h" #include "event.h" -#include "nest.h" +#include "nest_impl.h" #include "random_generators.h" #include "ring_buffer.h" #include "stimulation_device.h" diff --git a/models/izhikevich.cpp b/models/izhikevich.cpp index 9865f74427..375460e378 100644 --- a/models/izhikevich.cpp +++ b/models/izhikevich.cpp @@ -30,8 +30,8 @@ #include "numerics.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -232,7 +232,7 @@ nest::izhikevich::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } // set new input current @@ -247,8 +247,8 @@ void nest::izhikevich::handle( SpikeEvent& e ) { assert( e.get_delay_steps() > 0 ); - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -258,7 +258,7 @@ nest::izhikevich::handle( CurrentEvent& e ) const double c = e.get_current(); const double w = e.get_weight(); - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/izhikevich.h b/models/izhikevich.h index 128020a698..e8dfb55bf7 100644 --- a/models/izhikevich.h +++ b/models/izhikevich.h @@ -29,7 +29,7 @@ #include "event.h" #include "nest_types.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/jonke_synapse.cpp b/models/jonke_synapse.cpp index 3aea1fb292..e261a4381e 100644 --- a/models/jonke_synapse.cpp +++ b/models/jonke_synapse.cpp @@ -22,7 +22,6 @@ #include "jonke_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/jonke_synapse.h b/models/jonke_synapse.h index e8bb578566..d8b2140be1 100644 --- a/models/jonke_synapse.h +++ b/models/jonke_synapse.h @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "common_synapse_properties.h" #include "connection.h" +#include "connection_manager.h" #include "connector_model.h" #include "event.h" @@ -329,7 +330,7 @@ jonke_synapse< targetidentifierT >::send( Event& e, size_t t, const JonkeCommonP ++start; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / cp.tau_plus_ ), cp ); } diff --git a/models/lin_rate.cpp b/models/lin_rate.cpp index 2db3fcafd1..2c524a2afd 100644 --- a/models/lin_rate.cpp +++ b/models/lin_rate.cpp @@ -24,8 +24,8 @@ // Includes from nestkernel #include "kernel_manager.h" -#include "model_manager_impl.h" -#include "nest_impl.h" + +#include namespace nest { diff --git a/models/lin_rate.h b/models/lin_rate.h index 5482c62aae..e11e025c0e 100644 --- a/models/lin_rate.h +++ b/models/lin_rate.h @@ -25,11 +25,8 @@ // Includes from models: #include "rate_neuron_ipn.h" -#include "rate_neuron_ipn_impl.h" #include "rate_neuron_opn.h" -#include "rate_neuron_opn_impl.h" #include "rate_transformer_node.h" -#include "rate_transformer_node_impl.h" namespace nest { diff --git a/models/mat2_psc_exp.cpp b/models/mat2_psc_exp.cpp index 104d20af0f..983b67d033 100644 --- a/models/mat2_psc_exp.cpp +++ b/models/mat2_psc_exp.cpp @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -341,7 +342,7 @@ nest::mat2_psc_exp::update( Time const& origin, const long from, const long to ) set_spiketime( Time::step( origin.get_steps() + lag + 1 ) ); SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } else @@ -366,12 +367,12 @@ nest::mat2_psc_exp::handle( SpikeEvent& e ) if ( e.get_weight() >= 0.0 ) { - B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spikes_ex_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } else { - B_.spikes_in_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.spikes_in_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); } } @@ -385,7 +386,7 @@ nest::mat2_psc_exp::handle( CurrentEvent& e ) const double w = e.get_weight(); // add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/mat2_psc_exp.h b/models/mat2_psc_exp.h index 6cecbb30b6..1d9d7630ed 100644 --- a/models/mat2_psc_exp.h +++ b/models/mat2_psc_exp.h @@ -31,7 +31,7 @@ #include "nest_types.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/mcculloch_pitts_neuron.cpp b/models/mcculloch_pitts_neuron.cpp index 2f8b15a6d9..9032171e44 100644 --- a/models/mcculloch_pitts_neuron.cpp +++ b/models/mcculloch_pitts_neuron.cpp @@ -24,9 +24,6 @@ // Includes from nestkernel #include "kernel_manager.h" -#include "model_manager_impl.h" -#include "nest_impl.h" -#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/mip_generator.cpp b/models/mip_generator.cpp index bf60516e97..e858b8784d 100644 --- a/models/mip_generator.cpp +++ b/models/mip_generator.cpp @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" @@ -142,7 +143,7 @@ nest::mip_generator::update( Time const& T, const long from, const long to ) DSSpikeEvent se; se.set_multiplicity( n_parent_spikes ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } } diff --git a/models/models.h b/models/models.h index 3065884cf3..8dd3c9f481 100644 --- a/models/models.h +++ b/models/models.h @@ -24,7 +24,7 @@ #define MODELS_H // Includes from nestkernel: -#include "nest.h" +#include "nest_impl.h" namespace nest { diff --git a/models/multimeter.cpp b/models/multimeter.cpp index 2943c45850..7273de8dde 100644 --- a/models/multimeter.cpp +++ b/models/multimeter.cpp @@ -22,13 +22,9 @@ #include "multimeter.h" -// Includes from nestkernel: -#include "event_delivery_manager_impl.h" -#include "model_manager_impl.h" -#include "nest_impl.h" - // Includes from libnestutil: #include "dict_util.h" +#include "event_delivery_manager_impl.h" namespace nest { @@ -210,7 +206,7 @@ multimeter::update( Time const& origin, const long from, const long ) // // Note that not all nodes receiving the request will necessarily answer. DataLoggingRequest req; - kernel().event_delivery_manager.send( *this, req ); + kernel::manager< EventDeliveryManager >.send( *this, req ); } void diff --git a/models/multimeter.h b/models/multimeter.h index 80a3a5991a..551160cb47 100644 --- a/models/multimeter.h +++ b/models/multimeter.h @@ -30,7 +30,9 @@ #include "connection.h" #include "device_node.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "nest_impl.h" #include "nest_timeconverter.h" #include "recording_device.h" @@ -38,6 +40,8 @@ #include "dictutils.h" #include "name.h" +#include "node_manager.h" + /* BeginUserDocs: device, recorder Short description @@ -247,7 +251,7 @@ nest::multimeter::get_status( DictionaryDatum& d ) const // siblings on other threads if ( get_thread() == 0 ) { - const std::vector< Node* > siblings = kernel().node_manager.get_thread_siblings( get_node_id() ); + const std::vector< Node* > siblings = kernel::manager< NodeManager >.get_thread_siblings( get_node_id() ); std::vector< Node* >::const_iterator s; for ( s = siblings.begin() + 1; s != siblings.end(); ++s ) { diff --git a/models/music_cont_in_proxy.cpp b/models/music_cont_in_proxy.cpp index b0301aa8e4..11783a7a01 100644 --- a/models/music_cont_in_proxy.cpp +++ b/models/music_cont_in_proxy.cpp @@ -29,7 +29,6 @@ #include "dict.h" #include "dictutils.h" #include "doubledatum.h" -#include "integerdatum.h" // Includes from libnestutil: #include "compose.hpp" @@ -37,8 +36,13 @@ #include "logging.h" // Includes from nestkernel: +#include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "music_manager.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" void nest::register_music_cont_in_proxy( const std::string& name ) @@ -133,7 +137,7 @@ nest::music_cont_in_proxy::pre_run_hook() // only publish the port once if ( not S_.published_ ) { - MUSIC::Setup* s = kernel().music_manager.get_music_setup(); + MUSIC::Setup* s = kernel::manager< MUSICManager >.get_music_setup(); if ( s == 0 ) { throw MUSICSimulationHasRun( get_name() ); diff --git a/models/music_cont_out_proxy.cpp b/models/music_cont_out_proxy.cpp index a3d57d4f58..c09d67012f 100644 --- a/models/music_cont_out_proxy.cpp +++ b/models/music_cont_out_proxy.cpp @@ -30,9 +30,14 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "music_manager.h" #include "nest_datums.h" #include "nest_impl.h" +#include "node_manager.h" +#include "universal_data_logger_impl.h" // Includes from libnestutil: #include "compose.hpp" @@ -41,8 +46,6 @@ // Includes from sli: #include "dict.h" #include "dictutils.h" -#include "doubledatum.h" -#include "integerdatum.h" void nest::register_music_cont_out_proxy( const std::string& name ) @@ -243,16 +246,16 @@ nest::music_cont_out_proxy::pre_run_hook() // only publish the output port once, if ( S_.published_ == false ) { - const size_t synmodel_id = kernel().model_manager.get_synapse_model_id( "static_synapse" ); + const size_t synmodel_id = kernel::manager< ModelManager >.get_synapse_model_id( "static_synapse" ); std::vector< MUSIC::GlobalIndex > music_index_map; DictionaryDatum dummy_params = new Dictionary(); for ( size_t i = 0; i < P_.targets_->size(); ++i ) { const size_t tnode_id = ( *P_.targets_ )[ i ]; - if ( kernel().node_manager.is_local_node_id( tnode_id ) ) + if ( kernel::manager< NodeManager >.is_local_node_id( tnode_id ) ) { - kernel().connection_manager.connect( get_node_id(), tnode_id, dummy_params, synmodel_id ); + kernel::manager< ConnectionManager >.connect( get_node_id(), tnode_id, dummy_params, synmodel_id ); for ( size_t j = 0; j < P_.record_from_.size(); ++j ) { @@ -261,7 +264,7 @@ nest::music_cont_out_proxy::pre_run_hook() } } - MUSIC::Setup* s = kernel().music_manager.get_music_setup(); + MUSIC::Setup* s = kernel::manager< MUSICManager >.get_music_setup(); if ( s == 0 ) { throw MUSICSimulationHasRun( get_name() ); @@ -324,7 +327,7 @@ nest::music_cont_out_proxy::get_status( DictionaryDatum& d ) const // siblings on other threads if ( get_thread() == 0 ) { - const std::vector< Node* > siblings = kernel().node_manager.get_thread_siblings( get_node_id() ); + const std::vector< Node* > siblings = kernel::manager< NodeManager >.get_thread_siblings( get_node_id() ); std::vector< Node* >::const_iterator s; for ( s = siblings.begin() + 1; s != siblings.end(); ++s ) { @@ -360,7 +363,7 @@ nest::music_cont_out_proxy::update( Time const& origin, const long from, const l // // Note that not all nodes receiving the request will necessarily answer. DataLoggingRequest req; - kernel().event_delivery_manager.send( *this, req ); + kernel::manager< EventDeliveryManager >.send( *this, req ); } void diff --git a/models/music_event_in_proxy.cpp b/models/music_event_in_proxy.cpp index 331d195f46..6a7e417640 100644 --- a/models/music_event_in_proxy.cpp +++ b/models/music_event_in_proxy.cpp @@ -31,16 +31,12 @@ #include "arraydatum.h" #include "dict.h" #include "dictutils.h" -#include "doubledatum.h" -#include "integerdatum.h" - -// Includes from libnestutil: -#include "compose.hpp" -#include "logging.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" +#include "connection_manager.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "music_manager.h" #include "nest_impl.h" void @@ -109,7 +105,7 @@ nest::music_event_in_proxy::music_event_in_proxy() , S_() { // Register port for the model so it is available as default - kernel().music_manager.register_music_in_port( P_.port_name_ ); + kernel::manager< MUSICManager >.register_music_in_port( P_.port_name_ ); } nest::music_event_in_proxy::music_event_in_proxy( const music_event_in_proxy& n ) @@ -118,7 +114,7 @@ nest::music_event_in_proxy::music_event_in_proxy( const music_event_in_proxy& n , S_( n.S_ ) { // Register port for node instance because MusicManager manages ports via reference count - kernel().music_manager.register_music_in_port( P_.port_name_ ); + kernel::manager< MUSICManager >.register_music_in_port( P_.port_name_ ); } @@ -137,7 +133,7 @@ nest::music_event_in_proxy::pre_run_hook() // register my port and my channel at the scheduler if ( not S_.registered_ ) { - kernel().music_manager.register_music_event_in_proxy( P_.port_name_, P_.channel_, this ); + kernel::manager< MUSICManager >.register_music_event_in_proxy( P_.port_name_, P_.channel_, this ); S_.registered_ = true; } } @@ -159,8 +155,8 @@ nest::music_event_in_proxy::set_status( const DictionaryDatum& d ) stmp.set( d, P_ ); // throws if BadProperty // if we get here, temporaries contain consistent set of properties - kernel().music_manager.unregister_music_in_port( P_.port_name_ ); - kernel().music_manager.register_music_in_port( ptmp.port_name_ ); + kernel::manager< MUSICManager >.unregister_music_in_port( P_.port_name_ ); + kernel::manager< MUSICManager >.register_music_in_port( ptmp.port_name_ ); P_ = ptmp; S_ = stmp; @@ -171,9 +167,9 @@ nest::music_event_in_proxy::handle( SpikeEvent& e ) { e.set_sender( *this ); - for ( size_t t = 0; t < kernel().vp_manager.get_num_threads(); ++t ) + for ( size_t t = 0; t < kernel::manager< VPManager >.get_num_threads(); ++t ) { - kernel().connection_manager.send_from_device( t, local_device_id_, e ); + kernel::manager< ConnectionManager >.send_from_device( t, local_device_id_, e ); } } diff --git a/models/music_event_out_proxy.cpp b/models/music_event_out_proxy.cpp index 7c30ccd47d..9d84689c64 100644 --- a/models/music_event_out_proxy.cpp +++ b/models/music_event_out_proxy.cpp @@ -31,7 +31,6 @@ #include "arraydatum.h" #include "dict.h" #include "dictutils.h" -#include "doubledatum.h" #include "integerdatum.h" // Includes from libnestutil: @@ -39,7 +38,9 @@ #include "logging.h" // Includes from nestkernel: +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "music_manager.h" #include "nest_impl.h" void @@ -137,7 +138,7 @@ nest::music_event_out_proxy::pre_run_hook() // only publish the output port once, if ( not S_.published_ ) { - MUSIC::Setup* s = kernel().music_manager.get_music_setup(); + MUSIC::Setup* s = kernel::manager< MUSICManager >.get_music_setup(); if ( s == 0 ) { throw MUSICSimulationHasRun( get_name() ); diff --git a/models/music_message_in_proxy.cpp b/models/music_message_in_proxy.cpp index b0b7aa4f82..e444c733ab 100644 --- a/models/music_message_in_proxy.cpp +++ b/models/music_message_in_proxy.cpp @@ -29,16 +29,19 @@ // Includes from sli: #include "arraydatum.h" -#include "doubledatum.h" -#include "integerdatum.h" // Includes from libnestutil: #include "compose.hpp" #include "logging.h" // Includes from nestkernel: +#include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "music_manager.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" void nest::register_music_message_in_proxy( const std::string& name ) @@ -131,7 +134,7 @@ nest::music_message_in_proxy::pre_run_hook() // only publish the port once, if ( not S_.published_ ) { - MUSIC::Setup* s = kernel().music_manager.get_music_setup(); + MUSIC::Setup* s = kernel::manager< MUSICManager >.get_music_setup(); if ( s == 0 ) { throw MUSICSimulationHasRun( get_name() ); diff --git a/models/music_rate_in_proxy.cpp b/models/music_rate_in_proxy.cpp index 20f6a23dd9..586ec1539a 100644 --- a/models/music_rate_in_proxy.cpp +++ b/models/music_rate_in_proxy.cpp @@ -29,7 +29,6 @@ #include "dict.h" #include "dictutils.h" #include "doubledatum.h" -#include "integerdatum.h" // Includes from libnestutil: #include "compose.hpp" @@ -37,8 +36,12 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "music_manager.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" void nest::register_music_rate_in_proxy( const std::string& name ) @@ -108,7 +111,7 @@ nest::music_rate_in_proxy::music_rate_in_proxy() , S_() { // Register port for the model so it is available as default - kernel().music_manager.register_music_in_port( P_.port_name_ ); + kernel::manager< MUSICManager >.register_music_in_port( P_.port_name_ ); } nest::music_rate_in_proxy::music_rate_in_proxy( const music_rate_in_proxy& n ) @@ -117,7 +120,7 @@ nest::music_rate_in_proxy::music_rate_in_proxy( const music_rate_in_proxy& n ) , S_( n.S_ ) { // Register port for node instance because MusicManager manages ports via reference count - kernel().music_manager.register_music_in_port( P_.port_name_ ); + kernel::manager< MUSICManager >.register_music_in_port( P_.port_name_ ); } @@ -136,7 +139,7 @@ nest::music_rate_in_proxy::pre_run_hook() // only publish the port once if ( not S_.registered_ ) { - kernel().music_manager.register_music_rate_in_proxy( P_.port_name_, P_.channel_, this ); + kernel::manager< MUSICManager >.register_music_rate_in_proxy( P_.port_name_, P_.channel_, this ); S_.registered_ = true; } } @@ -160,8 +163,8 @@ nest::music_rate_in_proxy::set_status( const DictionaryDatum& d ) stmp.set( d, P_ ); // throws if BadProperty // if we get here, temporaries contain consistent set of properties - kernel().music_manager.unregister_music_in_port( P_.port_name_ ); - kernel().music_manager.register_music_in_port( ptmp.port_name_ ); + kernel::manager< MUSICManager >.unregister_music_in_port( P_.port_name_ ); + kernel::manager< MUSICManager >.register_music_in_port( ptmp.port_name_ ); P_ = ptmp; S_ = stmp; } @@ -174,7 +177,7 @@ nest::music_rate_in_proxy::update( Time const&, const long, const long ) void nest::music_rate_in_proxy::handle( InstantaneousRateConnectionEvent& e ) { - kernel().event_delivery_manager.send_secondary( *this, e ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, e ); } diff --git a/models/music_rate_out_proxy.cpp b/models/music_rate_out_proxy.cpp index 9753421447..32c2c1f013 100644 --- a/models/music_rate_out_proxy.cpp +++ b/models/music_rate_out_proxy.cpp @@ -24,23 +24,23 @@ #ifdef HAVE_MUSIC -// C++ includes: -#include - // Includes from sli: #include "arraydatum.h" #include "dict.h" #include "dictutils.h" -#include "doubledatum.h" -#include "integerdatum.h" // Includes from libnestutil: #include "compose.hpp" #include "logging.h" // Includes from nestkernel: +#include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "music_manager.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" /* ---------------------------------------------------------------- * Default constructors defining default parameters and state @@ -146,7 +146,7 @@ nest::music_rate_out_proxy::pre_run_hook() // only publish the output port once, if ( not S_.published_ ) { - MUSIC::Setup* s = kernel().music_manager.get_music_setup(); + MUSIC::Setup* s = kernel::manager< MUSICManager >.get_music_setup(); if ( s == 0 ) { diff --git a/models/noise_generator.cpp b/models/noise_generator.cpp index 7bc72369da..4a58406fe3 100644 --- a/models/noise_generator.cpp +++ b/models/noise_generator.cpp @@ -30,6 +30,8 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -39,6 +41,8 @@ #include "dictutils.h" #include "doubledatum.h" +#include "nest_timeconverter.h" + namespace nest { void @@ -243,7 +247,7 @@ nest::noise_generator::pre_run_hook() V_.dt_steps_ = P_.dt_.get_steps(); const double h = Time::get_resolution().get_ms(); - const double t = kernel().simulation_manager.get_time().get_ms(); + const double t = kernel::manager< SimulationManager >.get_time().get_ms(); // scale Hz to ms const double omega = 2.0 * numerics::pi * P_.freq_ / 1000.0; @@ -339,7 +343,7 @@ nest::noise_generator::update( Time const& origin, const long from, const long t B_.logger_.record_data( origin.get_steps() + offs ); DSCurrentEvent ce; - kernel().event_delivery_manager.send( *this, ce, offs ); + kernel::manager< EventDeliveryManager >.send( *this, ce, offs ); } } diff --git a/models/noise_generator.h b/models/noise_generator.h index 8f73511ae3..c465d5f2a8 100644 --- a/models/noise_generator.h +++ b/models/noise_generator.h @@ -28,13 +28,11 @@ // Includes from nestkernel: #include "connection.h" -#include "device_node.h" #include "event.h" -#include "nest_timeconverter.h" #include "nest_types.h" #include "random_generators.h" #include "stimulation_device.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { @@ -300,7 +298,7 @@ class noise_generator : public StimulationDevice inline size_t noise_generator::handles_test_event( DataLoggingRequest& dlr, size_t receptor_type ) { - if ( kernel().vp_manager.get_num_threads() > 1 ) + if ( kernel::manager< VPManager >.get_num_threads() > 1 ) { throw KernelException( "Recording from a noise_generator is only possible in single-threaded mode." ); } diff --git a/models/parrot_neuron.cpp b/models/parrot_neuron.cpp index 6009758f02..a924b413b8 100644 --- a/models/parrot_neuron.cpp +++ b/models/parrot_neuron.cpp @@ -23,17 +23,12 @@ #include "parrot_neuron.h" -// Includes from libnestutil: -#include "numerics.h" - // Includes from nestkernel: -#include "event_delivery_manager_impl.h" -#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -// Includes from sli: -#include "dictutils.h" +#include "nest_impl.h" namespace nest { @@ -67,7 +62,7 @@ parrot_neuron::update( Time const& origin, const long from, const long to ) // create a new SpikeEvent, set its multiplicity and send it SpikeEvent se; se.set_multiplicity( current_spikes_n ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); // set the spike times, respecting the multiplicity for ( unsigned long i = 0; i < current_spikes_n; i++ ) @@ -96,7 +91,7 @@ parrot_neuron::handle( SpikeEvent& e ) // Repeat only spikes incoming on port 0, port 1 will be ignored if ( 0 == e.get_rport() ) { - B_.n_spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.n_spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), static_cast< double >( e.get_multiplicity() ) ); } } diff --git a/models/parrot_neuron_ps.cpp b/models/parrot_neuron_ps.cpp index 18140972a8..c48ad3e12b 100644 --- a/models/parrot_neuron_ps.cpp +++ b/models/parrot_neuron_ps.cpp @@ -26,13 +26,14 @@ #include "numerics.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" -// Includes from sli: -#include "dictutils.h" +#include "event_delivery_manager.h" +#include "nest_impl.h" namespace nest { @@ -82,7 +83,7 @@ parrot_neuron_ps::update( Time const& origin, long const from, long const to ) SpikeEvent se; se.set_multiplicity( multiplicity ); se.set_offset( ev_offset ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); for ( unsigned long i = 0; i < multiplicity; ++i ) { @@ -119,7 +120,7 @@ parrot_neuron_ps::handle( SpikeEvent& e ) const long Tdeliver = e.get_stamp().get_steps() + e.get_delay_steps() - 1; // parrot ignores weight of incoming connection, store multiplicity - B_.events_.add_spike( e.get_rel_delivery_steps( nest::kernel().simulation_manager.get_slice_origin() ), + B_.events_.add_spike( e.get_rel_delivery_steps( nest::kernel::manager< SimulationManager >.get_slice_origin() ), Tdeliver, e.get_offset(), static_cast< double >( e.get_multiplicity() ) ); diff --git a/models/poisson_generator.cpp b/models/poisson_generator.cpp index 516a886bca..d5f85d774d 100644 --- a/models/poisson_generator.cpp +++ b/models/poisson_generator.cpp @@ -25,6 +25,7 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" @@ -138,7 +139,7 @@ nest::poisson_generator::update( Time const& T, const long from, const long to ) } DSSpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } diff --git a/models/poisson_generator_ps.cpp b/models/poisson_generator_ps.cpp index 7a913d15bc..7e9d730c31 100644 --- a/models/poisson_generator_ps.cpp +++ b/models/poisson_generator_ps.cpp @@ -27,12 +27,13 @@ #include // Includes from nestkernel: -#include "event_delivery_manager_impl.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" // Includes from libnestutil: #include "dict_util.h" +#include "event_delivery_manager_impl.h" // Includes from sli: #include "dict.h" @@ -205,7 +206,7 @@ nest::poisson_generator_ps::update( Time const& T, const long from, const long t // the event hook then sends out the real spikes with offgrid timing // We pretend to send at T+from DSSpikeEvent se; - kernel().event_delivery_manager.send( *this, se, from ); + kernel::manager< EventDeliveryManager >.send( *this, se, from ); } } diff --git a/models/pp_cond_exp_mc_urbanczik.cpp b/models/pp_cond_exp_mc_urbanczik.cpp index 04d58df15f..e1108f49b2 100644 --- a/models/pp_cond_exp_mc_urbanczik.cpp +++ b/models/pp_cond_exp_mc_urbanczik.cpp @@ -27,22 +27,23 @@ // C++ includes: #include -#include // Includes from libnestutil: #include "numerics.h" // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" -#include "model_manager_impl.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" +#include "urbanczik_archiving_node_impl.h" // Includes from sli: #include "dict.h" #include "dictutils.h" +#include "nest_impl.h" + /* ---------------------------------------------------------------- * Compartment name list * ---------------------------------------------------------------- */ @@ -665,7 +666,7 @@ nest::pp_cond_exp_mc_urbanczik::update( Time const& origin, const long from, con // And send the spike event SpikeEvent se; se.set_multiplicity( n_spikes ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); // Set spike time in order to make plasticity rules work for ( unsigned int i = 0; i < n_spikes; i++ ) @@ -702,7 +703,8 @@ nest::pp_cond_exp_mc_urbanczik::handle( SpikeEvent& e ) assert( e.get_rport() < 2 * NCOMP ); B_.spikes_[ e.get_rport() ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -714,7 +716,8 @@ nest::pp_cond_exp_mc_urbanczik::handle( CurrentEvent& e ) // add weighted current; HEP 2002-10-04 B_.currents_[ e.get_rport() ].add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_current() ); + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_current() ); } void diff --git a/models/pp_cond_exp_mc_urbanczik.h b/models/pp_cond_exp_mc_urbanczik.h index 9a109247bb..7d17d80a1b 100644 --- a/models/pp_cond_exp_mc_urbanczik.h +++ b/models/pp_cond_exp_mc_urbanczik.h @@ -43,9 +43,8 @@ #include "random_generators.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" #include "urbanczik_archiving_node.h" -#include "urbanczik_archiving_node_impl.h" // Includes from sli: #include "dictdatum.h" diff --git a/models/pp_psc_delta.cpp b/models/pp_psc_delta.cpp index 482fde1dff..b340ea7677 100644 --- a/models/pp_psc_delta.cpp +++ b/models/pp_psc_delta.cpp @@ -35,6 +35,7 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -432,7 +433,7 @@ nest::pp_psc_delta::update( Time const& origin, const long from, const long to ) // And send the spike event SpikeEvent se; se.set_multiplicity( n_spikes ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); // set spike time for STDP to work, // see https://github.com/nest/nest-simulator/issues/77 @@ -471,8 +472,8 @@ nest::pp_psc_delta::handle( SpikeEvent& e ) // explicitly, since it depends on delay and offset within // the update cycle. The way it is done here works, but // is clumsy and should be improved. - B_.spikes_.add_value( - e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), e.get_weight() * e.get_multiplicity() ); + B_.spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), + e.get_weight() * e.get_multiplicity() ); } void @@ -484,7 +485,7 @@ nest::pp_psc_delta::handle( CurrentEvent& e ) const double w = e.get_weight(); // Add weighted current; HEP 2002-10-04 - B_.currents_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), w * c ); + B_.currents_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), w * c ); } void diff --git a/models/pp_psc_delta.h b/models/pp_psc_delta.h index 979f9373b3..6982247498 100644 --- a/models/pp_psc_delta.h +++ b/models/pp_psc_delta.h @@ -30,7 +30,7 @@ #include "nest_types.h" #include "random_generators.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/ppd_sup_generator.cpp b/models/ppd_sup_generator.cpp index 32eb092145..455e16bff7 100644 --- a/models/ppd_sup_generator.cpp +++ b/models/ppd_sup_generator.cpp @@ -31,8 +31,11 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" // Includes from sli: #include "dict.h" @@ -263,7 +266,7 @@ nest::ppd_sup_generator::update( Time const& T, const long from, const long to ) } DSSpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } diff --git a/models/pulsepacket_generator.cpp b/models/pulsepacket_generator.cpp index 19b4db16c6..6b436adef7 100644 --- a/models/pulsepacket_generator.cpp +++ b/models/pulsepacket_generator.cpp @@ -27,11 +27,11 @@ // Includes from libnestutil: #include "dict_util.h" -#include "numerics.h" // Includes from nestkernel: #include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" @@ -149,7 +149,7 @@ nest::pulsepacket_generator::pre_run_hook() V_.tolerance = 1.0; } - const double now = ( kernel().simulation_manager.get_time() ).get_ms(); + const double now = ( kernel::manager< SimulationManager >.get_time() ).get_ms(); V_.start_center_idx_ = 0; V_.stop_center_idx_ = 0; @@ -227,7 +227,7 @@ nest::pulsepacket_generator::update( Time const& T, const long, const long to ) { SpikeEvent se; se.set_multiplicity( n_spikes ); - kernel().event_delivery_manager.send( *this, se, prev_spike - T.get_steps() ); + kernel::manager< EventDeliveryManager >.send( *this, se, prev_spike - T.get_steps() ); n_spikes = 0; } } diff --git a/models/quantal_stp_synapse.cpp b/models/quantal_stp_synapse.cpp index 829579605f..42b9b349b1 100644 --- a/models/quantal_stp_synapse.cpp +++ b/models/quantal_stp_synapse.cpp @@ -21,9 +21,7 @@ */ #include "quantal_stp_synapse.h" -#include "quantal_stp_synapse_impl.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/quantal_stp_synapse.h b/models/quantal_stp_synapse.h index 41b2fbf51d..4eb66cfe18 100644 --- a/models/quantal_stp_synapse.h +++ b/models/quantal_stp_synapse.h @@ -26,6 +26,8 @@ // Includes from nestkernel: #include "connection.h" +#include "nest_impl.h" + namespace nest { @@ -259,6 +261,70 @@ quantal_stp_synapse< targetidentifierT >::send( Event& e, size_t t, const Common return send_spike; } +template < typename targetidentifierT > +quantal_stp_synapse< targetidentifierT >::quantal_stp_synapse() + : ConnectionBase() + , weight_( 1.0 ) + , U_( 0.5 ) + , u_( U_ ) + , tau_rec_( 800.0 ) + , tau_fac_( 0.0 ) + , n_( 1 ) + , a_( n_ ) + , t_lastspike_( -1.0 ) +{ +} + +template < typename targetidentifierT > +void +quantal_stp_synapse< targetidentifierT >::get_status( DictionaryDatum& d ) const +{ + ConnectionBase::get_status( d ); + def< double >( d, names::weight, weight_ ); + def< double >( d, names::dU, U_ ); + def< double >( d, names::u, u_ ); + def< double >( d, names::tau_rec, tau_rec_ ); + def< double >( d, names::tau_fac, tau_fac_ ); + def< int >( d, names::n, n_ ); + def< int >( d, names::a, a_ ); +} + + +template < typename targetidentifierT > +void +quantal_stp_synapse< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) +{ + ConnectionBase::set_status( d, cm ); + updateValue< double >( d, names::weight, weight_ ); + + updateValue< double >( d, names::dU, U_ ); + if ( U_ > 1.0 or U_ < 0.0 ) + { + throw BadProperty( "'U' must be in [0,1]." ); + } + + updateValue< double >( d, names::u, u_ ); + if ( u_ > 1.0 or u_ < 0.0 ) + { + throw BadProperty( "'u' must be in [0,1]." ); + } + + updateValue< double >( d, names::tau_rec, tau_rec_ ); + if ( tau_rec_ <= 0.0 ) + { + throw BadProperty( "'tau_rec' must be > 0." ); + } + + updateValue< double >( d, names::tau_fac, tau_fac_ ); + if ( tau_fac_ < 0.0 ) + { + throw BadProperty( "'tau_fac' must be >= 0." ); + } + + updateValue< long >( d, names::n, n_ ); + updateValue< long >( d, names::a, a_ ); +} + } // namespace #endif // QUANTAL_STP_SYNAPSE_H diff --git a/models/quantal_stp_synapse_impl.h b/models/quantal_stp_synapse_impl.h deleted file mode 100644 index 1df262df46..0000000000 --- a/models/quantal_stp_synapse_impl.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * quantal_stp_synapse_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - */ - -#ifndef QUANTAL_STP_SYNAPSE_IMPL_H -#define QUANTAL_STP_SYNAPSE_IMPL_H - -#include "quantal_stp_synapse.h" - -// Includes from nestkernel: -#include "connection.h" -#include "connector_model.h" -#include "nest_names.h" - -// Includes from sli: -#include "dictutils.h" - -namespace nest -{ - -template < typename targetidentifierT > -quantal_stp_synapse< targetidentifierT >::quantal_stp_synapse() - : ConnectionBase() - , weight_( 1.0 ) - , U_( 0.5 ) - , u_( U_ ) - , tau_rec_( 800.0 ) - , tau_fac_( 0.0 ) - , n_( 1 ) - , a_( n_ ) - , t_lastspike_( -1.0 ) -{ -} - -template < typename targetidentifierT > -void -quantal_stp_synapse< targetidentifierT >::get_status( DictionaryDatum& d ) const -{ - ConnectionBase::get_status( d ); - def< double >( d, names::weight, weight_ ); - def< double >( d, names::dU, U_ ); - def< double >( d, names::u, u_ ); - def< double >( d, names::tau_rec, tau_rec_ ); - def< double >( d, names::tau_fac, tau_fac_ ); - def< int >( d, names::n, n_ ); - def< int >( d, names::a, a_ ); -} - - -template < typename targetidentifierT > -void -quantal_stp_synapse< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) -{ - ConnectionBase::set_status( d, cm ); - updateValue< double >( d, names::weight, weight_ ); - - updateValue< double >( d, names::dU, U_ ); - if ( U_ > 1.0 or U_ < 0.0 ) - { - throw BadProperty( "'U' must be in [0,1]." ); - } - - updateValue< double >( d, names::u, u_ ); - if ( u_ > 1.0 or u_ < 0.0 ) - { - throw BadProperty( "'u' must be in [0,1]." ); - } - - updateValue< double >( d, names::tau_rec, tau_rec_ ); - if ( tau_rec_ <= 0.0 ) - { - throw BadProperty( "'tau_rec' must be > 0." ); - } - - updateValue< double >( d, names::tau_fac, tau_fac_ ); - if ( tau_fac_ < 0.0 ) - { - throw BadProperty( "'tau_fac' must be >= 0." ); - } - - updateValue< long >( d, names::n, n_ ); - updateValue< long >( d, names::a, a_ ); -} - -} // of namespace nest - -#endif // #ifndef QUANTAL_STP_SYNAPSE_IMPL_H diff --git a/models/rate_connection_delayed.cpp b/models/rate_connection_delayed.cpp index 8e2c986a90..ecc1367707 100644 --- a/models/rate_connection_delayed.cpp +++ b/models/rate_connection_delayed.cpp @@ -22,7 +22,6 @@ #include "rate_connection_delayed.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/rate_connection_instantaneous.cpp b/models/rate_connection_instantaneous.cpp index 89c88c5bd5..0b06271415 100644 --- a/models/rate_connection_instantaneous.cpp +++ b/models/rate_connection_instantaneous.cpp @@ -22,7 +22,6 @@ #include "rate_connection_instantaneous.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/rate_neuron_ipn.h b/models/rate_neuron_ipn.h index 14c22920ac..d10e8f3a3d 100644 --- a/models/rate_neuron_ipn.h +++ b/models/rate_neuron_ipn.h @@ -23,22 +23,31 @@ #ifndef RATE_NEURON_IPN_H #define RATE_NEURON_IPN_H -// Generated includes: -#include "config.h" - // C++ includes: +#include // in case we need isnan() // fabs #include // Includes from nestkernel: #include "archiving_node.h" #include "connection.h" #include "event.h" -#include "nest_types.h" +#include "exceptions.h" +#include "genericmodel_impl.h" +#include "kernel_manager.h" +#include "nest_impl.h" #include "node.h" #include "random_generators.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" + +// Includes from libnestutil: +#include "dict_util.h" +#include "numerics.h" + +// Includes from sli: +#include "dict.h" +#include "dictutils.h" namespace nest { @@ -385,6 +394,429 @@ rate_neuron_ipn< TNonlinearities >::set_status( const DictionaryDatum& d ) nonlinearities_.set( d, this ); } +/* ---------------------------------------------------------------- + * Recordables map + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +RecordablesMap< rate_neuron_ipn< TNonlinearities > > rate_neuron_ipn< TNonlinearities >::recordablesMap_; + +/* ---------------------------------------------------------------- + * Default constructors defining default parameters and state + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +rate_neuron_ipn< TNonlinearities >::Parameters_::Parameters_() + : tau_( 10.0 ) // ms + , lambda_( 1.0 ) // ms + , sigma_( 1.0 ) + , mu_( 0.0 ) + , rectify_rate_( 0.0 ) + , linear_summation_( true ) + , rectify_output_( false ) + , mult_coupling_( false ) +{ + recordablesMap_.create(); +} + +template < class TNonlinearities > +rate_neuron_ipn< TNonlinearities >::State_::State_() + : rate_( 0.0 ) + , noise_( 0.0 ) +{ +} + +/* ---------------------------------------------------------------- + * Parameter and state extractions and manipulation functions + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +void +rate_neuron_ipn< TNonlinearities >::Parameters_::get( DictionaryDatum& d ) const +{ + def< double >( d, names::tau, tau_ ); + def< double >( d, names::lambda, lambda_ ); + def< double >( d, names::sigma, sigma_ ); + def< double >( d, names::mu, mu_ ); + def< double >( d, names::rectify_rate, rectify_rate_ ); + def< bool >( d, names::linear_summation, linear_summation_ ); + def< bool >( d, names::rectify_output, rectify_output_ ); + def< bool >( d, names::mult_coupling, mult_coupling_ ); + + // Also allow old names (to not break old scripts) + def< double >( d, names::std, sigma_ ); + def< double >( d, names::mean, mu_ ); +} + +template < class TNonlinearities > +void +rate_neuron_ipn< TNonlinearities >::Parameters_::set( const DictionaryDatum& d, Node* node ) +{ + updateValueParam< double >( d, names::tau, tau_, node ); + updateValueParam< double >( d, names::lambda, lambda_, node ); + updateValueParam< double >( d, names::mu, mu_, node ); + updateValueParam< double >( d, names::rectify_rate, rectify_rate_, node ); + updateValueParam< double >( d, names::sigma, sigma_, node ); + updateValueParam< bool >( d, names::linear_summation, linear_summation_, node ); + updateValueParam< bool >( d, names::rectify_output, rectify_output_, node ); + updateValueParam< bool >( d, names::mult_coupling, mult_coupling_, node ); + + // Check for old names + if ( updateValueParam< double >( d, names::mean, mu_, node ) ) + { + LOG( M_WARNING, + "rate_neuron_ipn< TNonlinearities >::Parameters_::set", + "The parameter mean has been renamed to mu. Please use the new " + "name from now on." ); + } + + if ( updateValueParam< double >( d, names::std, sigma_, node ) ) + { + LOG( M_WARNING, + "rate_neuron_ipn< TNonlinearities >::Parameters_::set", + "The parameter std has been renamed to sigma. Please use the new " + "name from now on." ); + } + + // Check for invalid parameters + if ( tau_ <= 0 ) + { + throw BadProperty( "Time constant must be > 0." ); + } + if ( lambda_ < 0 ) + { + throw BadProperty( "Passive decay rate must be >= 0." ); + } + if ( sigma_ < 0 ) + { + throw BadProperty( "Noise parameter must not be negative." ); + } + if ( rectify_rate_ < 0 ) + { + throw BadProperty( "Rectifying rate must not be negative." ); + } +} + +template < class TNonlinearities > +void +rate_neuron_ipn< TNonlinearities >::State_::get( DictionaryDatum& d ) const +{ + def< double >( d, names::rate, rate_ ); // Rate + def< double >( d, names::noise, noise_ ); // Noise +} + +template < class TNonlinearities > +void +rate_neuron_ipn< TNonlinearities >::State_::set( const DictionaryDatum& d, Node* node ) +{ + updateValueParam< double >( d, names::rate, rate_, node ); // Rate +} + +template < class TNonlinearities > +rate_neuron_ipn< TNonlinearities >::Buffers_::Buffers_( rate_neuron_ipn< TNonlinearities >& n ) + : logger_( n ) +{ +} + +template < class TNonlinearities > +rate_neuron_ipn< TNonlinearities >::Buffers_::Buffers_( const Buffers_&, rate_neuron_ipn< TNonlinearities >& n ) + : logger_( n ) +{ +} + +/* ---------------------------------------------------------------- + * Default and copy constructor for node + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn() + : ArchivingNode() + , P_() + , S_() + , B_( *this ) +{ + recordablesMap_.create(); + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); +} + +template < class TNonlinearities > +rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn( const rate_neuron_ipn& n ) + : ArchivingNode( n ) + , nonlinearities_( n.nonlinearities_ ) + , P_( n.P_ ) + , S_( n.S_ ) + , B_( n.B_, *this ) +{ + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); +} + +/* ---------------------------------------------------------------- + * Node initialization functions + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +void +rate_neuron_ipn< TNonlinearities >::init_buffers_() +{ + B_.delayed_rates_ex_.clear(); // includes resize + B_.delayed_rates_in_.clear(); // includes resize + + // resize buffers + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); + B_.instant_rates_ex_.resize( buffer_size, 0.0 ); + B_.instant_rates_in_.resize( buffer_size, 0.0 ); + B_.last_y_values.resize( buffer_size, 0.0 ); + B_.random_numbers.resize( buffer_size, numerics::nan ); + + // initialize random numbers + for ( unsigned int i = 0; i < buffer_size; i++ ) + { + B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) ); + } + + B_.logger_.reset(); // includes resize + ArchivingNode::clear_history(); +} + +template < class TNonlinearities > +void +rate_neuron_ipn< TNonlinearities >::pre_run_hook() +{ + B_.logger_.init(); // ensures initialization in case mm connected after Simulate + + const double h = Time::get_resolution().get_ms(); + + if ( P_.lambda_ > 0 ) + { + // use stochastic exponential Euler method + V_.P1_ = std::exp( -P_.lambda_ * h / P_.tau_ ); + V_.P2_ = -1.0 / P_.lambda_ * numerics::expm1( -P_.lambda_ * h / P_.tau_ ); + V_.input_noise_factor_ = std::sqrt( -0.5 / P_.lambda_ * numerics::expm1( -2. * P_.lambda_ * h / P_.tau_ ) ); + } + else + { + // use Euler-Maruyama method + V_.P1_ = 1; + V_.P2_ = h / P_.tau_; + V_.input_noise_factor_ = std::sqrt( h / P_.tau_ ); + } +} + +/* ---------------------------------------------------------------- + * Update and event handling functions + */ + +template < class TNonlinearities > +bool +rate_neuron_ipn< TNonlinearities >::update_( Time const& origin, + const long from, + const long to, + const bool called_from_wfr_update ) +{ + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); + const double wfr_tol = kernel::manager< SimulationManager >.get_wfr_tol(); + bool wfr_tol_exceeded = false; + + // allocate memory to store rates to be sent by rate events + std::vector< double > new_rates( buffer_size, 0.0 ); + + for ( long lag = from; lag < to; ++lag ) + { + // store rate + new_rates[ lag ] = S_.rate_; + // get noise + S_.noise_ = P_.sigma_ * B_.random_numbers[ lag ]; + // propagate rate to new time step (exponential integration) + S_.rate_ = V_.P1_ * new_rates[ lag ] + V_.P2_ * P_.mu_ + V_.input_noise_factor_ * S_.noise_; + + double delayed_rates_in = 0; + double delayed_rates_ex = 0; + if ( called_from_wfr_update ) + { + // use get_value_wfr_update to keep values in buffer + delayed_rates_in = B_.delayed_rates_in_.get_value_wfr_update( lag ); + delayed_rates_ex = B_.delayed_rates_ex_.get_value_wfr_update( lag ); + } + else + { + // use get_value to clear values in buffer after reading + delayed_rates_in = B_.delayed_rates_in_.get_value( lag ); + delayed_rates_ex = B_.delayed_rates_ex_.get_value( lag ); + } + double instant_rates_in = B_.instant_rates_in_[ lag ]; + double instant_rates_ex = B_.instant_rates_ex_[ lag ]; + double H_ex = 1.; // valid value for non-multiplicative coupling + double H_in = 1.; // valid value for non-multiplicative coupling + if ( P_.mult_coupling_ ) + { + H_ex = nonlinearities_.mult_coupling_ex( new_rates[ lag ] ); + H_in = nonlinearities_.mult_coupling_in( new_rates[ lag ] ); + } + + if ( P_.linear_summation_ ) + { + // In this case we explicitly need to distinguish the cases of + // multiplicative coupling and non-multiplicative coupling in + // order to compute input( ex + in ) instead of input(ex) + input(in) in + // the non-multiplicative case. + if ( P_.mult_coupling_ ) + { + S_.rate_ += V_.P2_ * H_ex * nonlinearities_.input( delayed_rates_ex + instant_rates_ex ); + S_.rate_ += V_.P2_ * H_in * nonlinearities_.input( delayed_rates_in + instant_rates_in ); + } + else + { + S_.rate_ += + V_.P2_ * nonlinearities_.input( delayed_rates_ex + instant_rates_ex + delayed_rates_in + instant_rates_in ); + } + } + else + { + // In this case multiplicative and non-multiplicative coupling + // can be handled with the same code. + S_.rate_ += V_.P2_ * H_ex * ( delayed_rates_ex + instant_rates_ex ); + S_.rate_ += V_.P2_ * H_in * ( delayed_rates_in + instant_rates_in ); + } + + if ( P_.rectify_output_ and S_.rate_ < P_.rectify_rate_ ) + { + S_.rate_ = P_.rectify_rate_; + } + + if ( called_from_wfr_update ) + { + // check if deviation from last iteration exceeds wfr_tol + wfr_tol_exceeded = wfr_tol_exceeded or fabs( S_.rate_ - B_.last_y_values[ lag ] ) > wfr_tol; + // update last_y_values for next wfr iteration + B_.last_y_values[ lag ] = S_.rate_; + } + else + { + // rate logging + B_.logger_.record_data( origin.get_steps() + lag ); + } + } + + if ( not called_from_wfr_update ) + { + // Send delay-rate-neuron-event. This only happens in the final iteration + // to avoid accumulation in the buffers of the receiving neurons. + DelayedRateConnectionEvent drve; + drve.set_coeffarray( new_rates ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, drve ); + + // clear last_y_values + std::vector< double >( buffer_size, 0.0 ).swap( B_.last_y_values ); + + // modifiy new_rates for rate-neuron-event as proxy for next min_delay + for ( long temp = from; temp < to; ++temp ) + { + new_rates[ temp ] = S_.rate_; + } + + // create new random numbers + B_.random_numbers.resize( buffer_size, numerics::nan ); + for ( unsigned int i = 0; i < buffer_size; i++ ) + { + B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) ); + } + } + + // Send rate-neuron-event + InstantaneousRateConnectionEvent rve; + rve.set_coeffarray( new_rates ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, rve ); + + // Reset variables + std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_ex_ ); + std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_in_ ); + + return wfr_tol_exceeded; +} + + +template < class TNonlinearities > +void +rate_neuron_ipn< TNonlinearities >::handle( InstantaneousRateConnectionEvent& e ) +{ + const double weight = e.get_weight(); + + size_t i = 0; + std::vector< unsigned int >::iterator it = e.begin(); + // The call to get_coeffvalue( it ) in this loop also advances the iterator it + while ( it != e.end() ) + { + if ( P_.linear_summation_ ) + { + if ( weight >= 0.0 ) + { + B_.instant_rates_ex_[ i ] += weight * e.get_coeffvalue( it ); + } + else + { + B_.instant_rates_in_[ i ] += weight * e.get_coeffvalue( it ); + } + } + else + { + if ( weight >= 0.0 ) + { + B_.instant_rates_ex_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); + } + else + { + B_.instant_rates_in_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); + } + } + i++; + } +} + +template < class TNonlinearities > +void +rate_neuron_ipn< TNonlinearities >::handle( DelayedRateConnectionEvent& e ) +{ + const double weight = e.get_weight(); + const long delay = e.get_delay_steps() - kernel::manager< ConnectionManager >.get_min_delay(); + + size_t i = 0; + std::vector< unsigned int >::iterator it = e.begin(); + // The call to get_coeffvalue( it ) in this loop also advances the iterator it + while ( it != e.end() ) + { + if ( P_.linear_summation_ ) + { + if ( weight >= 0.0 ) + { + B_.delayed_rates_ex_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); + } + else + { + B_.delayed_rates_in_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); + } + } + else + { + if ( weight >= 0.0 ) + { + B_.delayed_rates_ex_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); + } + else + { + B_.delayed_rates_in_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); + } + } + ++i; + } +} + +template < class TNonlinearities > +void +rate_neuron_ipn< TNonlinearities >::handle( DataLoggingRequest& e ) +{ + B_.logger_.handle( e ); +} + } // namespace #endif /* #ifndef RATE_NEURON_IPN_H */ diff --git a/models/rate_neuron_ipn_impl.h b/models/rate_neuron_ipn_impl.h deleted file mode 100644 index 286c22c0af..0000000000 --- a/models/rate_neuron_ipn_impl.h +++ /dev/null @@ -1,479 +0,0 @@ -/* - * rate_neuron_ipn_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - */ - -#ifndef RATE_NEURON_IPN_IMPL_H -#define RATE_NEURON_IPN_IMPL_H - -#include "rate_neuron_ipn.h" - -// C++ includes: -#include // in case we need isnan() // fabs -#include -#include -#include -#include -#include - -// Includes from libnestutil: -#include "dict_util.h" -#include "numerics.h" - -// Includes from nestkernel: -#include "exceptions.h" -#include "kernel_manager.h" -#include "universal_data_logger_impl.h" - -// Includes from sli: -#include "dict.h" -#include "dictutils.h" -#include "doubledatum.h" -#include "integerdatum.h" - -namespace nest -{ - -/* ---------------------------------------------------------------- - * Recordables map - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -RecordablesMap< rate_neuron_ipn< TNonlinearities > > rate_neuron_ipn< TNonlinearities >::recordablesMap_; - -/* ---------------------------------------------------------------- - * Default constructors defining default parameters and state - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -nest::rate_neuron_ipn< TNonlinearities >::Parameters_::Parameters_() - : tau_( 10.0 ) // ms - , lambda_( 1.0 ) // ms - , sigma_( 1.0 ) - , mu_( 0.0 ) - , rectify_rate_( 0.0 ) - , linear_summation_( true ) - , rectify_output_( false ) - , mult_coupling_( false ) -{ - recordablesMap_.create(); -} - -template < class TNonlinearities > -nest::rate_neuron_ipn< TNonlinearities >::State_::State_() - : rate_( 0.0 ) - , noise_( 0.0 ) -{ -} - -/* ---------------------------------------------------------------- - * Parameter and state extractions and manipulation functions - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -void -nest::rate_neuron_ipn< TNonlinearities >::Parameters_::get( DictionaryDatum& d ) const -{ - def< double >( d, names::tau, tau_ ); - def< double >( d, names::lambda, lambda_ ); - def< double >( d, names::sigma, sigma_ ); - def< double >( d, names::mu, mu_ ); - def< double >( d, names::rectify_rate, rectify_rate_ ); - def< bool >( d, names::linear_summation, linear_summation_ ); - def< bool >( d, names::rectify_output, rectify_output_ ); - def< bool >( d, names::mult_coupling, mult_coupling_ ); - - // Also allow old names (to not break old scripts) - def< double >( d, names::std, sigma_ ); - def< double >( d, names::mean, mu_ ); -} - -template < class TNonlinearities > -void -nest::rate_neuron_ipn< TNonlinearities >::Parameters_::set( const DictionaryDatum& d, Node* node ) -{ - updateValueParam< double >( d, names::tau, tau_, node ); - updateValueParam< double >( d, names::lambda, lambda_, node ); - updateValueParam< double >( d, names::mu, mu_, node ); - updateValueParam< double >( d, names::rectify_rate, rectify_rate_, node ); - updateValueParam< double >( d, names::sigma, sigma_, node ); - updateValueParam< bool >( d, names::linear_summation, linear_summation_, node ); - updateValueParam< bool >( d, names::rectify_output, rectify_output_, node ); - updateValueParam< bool >( d, names::mult_coupling, mult_coupling_, node ); - - // Check for old names - if ( updateValueParam< double >( d, names::mean, mu_, node ) ) - { - LOG( M_WARNING, - "rate_neuron_ipn< TNonlinearities >::Parameters_::set", - "The parameter mean has been renamed to mu. Please use the new " - "name from now on." ); - } - - if ( updateValueParam< double >( d, names::std, sigma_, node ) ) - { - LOG( M_WARNING, - "rate_neuron_ipn< TNonlinearities >::Parameters_::set", - "The parameter std has been renamed to sigma. Please use the new " - "name from now on." ); - } - - // Check for invalid parameters - if ( tau_ <= 0 ) - { - throw BadProperty( "Time constant must be > 0." ); - } - if ( lambda_ < 0 ) - { - throw BadProperty( "Passive decay rate must be >= 0." ); - } - if ( sigma_ < 0 ) - { - throw BadProperty( "Noise parameter must not be negative." ); - } - if ( rectify_rate_ < 0 ) - { - throw BadProperty( "Rectifying rate must not be negative." ); - } -} - -template < class TNonlinearities > -void -nest::rate_neuron_ipn< TNonlinearities >::State_::get( DictionaryDatum& d ) const -{ - def< double >( d, names::rate, rate_ ); // Rate - def< double >( d, names::noise, noise_ ); // Noise -} - -template < class TNonlinearities > -void -nest::rate_neuron_ipn< TNonlinearities >::State_::set( const DictionaryDatum& d, Node* node ) -{ - updateValueParam< double >( d, names::rate, rate_, node ); // Rate -} - -template < class TNonlinearities > -nest::rate_neuron_ipn< TNonlinearities >::Buffers_::Buffers_( rate_neuron_ipn< TNonlinearities >& n ) - : logger_( n ) -{ -} - -template < class TNonlinearities > -nest::rate_neuron_ipn< TNonlinearities >::Buffers_::Buffers_( const Buffers_&, rate_neuron_ipn< TNonlinearities >& n ) - : logger_( n ) -{ -} - -/* ---------------------------------------------------------------- - * Default and copy constructor for node - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -nest::rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn() - : ArchivingNode() - , P_() - , S_() - , B_( *this ) -{ - recordablesMap_.create(); - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); -} - -template < class TNonlinearities > -nest::rate_neuron_ipn< TNonlinearities >::rate_neuron_ipn( const rate_neuron_ipn& n ) - : ArchivingNode( n ) - , nonlinearities_( n.nonlinearities_ ) - , P_( n.P_ ) - , S_( n.S_ ) - , B_( n.B_, *this ) -{ - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); -} - -/* ---------------------------------------------------------------- - * Node initialization functions - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -void -nest::rate_neuron_ipn< TNonlinearities >::init_buffers_() -{ - B_.delayed_rates_ex_.clear(); // includes resize - B_.delayed_rates_in_.clear(); // includes resize - - // resize buffers - const size_t buffer_size = kernel().connection_manager.get_min_delay(); - B_.instant_rates_ex_.resize( buffer_size, 0.0 ); - B_.instant_rates_in_.resize( buffer_size, 0.0 ); - B_.last_y_values.resize( buffer_size, 0.0 ); - B_.random_numbers.resize( buffer_size, numerics::nan ); - - // initialize random numbers - for ( unsigned int i = 0; i < buffer_size; i++ ) - { - B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) ); - } - - B_.logger_.reset(); // includes resize - ArchivingNode::clear_history(); -} - -template < class TNonlinearities > -void -nest::rate_neuron_ipn< TNonlinearities >::pre_run_hook() -{ - B_.logger_.init(); // ensures initialization in case mm connected after Simulate - - const double h = Time::get_resolution().get_ms(); - - if ( P_.lambda_ > 0 ) - { - // use stochastic exponential Euler method - V_.P1_ = std::exp( -P_.lambda_ * h / P_.tau_ ); - V_.P2_ = -1.0 / P_.lambda_ * numerics::expm1( -P_.lambda_ * h / P_.tau_ ); - V_.input_noise_factor_ = std::sqrt( -0.5 / P_.lambda_ * numerics::expm1( -2. * P_.lambda_ * h / P_.tau_ ) ); - } - else - { - // use Euler-Maruyama method - V_.P1_ = 1; - V_.P2_ = h / P_.tau_; - V_.input_noise_factor_ = std::sqrt( h / P_.tau_ ); - } -} - -/* ---------------------------------------------------------------- - * Update and event handling functions - */ - -template < class TNonlinearities > -bool -nest::rate_neuron_ipn< TNonlinearities >::update_( Time const& origin, - const long from, - const long to, - const bool called_from_wfr_update ) -{ - const size_t buffer_size = kernel().connection_manager.get_min_delay(); - const double wfr_tol = kernel().simulation_manager.get_wfr_tol(); - bool wfr_tol_exceeded = false; - - // allocate memory to store rates to be sent by rate events - std::vector< double > new_rates( buffer_size, 0.0 ); - - for ( long lag = from; lag < to; ++lag ) - { - // store rate - new_rates[ lag ] = S_.rate_; - // get noise - S_.noise_ = P_.sigma_ * B_.random_numbers[ lag ]; - // propagate rate to new time step (exponential integration) - S_.rate_ = V_.P1_ * new_rates[ lag ] + V_.P2_ * P_.mu_ + V_.input_noise_factor_ * S_.noise_; - - double delayed_rates_in = 0; - double delayed_rates_ex = 0; - if ( called_from_wfr_update ) - { - // use get_value_wfr_update to keep values in buffer - delayed_rates_in = B_.delayed_rates_in_.get_value_wfr_update( lag ); - delayed_rates_ex = B_.delayed_rates_ex_.get_value_wfr_update( lag ); - } - else - { - // use get_value to clear values in buffer after reading - delayed_rates_in = B_.delayed_rates_in_.get_value( lag ); - delayed_rates_ex = B_.delayed_rates_ex_.get_value( lag ); - } - double instant_rates_in = B_.instant_rates_in_[ lag ]; - double instant_rates_ex = B_.instant_rates_ex_[ lag ]; - double H_ex = 1.; // valid value for non-multiplicative coupling - double H_in = 1.; // valid value for non-multiplicative coupling - if ( P_.mult_coupling_ ) - { - H_ex = nonlinearities_.mult_coupling_ex( new_rates[ lag ] ); - H_in = nonlinearities_.mult_coupling_in( new_rates[ lag ] ); - } - - if ( P_.linear_summation_ ) - { - // In this case we explicitly need to distinguish the cases of - // multiplicative coupling and non-multiplicative coupling in - // order to compute input( ex + in ) instead of input(ex) + input(in) in - // the non-multiplicative case. - if ( P_.mult_coupling_ ) - { - S_.rate_ += V_.P2_ * H_ex * nonlinearities_.input( delayed_rates_ex + instant_rates_ex ); - S_.rate_ += V_.P2_ * H_in * nonlinearities_.input( delayed_rates_in + instant_rates_in ); - } - else - { - S_.rate_ += - V_.P2_ * nonlinearities_.input( delayed_rates_ex + instant_rates_ex + delayed_rates_in + instant_rates_in ); - } - } - else - { - // In this case multiplicative and non-multiplicative coupling - // can be handled with the same code. - S_.rate_ += V_.P2_ * H_ex * ( delayed_rates_ex + instant_rates_ex ); - S_.rate_ += V_.P2_ * H_in * ( delayed_rates_in + instant_rates_in ); - } - - if ( P_.rectify_output_ and S_.rate_ < P_.rectify_rate_ ) - { - S_.rate_ = P_.rectify_rate_; - } - - if ( called_from_wfr_update ) - { - // check if deviation from last iteration exceeds wfr_tol - wfr_tol_exceeded = wfr_tol_exceeded or fabs( S_.rate_ - B_.last_y_values[ lag ] ) > wfr_tol; - // update last_y_values for next wfr iteration - B_.last_y_values[ lag ] = S_.rate_; - } - else - { - // rate logging - B_.logger_.record_data( origin.get_steps() + lag ); - } - } - - if ( not called_from_wfr_update ) - { - // Send delay-rate-neuron-event. This only happens in the final iteration - // to avoid accumulation in the buffers of the receiving neurons. - DelayedRateConnectionEvent drve; - drve.set_coeffarray( new_rates ); - kernel().event_delivery_manager.send_secondary( *this, drve ); - - // clear last_y_values - std::vector< double >( buffer_size, 0.0 ).swap( B_.last_y_values ); - - // modifiy new_rates for rate-neuron-event as proxy for next min_delay - for ( long temp = from; temp < to; ++temp ) - { - new_rates[ temp ] = S_.rate_; - } - - // create new random numbers - B_.random_numbers.resize( buffer_size, numerics::nan ); - for ( unsigned int i = 0; i < buffer_size; i++ ) - { - B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) ); - } - } - - // Send rate-neuron-event - InstantaneousRateConnectionEvent rve; - rve.set_coeffarray( new_rates ); - kernel().event_delivery_manager.send_secondary( *this, rve ); - - // Reset variables - std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_ex_ ); - std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_in_ ); - - return wfr_tol_exceeded; -} - - -template < class TNonlinearities > -void -nest::rate_neuron_ipn< TNonlinearities >::handle( InstantaneousRateConnectionEvent& e ) -{ - const double weight = e.get_weight(); - - size_t i = 0; - std::vector< unsigned int >::iterator it = e.begin(); - // The call to get_coeffvalue( it ) in this loop also advances the iterator it - while ( it != e.end() ) - { - if ( P_.linear_summation_ ) - { - if ( weight >= 0.0 ) - { - B_.instant_rates_ex_[ i ] += weight * e.get_coeffvalue( it ); - } - else - { - B_.instant_rates_in_[ i ] += weight * e.get_coeffvalue( it ); - } - } - else - { - if ( weight >= 0.0 ) - { - B_.instant_rates_ex_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); - } - else - { - B_.instant_rates_in_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); - } - } - i++; - } -} - -template < class TNonlinearities > -void -nest::rate_neuron_ipn< TNonlinearities >::handle( DelayedRateConnectionEvent& e ) -{ - const double weight = e.get_weight(); - const long delay = e.get_delay_steps() - kernel().connection_manager.get_min_delay(); - - size_t i = 0; - std::vector< unsigned int >::iterator it = e.begin(); - // The call to get_coeffvalue( it ) in this loop also advances the iterator it - while ( it != e.end() ) - { - if ( P_.linear_summation_ ) - { - if ( weight >= 0.0 ) - { - B_.delayed_rates_ex_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); - } - else - { - B_.delayed_rates_in_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); - } - } - else - { - if ( weight >= 0.0 ) - { - B_.delayed_rates_ex_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); - } - else - { - B_.delayed_rates_in_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); - } - } - ++i; - } -} - -template < class TNonlinearities > -void -nest::rate_neuron_ipn< TNonlinearities >::handle( DataLoggingRequest& e ) -{ - B_.logger_.handle( e ); -} - -} // namespace - -#endif /* #ifndef RATE_NEURON_IPN_IMPL_H */ diff --git a/models/rate_neuron_opn.h b/models/rate_neuron_opn.h index 1d4232c111..09629cde49 100644 --- a/models/rate_neuron_opn.h +++ b/models/rate_neuron_opn.h @@ -23,22 +23,30 @@ #ifndef RATE_NEURON_OPN_H #define RATE_NEURON_OPN_H -// Generated includes: -#include "config.h" - // C++ includes: +#include // in case we need isnan() // fabs #include +// Includes from libnestutil: +#include "numerics.h" + +// Includes from sli: +#include "dict.h" +#include "dictutils.h" + // Includes from nestkernel: #include "archiving_node.h" #include "connection.h" #include "event.h" -#include "nest_types.h" +#include "exceptions.h" +#include "genericmodel_impl.h" +#include "kernel_manager.h" +#include "nest_impl.h" #include "node.h" #include "random_generators.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { @@ -383,6 +391,403 @@ rate_neuron_opn< TNonlinearities >::set_status( const DictionaryDatum& d ) nonlinearities_.set( d, this ); } +/* ---------------------------------------------------------------- + * Recordables map + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +RecordablesMap< rate_neuron_opn< TNonlinearities > > rate_neuron_opn< TNonlinearities >::recordablesMap_; + + +/* ---------------------------------------------------------------- + * Default constructors defining default parameters and state + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +nest::rate_neuron_opn< TNonlinearities >::Parameters_::Parameters_() + : tau_( 10.0 ) // ms + , sigma_( 1.0 ) + , mu_( 0.0 ) + , linear_summation_( true ) + , mult_coupling_( false ) +{ + recordablesMap_.create(); +} + +template < class TNonlinearities > +nest::rate_neuron_opn< TNonlinearities >::State_::State_() + : rate_( 0.0 ) + , noise_( 0.0 ) + , noisy_rate_( 0.0 ) +{ +} + +/* ---------------------------------------------------------------- + * Parameter and state extractions and manipulation functions + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +void +nest::rate_neuron_opn< TNonlinearities >::Parameters_::get( DictionaryDatum& d ) const +{ + def< double >( d, names::tau, tau_ ); + def< double >( d, names::sigma, sigma_ ); + def< double >( d, names::mu, mu_ ); + def< bool >( d, names::linear_summation, linear_summation_ ); + def< bool >( d, names::mult_coupling, mult_coupling_ ); + + // Also allow old names (to not break old scripts) + def< double >( d, names::std, sigma_ ); + def< double >( d, names::mean, mu_ ); +} + +template < class TNonlinearities > +void +nest::rate_neuron_opn< TNonlinearities >::Parameters_::set( const DictionaryDatum& d, Node* node ) +{ + updateValueParam< double >( d, names::tau, tau_, node ); + updateValueParam< double >( d, names::mu, mu_, node ); + updateValueParam< double >( d, names::sigma, sigma_, node ); + updateValueParam< bool >( d, names::linear_summation, linear_summation_, node ); + updateValueParam< bool >( d, names::mult_coupling, mult_coupling_, node ); + + // Check for old names + if ( updateValueParam< double >( d, names::mean, mu_, node ) ) + { + LOG( M_WARNING, + "rate_neuron_opn< TNonlinearities >::Parameters_::set", + "The parameter mean has been renamed to mu. Please use the new " + "name from now on." ); + } + + if ( updateValueParam< double >( d, names::std, sigma_, node ) ) + { + LOG( M_WARNING, + "rate_neuron_opn< TNonlinearities >::Parameters_::set", + "The parameter std has been renamed to sigma. Please use the new " + "name from now on." ); + } + + // Check for invalid parameters + if ( tau_ <= 0 ) + { + throw BadProperty( "Time constant must be > 0." ); + } + if ( sigma_ < 0 ) + { + throw BadProperty( "Noise parameter must not be negative." ); + } +} + +template < class TNonlinearities > +void +nest::rate_neuron_opn< TNonlinearities >::State_::get( DictionaryDatum& d ) const +{ + def< double >( d, names::rate, rate_ ); // Rate + def< double >( d, names::noise, noise_ ); // Noise + def< double >( d, names::noisy_rate, noisy_rate_ ); // Noisy rate +} + +template < class TNonlinearities > +void +nest::rate_neuron_opn< TNonlinearities >::State_::set( const DictionaryDatum& d, Node* node ) +{ + updateValueParam< double >( d, names::rate, rate_, node ); // Rate +} + +template < class TNonlinearities > +nest::rate_neuron_opn< TNonlinearities >::Buffers_::Buffers_( rate_neuron_opn< TNonlinearities >& n ) + : logger_( n ) +{ +} + +template < class TNonlinearities > +nest::rate_neuron_opn< TNonlinearities >::Buffers_::Buffers_( const Buffers_&, rate_neuron_opn< TNonlinearities >& n ) + : logger_( n ) +{ +} + +/* ---------------------------------------------------------------- + * Default and copy constructor for node + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +nest::rate_neuron_opn< TNonlinearities >::rate_neuron_opn() + : ArchivingNode() + , P_() + , S_() + , B_( *this ) +{ + recordablesMap_.create(); + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); +} + +template < class TNonlinearities > +nest::rate_neuron_opn< TNonlinearities >::rate_neuron_opn( const rate_neuron_opn& n ) + : ArchivingNode( n ) + , P_( n.P_ ) + , S_( n.S_ ) + , B_( n.B_, *this ) +{ + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); +} + +/* ---------------------------------------------------------------- + * Node initialization functions + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +void +nest::rate_neuron_opn< TNonlinearities >::init_buffers_() +{ + B_.delayed_rates_ex_.clear(); // includes resize + B_.delayed_rates_in_.clear(); // includes resize + + // resize buffers + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); + B_.instant_rates_ex_.resize( buffer_size, 0.0 ); + B_.instant_rates_in_.resize( buffer_size, 0.0 ); + B_.last_y_values.resize( buffer_size, 0.0 ); + B_.random_numbers.resize( buffer_size, numerics::nan ); + + // initialize random numbers + for ( unsigned int i = 0; i < buffer_size; i++ ) + { + B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) ); + } + + B_.logger_.reset(); // includes resize + ArchivingNode::clear_history(); +} + +template < class TNonlinearities > +void +nest::rate_neuron_opn< TNonlinearities >::pre_run_hook() +{ + B_.logger_.init(); // ensures initialization in case mm connected after Simulate + + const double h = Time::get_resolution().get_ms(); + + // propagators + V_.P1_ = std::exp( -h / P_.tau_ ); + V_.P2_ = -numerics::expm1( -h / P_.tau_ ); + + // Gaussian white noise approximated by piecewise constant value + V_.output_noise_factor_ = std::sqrt( P_.tau_ / h ); +} + +/* ---------------------------------------------------------------- + * Update and event handling functions + */ + +template < class TNonlinearities > +bool +nest::rate_neuron_opn< TNonlinearities >::update_( Time const& origin, + const long from, + const long to, + const bool called_from_wfr_update ) +{ + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); + const double wfr_tol = kernel::manager< SimulationManager >.get_wfr_tol(); + bool wfr_tol_exceeded = false; + + // allocate memory to store rates to be sent by rate events + std::vector< double > new_rates( buffer_size, 0.0 ); + + for ( long lag = from; lag < to; ++lag ) + { + // get noise + S_.noise_ = P_.sigma_ * B_.random_numbers[ lag ]; + // the noise is added to the noisy_rate variable + S_.noisy_rate_ = S_.rate_ + V_.output_noise_factor_ * S_.noise_; + // store rate + new_rates[ lag ] = S_.noisy_rate_; + // propagate rate to new time step (exponential integration) + S_.rate_ = V_.P1_ * S_.rate_ + V_.P2_ * P_.mu_; + + double delayed_rates_in = 0; + double delayed_rates_ex = 0; + if ( called_from_wfr_update ) + { + // use get_value_wfr_update to keep values in buffer + delayed_rates_in = B_.delayed_rates_in_.get_value_wfr_update( lag ); + delayed_rates_ex = B_.delayed_rates_ex_.get_value_wfr_update( lag ); + } + else + { + // use get_value to clear values in buffer after reading + delayed_rates_in = B_.delayed_rates_in_.get_value( lag ); + delayed_rates_ex = B_.delayed_rates_ex_.get_value( lag ); + } + double instant_rates_in = B_.instant_rates_in_[ lag ]; + double instant_rates_ex = B_.instant_rates_ex_[ lag ]; + double H_ex = 1.; // valid value for non-multiplicative coupling + double H_in = 1.; // valid value for non-multiplicative coupling + if ( P_.mult_coupling_ ) + { + H_ex = nonlinearities_.mult_coupling_ex( new_rates[ lag ] ); + H_in = nonlinearities_.mult_coupling_in( new_rates[ lag ] ); + } + + if ( P_.linear_summation_ ) + { + // In this case we explicitly need to distinguish the cases of + // multiplicative coupling and non-multiplicative coupling in + // order to compute input( ex + in ) instead of input(ex) + input(in) in + // the non-multiplicative case. + if ( P_.mult_coupling_ ) + { + S_.rate_ += V_.P2_ * H_ex * nonlinearities_.input( delayed_rates_ex + instant_rates_ex ); + S_.rate_ += V_.P2_ * H_in * nonlinearities_.input( delayed_rates_in + instant_rates_in ); + } + else + { + S_.rate_ += + V_.P2_ * nonlinearities_.input( delayed_rates_ex + instant_rates_ex + delayed_rates_in + instant_rates_in ); + } + } + else + { + // In this case multiplicative and non-multiplicative coupling + // can be handled with the same code. + S_.rate_ += V_.P2_ * H_ex * ( delayed_rates_ex + instant_rates_ex ); + S_.rate_ += V_.P2_ * H_in * ( delayed_rates_in + instant_rates_in ); + } + + if ( called_from_wfr_update ) + { + // check if deviation from last iteration exceeds wfr_tol + wfr_tol_exceeded = wfr_tol_exceeded or fabs( S_.rate_ - B_.last_y_values[ lag ] ) > wfr_tol; + // update last_y_values for next wfr iteration + B_.last_y_values[ lag ] = S_.rate_; + } + else + { + // rate logging + B_.logger_.record_data( origin.get_steps() + lag ); + } + } + + if ( not called_from_wfr_update ) + { + // Send delay-rate-neuron-event. This only happens in the final iteration + // to avoid accumulation in the buffers of the receiving neurons. + DelayedRateConnectionEvent drve; + drve.set_coeffarray( new_rates ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, drve ); + + // clear last_y_values + std::vector< double >( buffer_size, 0.0 ).swap( B_.last_y_values ); + + // modify new_rates for rate-neuron-event as proxy for next min_delay + for ( long temp = from; temp < to; ++temp ) + { + new_rates[ temp ] = S_.noisy_rate_; + } + + // create new random numbers + B_.random_numbers.resize( buffer_size, numerics::nan ); + for ( unsigned int i = 0; i < buffer_size; i++ ) + { + B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) ); + } + } + + // Send rate-neuron-event + InstantaneousRateConnectionEvent rve; + rve.set_coeffarray( new_rates ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, rve ); + + // Reset variables + std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_ex_ ); + std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_in_ ); + + return wfr_tol_exceeded; +} + + +template < class TNonlinearities > +void +nest::rate_neuron_opn< TNonlinearities >::handle( InstantaneousRateConnectionEvent& e ) +{ + const double weight = e.get_weight(); + + size_t i = 0; + std::vector< unsigned int >::iterator it = e.begin(); + // The call to get_coeffvalue( it ) in this loop also advances the iterator it + while ( it != e.end() ) + { + if ( P_.linear_summation_ ) + { + if ( weight >= 0.0 ) + { + B_.instant_rates_ex_[ i ] += weight * e.get_coeffvalue( it ); + } + else + { + B_.instant_rates_in_[ i ] += weight * e.get_coeffvalue( it ); + } + } + else + { + if ( weight >= 0.0 ) + { + B_.instant_rates_ex_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); + } + else + { + B_.instant_rates_in_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); + } + } + i++; + } +} + +template < class TNonlinearities > +void +nest::rate_neuron_opn< TNonlinearities >::handle( DelayedRateConnectionEvent& e ) +{ + const double weight = e.get_weight(); + const long delay = e.get_delay_steps() - kernel::manager< ConnectionManager >.get_min_delay(); + + size_t i = 0; + std::vector< unsigned int >::iterator it = e.begin(); + // The call to get_coeffvalue( it ) in this loop also advances the iterator it + while ( it != e.end() ) + { + if ( P_.linear_summation_ ) + { + if ( weight >= 0.0 ) + { + B_.delayed_rates_ex_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); + } + else + { + B_.delayed_rates_in_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); + } + } + else + { + if ( weight >= 0.0 ) + { + B_.delayed_rates_ex_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); + } + else + { + B_.delayed_rates_in_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); + } + } + ++i; + } +} + +template < class TNonlinearities > +void +nest::rate_neuron_opn< TNonlinearities >::handle( DataLoggingRequest& e ) +{ + B_.logger_.handle( e ); +} + } // namespace #endif /* #ifndef RATE_NEURON_OPN_H */ diff --git a/models/rate_neuron_opn_impl.h b/models/rate_neuron_opn_impl.h deleted file mode 100644 index 2479fe8c23..0000000000 --- a/models/rate_neuron_opn_impl.h +++ /dev/null @@ -1,452 +0,0 @@ -/* - * rate_neuron_opn_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - */ - -#ifndef RATE_NEURON_OPN_IMPL_H -#define RATE_NEURON_OPN_IMPL_H - -#include "rate_neuron_opn.h" - -// C++ includes: -#include // in case we need isnan() // fabs -#include -#include -#include -#include -#include - -// Includes from libnestutil: -#include "numerics.h" - -// Includes from nestkernel: -#include "exceptions.h" -#include "kernel_manager.h" -#include "universal_data_logger_impl.h" - -// Includes from sli: -#include "dict.h" -#include "dictutils.h" -#include "doubledatum.h" -#include "integerdatum.h" - -namespace nest -{ - -/* ---------------------------------------------------------------- - * Recordables map - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -RecordablesMap< rate_neuron_opn< TNonlinearities > > rate_neuron_opn< TNonlinearities >::recordablesMap_; - - -/* ---------------------------------------------------------------- - * Default constructors defining default parameters and state - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -nest::rate_neuron_opn< TNonlinearities >::Parameters_::Parameters_() - : tau_( 10.0 ) // ms - , sigma_( 1.0 ) - , mu_( 0.0 ) - , linear_summation_( true ) - , mult_coupling_( false ) -{ - recordablesMap_.create(); -} - -template < class TNonlinearities > -nest::rate_neuron_opn< TNonlinearities >::State_::State_() - : rate_( 0.0 ) - , noise_( 0.0 ) - , noisy_rate_( 0.0 ) -{ -} - -/* ---------------------------------------------------------------- - * Parameter and state extractions and manipulation functions - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -void -nest::rate_neuron_opn< TNonlinearities >::Parameters_::get( DictionaryDatum& d ) const -{ - def< double >( d, names::tau, tau_ ); - def< double >( d, names::sigma, sigma_ ); - def< double >( d, names::mu, mu_ ); - def< bool >( d, names::linear_summation, linear_summation_ ); - def< bool >( d, names::mult_coupling, mult_coupling_ ); - - // Also allow old names (to not break old scripts) - def< double >( d, names::std, sigma_ ); - def< double >( d, names::mean, mu_ ); -} - -template < class TNonlinearities > -void -nest::rate_neuron_opn< TNonlinearities >::Parameters_::set( const DictionaryDatum& d, Node* node ) -{ - updateValueParam< double >( d, names::tau, tau_, node ); - updateValueParam< double >( d, names::mu, mu_, node ); - updateValueParam< double >( d, names::sigma, sigma_, node ); - updateValueParam< bool >( d, names::linear_summation, linear_summation_, node ); - updateValueParam< bool >( d, names::mult_coupling, mult_coupling_, node ); - - // Check for old names - if ( updateValueParam< double >( d, names::mean, mu_, node ) ) - { - LOG( M_WARNING, - "rate_neuron_opn< TNonlinearities >::Parameters_::set", - "The parameter mean has been renamed to mu. Please use the new " - "name from now on." ); - } - - if ( updateValueParam< double >( d, names::std, sigma_, node ) ) - { - LOG( M_WARNING, - "rate_neuron_opn< TNonlinearities >::Parameters_::set", - "The parameter std has been renamed to sigma. Please use the new " - "name from now on." ); - } - - // Check for invalid parameters - if ( tau_ <= 0 ) - { - throw BadProperty( "Time constant must be > 0." ); - } - if ( sigma_ < 0 ) - { - throw BadProperty( "Noise parameter must not be negative." ); - } -} - -template < class TNonlinearities > -void -nest::rate_neuron_opn< TNonlinearities >::State_::get( DictionaryDatum& d ) const -{ - def< double >( d, names::rate, rate_ ); // Rate - def< double >( d, names::noise, noise_ ); // Noise - def< double >( d, names::noisy_rate, noisy_rate_ ); // Noisy rate -} - -template < class TNonlinearities > -void -nest::rate_neuron_opn< TNonlinearities >::State_::set( const DictionaryDatum& d, Node* node ) -{ - updateValueParam< double >( d, names::rate, rate_, node ); // Rate -} - -template < class TNonlinearities > -nest::rate_neuron_opn< TNonlinearities >::Buffers_::Buffers_( rate_neuron_opn< TNonlinearities >& n ) - : logger_( n ) -{ -} - -template < class TNonlinearities > -nest::rate_neuron_opn< TNonlinearities >::Buffers_::Buffers_( const Buffers_&, rate_neuron_opn< TNonlinearities >& n ) - : logger_( n ) -{ -} - -/* ---------------------------------------------------------------- - * Default and copy constructor for node - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -nest::rate_neuron_opn< TNonlinearities >::rate_neuron_opn() - : ArchivingNode() - , P_() - , S_() - , B_( *this ) -{ - recordablesMap_.create(); - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); -} - -template < class TNonlinearities > -nest::rate_neuron_opn< TNonlinearities >::rate_neuron_opn( const rate_neuron_opn& n ) - : ArchivingNode( n ) - , P_( n.P_ ) - , S_( n.S_ ) - , B_( n.B_, *this ) -{ - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); -} - -/* ---------------------------------------------------------------- - * Node initialization functions - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -void -nest::rate_neuron_opn< TNonlinearities >::init_buffers_() -{ - B_.delayed_rates_ex_.clear(); // includes resize - B_.delayed_rates_in_.clear(); // includes resize - - // resize buffers - const size_t buffer_size = kernel().connection_manager.get_min_delay(); - B_.instant_rates_ex_.resize( buffer_size, 0.0 ); - B_.instant_rates_in_.resize( buffer_size, 0.0 ); - B_.last_y_values.resize( buffer_size, 0.0 ); - B_.random_numbers.resize( buffer_size, numerics::nan ); - - // initialize random numbers - for ( unsigned int i = 0; i < buffer_size; i++ ) - { - B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) ); - } - - B_.logger_.reset(); // includes resize - ArchivingNode::clear_history(); -} - -template < class TNonlinearities > -void -nest::rate_neuron_opn< TNonlinearities >::pre_run_hook() -{ - B_.logger_.init(); // ensures initialization in case mm connected after Simulate - - const double h = Time::get_resolution().get_ms(); - - // propagators - V_.P1_ = std::exp( -h / P_.tau_ ); - V_.P2_ = -numerics::expm1( -h / P_.tau_ ); - - // Gaussian white noise approximated by piecewise constant value - V_.output_noise_factor_ = std::sqrt( P_.tau_ / h ); -} - -/* ---------------------------------------------------------------- - * Update and event handling functions - */ - -template < class TNonlinearities > -bool -nest::rate_neuron_opn< TNonlinearities >::update_( Time const& origin, - const long from, - const long to, - const bool called_from_wfr_update ) -{ - const size_t buffer_size = kernel().connection_manager.get_min_delay(); - const double wfr_tol = kernel().simulation_manager.get_wfr_tol(); - bool wfr_tol_exceeded = false; - - // allocate memory to store rates to be sent by rate events - std::vector< double > new_rates( buffer_size, 0.0 ); - - for ( long lag = from; lag < to; ++lag ) - { - // get noise - S_.noise_ = P_.sigma_ * B_.random_numbers[ lag ]; - // the noise is added to the noisy_rate variable - S_.noisy_rate_ = S_.rate_ + V_.output_noise_factor_ * S_.noise_; - // store rate - new_rates[ lag ] = S_.noisy_rate_; - // propagate rate to new time step (exponential integration) - S_.rate_ = V_.P1_ * S_.rate_ + V_.P2_ * P_.mu_; - - double delayed_rates_in = 0; - double delayed_rates_ex = 0; - if ( called_from_wfr_update ) - { - // use get_value_wfr_update to keep values in buffer - delayed_rates_in = B_.delayed_rates_in_.get_value_wfr_update( lag ); - delayed_rates_ex = B_.delayed_rates_ex_.get_value_wfr_update( lag ); - } - else - { - // use get_value to clear values in buffer after reading - delayed_rates_in = B_.delayed_rates_in_.get_value( lag ); - delayed_rates_ex = B_.delayed_rates_ex_.get_value( lag ); - } - double instant_rates_in = B_.instant_rates_in_[ lag ]; - double instant_rates_ex = B_.instant_rates_ex_[ lag ]; - double H_ex = 1.; // valid value for non-multiplicative coupling - double H_in = 1.; // valid value for non-multiplicative coupling - if ( P_.mult_coupling_ ) - { - H_ex = nonlinearities_.mult_coupling_ex( new_rates[ lag ] ); - H_in = nonlinearities_.mult_coupling_in( new_rates[ lag ] ); - } - - if ( P_.linear_summation_ ) - { - // In this case we explicitly need to distinguish the cases of - // multiplicative coupling and non-multiplicative coupling in - // order to compute input( ex + in ) instead of input(ex) + input(in) in - // the non-multiplicative case. - if ( P_.mult_coupling_ ) - { - S_.rate_ += V_.P2_ * H_ex * nonlinearities_.input( delayed_rates_ex + instant_rates_ex ); - S_.rate_ += V_.P2_ * H_in * nonlinearities_.input( delayed_rates_in + instant_rates_in ); - } - else - { - S_.rate_ += - V_.P2_ * nonlinearities_.input( delayed_rates_ex + instant_rates_ex + delayed_rates_in + instant_rates_in ); - } - } - else - { - // In this case multiplicative and non-multiplicative coupling - // can be handled with the same code. - S_.rate_ += V_.P2_ * H_ex * ( delayed_rates_ex + instant_rates_ex ); - S_.rate_ += V_.P2_ * H_in * ( delayed_rates_in + instant_rates_in ); - } - - if ( called_from_wfr_update ) - { - // check if deviation from last iteration exceeds wfr_tol - wfr_tol_exceeded = wfr_tol_exceeded or fabs( S_.rate_ - B_.last_y_values[ lag ] ) > wfr_tol; - // update last_y_values for next wfr iteration - B_.last_y_values[ lag ] = S_.rate_; - } - else - { - // rate logging - B_.logger_.record_data( origin.get_steps() + lag ); - } - } - - if ( not called_from_wfr_update ) - { - // Send delay-rate-neuron-event. This only happens in the final iteration - // to avoid accumulation in the buffers of the receiving neurons. - DelayedRateConnectionEvent drve; - drve.set_coeffarray( new_rates ); - kernel().event_delivery_manager.send_secondary( *this, drve ); - - // clear last_y_values - std::vector< double >( buffer_size, 0.0 ).swap( B_.last_y_values ); - - // modify new_rates for rate-neuron-event as proxy for next min_delay - for ( long temp = from; temp < to; ++temp ) - { - new_rates[ temp ] = S_.noisy_rate_; - } - - // create new random numbers - B_.random_numbers.resize( buffer_size, numerics::nan ); - for ( unsigned int i = 0; i < buffer_size; i++ ) - { - B_.random_numbers[ i ] = V_.normal_dist_( get_vp_specific_rng( get_thread() ) ); - } - } - - // Send rate-neuron-event - InstantaneousRateConnectionEvent rve; - rve.set_coeffarray( new_rates ); - kernel().event_delivery_manager.send_secondary( *this, rve ); - - // Reset variables - std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_ex_ ); - std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_in_ ); - - return wfr_tol_exceeded; -} - - -template < class TNonlinearities > -void -nest::rate_neuron_opn< TNonlinearities >::handle( InstantaneousRateConnectionEvent& e ) -{ - const double weight = e.get_weight(); - - size_t i = 0; - std::vector< unsigned int >::iterator it = e.begin(); - // The call to get_coeffvalue( it ) in this loop also advances the iterator it - while ( it != e.end() ) - { - if ( P_.linear_summation_ ) - { - if ( weight >= 0.0 ) - { - B_.instant_rates_ex_[ i ] += weight * e.get_coeffvalue( it ); - } - else - { - B_.instant_rates_in_[ i ] += weight * e.get_coeffvalue( it ); - } - } - else - { - if ( weight >= 0.0 ) - { - B_.instant_rates_ex_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); - } - else - { - B_.instant_rates_in_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); - } - } - i++; - } -} - -template < class TNonlinearities > -void -nest::rate_neuron_opn< TNonlinearities >::handle( DelayedRateConnectionEvent& e ) -{ - const double weight = e.get_weight(); - const long delay = e.get_delay_steps() - kernel().connection_manager.get_min_delay(); - - size_t i = 0; - std::vector< unsigned int >::iterator it = e.begin(); - // The call to get_coeffvalue( it ) in this loop also advances the iterator it - while ( it != e.end() ) - { - if ( P_.linear_summation_ ) - { - if ( weight >= 0.0 ) - { - B_.delayed_rates_ex_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); - } - else - { - B_.delayed_rates_in_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); - } - } - else - { - if ( weight >= 0.0 ) - { - B_.delayed_rates_ex_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); - } - else - { - B_.delayed_rates_in_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); - } - } - ++i; - } -} - -template < class TNonlinearities > -void -nest::rate_neuron_opn< TNonlinearities >::handle( DataLoggingRequest& e ) -{ - B_.logger_.handle( e ); -} - -} // namespace - -#endif /* #ifndef RATE_NEURON_OPN_IMPL_H */ diff --git a/models/rate_transformer_node.h b/models/rate_transformer_node.h index 50383f18f7..709d8b869a 100644 --- a/models/rate_transformer_node.h +++ b/models/rate_transformer_node.h @@ -37,7 +37,7 @@ #include "node.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { @@ -327,6 +327,268 @@ rate_transformer_node< TNonlinearities >::set_status( const DictionaryDatum& d ) nonlinearities_.set( d, this ); } +/* ---------------------------------------------------------------- + * Recordables map + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +RecordablesMap< rate_transformer_node< TNonlinearities > > rate_transformer_node< TNonlinearities >::recordablesMap_; + +/* ---------------------------------------------------------------- + * Default constructors defining default parameters and state + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +nest::rate_transformer_node< TNonlinearities >::Parameters_::Parameters_() + : linear_summation_( true ) +{ +} + +template < class TNonlinearities > +nest::rate_transformer_node< TNonlinearities >::State_::State_() + : rate_( 0.0 ) +{ +} + +/* ---------------------------------------------------------------- + * Parameter and state extractions and manipulation functions + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +void +nest::rate_transformer_node< TNonlinearities >::Parameters_::get( DictionaryDatum& d ) const +{ + def< bool >( d, names::linear_summation, linear_summation_ ); +} + +template < class TNonlinearities > +void +nest::rate_transformer_node< TNonlinearities >::Parameters_::set( const DictionaryDatum& d, Node* node ) +{ + updateValueParam< bool >( d, names::linear_summation, linear_summation_, node ); +} + +template < class TNonlinearities > +void +nest::rate_transformer_node< TNonlinearities >::State_::get( DictionaryDatum& d ) const +{ + def< double >( d, names::rate, rate_ ); // Rate +} + +template < class TNonlinearities > +void +nest::rate_transformer_node< TNonlinearities >::State_::set( const DictionaryDatum& d, Node* node ) +{ + updateValueParam< double >( d, names::rate, rate_, node ); // Rate +} + +template < class TNonlinearities > +nest::rate_transformer_node< TNonlinearities >::Buffers_::Buffers_( rate_transformer_node< TNonlinearities >& n ) + : logger_( n ) +{ +} + +template < class TNonlinearities > +nest::rate_transformer_node< TNonlinearities >::Buffers_::Buffers_( const Buffers_&, + rate_transformer_node< TNonlinearities >& n ) + : logger_( n ) +{ +} + +/* ---------------------------------------------------------------- + * Default and copy constructor for node + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +nest::rate_transformer_node< TNonlinearities >::rate_transformer_node() + : ArchivingNode() + , S_() + , B_( *this ) +{ + recordablesMap_.create(); + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); +} + +template < class TNonlinearities > +nest::rate_transformer_node< TNonlinearities >::rate_transformer_node( const rate_transformer_node& n ) + : ArchivingNode( n ) + , nonlinearities_( n.nonlinearities_ ) + , S_( n.S_ ) + , B_( n.B_, *this ) +{ + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); +} + +/* ---------------------------------------------------------------- + * Node initialization functions + * ---------------------------------------------------------------- */ + +template < class TNonlinearities > +void +nest::rate_transformer_node< TNonlinearities >::init_buffers_() +{ + B_.delayed_rates_.clear(); // includes resize + + // resize buffers + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); + B_.instant_rates_.resize( buffer_size, 0.0 ); + B_.last_y_values.resize( buffer_size, 0.0 ); + + B_.logger_.reset(); // includes resize + ArchivingNode::clear_history(); +} + +template < class TNonlinearities > +void +nest::rate_transformer_node< TNonlinearities >::pre_run_hook() +{ + B_.logger_.init(); // ensures initialization in case mm connected after Simulate +} + +/* ---------------------------------------------------------------- + * Update and event handling functions + */ + +template < class TNonlinearities > +bool +nest::rate_transformer_node< TNonlinearities >::update_( Time const& origin, + const long from, + const long to, + const bool called_from_wfr_update ) +{ + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); + const double wfr_tol = kernel::manager< SimulationManager >.get_wfr_tol(); + bool wfr_tol_exceeded = false; + + // allocate memory to store rates to be sent by rate events + std::vector< double > new_rates( buffer_size, 0.0 ); + + for ( long lag = from; lag < to; ++lag ) + { + // store rate + new_rates[ lag ] = S_.rate_; + // reinitialize output rate + S_.rate_ = 0.0; + + double delayed_rates = 0; + if ( called_from_wfr_update ) + { + // use get_value_wfr_update to keep values in buffer + delayed_rates = B_.delayed_rates_.get_value_wfr_update( lag ); + } + else + { + // use get_value to clear values in buffer after reading + delayed_rates = B_.delayed_rates_.get_value( lag ); + } + + if ( P_.linear_summation_ ) + { + S_.rate_ += nonlinearities_.input( delayed_rates + B_.instant_rates_[ lag ] ); + } + else + { + S_.rate_ += delayed_rates + B_.instant_rates_[ lag ]; + } + + if ( called_from_wfr_update ) + { + // check if deviation from last iteration exceeds wfr_tol + wfr_tol_exceeded = wfr_tol_exceeded or fabs( S_.rate_ - B_.last_y_values[ lag ] ) > wfr_tol; + // update last_y_values for next wfr iteration + B_.last_y_values[ lag ] = S_.rate_; + } + else + { + // rate logging + B_.logger_.record_data( origin.get_steps() + lag ); + } + } + + if ( not called_from_wfr_update ) + { + // Send delay-rate-neuron-event. This only happens in the final iteration + // to avoid accumulation in the buffers of the receiving neurons. + DelayedRateConnectionEvent drve; + drve.set_coeffarray( new_rates ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, drve ); + + // clear last_y_values + std::vector< double >( buffer_size, 0.0 ).swap( B_.last_y_values ); + + // modifiy new_rates for rate-neuron-event as proxy for next min_delay + for ( long temp = from; temp < to; ++temp ) + { + new_rates[ temp ] = S_.rate_; + } + } + + // Send rate-neuron-event + InstantaneousRateConnectionEvent rve; + rve.set_coeffarray( new_rates ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, rve ); + + // Reset variables + std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_ ); + + return wfr_tol_exceeded; +} + + +template < class TNonlinearities > +void +nest::rate_transformer_node< TNonlinearities >::handle( InstantaneousRateConnectionEvent& e ) +{ + const double weight = e.get_weight(); + + size_t i = 0; + std::vector< unsigned int >::iterator it = e.begin(); + // The call to get_coeffvalue( it ) in this loop also advances the iterator it + while ( it != e.end() ) + { + if ( P_.linear_summation_ ) + { + B_.instant_rates_[ i ] += weight * e.get_coeffvalue( it ); + } + else + { + B_.instant_rates_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); + } + ++i; + } +} + +template < class TNonlinearities > +void +nest::rate_transformer_node< TNonlinearities >::handle( DelayedRateConnectionEvent& e ) +{ + const double weight = e.get_weight(); + const long delay = e.get_delay_steps() - kernel::manager< ConnectionManager >.get_min_delay(); + + size_t i = 0; + std::vector< unsigned int >::iterator it = e.begin(); + // The call to get_coeffvalue( it ) in this loop also advances the iterator it + while ( it != e.end() ) + { + if ( P_.linear_summation_ ) + { + B_.delayed_rates_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); + } + else + { + B_.delayed_rates_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); + } + ++i; + } +} + +template < class TNonlinearities > +void +nest::rate_transformer_node< TNonlinearities >::handle( DataLoggingRequest& e ) +{ + B_.logger_.handle( e ); +} + } // namespace #endif /* #ifndef RATE_TRANSFORMER_NODE_H */ diff --git a/models/rate_transformer_node_impl.h b/models/rate_transformer_node_impl.h deleted file mode 100644 index 2809b97130..0000000000 --- a/models/rate_transformer_node_impl.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - * rate_transformer_node_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - */ - -#ifndef RATE_TRANSFORMER_NODE_IMPL_H -#define RATE_TRANSFORMER_NODE_IMPL_H - -#include "rate_transformer_node.h" - -// C++ includes: -#include // in case we need isnan() // fabs -#include -#include -#include -#include -#include - -// Includes from libnestutil: -#include "dict_util.h" -#include "numerics.h" - - -// Includes from nestkernel: -#include "exceptions.h" -#include "kernel_manager.h" -#include "universal_data_logger_impl.h" - -// Includes from sli: -#include "dict.h" -#include "dictutils.h" -#include "doubledatum.h" -#include "integerdatum.h" - -namespace nest -{ - -/* ---------------------------------------------------------------- - * Recordables map - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -RecordablesMap< rate_transformer_node< TNonlinearities > > rate_transformer_node< TNonlinearities >::recordablesMap_; - -/* ---------------------------------------------------------------- - * Default constructors defining default parameters and state - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -nest::rate_transformer_node< TNonlinearities >::Parameters_::Parameters_() - : linear_summation_( true ) -{ -} - -template < class TNonlinearities > -nest::rate_transformer_node< TNonlinearities >::State_::State_() - : rate_( 0.0 ) -{ -} - -/* ---------------------------------------------------------------- - * Parameter and state extractions and manipulation functions - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -void -nest::rate_transformer_node< TNonlinearities >::Parameters_::get( DictionaryDatum& d ) const -{ - def< bool >( d, names::linear_summation, linear_summation_ ); -} - -template < class TNonlinearities > -void -nest::rate_transformer_node< TNonlinearities >::Parameters_::set( const DictionaryDatum& d, Node* node ) -{ - updateValueParam< bool >( d, names::linear_summation, linear_summation_, node ); -} - -template < class TNonlinearities > -void -nest::rate_transformer_node< TNonlinearities >::State_::get( DictionaryDatum& d ) const -{ - def< double >( d, names::rate, rate_ ); // Rate -} - -template < class TNonlinearities > -void -nest::rate_transformer_node< TNonlinearities >::State_::set( const DictionaryDatum& d, Node* node ) -{ - updateValueParam< double >( d, names::rate, rate_, node ); // Rate -} - -template < class TNonlinearities > -nest::rate_transformer_node< TNonlinearities >::Buffers_::Buffers_( rate_transformer_node< TNonlinearities >& n ) - : logger_( n ) -{ -} - -template < class TNonlinearities > -nest::rate_transformer_node< TNonlinearities >::Buffers_::Buffers_( const Buffers_&, - rate_transformer_node< TNonlinearities >& n ) - : logger_( n ) -{ -} - -/* ---------------------------------------------------------------- - * Default and copy constructor for node - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -nest::rate_transformer_node< TNonlinearities >::rate_transformer_node() - : ArchivingNode() - , S_() - , B_( *this ) -{ - recordablesMap_.create(); - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); -} - -template < class TNonlinearities > -nest::rate_transformer_node< TNonlinearities >::rate_transformer_node( const rate_transformer_node& n ) - : ArchivingNode( n ) - , nonlinearities_( n.nonlinearities_ ) - , S_( n.S_ ) - , B_( n.B_, *this ) -{ - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); -} - -/* ---------------------------------------------------------------- - * Node initialization functions - * ---------------------------------------------------------------- */ - -template < class TNonlinearities > -void -nest::rate_transformer_node< TNonlinearities >::init_buffers_() -{ - B_.delayed_rates_.clear(); // includes resize - - // resize buffers - const size_t buffer_size = kernel().connection_manager.get_min_delay(); - B_.instant_rates_.resize( buffer_size, 0.0 ); - B_.last_y_values.resize( buffer_size, 0.0 ); - - B_.logger_.reset(); // includes resize - ArchivingNode::clear_history(); -} - -template < class TNonlinearities > -void -nest::rate_transformer_node< TNonlinearities >::pre_run_hook() -{ - B_.logger_.init(); // ensures initialization in case mm connected after Simulate -} - -/* ---------------------------------------------------------------- - * Update and event handling functions - */ - -template < class TNonlinearities > -bool -nest::rate_transformer_node< TNonlinearities >::update_( Time const& origin, - const long from, - const long to, - const bool called_from_wfr_update ) -{ - const size_t buffer_size = kernel().connection_manager.get_min_delay(); - const double wfr_tol = kernel().simulation_manager.get_wfr_tol(); - bool wfr_tol_exceeded = false; - - // allocate memory to store rates to be sent by rate events - std::vector< double > new_rates( buffer_size, 0.0 ); - - for ( long lag = from; lag < to; ++lag ) - { - // store rate - new_rates[ lag ] = S_.rate_; - // reinitialize output rate - S_.rate_ = 0.0; - - double delayed_rates = 0; - if ( called_from_wfr_update ) - { - // use get_value_wfr_update to keep values in buffer - delayed_rates = B_.delayed_rates_.get_value_wfr_update( lag ); - } - else - { - // use get_value to clear values in buffer after reading - delayed_rates = B_.delayed_rates_.get_value( lag ); - } - - if ( P_.linear_summation_ ) - { - S_.rate_ += nonlinearities_.input( delayed_rates + B_.instant_rates_[ lag ] ); - } - else - { - S_.rate_ += delayed_rates + B_.instant_rates_[ lag ]; - } - - if ( called_from_wfr_update ) - { - // check if deviation from last iteration exceeds wfr_tol - wfr_tol_exceeded = wfr_tol_exceeded or fabs( S_.rate_ - B_.last_y_values[ lag ] ) > wfr_tol; - // update last_y_values for next wfr iteration - B_.last_y_values[ lag ] = S_.rate_; - } - else - { - // rate logging - B_.logger_.record_data( origin.get_steps() + lag ); - } - } - - if ( not called_from_wfr_update ) - { - // Send delay-rate-neuron-event. This only happens in the final iteration - // to avoid accumulation in the buffers of the receiving neurons. - DelayedRateConnectionEvent drve; - drve.set_coeffarray( new_rates ); - kernel().event_delivery_manager.send_secondary( *this, drve ); - - // clear last_y_values - std::vector< double >( buffer_size, 0.0 ).swap( B_.last_y_values ); - - // modifiy new_rates for rate-neuron-event as proxy for next min_delay - for ( long temp = from; temp < to; ++temp ) - { - new_rates[ temp ] = S_.rate_; - } - } - - // Send rate-neuron-event - InstantaneousRateConnectionEvent rve; - rve.set_coeffarray( new_rates ); - kernel().event_delivery_manager.send_secondary( *this, rve ); - - // Reset variables - std::vector< double >( buffer_size, 0.0 ).swap( B_.instant_rates_ ); - - return wfr_tol_exceeded; -} - - -template < class TNonlinearities > -void -nest::rate_transformer_node< TNonlinearities >::handle( InstantaneousRateConnectionEvent& e ) -{ - const double weight = e.get_weight(); - - size_t i = 0; - std::vector< unsigned int >::iterator it = e.begin(); - // The call to get_coeffvalue( it ) in this loop also advances the iterator it - while ( it != e.end() ) - { - if ( P_.linear_summation_ ) - { - B_.instant_rates_[ i ] += weight * e.get_coeffvalue( it ); - } - else - { - B_.instant_rates_[ i ] += weight * nonlinearities_.input( e.get_coeffvalue( it ) ); - } - ++i; - } -} - -template < class TNonlinearities > -void -nest::rate_transformer_node< TNonlinearities >::handle( DelayedRateConnectionEvent& e ) -{ - const double weight = e.get_weight(); - const long delay = e.get_delay_steps() - kernel().connection_manager.get_min_delay(); - - size_t i = 0; - std::vector< unsigned int >::iterator it = e.begin(); - // The call to get_coeffvalue( it ) in this loop also advances the iterator it - while ( it != e.end() ) - { - if ( P_.linear_summation_ ) - { - B_.delayed_rates_.add_value( delay + i, weight * e.get_coeffvalue( it ) ); - } - else - { - B_.delayed_rates_.add_value( delay + i, weight * nonlinearities_.input( e.get_coeffvalue( it ) ) ); - } - ++i; - } -} - -template < class TNonlinearities > -void -nest::rate_transformer_node< TNonlinearities >::handle( DataLoggingRequest& e ) -{ - B_.logger_.handle( e ); -} - -} // namespace - -#endif /* #ifndef RATE_TRANSFORMER_NODE_IMPL_H */ diff --git a/models/sic_connection.cpp b/models/sic_connection.cpp index d10b3b412b..8ef6421bab 100644 --- a/models/sic_connection.cpp +++ b/models/sic_connection.cpp @@ -22,7 +22,6 @@ #include "sic_connection.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/siegert_neuron.cpp b/models/siegert_neuron.cpp index ec39ab5cec..350e6d7edf 100644 --- a/models/siegert_neuron.cpp +++ b/models/siegert_neuron.cpp @@ -26,7 +26,6 @@ // C++ includes: #include // in case we need isnan() // fabs -#include #include // Includes from libnestutil: @@ -35,12 +34,12 @@ // Includes from nestkernel: #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" // Includes from sli: -#include "dict.h" #include "dictutils.h" struct my_params @@ -191,7 +190,7 @@ nest::siegert_neuron::siegert_neuron() , B_( *this ) { recordablesMap_.create(); - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); gsl_w_ = gsl_integration_workspace_alloc( 1000 ); } @@ -201,7 +200,7 @@ nest::siegert_neuron::siegert_neuron( const siegert_neuron& n ) , S_( n.S_ ) , B_( n.B_, *this ) { - Node::set_node_uses_wfr( kernel().simulation_manager.use_wfr() ); + Node::set_node_uses_wfr( kernel::manager< SimulationManager >.use_wfr() ); gsl_w_ = gsl_integration_workspace_alloc( 1000 ); } @@ -284,7 +283,7 @@ void nest::siegert_neuron::init_buffers_() { // resize buffers - const size_t buffer_size = kernel().connection_manager.get_min_delay(); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); B_.drift_input_.resize( buffer_size, 0.0 ); B_.diffusion_input_.resize( buffer_size, 0.0 ); B_.last_y_values.resize( buffer_size, 0.0 ); @@ -312,8 +311,8 @@ nest::siegert_neuron::pre_run_hook() bool nest::siegert_neuron::update_( Time const& origin, const long from, const long to, const bool called_from_wfr_update ) { - const size_t buffer_size = kernel().connection_manager.get_min_delay(); - const double wfr_tol = kernel().simulation_manager.get_wfr_tol(); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); + const double wfr_tol = kernel::manager< SimulationManager >.get_wfr_tol(); bool wfr_tol_exceeded = false; // allocate memory to store rates to be sent by rate events @@ -357,7 +356,7 @@ nest::siegert_neuron::update_( Time const& origin, const long from, const long t // Send diffusion-event DiffusionConnectionEvent rve; rve.set_coeffarray( new_rates ); - kernel().event_delivery_manager.send_secondary( *this, rve ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, rve ); // Reset variables std::vector< double >( buffer_size, 0.0 ).swap( B_.drift_input_ ); diff --git a/models/siegert_neuron.h b/models/siegert_neuron.h index a96fce211f..ff75a77497 100644 --- a/models/siegert_neuron.h +++ b/models/siegert_neuron.h @@ -40,7 +40,7 @@ #include "node.h" #include "recordables_map.h" #include "ring_buffer.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/sigmoid_rate.cpp b/models/sigmoid_rate.cpp index b50e5b5867..c23914e06b 100644 --- a/models/sigmoid_rate.cpp +++ b/models/sigmoid_rate.cpp @@ -22,10 +22,7 @@ #include "sigmoid_rate.h" -// Includes from nestkernel -#include "kernel_manager.h" -#include "model_manager_impl.h" -#include "nest_impl.h" +#include "dict_util.h" namespace nest { diff --git a/models/sigmoid_rate.h b/models/sigmoid_rate.h index 634ce53f9f..a675c77937 100644 --- a/models/sigmoid_rate.h +++ b/models/sigmoid_rate.h @@ -28,9 +28,7 @@ // Includes from models: #include "rate_neuron_ipn.h" -#include "rate_neuron_ipn_impl.h" #include "rate_transformer_node.h" -#include "rate_transformer_node_impl.h" namespace nest diff --git a/models/sigmoid_rate_gg_1998.cpp b/models/sigmoid_rate_gg_1998.cpp index 2fcea61a4a..b322f81b56 100644 --- a/models/sigmoid_rate_gg_1998.cpp +++ b/models/sigmoid_rate_gg_1998.cpp @@ -22,10 +22,7 @@ #include "sigmoid_rate_gg_1998.h" -// Includes from nestkernel -#include "kernel_manager.h" -#include "model_manager_impl.h" -#include "nest_impl.h" +#include "dict_util.h" namespace nest { diff --git a/models/sigmoid_rate_gg_1998.h b/models/sigmoid_rate_gg_1998.h index 6039d9692b..b12c2c7df7 100644 --- a/models/sigmoid_rate_gg_1998.h +++ b/models/sigmoid_rate_gg_1998.h @@ -28,9 +28,7 @@ // Includes from models: #include "rate_neuron_ipn.h" -#include "rate_neuron_ipn_impl.h" #include "rate_transformer_node.h" -#include "rate_transformer_node_impl.h" namespace nest { diff --git a/models/sinusoidal_gamma_generator.cpp b/models/sinusoidal_gamma_generator.cpp index 30c49fe411..0bcf374318 100644 --- a/models/sinusoidal_gamma_generator.cpp +++ b/models/sinusoidal_gamma_generator.cpp @@ -37,9 +37,9 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "booldatum.h" @@ -250,7 +250,7 @@ nest::sinusoidal_gamma_generator::init_buffers_() StimulationDevice::init_buffers(); B_.logger_.reset(); - std::vector< double >( P_.num_trains_, kernel().simulation_manager.get_time().get_ms() ).swap( B_.t0_ms_ ); + std::vector< double >( P_.num_trains_, kernel::manager< SimulationManager >.get_time().get_ms() ).swap( B_.t0_ms_ ); std::vector< double >( P_.num_trains_, 0.0 ).swap( B_.Lambda_t0_ ); B_.P_prev_ = P_; } @@ -286,7 +286,7 @@ nest::sinusoidal_gamma_generator::pre_run_hook() V_.h_ = Time::get_resolution().get_ms(); V_.rng_ = get_vp_specific_rng( get_thread() ); - const double t_ms = kernel().simulation_manager.get_time().get_ms(); + const double t_ms = kernel::manager< SimulationManager >.get_time().get_ms(); // if new connections were created during simulation break, resize accordingly // this is a no-op if no new connections were created @@ -330,14 +330,14 @@ nest::sinusoidal_gamma_generator::update( Time const& origin, const long from, c if ( P_.individual_spike_trains_ ) { DSSpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } else { if ( V_.rng_->drand() < hazard_( 0 ) ) { SpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); B_.t0_ms_[ 0 ] = V_.t_ms_; B_.Lambda_t0_[ 0 ] = 0; } diff --git a/models/sinusoidal_gamma_generator.h b/models/sinusoidal_gamma_generator.h index 2a570caa6b..fb2393a109 100644 --- a/models/sinusoidal_gamma_generator.h +++ b/models/sinusoidal_gamma_generator.h @@ -33,11 +33,10 @@ // Includes from nestkernel: #include "connection.h" -#include "device_node.h" #include "event.h" #include "nest_types.h" #include "stimulation_device.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/sinusoidal_poisson_generator.cpp b/models/sinusoidal_poisson_generator.cpp index 6a24cfae5f..77222f3bd1 100644 --- a/models/sinusoidal_poisson_generator.cpp +++ b/models/sinusoidal_poisson_generator.cpp @@ -33,9 +33,9 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "booldatum.h" @@ -223,7 +223,7 @@ nest::sinusoidal_poisson_generator::pre_run_hook() // time resolution V_.h_ = Time::get_resolution().get_ms(); - const double t = kernel().simulation_manager.get_time().get_ms(); + const double t = kernel::manager< SimulationManager >.get_time().get_ms(); // initial state S_.y_0_ = P_.amplitude_ * std::cos( P_.om_ * t + P_.phi_ ); @@ -270,7 +270,7 @@ nest::sinusoidal_poisson_generator::update( Time const& origin, const long from, if ( P_.individual_spike_trains_ ) { DSSpikeEvent se; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } else { @@ -278,7 +278,7 @@ nest::sinusoidal_poisson_generator::update( Time const& origin, const long from, long n_spikes = V_.poisson_dist_( rng, param ); SpikeEvent se; se.set_multiplicity( n_spikes ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } // store rate in spks/s diff --git a/models/sinusoidal_poisson_generator.h b/models/sinusoidal_poisson_generator.h index ebf231901e..f686652744 100644 --- a/models/sinusoidal_poisson_generator.h +++ b/models/sinusoidal_poisson_generator.h @@ -30,7 +30,7 @@ #include "nest_types.h" #include "random_generators.h" #include "stimulation_device.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/spike_dilutor.cpp b/models/spike_dilutor.cpp index b4d105a70d..617a7a0ead 100644 --- a/models/spike_dilutor.cpp +++ b/models/spike_dilutor.cpp @@ -26,15 +26,15 @@ #include "dict_util.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" +#include "event_delivery_manager.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" -#include "model_manager_impl.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" // Includes from sli: #include "dict.h" -#include "dictutils.h" void nest::register_spike_dilutor( const std::string& name ) @@ -100,7 +100,7 @@ nest::spike_dilutor::init_state_() // This check cannot be done in the copy constructor because that is also used to // create model prototypes. Since spike_dilutor is deprecated anyways, we put this // brute-force solution here. - if ( kernel().vp_manager.get_num_threads() > 1 ) + if ( kernel::manager< VPManager >.get_num_threads() > 1 ) { throw KernelException( "The network contains a spike_dilutor which cannot be used with multiple threads." ); } @@ -143,7 +143,7 @@ nest::spike_dilutor::update( Time const& T, const long from, const long to ) DSSpikeEvent se; se.set_multiplicity( n_mother_spikes ); - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } } } @@ -184,6 +184,6 @@ nest::spike_dilutor::event_hook( DSSpikeEvent& e ) void nest::spike_dilutor::handle( SpikeEvent& e ) { - B_.n_spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.n_spikes_.add_value( e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), static_cast< double >( e.get_multiplicity() ) ); } diff --git a/models/spike_generator.cpp b/models/spike_generator.cpp index c6153ede4c..4c3da354fc 100644 --- a/models/spike_generator.cpp +++ b/models/spike_generator.cpp @@ -23,13 +23,15 @@ #include "spike_generator.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" // Includes from libnestutil: #include "dict_util.h" +#include "event_delivery_manager_impl.h" // Includes from sli: #include "arraydatum.h" @@ -388,7 +390,7 @@ nest::spike_generator::update( Time const& sliceT0, const long from, const long long lag = Time( tnext_stamp - sliceT0 ).get_steps() - 1; // all spikes are sent locally, so offset information is always preserved - kernel().event_delivery_manager.send( *this, *se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, *se, lag ); delete se; } diff --git a/models/spike_generator.h b/models/spike_generator.h index a7f5ce41c8..767f68df60 100644 --- a/models/spike_generator.h +++ b/models/spike_generator.h @@ -379,7 +379,7 @@ nest::spike_generator::set_status( const DictionaryDatum& d ) } // throws if BadProperty - ptmp.set( d, S_, origin, kernel().simulation_manager.get_time(), this ); + ptmp.set( d, S_, origin, kernel::manager< SimulationManager >.get_time(), this ); // We now know that ptmp is consistent. We do not write it back // to P_ before we are also sure that the properties to be set diff --git a/models/spike_recorder.cpp b/models/spike_recorder.cpp index 5769fa60e7..68ad208f0d 100644 --- a/models/spike_recorder.cpp +++ b/models/spike_recorder.cpp @@ -23,18 +23,11 @@ #include "spike_recorder.h" -// Includes from libnestutil: -#include "compose.hpp" - // Includes from nestkernel: -#include "event_delivery_manager_impl.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" -#include "model_manager_impl.h" #include "nest_impl.h" - -// Includes from sli: -#include "dict.h" -#include "dictutils.h" +#include "node_manager.h" void nest::register_spike_recorder( const std::string& name ) @@ -84,7 +77,7 @@ nest::spike_recorder::get_status( DictionaryDatum& d ) const // if we are the device on thread 0, also get the data from the siblings on other threads if ( get_thread() == 0 ) { - const std::vector< Node* > siblings = kernel().node_manager.get_thread_siblings( get_node_id() ); + const std::vector< Node* > siblings = kernel::manager< NodeManager >.get_thread_siblings( get_node_id() ); std::vector< Node* >::const_iterator s; for ( s = siblings.begin() + 1; s != siblings.end(); ++s ) { diff --git a/models/spike_recorder.h b/models/spike_recorder.h index 91c2b7e1b7..31d9d52b15 100644 --- a/models/spike_recorder.h +++ b/models/spike_recorder.h @@ -33,6 +33,8 @@ #include "nest_types.h" #include "recording_device.h" +#include "nest_names.h" + /* BeginUserDocs: device, recorder, spike Short description diff --git a/models/spike_train_injector.cpp b/models/spike_train_injector.cpp index 9d596a8e5a..a107a5f905 100644 --- a/models/spike_train_injector.cpp +++ b/models/spike_train_injector.cpp @@ -23,14 +23,15 @@ #include "spike_train_injector.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" -#include "model_manager_impl.h" #include "nest_impl.h" +#include "universal_data_logger_impl.h" // Includes from libnestutil: #include "dict_util.h" +#include "event_delivery_manager_impl.h" // Includes from sli: #include "arraydatum.h" @@ -305,7 +306,7 @@ spike_train_injector::pre_run_hook() // is not an exclusive precise spiking model if ( is_off_grid() ) { - kernel().event_delivery_manager.set_off_grid_communication( true ); + kernel::manager< EventDeliveryManager >.set_off_grid_communication( true ); LOG( M_INFO, "spike_train_injector::pre_run_hook", "Spike train injector has been configured to emit precisely timed " @@ -379,7 +380,7 @@ spike_train_injector::update( Time const& sliceT0, const long from, const long t // we need to subtract one from stamp which is added again in send() long lag = Time( tnext_stamp - sliceT0 ).get_steps() - 1; - kernel().event_delivery_manager.send( *this, se, lag ); + kernel::manager< EventDeliveryManager >.send( *this, se, lag ); } ++S_.position_; diff --git a/models/spike_train_injector.h b/models/spike_train_injector.h index 8d82529c1a..44b4c0a057 100644 --- a/models/spike_train_injector.h +++ b/models/spike_train_injector.h @@ -366,7 +366,7 @@ spike_train_injector::set_status( const DictionaryDatum& d ) } // throws if BadProperty - ptmp.set( d, S_, origin, kernel().simulation_manager.get_time(), this ); + ptmp.set( d, S_, origin, kernel::manager< SimulationManager >.get_time(), this ); // We now know that ptmp is consistent. We do not write it back // to P_ before we are also sure that the properties to be set diff --git a/models/spin_detector.cpp b/models/spin_detector.cpp index 190ece15cb..3fe616bdbd 100644 --- a/models/spin_detector.cpp +++ b/models/spin_detector.cpp @@ -22,19 +22,12 @@ #include "spin_detector.h" - -// Includes from libnestutil: -#include "compose.hpp" - // Includes from nestkernel: -#include "event_delivery_manager_impl.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" -#include "model_manager_impl.h" #include "nest_impl.h" +#include "node_manager.h" -// Includes from sli: -#include "dict.h" -#include "dictutils.h" void nest::register_spin_detector( const std::string& name ) @@ -98,7 +91,7 @@ nest::spin_detector::get_status( DictionaryDatum& d ) const // siblings on other threads if ( get_thread() == 0 ) { - const std::vector< Node* > siblings = kernel().node_manager.get_thread_siblings( get_node_id() ); + const std::vector< Node* > siblings = kernel::manager< NodeManager >.get_thread_siblings( get_node_id() ); std::vector< Node* >::const_iterator s; for ( s = siblings.begin() + 1; s != siblings.end(); ++s ) { diff --git a/models/spin_detector.h b/models/spin_detector.h index 2cb2ef1775..d26fc9c3cf 100644 --- a/models/spin_detector.h +++ b/models/spin_detector.h @@ -35,6 +35,8 @@ #include "nest_types.h" #include "recording_device.h" +#include + namespace nest { diff --git a/models/static_synapse.cpp b/models/static_synapse.cpp index 5149f4032f..12d658aa02 100644 --- a/models/static_synapse.cpp +++ b/models/static_synapse.cpp @@ -22,7 +22,6 @@ #include "static_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/static_synapse.h b/models/static_synapse.h index 25ebf2ce61..5919e5d692 100644 --- a/models/static_synapse.h +++ b/models/static_synapse.h @@ -25,6 +25,7 @@ // Includes from nestkernel: #include "connection.h" +#include "event_delivery_manager.h" namespace nest { @@ -186,7 +187,6 @@ template < typename targetidentifierT > void static_synapse< targetidentifierT >::get_status( DictionaryDatum& d ) const { - ConnectionBase::get_status( d ); def< double >( d, names::weight, weight_ ); def< long >( d, names::size_of, sizeof( *this ) ); diff --git a/models/static_synapse_hom_w.cpp b/models/static_synapse_hom_w.cpp index 5b5694fa67..54f4926fda 100644 --- a/models/static_synapse_hom_w.cpp +++ b/models/static_synapse_hom_w.cpp @@ -22,7 +22,6 @@ #include "static_synapse_hom_w.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/stdp_dopamine_synapse.cpp b/models/stdp_dopamine_synapse.cpp index 1a7ba75eca..c00ead4708 100644 --- a/models/stdp_dopamine_synapse.cpp +++ b/models/stdp_dopamine_synapse.cpp @@ -24,14 +24,14 @@ // Includes from nestkernel: #include "common_synapse_properties.h" -#include "connector_model.h" -#include "event.h" #include "kernel_manager.h" -#include "nest_impl.h" // Includes from sli: #include "dictdatum.h" +#include "nest_impl.h" +#include "node_manager.h" + void nest::register_stdp_dopamine_synapse( const std::string& name ) { @@ -89,8 +89,8 @@ STDPDopaCommonProperties::set_status( const DictionaryDatum& d, ConnectorModel& throw BadProperty( "Property volume_transmitter must be a single element NodeCollection" ); } - const size_t tid = kernel().vp_manager.get_thread_id(); - Node* vt_node = kernel().node_manager.get_node_or_proxy( ( *vt_datum )[ 0 ], tid ); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); + Node* vt_node = kernel::manager< NodeManager >.get_node_or_proxy( ( *vt_datum )[ 0 ], tid ); volume_transmitter* vt = dynamic_cast< volume_transmitter* >( vt_node ); if ( not vt ) { diff --git a/models/stdp_dopamine_synapse.h b/models/stdp_dopamine_synapse.h index 30a1971ffc..95cb28e766 100644 --- a/models/stdp_dopamine_synapse.h +++ b/models/stdp_dopamine_synapse.h @@ -395,7 +395,7 @@ void stdp_dopamine_synapse< targetidentifierT >::check_synapse_params( const DictionaryDatum& syn_spec ) const { // Setting of parameter c and n not thread safe. - if ( kernel().vp_manager.get_num_threads() > 1 ) + if ( kernel::manager< VPManager >.get_num_threads() > 1 ) { if ( syn_spec->known( names::c ) ) { @@ -457,7 +457,8 @@ stdp_dopamine_synapse< targetidentifierT >::process_dopa_spikes_( const std::vec // process dopa spikes in (t0, t1] // propagate weight from t0 to t1 if ( ( dopa_spikes.size() > dopa_spikes_idx_ + 1 ) - and ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ > -1.0 * kernel().connection_manager.get_stdp_eps() ) ) + and ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ + > -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ) ) { // there is at least 1 dopa spike in (t0, t1] // propagate weight up to first dopa spike and update dopamine trace @@ -471,7 +472,8 @@ stdp_dopamine_synapse< targetidentifierT >::process_dopa_spikes_( const std::vec // process remaining dopa spikes in (t0, t1] double cd; while ( ( dopa_spikes.size() > dopa_spikes_idx_ + 1 ) - and ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ > -1.0 * kernel().connection_manager.get_stdp_eps() ) ) + and ( t1 - dopa_spikes[ dopa_spikes_idx_ + 1 ].spike_time_ + > -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ) ) { // propagate weight up to next dopa spike and update dopamine trace // weight and dopamine trace n are at time of last dopa spike td but @@ -553,7 +555,7 @@ stdp_dopamine_synapse< targetidentifierT >::send( Event& e, size_t t, const STDP minus_dt = t_last_update_ - t0; // facilitate only in case of post- after presyn. spike // skip facilitation if pre- and postsyn. spike occur at the same time - if ( t_spike - start->t_ > kernel().connection_manager.get_stdp_eps() ) + if ( t_spike - start->t_ > kernel::manager< ConnectionManager >.get_stdp_eps() ) { facilitate_( Kplus_ * std::exp( minus_dt / cp.tau_plus_ ), cp ); } diff --git a/models/stdp_facetshw_synapse_hom.cpp b/models/stdp_facetshw_synapse_hom.cpp index 09c328f4b1..70aedf8e5e 100644 --- a/models/stdp_facetshw_synapse_hom.cpp +++ b/models/stdp_facetshw_synapse_hom.cpp @@ -21,9 +21,7 @@ */ #include "stdp_facetshw_synapse_hom.h" -#include "stdp_facetshw_synapse_hom_impl.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/stdp_facetshw_synapse_hom.h b/models/stdp_facetshw_synapse_hom.h index 2b103eed48..3f2321c007 100644 --- a/models/stdp_facetshw_synapse_hom.h +++ b/models/stdp_facetshw_synapse_hom.h @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "common_synapse_properties.h" #include "connection.h" +#include "connection_manager.h" namespace nest { @@ -513,7 +514,7 @@ stdp_facetshw_synapse_hom< targetidentifierT >::send( Event& e, // get_history() should make sure that // start->t_ > t_lastspike_ - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt_causal < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt_causal < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); a_causal_ += std::exp( minus_dt_causal / cp.tau_plus_ ); @@ -536,6 +537,302 @@ stdp_facetshw_synapse_hom< targetidentifierT >::send( Event& e, return true; } + +template < typename targetidentifierT > +STDPFACETSHWHomCommonProperties< targetidentifierT >::STDPFACETSHWHomCommonProperties() + : CommonSynapseProperties() + , tau_plus_( 20.0 ) + , tau_minus_( 20.0 ) + , Wmax_( 100.0 ) + , no_synapses_( 0 ) + , synapses_per_driver_( 50 ) // hardware efficiency of 50/256=20%, + // which is comparable to Fieres et al. (2008) + , driver_readout_time_( 15.0 ) // in ms; measured on hardware +{ + lookuptable_0_.resize( 16 ); + lookuptable_1_.resize( 16 ); + lookuptable_2_.resize( 16 ); + + // intermediate Guetig (mu=0.4) + // with r=4 bits and n=36 SSPs, see [3]_ + lookuptable_0_.at( 0 ) = 2; + lookuptable_0_.at( 1 ) = 3; + lookuptable_0_.at( 2 ) = 4; + lookuptable_0_.at( 3 ) = 4; + lookuptable_0_.at( 4 ) = 5; + lookuptable_0_.at( 5 ) = 6; + lookuptable_0_.at( 6 ) = 7; + lookuptable_0_.at( 7 ) = 8; + lookuptable_0_.at( 8 ) = 9; + lookuptable_0_.at( 9 ) = 10; + lookuptable_0_.at( 10 ) = 11; + lookuptable_0_.at( 11 ) = 12; + lookuptable_0_.at( 12 ) = 13; + lookuptable_0_.at( 13 ) = 14; + lookuptable_0_.at( 14 ) = 14; + lookuptable_0_.at( 15 ) = 15; + + lookuptable_1_.at( 0 ) = 0; + lookuptable_1_.at( 1 ) = 0; + lookuptable_1_.at( 2 ) = 1; + lookuptable_1_.at( 3 ) = 2; + lookuptable_1_.at( 4 ) = 3; + lookuptable_1_.at( 5 ) = 4; + lookuptable_1_.at( 6 ) = 5; + lookuptable_1_.at( 7 ) = 6; + lookuptable_1_.at( 8 ) = 7; + lookuptable_1_.at( 9 ) = 8; + lookuptable_1_.at( 10 ) = 9; + lookuptable_1_.at( 11 ) = 10; + lookuptable_1_.at( 12 ) = 10; + lookuptable_1_.at( 13 ) = 11; + lookuptable_1_.at( 14 ) = 12; + lookuptable_1_.at( 15 ) = 13; + + for ( size_t i = 0; i < lookuptable_0_.size(); ++i ) + { + lookuptable_2_.at( i ) = i; + } + + configbit_0_.resize( 4 ); + configbit_1_.resize( 4 ); + + // see [4]_ + configbit_0_.at( 0 ) = 0; + configbit_0_.at( 1 ) = 0; + configbit_0_.at( 2 ) = 1; + configbit_0_.at( 3 ) = 0; + configbit_1_.at( 0 ) = 0; + configbit_1_.at( 1 ) = 1; + configbit_1_.at( 2 ) = 0; + configbit_1_.at( 3 ) = 0; + + reset_pattern_.resize( 6 ); + for ( size_t i = 0; i < reset_pattern_.size(); ++i ) + { + reset_pattern_.at( i ) = true; + } + + weight_per_lut_entry_ = Wmax_ / ( lookuptable_0_.size() - 1 ); + calc_readout_cycle_duration_(); +} + +template < typename targetidentifierT > +void +STDPFACETSHWHomCommonProperties< targetidentifierT >::calc_readout_cycle_duration_() +{ + readout_cycle_duration_ = int( ( no_synapses_ - 1.0 ) / synapses_per_driver_ + 1.0 ) * driver_readout_time_; +} + +template < typename targetidentifierT > +void +STDPFACETSHWHomCommonProperties< targetidentifierT >::get_status( DictionaryDatum& d ) const +{ + CommonSynapseProperties::get_status( d ); + + def< double >( d, names::tau_plus, tau_plus_ ); + def< double >( d, names::tau_minus_stdp, tau_minus_ ); + def< double >( d, names::Wmax, Wmax_ ); + def< double >( d, names::weight_per_lut_entry, weight_per_lut_entry_ ); + + def< long >( d, names::no_synapses, no_synapses_ ); + def< long >( d, names::synapses_per_driver, synapses_per_driver_ ); + def< double >( d, names::driver_readout_time, driver_readout_time_ ); + def< double >( d, names::readout_cycle_duration, readout_cycle_duration_ ); + + ( *d )[ names::lookuptable_0 ] = IntVectorDatum( new std::vector< long >( lookuptable_0_ ) ); + ( *d )[ names::lookuptable_1 ] = IntVectorDatum( new std::vector< long >( lookuptable_1_ ) ); + ( *d )[ names::lookuptable_2 ] = IntVectorDatum( new std::vector< long >( lookuptable_2_ ) ); + ( *d )[ names::configbit_0 ] = IntVectorDatum( new std::vector< long >( configbit_0_ ) ); + ( *d )[ names::configbit_1 ] = IntVectorDatum( new std::vector< long >( configbit_1_ ) ); + ( *d )[ names::reset_pattern ] = IntVectorDatum( new std::vector< long >( reset_pattern_ ) ); +} + +template < typename targetidentifierT > +void +STDPFACETSHWHomCommonProperties< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) +{ + CommonSynapseProperties::set_status( d, cm ); + + updateValue< double >( d, names::tau_plus, tau_plus_ ); + updateValue< double >( d, names::tau_minus_stdp, tau_minus_ ); + if ( updateValue< double >( d, names::Wmax, Wmax_ ) ) + { + weight_per_lut_entry_ = Wmax_ / ( lookuptable_0_.size() - 1 ); + } + + // TP: they should not be allowed to be changed! But needed for CopyModel ... + updateValue< double >( d, names::weight_per_lut_entry, weight_per_lut_entry_ ); + updateValue< double >( d, names::readout_cycle_duration, readout_cycle_duration_ ); + if ( updateValue< long >( d, names::no_synapses, no_synapses_ ) ) + { + calc_readout_cycle_duration_(); + } + + if ( updateValue< long >( d, names::synapses_per_driver, synapses_per_driver_ ) ) + { + calc_readout_cycle_duration_(); + } + if ( updateValue< double >( d, names::driver_readout_time, driver_readout_time_ ) ) + { + calc_readout_cycle_duration_(); + } + + if ( d->known( names::lookuptable_0 ) ) + { + updateValue< std::vector< long > >( d, names::lookuptable_0, lookuptable_0_ ); + + // right size? + if ( lookuptable_0_.size() != lookuptable_1_.size() ) + { + throw BadProperty( "Look-up table has not 2^4 entries!" ); + } + + // are look-up table entries out of bounds? + for ( size_t i = 0; i < size_t( lookuptable_0_.size() ); ++i ) + { + if ( lookuptable_0_[ i ] < 0 or lookuptable_0_[ i ] > 15 ) + { + throw BadProperty( "Look-up table entries must be integers in [0,15]" ); + } + } + } + if ( d->known( names::lookuptable_1 ) ) + { + updateValue< std::vector< long > >( d, names::lookuptable_1, lookuptable_1_ ); + + // right size? + if ( lookuptable_1_.size() != lookuptable_0_.size() ) + { + throw BadProperty( "Look-up table has not 2^4 entries!" ); + } + + // are look-up table entries out of bounds? + for ( size_t i = 0; i < size_t( lookuptable_1_.size() ); ++i ) + { + if ( lookuptable_1_[ i ] < 0 or lookuptable_1_[ i ] > 15 ) + { + throw BadProperty( "Look-up table entries must be integers in [0,15]" ); + } + } + } + if ( d->known( names::lookuptable_2 ) ) + { + updateValue< std::vector< long > >( d, names::lookuptable_2, lookuptable_2_ ); + + // right size? + if ( lookuptable_2_.size() != lookuptable_0_.size() ) + { + throw BadProperty( "Look-up table has not 2^4 entries!" ); + } + + // are look-up table entries out of bounds? + for ( size_t i = 0; i < size_t( lookuptable_2_.size() ); ++i ) + { + if ( lookuptable_2_[ i ] < 0 or lookuptable_2_[ i ] > 15 ) + { + throw BadProperty( "Look-up table entries must be integers in [0,15]" ); + } + } + } + + if ( d->known( names::configbit_0 ) ) + { + updateValue< std::vector< long > >( d, names::configbit_0, configbit_0_ ); + + // right size? + if ( configbit_0_.size() != 4 ) + { + throw BadProperty( "Wrong number of configuration bits (!=4)." ); + } + } + if ( d->known( names::configbit_1 ) ) + { + updateValue< std::vector< long > >( d, names::configbit_1, configbit_1_ ); + + // right size? + if ( configbit_1_.size() != 4 ) + { + throw BadProperty( "Wrong number of configuration bits (!=4)." ); + } + } + if ( d->known( names::reset_pattern ) ) + { + updateValue< std::vector< long > >( d, names::reset_pattern, reset_pattern_ ); + + // right size? + if ( reset_pattern_.size() != 6 ) + { + throw BadProperty( "Wrong number of reset bits (!=6)." ); + } + } +} + + +// +// Implementation of class stdp_facetshw_synapse_hom. +// +template < typename targetidentifierT > +stdp_facetshw_synapse_hom< targetidentifierT >::stdp_facetshw_synapse_hom() + : weight_( 1.0 ) + , a_causal_( 0.0 ) + , a_acausal_( 0.0 ) + , a_thresh_th_( 21.835 ) + , a_thresh_tl_( 21.835 ) // exp(-10ms/20ms) * 36SSPs + , init_flag_( false ) + , synapse_id_( 0 ) + , next_readout_time_( 0.0 ) + , discrete_weight_( 0 ) + , t_lastspike_( 0.0 ) +{ +} + +template < typename targetidentifierT > +void +stdp_facetshw_synapse_hom< targetidentifierT >::get_status( DictionaryDatum& d ) const +{ + // base class properties, different for individual synapse + ConnectionBase::get_status( d ); + def< double >( d, names::weight, weight_ ); + + // own properties, different for individual synapse + def< double >( d, names::a_causal, a_causal_ ); + def< double >( d, names::a_acausal, a_acausal_ ); + def< double >( d, names::a_thresh_th, a_thresh_th_ ); + def< double >( d, names::a_thresh_tl, a_thresh_tl_ ); + + def< bool >( d, names::init_flag, init_flag_ ); + def< long >( d, names::synapse_id, synapse_id_ ); + def< double >( d, names::next_readout_time, next_readout_time_ ); + // useful to get conversion before activity, but weight_per_lut_entry_ not + // known here + // def(d, "discrete_weight", + // entry_to_weight_(weight_to_entry_(weight_, + // weight_per_lut_entry_), weight_per_lut_entry_)); +} + +template < typename targetidentifierT > +void +stdp_facetshw_synapse_hom< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) +{ + // base class properties + ConnectionBase::set_status( d, cm ); + updateValue< double >( d, names::weight, weight_ ); + + updateValue< double >( d, names::a_causal, a_causal_ ); + updateValue< double >( d, names::a_acausal, a_acausal_ ); + updateValue< double >( d, names::a_thresh_th, a_thresh_th_ ); + updateValue< double >( d, names::a_thresh_tl, a_thresh_tl_ ); + + updateValue< long >( d, names::synapse_id, synapse_id_ ); + + // TP: they should not be allowed to be changed! But needed for CopyModel ... + updateValue< bool >( d, names::init_flag, init_flag_ ); + updateValue< double >( d, names::next_readout_time, next_readout_time_ ); + + // setting discrete_weight_ does not make sense, is temporary variable +} + } // of namespace nest #endif // of #ifndef STDP_SYNAPSE_FACETSHW_HOM_H diff --git a/models/stdp_facetshw_synapse_hom_impl.h b/models/stdp_facetshw_synapse_hom_impl.h deleted file mode 100644 index 765b814715..0000000000 --- a/models/stdp_facetshw_synapse_hom_impl.h +++ /dev/null @@ -1,339 +0,0 @@ -/* - * stdp_facetshw_synapse_hom_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - */ - -#ifndef STDP_SYNAPSE_FACETSHW_HOM_IMPL_H -#define STDP_SYNAPSE_FACETSHW_HOM_IMPL_H - -#include "stdp_facetshw_synapse_hom.h" - -// Includes from nestkernel: -#include "common_synapse_properties.h" -#include "connector_model.h" -#include "event.h" - -// Includes from sli: -#include "dictdatum.h" - -namespace nest -{ -// -// Implementation of class STDPFACETSHWHomCommonProperties. -// - -template < typename targetidentifierT > -STDPFACETSHWHomCommonProperties< targetidentifierT >::STDPFACETSHWHomCommonProperties() - : CommonSynapseProperties() - , tau_plus_( 20.0 ) - , tau_minus_( 20.0 ) - , Wmax_( 100.0 ) - , no_synapses_( 0 ) - , synapses_per_driver_( 50 ) // hardware efficiency of 50/256=20%, - // which is comparable to Fieres et al. (2008) - , driver_readout_time_( 15.0 ) // in ms; measured on hardware -{ - lookuptable_0_.resize( 16 ); - lookuptable_1_.resize( 16 ); - lookuptable_2_.resize( 16 ); - - // intermediate Guetig (mu=0.4) - // with r=4 bits and n=36 SSPs, see [3]_ - lookuptable_0_.at( 0 ) = 2; - lookuptable_0_.at( 1 ) = 3; - lookuptable_0_.at( 2 ) = 4; - lookuptable_0_.at( 3 ) = 4; - lookuptable_0_.at( 4 ) = 5; - lookuptable_0_.at( 5 ) = 6; - lookuptable_0_.at( 6 ) = 7; - lookuptable_0_.at( 7 ) = 8; - lookuptable_0_.at( 8 ) = 9; - lookuptable_0_.at( 9 ) = 10; - lookuptable_0_.at( 10 ) = 11; - lookuptable_0_.at( 11 ) = 12; - lookuptable_0_.at( 12 ) = 13; - lookuptable_0_.at( 13 ) = 14; - lookuptable_0_.at( 14 ) = 14; - lookuptable_0_.at( 15 ) = 15; - - lookuptable_1_.at( 0 ) = 0; - lookuptable_1_.at( 1 ) = 0; - lookuptable_1_.at( 2 ) = 1; - lookuptable_1_.at( 3 ) = 2; - lookuptable_1_.at( 4 ) = 3; - lookuptable_1_.at( 5 ) = 4; - lookuptable_1_.at( 6 ) = 5; - lookuptable_1_.at( 7 ) = 6; - lookuptable_1_.at( 8 ) = 7; - lookuptable_1_.at( 9 ) = 8; - lookuptable_1_.at( 10 ) = 9; - lookuptable_1_.at( 11 ) = 10; - lookuptable_1_.at( 12 ) = 10; - lookuptable_1_.at( 13 ) = 11; - lookuptable_1_.at( 14 ) = 12; - lookuptable_1_.at( 15 ) = 13; - - for ( size_t i = 0; i < lookuptable_0_.size(); ++i ) - { - lookuptable_2_.at( i ) = i; - } - - configbit_0_.resize( 4 ); - configbit_1_.resize( 4 ); - - // see [4]_ - configbit_0_.at( 0 ) = 0; - configbit_0_.at( 1 ) = 0; - configbit_0_.at( 2 ) = 1; - configbit_0_.at( 3 ) = 0; - configbit_1_.at( 0 ) = 0; - configbit_1_.at( 1 ) = 1; - configbit_1_.at( 2 ) = 0; - configbit_1_.at( 3 ) = 0; - - reset_pattern_.resize( 6 ); - for ( size_t i = 0; i < reset_pattern_.size(); ++i ) - { - reset_pattern_.at( i ) = true; - } - - weight_per_lut_entry_ = Wmax_ / ( lookuptable_0_.size() - 1 ); - calc_readout_cycle_duration_(); -} - -template < typename targetidentifierT > -void -STDPFACETSHWHomCommonProperties< targetidentifierT >::calc_readout_cycle_duration_() -{ - readout_cycle_duration_ = int( ( no_synapses_ - 1.0 ) / synapses_per_driver_ + 1.0 ) * driver_readout_time_; -} - -template < typename targetidentifierT > -void -STDPFACETSHWHomCommonProperties< targetidentifierT >::get_status( DictionaryDatum& d ) const -{ - CommonSynapseProperties::get_status( d ); - - def< double >( d, names::tau_plus, tau_plus_ ); - def< double >( d, names::tau_minus_stdp, tau_minus_ ); - def< double >( d, names::Wmax, Wmax_ ); - def< double >( d, names::weight_per_lut_entry, weight_per_lut_entry_ ); - - def< long >( d, names::no_synapses, no_synapses_ ); - def< long >( d, names::synapses_per_driver, synapses_per_driver_ ); - def< double >( d, names::driver_readout_time, driver_readout_time_ ); - def< double >( d, names::readout_cycle_duration, readout_cycle_duration_ ); - - ( *d )[ names::lookuptable_0 ] = IntVectorDatum( new std::vector< long >( lookuptable_0_ ) ); - ( *d )[ names::lookuptable_1 ] = IntVectorDatum( new std::vector< long >( lookuptable_1_ ) ); - ( *d )[ names::lookuptable_2 ] = IntVectorDatum( new std::vector< long >( lookuptable_2_ ) ); - ( *d )[ names::configbit_0 ] = IntVectorDatum( new std::vector< long >( configbit_0_ ) ); - ( *d )[ names::configbit_1 ] = IntVectorDatum( new std::vector< long >( configbit_1_ ) ); - ( *d )[ names::reset_pattern ] = IntVectorDatum( new std::vector< long >( reset_pattern_ ) ); -} - -template < typename targetidentifierT > -void -STDPFACETSHWHomCommonProperties< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) -{ - CommonSynapseProperties::set_status( d, cm ); - - updateValue< double >( d, names::tau_plus, tau_plus_ ); - updateValue< double >( d, names::tau_minus_stdp, tau_minus_ ); - if ( updateValue< double >( d, names::Wmax, Wmax_ ) ) - { - weight_per_lut_entry_ = Wmax_ / ( lookuptable_0_.size() - 1 ); - } - - // TP: they should not be allowed to be changed! But needed for CopyModel ... - updateValue< double >( d, names::weight_per_lut_entry, weight_per_lut_entry_ ); - updateValue< double >( d, names::readout_cycle_duration, readout_cycle_duration_ ); - if ( updateValue< long >( d, names::no_synapses, no_synapses_ ) ) - { - calc_readout_cycle_duration_(); - } - - if ( updateValue< long >( d, names::synapses_per_driver, synapses_per_driver_ ) ) - { - calc_readout_cycle_duration_(); - } - if ( updateValue< double >( d, names::driver_readout_time, driver_readout_time_ ) ) - { - calc_readout_cycle_duration_(); - } - - if ( d->known( names::lookuptable_0 ) ) - { - updateValue< std::vector< long > >( d, names::lookuptable_0, lookuptable_0_ ); - - // right size? - if ( lookuptable_0_.size() != lookuptable_1_.size() ) - { - throw BadProperty( "Look-up table has not 2^4 entries!" ); - } - - // are look-up table entries out of bounds? - for ( size_t i = 0; i < size_t( lookuptable_0_.size() ); ++i ) - { - if ( lookuptable_0_[ i ] < 0 or lookuptable_0_[ i ] > 15 ) - { - throw BadProperty( "Look-up table entries must be integers in [0,15]" ); - } - } - } - if ( d->known( names::lookuptable_1 ) ) - { - updateValue< std::vector< long > >( d, names::lookuptable_1, lookuptable_1_ ); - - // right size? - if ( lookuptable_1_.size() != lookuptable_0_.size() ) - { - throw BadProperty( "Look-up table has not 2^4 entries!" ); - } - - // are look-up table entries out of bounds? - for ( size_t i = 0; i < size_t( lookuptable_1_.size() ); ++i ) - { - if ( lookuptable_1_[ i ] < 0 or lookuptable_1_[ i ] > 15 ) - { - throw BadProperty( "Look-up table entries must be integers in [0,15]" ); - } - } - } - if ( d->known( names::lookuptable_2 ) ) - { - updateValue< std::vector< long > >( d, names::lookuptable_2, lookuptable_2_ ); - - // right size? - if ( lookuptable_2_.size() != lookuptable_0_.size() ) - { - throw BadProperty( "Look-up table has not 2^4 entries!" ); - } - - // are look-up table entries out of bounds? - for ( size_t i = 0; i < size_t( lookuptable_2_.size() ); ++i ) - { - if ( lookuptable_2_[ i ] < 0 or lookuptable_2_[ i ] > 15 ) - { - throw BadProperty( "Look-up table entries must be integers in [0,15]" ); - } - } - } - - if ( d->known( names::configbit_0 ) ) - { - updateValue< std::vector< long > >( d, names::configbit_0, configbit_0_ ); - - // right size? - if ( configbit_0_.size() != 4 ) - { - throw BadProperty( "Wrong number of configuration bits (!=4)." ); - } - } - if ( d->known( names::configbit_1 ) ) - { - updateValue< std::vector< long > >( d, names::configbit_1, configbit_1_ ); - - // right size? - if ( configbit_1_.size() != 4 ) - { - throw BadProperty( "Wrong number of configuration bits (!=4)." ); - } - } - if ( d->known( names::reset_pattern ) ) - { - updateValue< std::vector< long > >( d, names::reset_pattern, reset_pattern_ ); - - // right size? - if ( reset_pattern_.size() != 6 ) - { - throw BadProperty( "Wrong number of reset bits (!=6)." ); - } - } -} - - -// -// Implementation of class stdp_facetshw_synapse_hom. -// -template < typename targetidentifierT > -stdp_facetshw_synapse_hom< targetidentifierT >::stdp_facetshw_synapse_hom() - : weight_( 1.0 ) - , a_causal_( 0.0 ) - , a_acausal_( 0.0 ) - , a_thresh_th_( 21.835 ) - , a_thresh_tl_( 21.835 ) // exp(-10ms/20ms) * 36SSPs - , init_flag_( false ) - , synapse_id_( 0 ) - , next_readout_time_( 0.0 ) - , discrete_weight_( 0 ) - , t_lastspike_( 0.0 ) -{ -} - -template < typename targetidentifierT > -void -stdp_facetshw_synapse_hom< targetidentifierT >::get_status( DictionaryDatum& d ) const -{ - // base class properties, different for individual synapse - ConnectionBase::get_status( d ); - def< double >( d, names::weight, weight_ ); - - // own properties, different for individual synapse - def< double >( d, names::a_causal, a_causal_ ); - def< double >( d, names::a_acausal, a_acausal_ ); - def< double >( d, names::a_thresh_th, a_thresh_th_ ); - def< double >( d, names::a_thresh_tl, a_thresh_tl_ ); - - def< bool >( d, names::init_flag, init_flag_ ); - def< long >( d, names::synapse_id, synapse_id_ ); - def< double >( d, names::next_readout_time, next_readout_time_ ); - // useful to get conversion before activity, but weight_per_lut_entry_ not - // known here - // def(d, "discrete_weight", - // entry_to_weight_(weight_to_entry_(weight_, - // weight_per_lut_entry_), weight_per_lut_entry_)); -} - -template < typename targetidentifierT > -void -stdp_facetshw_synapse_hom< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) -{ - // base class properties - ConnectionBase::set_status( d, cm ); - updateValue< double >( d, names::weight, weight_ ); - - updateValue< double >( d, names::a_causal, a_causal_ ); - updateValue< double >( d, names::a_acausal, a_acausal_ ); - updateValue< double >( d, names::a_thresh_th, a_thresh_th_ ); - updateValue< double >( d, names::a_thresh_tl, a_thresh_tl_ ); - - updateValue< long >( d, names::synapse_id, synapse_id_ ); - - // TP: they should not be allowed to be changed! But needed for CopyModel ... - updateValue< bool >( d, names::init_flag, init_flag_ ); - updateValue< double >( d, names::next_readout_time, next_readout_time_ ); - - // setting discrete_weight_ does not make sense, is temporary variable -} - -} // of namespace nest - -#endif // #ifndef STDP_SYNAPSE_FACETSHW_HOM_IMPL_H diff --git a/models/stdp_nn_pre_centered_synapse.cpp b/models/stdp_nn_pre_centered_synapse.cpp index baa03ddfa5..98c5b9c48a 100644 --- a/models/stdp_nn_pre_centered_synapse.cpp +++ b/models/stdp_nn_pre_centered_synapse.cpp @@ -22,7 +22,6 @@ #include "stdp_nn_pre_centered_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/stdp_nn_pre_centered_synapse.h b/models/stdp_nn_pre_centered_synapse.h index ec2791efbf..c02c53790d 100644 --- a/models/stdp_nn_pre_centered_synapse.h +++ b/models/stdp_nn_pre_centered_synapse.h @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "common_synapse_properties.h" #include "connection.h" +#include "connection_manager.h" #include "connector_model.h" #include "event.h" @@ -285,7 +286,7 @@ stdp_nn_pre_centered_synapse< targetidentifierT >::send( Event& e, size_t t, con // get_history() should make sure that // start->t_ > t_lastspike_ - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_plus_ ) ); diff --git a/models/stdp_nn_restr_synapse.cpp b/models/stdp_nn_restr_synapse.cpp index c531ac5c38..7c09102627 100644 --- a/models/stdp_nn_restr_synapse.cpp +++ b/models/stdp_nn_restr_synapse.cpp @@ -22,7 +22,6 @@ #include "stdp_nn_restr_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/stdp_nn_restr_synapse.h b/models/stdp_nn_restr_synapse.h index 7562266dc3..29ff77b548 100644 --- a/models/stdp_nn_restr_synapse.h +++ b/models/stdp_nn_restr_synapse.h @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "common_synapse_properties.h" #include "connection.h" +#include "connection_manager.h" #include "connector_model.h" #include "event.h" @@ -280,7 +281,7 @@ stdp_nn_restr_synapse< targetidentifierT >::send( Event& e, size_t t, const Comm // get_history() should make sure that // start->t_ > t_lastspike_ - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); weight_ = facilitate_( weight_, std::exp( minus_dt / tau_plus_ ) ); } diff --git a/models/stdp_nn_symm_synapse.cpp b/models/stdp_nn_symm_synapse.cpp index b1b69b3b26..db56fdaa83 100644 --- a/models/stdp_nn_symm_synapse.cpp +++ b/models/stdp_nn_symm_synapse.cpp @@ -22,7 +22,6 @@ #include "stdp_nn_symm_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/stdp_nn_symm_synapse.h b/models/stdp_nn_symm_synapse.h index 92970ec8ec..3c36c7b393 100644 --- a/models/stdp_nn_symm_synapse.h +++ b/models/stdp_nn_symm_synapse.h @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "common_synapse_properties.h" #include "connection.h" +#include "connection_manager.h" #include "connector_model.h" #include "event.h" @@ -278,7 +279,7 @@ stdp_nn_symm_synapse< targetidentifierT >::send( Event& e, size_t t, const Commo // get_history() should make sure that // start->t_ > t_lastspike_ - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); weight_ = facilitate_( weight_, std::exp( minus_dt / tau_plus_ ) ); } diff --git a/models/stdp_pl_synapse_hom.cpp b/models/stdp_pl_synapse_hom.cpp index 3bc6a0c247..dc6f42a8a5 100644 --- a/models/stdp_pl_synapse_hom.cpp +++ b/models/stdp_pl_synapse_hom.cpp @@ -24,13 +24,13 @@ // Includes from nestkernel: #include "common_synapse_properties.h" -#include "connector_model.h" #include "event.h" -#include "nest_impl.h" // Includes from sli: #include "dictdatum.h" +#include "nest_impl.h" + void nest::register_stdp_pl_synapse_hom( const std::string& name ) { diff --git a/models/stdp_pl_synapse_hom.h b/models/stdp_pl_synapse_hom.h index b01a79c79d..3515d729d1 100644 --- a/models/stdp_pl_synapse_hom.h +++ b/models/stdp_pl_synapse_hom.h @@ -28,6 +28,7 @@ // Includes from nestkernel: #include "connection.h" +#include "connection_manager.h" namespace nest { @@ -281,7 +282,7 @@ stdp_pl_synapse_hom< targetidentifierT >::send( Event& e, size_t t, const STDPPL start++; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt * cp.tau_plus_inv_ ), cp ); } diff --git a/models/stdp_synapse.cpp b/models/stdp_synapse.cpp index cbd48650ad..c4a6e5c47c 100644 --- a/models/stdp_synapse.cpp +++ b/models/stdp_synapse.cpp @@ -22,7 +22,6 @@ #include "stdp_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/stdp_synapse.h b/models/stdp_synapse.h index 61b3cbcafa..2ce0605c47 100644 --- a/models/stdp_synapse.h +++ b/models/stdp_synapse.h @@ -29,6 +29,7 @@ // Includes from nestkernel: #include "common_synapse_properties.h" #include "connection.h" +#include "connection_manager.h" #include "connector_model.h" #include "event.h" @@ -268,7 +269,7 @@ stdp_synapse< targetidentifierT >::send( Event& e, size_t t, const CommonSynapse ++start; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_plus_ ) ); } diff --git a/models/stdp_synapse_hom.cpp b/models/stdp_synapse_hom.cpp index fccdf1b148..c017a4a346 100644 --- a/models/stdp_synapse_hom.cpp +++ b/models/stdp_synapse_hom.cpp @@ -24,12 +24,12 @@ // Includes from nestkernel: #include "common_synapse_properties.h" -#include "connector_model.h" -#include "nest_impl.h" // Includes from sli: #include "dictdatum.h" +#include "nest_impl.h" + void nest::register_stdp_synapse_hom( const std::string& name ) { diff --git a/models/stdp_synapse_hom.h b/models/stdp_synapse_hom.h index 803f513585..3766889b15 100644 --- a/models/stdp_synapse_hom.h +++ b/models/stdp_synapse_hom.h @@ -28,6 +28,7 @@ // Includes from nestkernel: #include "connection.h" +#include "connection_manager.h" namespace nest { @@ -316,7 +317,7 @@ stdp_synapse_hom< targetidentifierT >::send( Event& e, size_t t, const STDPHomCo ++start; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / cp.tau_plus_ ), cp ); } diff --git a/models/stdp_triplet_synapse.cpp b/models/stdp_triplet_synapse.cpp index 597c1ee9c6..b3aeb3d1bc 100644 --- a/models/stdp_triplet_synapse.cpp +++ b/models/stdp_triplet_synapse.cpp @@ -22,7 +22,6 @@ #include "stdp_triplet_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/stdp_triplet_synapse.h b/models/stdp_triplet_synapse.h index f2a8f8ced3..f6e20ae9f0 100644 --- a/models/stdp_triplet_synapse.h +++ b/models/stdp_triplet_synapse.h @@ -25,6 +25,7 @@ // C-header for math.h since copysign() is in C99 but not C++98 #include "connection.h" +#include "connection_manager.h" #include namespace nest @@ -286,7 +287,7 @@ stdp_triplet_synapse< targetidentifierT >::send( Event& e, size_t t, const Commo ++start; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_plus_ ), ky ); } diff --git a/models/step_current_generator.cpp b/models/step_current_generator.cpp index d006dc30af..8876b6fded 100644 --- a/models/step_current_generator.cpp +++ b/models/step_current_generator.cpp @@ -24,6 +24,8 @@ // Includes from nestkernel: #include "event_delivery_manager_impl.h" +#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" #include "universal_data_logger_impl.h" @@ -33,6 +35,8 @@ #include "dict.h" #include "dictutils.h" +#include "nest_impl.h" + namespace nest { void @@ -312,7 +316,7 @@ nest::step_current_generator::update( Time const& origin, const long from, const CurrentEvent ce; ce.set_current( B_.amp_ ); S_.I_ = B_.amp_; - kernel().event_delivery_manager.send( *this, ce, offs ); + kernel::manager< EventDeliveryManager >.send( *this, ce, offs ); } B_.logger_.record_data( origin.get_steps() + offs ); } diff --git a/models/step_current_generator.h b/models/step_current_generator.h index 5d8d8fc04c..f3cc384464 100644 --- a/models/step_current_generator.h +++ b/models/step_current_generator.h @@ -34,7 +34,7 @@ #include "nest_types.h" #include "ring_buffer.h" #include "stimulation_device.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/step_rate_generator.cpp b/models/step_rate_generator.cpp index dfe104987d..f5f95cc728 100644 --- a/models/step_rate_generator.cpp +++ b/models/step_rate_generator.cpp @@ -23,16 +23,17 @@ #include "step_rate_generator.h" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" #include "nest_impl.h" -#include "universal_data_logger_impl.h" // Includes from sli: #include "booldatum.h" #include "dict.h" #include "dictutils.h" +#include "nest_impl.h" + namespace nest { void @@ -285,7 +286,7 @@ nest::step_rate_generator::update( Time const& origin, const long from, const lo const long t0 = origin.get_steps(); // allocate memory to store rates to be sent by rate events - const size_t buffer_size = kernel().connection_manager.get_min_delay(); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); std::vector< double > new_rates( buffer_size, 0.0 ); // Skip any times in the past. Since we must send events proactively, @@ -327,7 +328,7 @@ nest::step_rate_generator::update( Time const& origin, const long from, const lo { DelayedRateConnectionEvent drve; drve.set_coeffarray( new_rates ); - kernel().event_delivery_manager.send_secondary( *this, drve ); + kernel::manager< EventDeliveryManager >.send_secondary( *this, drve ); } } diff --git a/models/step_rate_generator.h b/models/step_rate_generator.h index 4853c15f7f..75829f0440 100644 --- a/models/step_rate_generator.h +++ b/models/step_rate_generator.h @@ -34,7 +34,7 @@ #include "nest_types.h" #include "ring_buffer.h" #include "stimulation_device.h" -#include "universal_data_logger.h" +#include "universal_data_logger_impl.h" namespace nest { diff --git a/models/tanh_rate.cpp b/models/tanh_rate.cpp index c1a41cb679..fccc105446 100644 --- a/models/tanh_rate.cpp +++ b/models/tanh_rate.cpp @@ -22,10 +22,7 @@ #include "tanh_rate.h" -// Includes from nestkernel -#include "kernel_manager.h" -#include "model_manager_impl.h" -#include "nest_impl.h" +#include namespace nest { diff --git a/models/tanh_rate.h b/models/tanh_rate.h index ce04f718b2..b8b4e599df 100644 --- a/models/tanh_rate.h +++ b/models/tanh_rate.h @@ -25,11 +25,8 @@ // Includes from models: #include "rate_neuron_ipn.h" -#include "rate_neuron_ipn_impl.h" #include "rate_neuron_opn.h" -#include "rate_neuron_opn_impl.h" #include "rate_transformer_node.h" -#include "rate_transformer_node_impl.h" namespace nest { diff --git a/models/threshold_lin_rate.cpp b/models/threshold_lin_rate.cpp index dbb877601e..fd91608874 100644 --- a/models/threshold_lin_rate.cpp +++ b/models/threshold_lin_rate.cpp @@ -22,10 +22,7 @@ #include "threshold_lin_rate.h" -// Includes from nestkernel -#include "kernel_manager.h" -#include "model_manager_impl.h" -#include "nest_impl.h" +#include "dict_util.h" namespace nest { diff --git a/models/threshold_lin_rate.h b/models/threshold_lin_rate.h index 2329f4064a..4c1dbeeea2 100644 --- a/models/threshold_lin_rate.h +++ b/models/threshold_lin_rate.h @@ -28,11 +28,8 @@ // Includes from models: #include "rate_neuron_ipn.h" -#include "rate_neuron_ipn_impl.h" #include "rate_neuron_opn.h" -#include "rate_neuron_opn_impl.h" #include "rate_transformer_node.h" -#include "rate_transformer_node_impl.h" namespace nest { diff --git a/models/tsodyks2_synapse.cpp b/models/tsodyks2_synapse.cpp index 0019c0b11f..87c62f7b0e 100644 --- a/models/tsodyks2_synapse.cpp +++ b/models/tsodyks2_synapse.cpp @@ -22,7 +22,6 @@ #include "tsodyks2_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/tsodyks_synapse.cpp b/models/tsodyks_synapse.cpp index 19e2222ae9..c7dce8ad64 100644 --- a/models/tsodyks_synapse.cpp +++ b/models/tsodyks_synapse.cpp @@ -22,7 +22,6 @@ #include "tsodyks_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/tsodyks_synapse_hom.cpp b/models/tsodyks_synapse_hom.cpp index 65e450ba2b..8d04c15f12 100644 --- a/models/tsodyks_synapse_hom.cpp +++ b/models/tsodyks_synapse_hom.cpp @@ -22,8 +22,6 @@ #include "tsodyks_synapse_hom.h" -// Includes from nestkernel: -#include "connector_model.h" #include "nest_impl.h" void diff --git a/models/urbanczik_synapse.cpp b/models/urbanczik_synapse.cpp index 8fd26b8550..ac510dc03d 100644 --- a/models/urbanczik_synapse.cpp +++ b/models/urbanczik_synapse.cpp @@ -22,7 +22,6 @@ #include "urbanczik_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/vogels_sprekeler_synapse.cpp b/models/vogels_sprekeler_synapse.cpp index e1279d0888..91db40cb98 100644 --- a/models/vogels_sprekeler_synapse.cpp +++ b/models/vogels_sprekeler_synapse.cpp @@ -22,7 +22,6 @@ #include "vogels_sprekeler_synapse.h" -// Includes from nestkernel: #include "nest_impl.h" void diff --git a/models/vogels_sprekeler_synapse.h b/models/vogels_sprekeler_synapse.h index cf30380486..2bdbe44510 100644 --- a/models/vogels_sprekeler_synapse.h +++ b/models/vogels_sprekeler_synapse.h @@ -25,6 +25,7 @@ // C-header for math.h since copysign() is in C99 but not C++98 #include "connection.h" +#include "connection_manager.h" #include namespace nest @@ -240,7 +241,7 @@ vogels_sprekeler_synapse< targetidentifierT >::send( Event& e, size_t t, const C ++start; // get_history() should make sure that // start->t_ > t_lastspike - dendritic_delay, i.e. minus_dt < 0 - assert( minus_dt < -1.0 * kernel().connection_manager.get_stdp_eps() ); + assert( minus_dt < -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); weight_ = facilitate_( weight_, Kplus_ * std::exp( minus_dt / tau_ ) ); } diff --git a/models/volume_transmitter.cpp b/models/volume_transmitter.cpp index 659838b288..b819526838 100644 --- a/models/volume_transmitter.cpp +++ b/models/volume_transmitter.cpp @@ -24,11 +24,10 @@ // Includes from nestkernel: -#include "connector_base.h" -#include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" -#include "model_manager_impl.h" #include "nest_impl.h" +#include "simulation_manager.h" #include "spikecounter.h" // Includes from libnestutil: @@ -98,7 +97,7 @@ void nest::volume_transmitter::pre_run_hook() { // +1 as pseudo dopa spike at t_trig is inserted after trigger_update_weight - B_.spikecounter_.reserve( kernel().connection_manager.get_min_delay() * P_.deliver_interval_ + 1 ); + B_.spikecounter_.reserve( kernel::manager< ConnectionManager >.get_min_delay() * P_.deliver_interval_ + 1 ); } void @@ -112,21 +111,23 @@ nest::volume_transmitter::update( const Time&, const long from, const long to ) multiplicity = B_.neuromodulatory_spikes_.get_value( lag ); if ( multiplicity > 0 ) { - t_spike = Time( Time::step( kernel().simulation_manager.get_slice_origin().get_steps() + lag + 1 ) ).get_ms(); + t_spike = + Time( Time::step( kernel::manager< SimulationManager >.get_slice_origin().get_steps() + lag + 1 ) ).get_ms(); B_.spikecounter_.push_back( spikecounter( t_spike, multiplicity ) ); } } // all spikes stored in spikecounter_ are delivered to the target synapses - if ( ( kernel().simulation_manager.get_slice_origin().get_steps() + to ) - % ( P_.deliver_interval_ * kernel().connection_manager.get_min_delay() ) + if ( ( kernel::manager< SimulationManager >.get_slice_origin().get_steps() + to ) + % ( P_.deliver_interval_ * kernel::manager< ConnectionManager >.get_min_delay() ) == 0 ) { - double t_trig = Time( Time::step( kernel().simulation_manager.get_slice_origin().get_steps() + to ) ).get_ms(); + double t_trig = + Time( Time::step( kernel::manager< SimulationManager >.get_slice_origin().get_steps() + to ) ).get_ms(); if ( not B_.spikecounter_.empty() ) { - kernel().connection_manager.trigger_update_weight( get_node_id(), B_.spikecounter_, t_trig ); + kernel::manager< ConnectionManager >.trigger_update_weight( get_node_id(), B_.spikecounter_, t_trig ); } // clear spikecounter @@ -141,6 +142,7 @@ nest::volume_transmitter::update( const Time&, const long from, const long to ) void nest::volume_transmitter::handle( SpikeEvent& e ) { - B_.neuromodulatory_spikes_.add_value( e.get_rel_delivery_steps( kernel().simulation_manager.get_slice_origin() ), + B_.neuromodulatory_spikes_.add_value( + e.get_rel_delivery_steps( kernel::manager< SimulationManager >.get_slice_origin() ), static_cast< double >( e.get_multiplicity() ) ); } diff --git a/models/weight_recorder.cpp b/models/weight_recorder.cpp index 33f1fef67d..22c32c2bde 100644 --- a/models/weight_recorder.cpp +++ b/models/weight_recorder.cpp @@ -27,12 +27,12 @@ #include "compose.hpp" // Includes from nestkernel: -#include "event_delivery_manager_impl.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" -#include "model_manager_impl.h" #include "nest_datums.h" #include "nest_impl.h" #include "node_collection.h" +#include "node_manager.h" // Includes from sli: #include "arraydatum.h" @@ -169,7 +169,7 @@ nest::weight_recorder::get_status( DictionaryDatum& d ) const // siblings on other threads if ( get_thread() == 0 ) { - const std::vector< Node* > siblings = kernel().node_manager.get_thread_siblings( get_node_id() ); + const std::vector< Node* > siblings = kernel::manager< NodeManager >.get_thread_siblings( get_node_id() ); std::vector< Node* >::const_iterator s; for ( s = siblings.begin() + 1; s != siblings.end(); ++s ) { diff --git a/models/weight_recorder.h b/models/weight_recorder.h index ef23ad8f6d..fbff6d2a64 100644 --- a/models/weight_recorder.h +++ b/models/weight_recorder.h @@ -23,14 +23,10 @@ #ifndef WEIGHT_RECORDER_H #define WEIGHT_RECORDER_H -// C++ includes: -#include - // Includes from nestkernel: -#include "device_node.h" #include "event.h" #include "exceptions.h" -#include "kernel_manager.h" +#include "nest_datums.h" #include "nest_types.h" #include "recording_device.h" diff --git a/nest/neststartup.cpp b/nest/neststartup.cpp index b27ba0abc5..59e269154f 100644 --- a/nest/neststartup.cpp +++ b/nest/neststartup.cpp @@ -123,9 +123,8 @@ neststartup( int* argc, char*** argv, SLIInterpreter& engine, std::string module void nestshutdown( int exitcode ) { - nest::kernel().finalize(); - nest::kernel().mpi_manager.mpi_finalize( exitcode ); - nest::KernelManager::destroy_kernel_manager(); + nest::kernel::manager< nest::KernelManager >.finalize(); + nest::kernel::manager< nest::MPIManager >.mpi_finalize( exitcode ); } #if defined( HAVE_LIBNEUROSIM ) && defined( _IS_PYNEST ) @@ -161,7 +160,7 @@ set_communicator( PyObject* pyobj ) throw nest::KernelException( "set_communicator: argument is not a mpi4py communicator" ); } - nest::kernel().mpi_manager.set_communicator( *PyMPIComm_Get( pyobj ) ); + nest::kernel::manager< nest::MPIManager >.set_communicator( *PyMPIComm_Get( pyobj ) ); } #else // ! HAVE_MPI4PY diff --git a/nestkernel/CMakeLists.txt b/nestkernel/CMakeLists.txt index ab3257a89f..a6720ed6ba 100644 --- a/nestkernel/CMakeLists.txt +++ b/nestkernel/CMakeLists.txt @@ -18,34 +18,35 @@ # along with NEST. If not, see . set ( nestkernel_sources - universal_data_logger_impl.h universal_data_logger.h + universal_data_logger.h recordables_map.h archiving_node.h archiving_node.cpp clopath_archiving_node.h clopath_archiving_node.cpp - urbanczik_archiving_node.h urbanczik_archiving_node_impl.h + urbanczik_archiving_node.h eprop_archiving_node.h eprop_archiving_node_impl.h - eprop_archiving_node_readout.h + eprop_archiving_node_readout.h eprop_archiving_node_readout_impl.h eprop_archiving_node_recurrent.h eprop_archiving_node_recurrent_impl.h common_synapse_properties.h common_synapse_properties.cpp - connection.h - connection_label.h - common_properties_hom_w.h - syn_id_delay.h - connector_base.h connector_base_impl.h - connector_model.h connector_model_impl.h connector_model.cpp + connection.h connection_impl.h + connection_label.h connection_label_impl.h + common_properties_hom_w.h common_properties_hom_w.cpp + syn_id_delay.h syn_id_delay.cpp + connector_base.h connector_base.cpp connector_base_impl.h + connector_model.h connector_model.cpp connector_model_impl.h connection_id.h connection_id.cpp deprecation_warning.h deprecation_warning.cpp device.h device.cpp - device_node.h + device_node.h device_node.cpp module_manager.h module_manager.cpp event.h event.cpp exceptions.h exceptions.cpp - genericmodel.h genericmodel_impl.h + genericmodel.h node_collection.h node_collection.cpp generic_factory.h + generic_factory_impl.h histentry.h histentry.cpp model.h model.cpp - model_manager.h model_manager_impl.h model_manager.cpp + model_manager.h model_manager.cpp model_manager_impl.h nest_datums.h nest_datums.cpp nest_names.cpp nest_names.h nestmodule.h nestmodule.cpp @@ -59,36 +60,39 @@ set ( nestkernel_sources proxynode.h proxynode.cpp random_generators.h recording_device.h recording_device.cpp - pseudo_recording_device.h - ring_buffer.h ring_buffer_impl.h ring_buffer.cpp - secondary_event.h secondary_event_impl.h + pseudo_recording_device.h pseudo_recording_device.cpp + ring_buffer.h ring_buffer.cpp ring_buffer_impl.h + secondary_event.h secondary_event.cpp secondary_event_impl.h slice_ring_buffer.cpp slice_ring_buffer.h spikecounter.h spikecounter.cpp stimulation_device.h stimulation_device.cpp - target_identifier.h + target_identifier.h target_identifier.cpp sparse_node_array.h sparse_node_array.cpp conn_parameter.h conn_parameter.cpp - conn_builder.h conn_builder_impl.h conn_builder.cpp + conn_builder.h conn_builder.cpp conn_builder_factory.h + conn_builder_factory.cpp + conn_builder_factory_impl.h conn_builder_conngen.h conn_builder_conngen.cpp sonata_connector.h sonata_connector.cpp music_event_handler.h music_event_handler.cpp music_rate_in_handler.h music_rate_in_handler.cpp music_manager.cpp music_manager.h - nest.h nest_impl.h nest.cpp + nest.h nest.cpp nest_impl.h synaptic_element.h synaptic_element.cpp growth_curve.h growth_curve.cpp growth_curve_factory.h kernel_manager.h kernel_manager.cpp - vp_manager.h vp_manager_impl.h vp_manager.cpp - io_manager.h io_manager_impl.h io_manager.cpp - mpi_manager.h mpi_manager_impl.h mpi_manager.cpp + vp_manager.h vp_manager.cpp + io_manager.h io_manager.cpp + mpi_manager.h mpi_manager.cpp mpi_manager_impl.h simulation_manager.h simulation_manager.cpp - connection_manager.h connection_manager_impl.h connection_manager.cpp - sp_manager.h sp_manager_impl.h sp_manager.cpp + connection_manager.h connection_manager.cpp connection_manager_impl.h + sp_manager.h sp_manager.cpp delay_checker.h delay_checker.cpp random_manager.h random_manager.cpp - event_delivery_manager.h event_delivery_manager_impl.h + event_delivery_manager.h + event_delivery_manager_impl.h event_delivery_manager.cpp node_manager.h node_manager.cpp logging_manager.h logging_manager.cpp @@ -98,27 +102,32 @@ set ( nestkernel_sources recording_backend_screen.h recording_backend_screen.cpp manager_interface.h target_table.h target_table.cpp - target_table_devices.h target_table_devices.cpp target_table_devices_impl.h - target.h target_data.h static_assert.h + target_table_devices.h target_table_devices.cpp + target.h target.cpp + static_assert.h + target_data.h target_data.cpp send_buffer_position.h send_buffer_position.cpp - source.h + source.h source.cpp source_table.h source_table.cpp - source_table_position.h - spike_data.h + source_table_position.h source_table_position.cpp + spike_data.h spike_data.cpp structural_plasticity_node.h structural_plasticity_node.cpp - connection_creator.h connection_creator.cpp connection_creator_impl.h + connection_creator.h connection_creator.cpp free_layer.h + free_layer_impl.h grid_layer.h + grid_layer_impl.h grid_mask.h + grid_mask_impl.h layer.h layer.cpp layer_impl.h mask.h mask.cpp mask_impl.h - ntree.h ntree_impl.h - position.h + ntree.h ntree.cpp ntree_impl.h + position.h position_impl.h spatial.h spatial.cpp stimulation_backend.h buffer_resize_log.h buffer_resize_log.cpp nest_extension_interface.h - stopwatch.h stopwatch_impl.h + stopwatch.h ) diff --git a/nestkernel/archiving_node.cpp b/nestkernel/archiving_node.cpp index 7ad511eb3c..6b3e16a63d 100644 --- a/nestkernel/archiving_node.cpp +++ b/nestkernel/archiving_node.cpp @@ -23,6 +23,7 @@ #include "archiving_node.h" // Includes from nestkernel: +#include "connection_manager.h" #include "kernel_manager.h" // Includes from sli: @@ -70,8 +71,8 @@ ArchivingNode::register_stdp_connection( double t_first_read, double delay ) // connections afterwards without leaving spikes in the history. // For details see bug #218. MH 08-04-22 - for ( std::deque< histentry >::iterator runner = history_.begin(); - runner != history_.end() and ( t_first_read - runner->t_ > -1.0 * kernel().connection_manager.get_stdp_eps() ); + for ( std::deque< histentry >::iterator runner = history_.begin(); runner != history_.end() + and ( t_first_read - runner->t_ > -1.0 * kernel::manager< ConnectionManager >.get_stdp_eps() ); ++runner ) { ( runner->access_counter_ )++; @@ -97,7 +98,7 @@ nest::ArchivingNode::get_K_value( double t ) int i = history_.size() - 1; while ( i >= 0 ) { - if ( t - history_[ i ].t_ > kernel().connection_manager.get_stdp_eps() ) + if ( t - history_[ i ].t_ > kernel::manager< ConnectionManager >.get_stdp_eps() ) { trace_ = ( history_[ i ].Kminus_ * std::exp( ( history_[ i ].t_ - t ) * tau_minus_inv_ ) ); return trace_; @@ -131,7 +132,7 @@ nest::ArchivingNode::get_K_values( double t, int i = history_.size() - 1; while ( i >= 0 ) { - if ( t - history_[ i ].t_ > kernel().connection_manager.get_stdp_eps() ) + if ( t - history_[ i ].t_ > kernel::manager< ConnectionManager >.get_stdp_eps() ) { K_triplet_value = ( history_[ i ].Kminus_triplet_ * std::exp( ( history_[ i ].t_ - t ) * tau_minus_triplet_inv_ ) ); @@ -162,8 +163,8 @@ nest::ArchivingNode::get_history( double t1, return; } std::deque< histentry >::reverse_iterator runner = history_.rbegin(); - const double t2_lim = t2 + kernel().connection_manager.get_stdp_eps(); - const double t1_lim = t1 + kernel().connection_manager.get_stdp_eps(); + const double t2_lim = t2 + kernel::manager< ConnectionManager >.get_stdp_eps(); + const double t1_lim = t1 + kernel::manager< ConnectionManager >.get_stdp_eps(); while ( runner != history_.rend() and runner->t_ >= t2_lim ) { ++runner; @@ -196,8 +197,9 @@ nest::ArchivingNode::set_spiketime( Time const& t_sp, double offset ) { const double next_t_sp = history_[ 1 ].t_; if ( history_.front().access_counter_ >= n_incoming_ - and t_sp_ms - next_t_sp > max_delay_ + Time::delay_steps_to_ms( kernel().connection_manager.get_min_delay() ) - + kernel().connection_manager.get_stdp_eps() ) + and t_sp_ms - next_t_sp > max_delay_ + + Time::delay_steps_to_ms( kernel::manager< ConnectionManager >.get_min_delay() ) + + kernel::manager< ConnectionManager >.get_stdp_eps() ) { history_.pop_front(); } @@ -273,5 +275,11 @@ nest::ArchivingNode::clear_history() history_.clear(); } +double +ArchivingNode::get_spiketime_ms() const +{ + + return last_spike_; +} } // of namespace nest diff --git a/nestkernel/archiving_node.h b/nestkernel/archiving_node.h index 86b402ed1a..25c8a73294 100644 --- a/nestkernel/archiving_node.h +++ b/nestkernel/archiving_node.h @@ -106,7 +106,7 @@ class ArchivingNode : public StructuralPlasticityNode /** * Return most recent spike time in ms */ - inline double get_spiketime_ms() const; + double get_spiketime_ms() const; /** * Clear spike history @@ -144,11 +144,5 @@ class ArchivingNode : public StructuralPlasticityNode std::deque< histentry > history_; }; -inline double -ArchivingNode::get_spiketime_ms() const -{ - return last_spike_; -} - } // of namespace #endif diff --git a/nestkernel/buffer_resize_log.cpp b/nestkernel/buffer_resize_log.cpp index a37e383c7a..be5ef455dc 100644 --- a/nestkernel/buffer_resize_log.cpp +++ b/nestkernel/buffer_resize_log.cpp @@ -23,8 +23,10 @@ #include "buffer_resize_log.h" // Includes from nestkernel: +#include "dictutils.h" #include "kernel_manager.h" #include "nest_names.h" +#include "simulation_manager.h" namespace nest { @@ -47,7 +49,7 @@ BufferResizeLog::clear() void BufferResizeLog::add_entry( size_t global_max_spikes_sent, size_t new_buffer_size ) { - time_steps_.emplace_back( kernel().simulation_manager.get_clock().get_steps() ); + time_steps_.emplace_back( kernel::manager< SimulationManager >.get_clock().get_steps() ); global_max_spikes_sent_.emplace_back( global_max_spikes_sent ); new_buffer_size_.emplace_back( new_buffer_size ); } diff --git a/nestkernel/clopath_archiving_node.cpp b/nestkernel/clopath_archiving_node.cpp index 42bb957ea2..b555d64105 100644 --- a/nestkernel/clopath_archiving_node.cpp +++ b/nestkernel/clopath_archiving_node.cpp @@ -23,6 +23,7 @@ #include "clopath_archiving_node.h" // Includes from nestkernel: +#include "connection_manager.h" #include "kernel_manager.h" // Includes from sli: @@ -71,7 +72,7 @@ nest::ClopathArchivingNode::init_clopath_buffers() // initialize the ltp-history ltd_hist_current_ = 0; - ltd_hist_len_ = kernel().connection_manager.get_max_delay() + 1; + ltd_hist_len_ = kernel::manager< ConnectionManager >.get_max_delay() + 1; ltd_history_.resize( ltd_hist_len_, histentry_extended( 0.0, 0.0, 0 ) ); } @@ -137,7 +138,7 @@ nest::ClopathArchivingNode::get_LTD_value( double t ) runner = ltd_history_.begin(); while ( runner != ltd_history_.end() ) { - if ( fabs( t - runner->t_ ) < kernel().connection_manager.get_stdp_eps() ) + if ( fabs( t - runner->t_ ) < kernel::manager< ConnectionManager >.get_stdp_eps() ) { return runner->dw_; } @@ -252,4 +253,17 @@ nest::ClopathArchivingNode::write_LTP_history( const double t_ltp_ms, double u, } } +double +ClopathArchivingNode::get_theta_minus() const +{ + + return theta_minus_; +} + +double +ClopathArchivingNode::get_theta_plus() const +{ + + return theta_plus_; +} } // of namespace nest diff --git a/nestkernel/clopath_archiving_node.h b/nestkernel/clopath_archiving_node.h index 64b5b82eca..8d6f687fa1 100644 --- a/nestkernel/clopath_archiving_node.h +++ b/nestkernel/clopath_archiving_node.h @@ -135,17 +135,6 @@ class ClopathArchivingNode : public ArchivingNode size_t ltd_hist_current_; }; -inline double -ClopathArchivingNode::get_theta_plus() const -{ - return theta_plus_; -} - -inline double -ClopathArchivingNode::get_theta_minus() const -{ - return theta_minus_; -} } // of namespace #endif diff --git a/nestkernel/sp_manager_impl.h b/nestkernel/common_properties_hom_w.cpp similarity index 55% rename from nestkernel/sp_manager_impl.h rename to nestkernel/common_properties_hom_w.cpp index 791ac78db2..e7dc1325dd 100644 --- a/nestkernel/sp_manager_impl.h +++ b/nestkernel/common_properties_hom_w.cpp @@ -1,5 +1,5 @@ /* - * sp_manager_impl.h + * common_properties_hom_w.cpp * * This file is part of NEST. * @@ -20,33 +20,36 @@ * */ -#ifndef SP_MANAGER_IMPL_H -#define SP_MANAGER_IMPL_H +#include "common_properties_hom_w.h" -#include "sp_manager.h" -// C++ includes: -#include +namespace nest +{ -// Includes from nestkernel: -#include "growth_curve.h" -#include "growth_curve_factory.h" +CommonPropertiesHomW::CommonPropertiesHomW() + : CommonSynapseProperties() + , weight_( 1.0 ) +{ +} -namespace nest +void +CommonPropertiesHomW::get_status( DictionaryDatum& d ) const { + CommonSynapseProperties::get_status( d ); + def< double >( d, names::weight, weight_ ); +} + +double +CommonPropertiesHomW::get_weight() const +{ + return weight_; +} -template < typename GrowthCurve > void -SPManager::register_growth_curve( const std::string& name ) +CommonPropertiesHomW::set_status( const DictionaryDatum& d, ConnectorModel& cm ) { - assert( not growthcurvedict_->known( name ) ); - GenericGrowthCurveFactory* nc = new GrowthCurveFactory< GrowthCurve >(); - assert( nc ); - const int id = growthcurve_factories_.size(); - growthcurve_factories_.push_back( nc ); - growthcurvedict_->insert( name, id ); + CommonSynapseProperties::set_status( d, cm ); + updateValue< double >( d, names::weight, weight_ ); } } // namespace nest - -#endif /* SP_MANAGER_IMPL_H */ diff --git a/nestkernel/common_properties_hom_w.h b/nestkernel/common_properties_hom_w.h index b5b8d16879..9304746a77 100644 --- a/nestkernel/common_properties_hom_w.h +++ b/nestkernel/common_properties_hom_w.h @@ -25,6 +25,8 @@ // Includes from nestkernel: #include "common_synapse_properties.h" +#include "dictutils.h" +#include "nest_names.h" namespace nest { @@ -35,34 +37,16 @@ namespace nest class CommonPropertiesHomW : public CommonSynapseProperties { public: - CommonPropertiesHomW() - : CommonSynapseProperties() - , weight_( 1.0 ) - { - } + CommonPropertiesHomW(); - void - get_status( DictionaryDatum& d ) const - { - CommonSynapseProperties::get_status( d ); - def< double >( d, names::weight, weight_ ); - } + void get_status( DictionaryDatum& d ) const; - double - get_weight() const - { - return weight_; - } + double get_weight() const; /** * Set properties from the values given in dictionary. */ - void - set_status( const DictionaryDatum& d, ConnectorModel& cm ) - { - CommonSynapseProperties::set_status( d, cm ); - updateValue< double >( d, names::weight, weight_ ); - } + void set_status( const DictionaryDatum& d, ConnectorModel& cm ); private: // data members common to all connections diff --git a/nestkernel/common_synapse_properties.cpp b/nestkernel/common_synapse_properties.cpp index 2a5053c0c3..a2d2ce97f2 100644 --- a/nestkernel/common_synapse_properties.cpp +++ b/nestkernel/common_synapse_properties.cpp @@ -24,9 +24,8 @@ // Includes from nestkernel: #include "connector_model.h" -#include "nest_timeconverter.h" -#include "nest_types.h" #include "node.h" +#include "node_manager.h" // Includes from models: #include "weight_recorder.h" @@ -64,8 +63,8 @@ CommonSynapseProperties::set_status( const DictionaryDatum& d, ConnectorModel& ) throw BadProperty( "Property weight_recorder must be a single element NodeCollection" ); } - const size_t tid = kernel().vp_manager.get_thread_id(); - Node* wr_node = kernel().node_manager.get_node_or_proxy( ( *wr_datum )[ 0 ], tid ); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); + Node* wr_node = kernel::manager< NodeManager >.get_node_or_proxy( ( *wr_datum )[ 0 ], tid ); weight_recorder* wr = dynamic_cast< weight_recorder* >( wr_node ); if ( not wr ) { @@ -81,4 +80,17 @@ CommonSynapseProperties::calibrate( const TimeConverter& ) { } +weight_recorder* +CommonSynapseProperties::get_weight_recorder() const +{ + + return weight_recorder_; +} + +long +CommonSynapseProperties::get_vt_node_id() const +{ + + return -1; +} } // namespace nest diff --git a/nestkernel/common_synapse_properties.h b/nestkernel/common_synapse_properties.h index fab02945c6..343e8986b4 100644 --- a/nestkernel/common_synapse_properties.h +++ b/nestkernel/common_synapse_properties.h @@ -23,12 +23,6 @@ #ifndef COMMON_SYNAPSE_PROPERTIES_H #define COMMON_SYNAPSE_PROPERTIES_H -// Includes from nestkernel: -#include "connector_model.h" -#include "nest_datums.h" -#include "nest_types.h" -#include "node.h" - // Includes from sli: #include "dictdatum.h" @@ -38,8 +32,8 @@ namespace nest // forward declarations class weight_recorder; -class ConnectorModel; class TimeConverter; +class ConnectorModel; /** * Class containing the common properties for all connections of a certain type. @@ -92,18 +86,6 @@ class CommonSynapseProperties weight_recorder* weight_recorder_; }; -inline long -CommonSynapseProperties::get_vt_node_id() const -{ - return -1; -} - -inline weight_recorder* -CommonSynapseProperties::get_weight_recorder() const -{ - return weight_recorder_; -} - } // of namespace nest diff --git a/nestkernel/conn_builder.cpp b/nestkernel/conn_builder.cpp index f70f00f0b4..8fddf80f32 100644 --- a/nestkernel/conn_builder.cpp +++ b/nestkernel/conn_builder.cpp @@ -26,14 +26,21 @@ #include "logging.h" // Includes from nestkernel: -#include "conn_builder_impl.h" #include "conn_parameter.h" #include "connection_manager.h" +#include "connector_model_impl.h" #include "exceptions.h" +#include "genericmodel_impl.h" #include "kernel_manager.h" +#include "logging_manager.h" +#include "model_manager.h" +#include "mpi_manager_impl.h" +#include "nest.h" #include "nest_names.h" #include "node.h" -#include "vp_manager_impl.h" +#include "node_manager.h" +#include "random_manager.h" +#include "sp_manager.h" // Includes from sli: #include "dict.h" @@ -51,7 +58,7 @@ nest::ConnBuilder::ConnBuilder( const std::string& primary_rule, const std::vector< DictionaryDatum >& syn_specs ) : third_in_builder_( nullptr ) , third_out_builder_( nullptr ) - , primary_builder_( kernel().connection_manager.get_conn_builder( primary_rule, + , primary_builder_( kernel::manager< ConnectionManager >.get_conn_builder( primary_rule, sources, targets, third_out_builder_, @@ -72,14 +79,14 @@ nest::ConnBuilder::ConnBuilder( const std::string& primary_rule, third, third_conn_spec, const_cast< std::map< Name, std::vector< DictionaryDatum > >& >( syn_specs )[ names::third_in ] ) ) - , third_out_builder_( kernel().connection_manager.get_third_conn_builder( third_rule, + , third_out_builder_( kernel::manager< ConnectionManager >.get_third_conn_builder( third_rule, third, targets, third_in_builder_, third_conn_spec, // const_cast here seems required, clang complains otherwise; try to clean up when Datums disappear const_cast< std::map< Name, std::vector< DictionaryDatum > >& >( syn_specs )[ names::third_out ] ) ) - , primary_builder_( kernel().connection_manager.get_conn_builder( primary_rule, + , primary_builder_( kernel::manager< ConnectionManager >.get_conn_builder( primary_rule, sources, targets, third_out_builder_, @@ -128,7 +135,7 @@ nest::BipartiteConnBuilder::BipartiteConnBuilder( NodeCollectionPTR sources, , allow_multapses_( true ) , make_symmetric_( false ) , creates_symmetric_connections_( false ) - , exceptions_raised_( kernel().vp_manager.get_num_threads() ) + , exceptions_raised_( kernel::manager< VPManager >.get_num_threads() ) , use_structural_plasticity_( false ) , parameters_requiring_skipping_() , param_dicts_() @@ -157,7 +164,7 @@ nest::BipartiteConnBuilder::BipartiteConnBuilder( NodeCollectionPTR sources, delays_.resize( syn_specs.size() ); synapse_params_.resize( syn_specs.size() ); synapse_model_id_.resize( syn_specs.size() ); - synapse_model_id_[ 0 ] = kernel().model_manager.get_synapse_model_id( "static_synapse" ); + synapse_model_id_[ 0 ] = kernel::manager< ModelManager >.get_synapse_model_id( "static_synapse" ); param_dicts_.resize( syn_specs.size() ); // loop through vector of synapse dictionaries, and set synapse parameters @@ -168,7 +175,8 @@ nest::BipartiteConnBuilder::BipartiteConnBuilder( NodeCollectionPTR sources, set_synapse_model_( syn_params, synapse_indx ); set_default_weight_or_delay_( syn_params, synapse_indx ); - DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( synapse_model_id_[ synapse_indx ] ); + DictionaryDatum syn_defaults = + kernel::manager< ModelManager >.get_connector_defaults( synapse_model_id_[ synapse_indx ] ); #ifdef HAVE_MUSIC // We allow music_channel as alias for receptor_type during connection setup @@ -232,9 +240,9 @@ nest::BipartiteConnBuilder::change_connected_synaptic_elements( size_t snode_id, int local = true; // check whether the source is on this mpi machine - if ( kernel().node_manager.is_local_node_id( snode_id ) ) + if ( kernel::manager< NodeManager >.is_local_node_id( snode_id ) ) { - Node* const source = kernel().node_manager.get_node_or_proxy( snode_id, tid ); + Node* const source = kernel::manager< NodeManager >.get_node_or_proxy( snode_id, tid ); const size_t source_thread = source->get_thread(); // check whether the source is on our thread @@ -246,13 +254,13 @@ nest::BipartiteConnBuilder::change_connected_synaptic_elements( size_t snode_id, } // check whether the target is on this mpi machine - if ( not kernel().node_manager.is_local_node_id( tnode_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( tnode_id ) ) { local = false; } else { - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); // check whether the target is on our thread if ( tid != target_thread ) @@ -269,6 +277,39 @@ nest::BipartiteConnBuilder::change_connected_synaptic_elements( size_t snode_id, return local; } +//! Return true if rule allows creation of symmetric connectivity +bool +nest::BipartiteConnBuilder::supports_symmetric() const +{ + return false; +} + +//! Return true if rule automatically creates symmetric connectivity +bool +nest::BipartiteConnBuilder::is_symmetric() const +{ + return false; +} + +bool +nest::BipartiteConnBuilder::allows_autapses() const +{ + return allow_autapses_; +} + +bool +nest::BipartiteConnBuilder::allows_multapses() const +{ + return allow_multapses_; +} + +//! Return true if rule is applicable only to nodes with proxies +bool +nest::BipartiteConnBuilder::requires_proxies() const +{ + return true; +} + void nest::BipartiteConnBuilder::connect() { @@ -277,7 +318,7 @@ nest::BipartiteConnBuilder::connect() for ( auto synapse_model_id : synapse_model_id_ ) { const ConnectorModel& synapse_model = - kernel().model_manager.get_connection_model( synapse_model_id, /* thread */ 0 ); + kernel::manager< ModelManager >.get_connection_model( synapse_model_id, /* thread */ 0 ); const bool requires_symmetric = synapse_model.has_property( ConnectionModelProperties::REQUIRES_SYMMETRIC ); if ( requires_symmetric and not( is_symmetric() or make_symmetric_ ) ) @@ -326,7 +367,7 @@ nest::BipartiteConnBuilder::connect() } } // check if any exceptions have been raised - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { if ( exceptions_raised_.at( tid ).get() ) { @@ -348,7 +389,7 @@ nest::BipartiteConnBuilder::disconnect() } // check if any exceptions have been raised - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { if ( exceptions_raised_.at( tid ).get() ) { @@ -364,7 +405,8 @@ nest::BipartiteConnBuilder::update_param_dict_( size_t snode_id, RngPtr rng, size_t synapse_indx ) { - assert( kernel().vp_manager.get_num_threads() == static_cast< size_t >( param_dicts_[ synapse_indx ].size() ) ); + assert( + kernel::manager< VPManager >.get_num_threads() == static_cast< size_t >( param_dicts_[ synapse_indx ].size() ) ); for ( auto synapse_parameter : synapse_params_[ synapse_indx ] ) { @@ -399,7 +441,7 @@ nest::BipartiteConnBuilder::single_connect_( size_t snode_id, Node& target, size if ( default_weight_and_delay_[ synapse_indx ] ) { - kernel().connection_manager.connect( snode_id, + kernel::manager< ConnectionManager >.connect( snode_id, &target, target_thread, synapse_model_id_[ synapse_indx ], @@ -407,7 +449,7 @@ nest::BipartiteConnBuilder::single_connect_( size_t snode_id, Node& target, size } else if ( default_weight_[ synapse_indx ] ) { - kernel().connection_manager.connect( snode_id, + kernel::manager< ConnectionManager >.connect( snode_id, &target, target_thread, synapse_model_id_[ synapse_indx ], @@ -416,7 +458,7 @@ nest::BipartiteConnBuilder::single_connect_( size_t snode_id, Node& target, size } else if ( default_delay_[ synapse_indx ] ) { - kernel().connection_manager.connect( snode_id, + kernel::manager< ConnectionManager >.connect( snode_id, &target, target_thread, synapse_model_id_[ synapse_indx ], @@ -428,7 +470,7 @@ nest::BipartiteConnBuilder::single_connect_( size_t snode_id, Node& target, size { const double delay = delays_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target ); const double weight = weights_[ synapse_indx ]->value_double( target_thread, rng, snode_id, &target ); - kernel().connection_manager.connect( snode_id, + kernel::manager< ConnectionManager >.connect( snode_id, &target, target_thread, synapse_model_id_[ synapse_indx ], @@ -491,10 +533,28 @@ nest::BipartiteConnBuilder::all_parameters_scalar_() const return all_scalar; } +void +nest::BipartiteConnBuilder::sp_connect_() +{ + throw NotImplemented( "This connection rule is not implemented for structural plasticity." ); +} + +void +nest::BipartiteConnBuilder::disconnect_() +{ + throw NotImplemented( "This disconnection rule is not implemented." ); +} + +void +nest::BipartiteConnBuilder::sp_disconnect_() +{ + throw NotImplemented( "This connection rule is not implemented for structural plasticity." ); +} + bool nest::BipartiteConnBuilder::loop_over_targets_() const { - return targets_->size() < kernel().node_manager.size() or not targets_->is_range() + return targets_->size() < kernel::manager< NodeManager >.size() or not targets_->is_range() or parameters_requiring_skipping_.size() > 0; } @@ -508,18 +568,20 @@ nest::BipartiteConnBuilder::set_synapse_model_( DictionaryDatum syn_params, size const std::string syn_name = ( *syn_params )[ names::synapse_model ]; // The following call will throw "UnknownSynapseType" if syn_name is not naming a known model - const size_t synapse_model_id = kernel().model_manager.get_synapse_model_id( syn_name ); + const size_t synapse_model_id = kernel::manager< ModelManager >.get_synapse_model_id( syn_name ); synapse_model_id_[ synapse_indx ] = synapse_model_id; // We need to make sure that Connect can process all synapse parameters specified. - const ConnectorModel& synapse_model = kernel().model_manager.get_connection_model( synapse_model_id, /* thread */ 0 ); + const ConnectorModel& synapse_model = + kernel::manager< ModelManager >.get_connection_model( synapse_model_id, /* thread */ 0 ); synapse_model.check_synapse_params( syn_params ); } void nest::BipartiteConnBuilder::set_default_weight_or_delay_( DictionaryDatum syn_params, size_t synapse_indx ) { - DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( synapse_model_id_[ synapse_indx ] ); + DictionaryDatum syn_defaults = + kernel::manager< ModelManager >.get_connector_defaults( synapse_model_id_[ synapse_indx ] ); // All synapse models have the possibility to set the delay (see SynIdDelay), but some have // homogeneous weights, hence it should be possible to set the delay without the weight. @@ -535,19 +597,19 @@ nest::BipartiteConnBuilder::set_default_weight_or_delay_( DictionaryDatum syn_pa if ( not default_weight_and_delay_[ synapse_indx ] ) { weights_[ synapse_indx ] = syn_params->known( names::weight ) - ? ConnParameter::create( ( *syn_params )[ names::weight ], kernel().vp_manager.get_num_threads() ) - : ConnParameter::create( ( *syn_defaults )[ names::weight ], kernel().vp_manager.get_num_threads() ); + ? ConnParameter::create( ( *syn_params )[ names::weight ], kernel::manager< VPManager >.get_num_threads() ) + : ConnParameter::create( ( *syn_defaults )[ names::weight ], kernel::manager< VPManager >.get_num_threads() ); register_parameters_requiring_skipping_( *weights_[ synapse_indx ] ); delays_[ synapse_indx ] = syn_params->known( names::delay ) - ? ConnParameter::create( ( *syn_params )[ names::delay ], kernel().vp_manager.get_num_threads() ) - : ConnParameter::create( ( *syn_defaults )[ names::delay ], kernel().vp_manager.get_num_threads() ); + ? ConnParameter::create( ( *syn_params )[ names::delay ], kernel::manager< VPManager >.get_num_threads() ) + : ConnParameter::create( ( *syn_defaults )[ names::delay ], kernel::manager< VPManager >.get_num_threads() ); } else if ( default_weight_[ synapse_indx ] ) { delays_[ synapse_indx ] = syn_params->known( names::delay ) - ? ConnParameter::create( ( *syn_params )[ names::delay ], kernel().vp_manager.get_num_threads() ) - : ConnParameter::create( ( *syn_defaults )[ names::delay ], kernel().vp_manager.get_num_threads() ); + ? ConnParameter::create( ( *syn_params )[ names::delay ], kernel::manager< VPManager >.get_num_threads() ) + : ConnParameter::create( ( *syn_defaults )[ names::delay ], kernel::manager< VPManager >.get_num_threads() ); } register_parameters_requiring_skipping_( *delays_[ synapse_indx ] ); } @@ -568,14 +630,14 @@ nest::BipartiteConnBuilder::set_synapse_params( DictionaryDatum syn_defaults, if ( syn_params->known( param_name ) ) { synapse_params_[ synapse_indx ][ param_name ] = - ConnParameter::create( ( *syn_params )[ param_name ], kernel().vp_manager.get_num_threads() ); + ConnParameter::create( ( *syn_params )[ param_name ], kernel::manager< VPManager >.get_num_threads() ); register_parameters_requiring_skipping_( *synapse_params_[ synapse_indx ][ param_name ] ); } } // Now create dictionary with dummy values that we will use to pass settings to the synapses created. We // create it here once to avoid re-creating the object over and over again. - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { param_dicts_[ synapse_indx ].push_back( new Dictionary() ); @@ -650,19 +712,70 @@ nest::BipartiteConnBuilder::reset_delays_() } } +size_t +nest::BipartiteConnBuilder::get_synapse_model() const +{ + if ( synapse_model_id_.size() > 1 ) + { + throw KernelException( "Can only retrieve synapse model when one synapse per connection is used." ); + } + return synapse_model_id_[ 0 ]; +} + + +bool +nest::BipartiteConnBuilder::get_default_delay() const +{ + if ( synapse_model_id_.size() > 1 ) + { + throw KernelException( "Can only retrieve default delay when one synapse per connection is used." ); + } + return default_delay_[ 0 ]; +} + +void +nest::BipartiteConnBuilder::register_parameters_requiring_skipping_( ConnParameter& param ) +{ + if ( param.is_array() ) + { + parameters_requiring_skipping_.push_back( ¶m ); + } +} + +void +nest::BipartiteConnBuilder::skip_conn_parameter_( size_t target_thread, size_t n_skip ) +{ + for ( std::vector< ConnParameter* >::iterator it = parameters_requiring_skipping_.begin(); + it != parameters_requiring_skipping_.end(); + ++it ) + { + ( *it )->skip( target_thread, n_skip ); + } +} + +void +nest::BipartiteConnBuilder::single_disconnect_( size_t snode_id, Node& target, size_t target_thread ) +{ + if ( synapse_model_id_.size() > 1 ) + { + throw KernelException( "Can only disconnect when single element syn_spec has been used." ); + } + kernel::manager< SPManager >.disconnect( snode_id, &target, target_thread, synapse_model_id_[ 0 ] ); +} + nest::ThirdInBuilder::ThirdInBuilder( NodeCollectionPTR sources, NodeCollectionPTR third, const DictionaryDatum& third_conn_spec, const std::vector< DictionaryDatum >& syn_specs ) : BipartiteConnBuilder( sources, third, nullptr, third_conn_spec, syn_specs ) - , source_third_gids_( kernel().vp_manager.get_num_threads(), nullptr ) - , source_third_counts_( kernel().vp_manager.get_num_threads(), nullptr ) + , source_third_gids_( kernel::manager< VPManager >.get_num_threads(), nullptr ) + , source_third_counts_( kernel::manager< VPManager >.get_num_threads(), nullptr ) { #pragma omp parallel { - const size_t thrd = kernel().vp_manager.get_thread_id(); + const size_t thrd = kernel::manager< VPManager >.get_thread_id(); source_third_gids_[ thrd ] = new BlockVector< SourceThirdInfo_ >(); - source_third_counts_[ thrd ] = new std::vector< size_t >( kernel().mpi_manager.get_num_processes(), 0 ); + source_third_counts_[ thrd ] = new std::vector< size_t >( kernel::manager< MPIManager >.get_num_processes(), 0 ); } } @@ -670,7 +783,7 @@ nest::ThirdInBuilder::~ThirdInBuilder() { #pragma omp parallel { - const size_t thrd = kernel().vp_manager.get_thread_id(); + const size_t thrd = kernel::manager< VPManager >.get_thread_id(); delete source_third_gids_[ thrd ]; delete source_third_counts_[ thrd ]; } @@ -679,9 +792,9 @@ nest::ThirdInBuilder::~ThirdInBuilder() void nest::ThirdInBuilder::register_connection( size_t primary_source_id, size_t third_node_id ) { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); const auto third_node_rank = - kernel().mpi_manager.get_process_id_of_vp( kernel().vp_manager.node_id_to_vp( third_node_id ) ); + kernel::manager< MPIManager >.get_process_id_of_vp( kernel::manager< VPManager >.node_id_to_vp( third_node_id ) ); source_third_gids_[ tid ]->push_back( { primary_source_id, third_node_id, third_node_rank } ); ++( ( *source_third_counts_[ tid ] )[ third_node_rank ] ); } @@ -689,10 +802,10 @@ nest::ThirdInBuilder::register_connection( size_t primary_source_id, size_t thir void nest::ThirdInBuilder::connect_() { - kernel().vp_manager.assert_single_threaded(); + kernel::manager< VPManager >.assert_single_threaded(); // count up how many source-third pairs we need to send to each rank - const size_t num_ranks = kernel().mpi_manager.get_num_processes(); + const size_t num_ranks = kernel::manager< MPIManager >.get_num_processes(); std::vector< size_t > source_third_per_rank( num_ranks, 0 ); for ( auto stcp : source_third_counts_ ) { @@ -705,9 +818,9 @@ nest::ThirdInBuilder::connect_() // now find global maximum; for simplicity, we will use this to configure buffers std::vector< long > max_stc( num_ranks ); // MPIManager does not support size_t - max_stc[ kernel().mpi_manager.get_rank() ] = + max_stc[ kernel::manager< MPIManager >.get_rank() ] = *std::max_element( source_third_per_rank.begin(), source_third_per_rank.end() ); - kernel().mpi_manager.communicate( max_stc ); + kernel::manager< MPIManager >.communicate( max_stc ); const size_t global_max_stc = *std::max_element( max_stc.begin(), max_stc.end() ); if ( global_max_stc == 0 ) @@ -746,7 +859,7 @@ nest::ThirdInBuilder::connect_() // force to master thread for compatibility with MPI standard #pragma omp master { - kernel().mpi_manager.communicate_Alltoall( send_stg, recv_stg, send_recv_count ); + kernel::manager< MPIManager >.communicate_Alltoall( send_stg, recv_stg, send_recv_count ); } // Now recv_stg contains all source-third pairs where third is on current rank @@ -754,8 +867,8 @@ nest::ThirdInBuilder::connect_() #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); - RngPtr rng = kernel().random_manager.get_vp_specific_rng( tid ); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); + RngPtr rng = kernel::manager< RandomManager >.get_vp_specific_rng( tid ); for ( size_t idx = 0; idx < recv_stg.size(); idx += 2 ) { @@ -769,11 +882,11 @@ nest::ThirdInBuilder::connect_() continue; } - if ( kernel().vp_manager.is_node_id_vp_local( third_gid ) ) + if ( kernel::manager< VPManager >.is_node_id_vp_local( third_gid ) ) { const auto source_gid = recv_stg[ idx + 1 ]; assert( source_gid > 0 ); - single_connect_( source_gid, *kernel().node_manager.get_node_or_proxy( third_gid, tid ), tid, rng ); + single_connect_( source_gid, *kernel::manager< NodeManager >.get_node_or_proxy( third_gid, tid ), tid, rng ); } } } @@ -789,6 +902,13 @@ nest::ThirdOutBuilder::ThirdOutBuilder( const NodeCollectionPTR third, { } +//! Only call third_connect() on ThirdOutBuilder +void +nest::ThirdOutBuilder::connect() +{ + assert( false ); +} + nest::ThirdBernoulliWithPoolBuilder::ThirdBernoulliWithPoolBuilder( const NodeCollectionPTR third, const NodeCollectionPTR targets, ThirdInBuilder* third_in, @@ -799,7 +919,7 @@ nest::ThirdBernoulliWithPoolBuilder::ThirdBernoulliWithPoolBuilder( const NodeCo , random_pool_( true ) , pool_size_( third->size() ) , targets_per_third_( targets->size() / third->size() ) - , pools_( kernel().vp_manager.get_num_threads(), nullptr ) + , pools_( kernel::manager< VPManager >.get_num_threads(), nullptr ) { updateValue< double >( conn_spec, names::p, p_ ); updateValue< long >( conn_spec, names::pool_size, pool_size_ ); @@ -842,7 +962,7 @@ nest::ThirdBernoulliWithPoolBuilder::ThirdBernoulliWithPoolBuilder( const NodeCo #pragma omp parallel { - const size_t thrd = kernel().vp_manager.get_thread_id(); + const size_t thrd = kernel::manager< VPManager >.get_thread_id(); pools_[ thrd ] = new TgtPoolMap_(); } @@ -857,7 +977,7 @@ nest::ThirdBernoulliWithPoolBuilder::ThirdBernoulliWithPoolBuilder( const NodeCo size_t idx = 0; for ( auto tgt_it = targets_->begin(); tgt_it != targets_->end(); ++tgt_it ) { - Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id ); + Node* const tgt = kernel::manager< NodeManager >.get_node_or_proxy( ( *tgt_it ).node_id ); if ( not tgt->is_proxy() ) { tgt->set_tmp_nc_index( idx++ ); // must be postfix @@ -870,7 +990,7 @@ nest::ThirdBernoulliWithPoolBuilder::~ThirdBernoulliWithPoolBuilder() { #pragma omp parallel { - const size_t thrd = kernel().vp_manager.get_thread_id(); + const size_t thrd = kernel::manager< VPManager >.get_thread_id(); delete pools_[ thrd ]; if ( not random_pool_ ) @@ -881,7 +1001,7 @@ nest::ThirdBernoulliWithPoolBuilder::~ThirdBernoulliWithPoolBuilder() // Here we can work in parallel since we just reset to invalid_index for ( auto tgt_it = targets_->thread_local_begin(); tgt_it != targets_->end(); ++tgt_it ) { - Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id, thrd ); + Node* const tgt = kernel::manager< NodeManager >.get_node_or_proxy( ( *tgt_it ).node_id, thrd ); assert( not tgt->is_proxy() ); tgt->set_tmp_nc_index( invalid_index ); } @@ -889,11 +1009,17 @@ nest::ThirdBernoulliWithPoolBuilder::~ThirdBernoulliWithPoolBuilder() } } +void +nest::ThirdBernoulliWithPoolBuilder::connect_() +{ + assert( false ); +} //!< only call third_connect() + void nest::ThirdBernoulliWithPoolBuilder::third_connect( size_t primary_source_id, Node& primary_target ) { // We assume target is on this thread - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); RngPtr rng = get_vp_specific_rng( tid ); // conditionally connect third factor @@ -959,6 +1085,19 @@ nest::OneToOneBuilder::OneToOneBuilder( const NodeCollectionPTR sources, } } +bool +nest::OneToOneBuilder::supports_symmetric() const +{ + return true; +} + +bool +nest::OneToOneBuilder::requires_proxies() const +{ + return false; +} + + void nest::OneToOneBuilder::connect_() { @@ -966,7 +1105,7 @@ nest::OneToOneBuilder::connect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -991,7 +1130,7 @@ nest::OneToOneBuilder::connect_() continue; } - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); if ( target->is_proxy() ) { // skip array parameters handled in other virtual processes @@ -1004,7 +1143,7 @@ nest::OneToOneBuilder::connect_() } else { - const SparseNodeArray& local_nodes = kernel().node_manager.get_local_nodes( tid ); + const SparseNodeArray& local_nodes = kernel::manager< NodeManager >.get_local_nodes( tid ); SparseNodeArray::const_iterator n; for ( n = local_nodes.begin(); n != local_nodes.end(); ++n ) { @@ -1045,7 +1184,7 @@ nest::OneToOneBuilder::disconnect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -1059,13 +1198,13 @@ nest::OneToOneBuilder::disconnect_() const size_t snode_id = ( *source_it ).node_id; // check whether the target is on this mpi machine - if ( not kernel().node_manager.is_local_node_id( tnode_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( tnode_id ) ) { // Disconnecting: no parameter skipping required continue; } - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); // check whether the target is a proxy @@ -1093,7 +1232,7 @@ nest::OneToOneBuilder::sp_connect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -1118,7 +1257,7 @@ nest::OneToOneBuilder::sp_connect_() skip_conn_parameter_( tid ); continue; } - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); single_connect_( snode_id, *target, target_thread, rng ); @@ -1140,7 +1279,7 @@ nest::OneToOneBuilder::sp_disconnect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -1158,7 +1297,7 @@ nest::OneToOneBuilder::sp_disconnect_() continue; } - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); single_disconnect_( snode_id, *target, target_thread ); @@ -1173,6 +1312,19 @@ nest::OneToOneBuilder::sp_disconnect_() } } +bool +nest::AllToAllBuilder::is_symmetric() const +{ + return nest::AllToAllBuilder::sources_ == nest::AllToAllBuilder::targets_ + and nest::AllToAllBuilder::all_parameters_scalar_(); +} + +bool +nest::AllToAllBuilder::requires_proxies() const +{ + return false; +} + void nest::AllToAllBuilder::connect_() { @@ -1180,7 +1332,7 @@ nest::AllToAllBuilder::connect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -1192,7 +1344,7 @@ nest::AllToAllBuilder::connect_() for ( ; target_it < targets_->end(); ++target_it ) { const size_t tnode_id = ( *target_it ).node_id; - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); if ( target->is_proxy() ) { skip_conn_parameter_( tid, sources_->size() ); @@ -1204,7 +1356,7 @@ nest::AllToAllBuilder::connect_() } else { - const SparseNodeArray& local_nodes = kernel().node_manager.get_local_nodes( tid ); + const SparseNodeArray& local_nodes = kernel::manager< NodeManager >.get_local_nodes( tid ); SparseNodeArray::const_iterator n; for ( n = local_nodes.begin(); n != local_nodes.end(); ++n ) { @@ -1268,7 +1420,7 @@ nest::AllToAllBuilder::sp_connect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { RngPtr rng = get_vp_specific_rng( tid ); @@ -1293,7 +1445,7 @@ nest::AllToAllBuilder::sp_connect_() skip_conn_parameter_( tid, sources_->size() ); continue; } - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); single_connect_( snode_id, *target, target_thread, rng ); } @@ -1315,7 +1467,7 @@ nest::AllToAllBuilder::disconnect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -1325,13 +1477,13 @@ nest::AllToAllBuilder::disconnect_() const size_t tnode_id = ( *target_it ).node_id; // check whether the target is on this mpi machine - if ( not kernel().node_manager.is_local_node_id( tnode_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( tnode_id ) ) { // Disconnecting: no parameter skipping required continue; } - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); // check whether the target is a proxy @@ -1364,7 +1516,7 @@ nest::AllToAllBuilder::sp_disconnect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -1383,7 +1535,7 @@ nest::AllToAllBuilder::sp_disconnect_() // Disconnecting: no parameter skipping required continue; } - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); single_disconnect_( snode_id, *target, target_thread ); } @@ -1461,7 +1613,7 @@ nest::FixedInDegreeBuilder::connect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -1473,7 +1625,7 @@ nest::FixedInDegreeBuilder::connect_() for ( ; target_it < targets_->end(); ++target_it ) { const size_t tnode_id = ( *target_it ).node_id; - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const long indegree_value = std::round( indegree_->value( rng, target ) ); if ( target->is_proxy() ) @@ -1488,7 +1640,7 @@ nest::FixedInDegreeBuilder::connect_() } else { - const SparseNodeArray& local_nodes = kernel().node_manager.get_local_nodes( tid ); + const SparseNodeArray& local_nodes = kernel::manager< NodeManager >.get_local_nodes( tid ); SparseNodeArray::const_iterator n; for ( n = local_nodes.begin(); n != local_nodes.end(); ++n ) { @@ -1636,7 +1788,7 @@ nest::FixedOutDegreeBuilder::connect_() std::vector< size_t > tgt_ids_; const long n_rnd = targets_->size(); - Node* source_node = kernel().node_manager.get_node_or_proxy( snode_id ); + Node* source_node = kernel::manager< NodeManager >.get_node_or_proxy( snode_id ); const long outdegree_value = std::round( outdegree_->value( grng, source_node ) ); for ( long j = 0; j < outdegree_value; ++j ) { @@ -1664,7 +1816,7 @@ nest::FixedOutDegreeBuilder::connect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -1673,7 +1825,7 @@ nest::FixedOutDegreeBuilder::connect_() std::vector< size_t >::const_iterator tnode_id_it = tgt_ids_.begin(); for ( ; tnode_id_it != tgt_ids_.end(); ++tnode_id_it ) { - Node* const target = kernel().node_manager.get_node_or_proxy( *tnode_id_it, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( *tnode_id_it, tid ); if ( target->is_proxy() ) { // skip array parameters handled in other virtual processes @@ -1733,7 +1885,7 @@ nest::FixedTotalNumberBuilder::FixedTotalNumberBuilder( NodeCollectionPTR source void nest::FixedTotalNumberBuilder::connect_() { - const int M = kernel().vp_manager.get_num_virtual_processes(); + const int M = kernel::manager< VPManager >.get_num_virtual_processes(); const long size_sources = sources_->size(); const long size_targets = targets_->size(); @@ -1743,12 +1895,12 @@ nest::FixedTotalNumberBuilder::connect_() // function std::vector< size_t > number_of_targets_on_vp( M, 0 ); std::vector< size_t > local_targets; - local_targets.reserve( size_targets / kernel().mpi_manager.get_num_processes() ); + local_targets.reserve( size_targets / kernel::manager< MPIManager >.get_num_processes() ); for ( size_t t = 0; t < targets_->size(); t++ ) { - int vp = kernel().vp_manager.node_id_to_vp( ( *targets_ )[ t ] ); + int vp = kernel::manager< VPManager >.node_id_to_vp( ( *targets_ )[ t ] ); ++number_of_targets_on_vp[ vp ]; - if ( kernel().vp_manager.is_local_vp( vp ) ) + if ( kernel::manager< VPManager >.is_local_vp( vp ) ) { local_targets.push_back( ( *targets_ )[ t ] ); } @@ -1804,13 +1956,13 @@ nest::FixedTotalNumberBuilder::connect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { - const size_t vp_id = kernel().vp_manager.thread_to_vp( tid ); + const size_t vp_id = kernel::manager< VPManager >.thread_to_vp( tid ); - if ( kernel().vp_manager.is_local_vp( vp_id ) ) + if ( kernel::manager< VPManager >.is_local_vp( vp_id ) ) { RngPtr rng = get_vp_specific_rng( tid ); @@ -1821,7 +1973,7 @@ nest::FixedTotalNumberBuilder::connect_() std::vector< size_t >::const_iterator tnode_id_it = local_targets.begin(); for ( ; tnode_id_it != local_targets.end(); ++tnode_id_it ) { - if ( kernel().vp_manager.node_id_to_vp( *tnode_id_it ) == vp_id ) + if ( kernel::manager< VPManager >.node_id_to_vp( *tnode_id_it ) == vp_id ) { thread_local_targets.push_back( *tnode_id_it ); } @@ -1844,7 +1996,7 @@ nest::FixedTotalNumberBuilder::connect_() // targets_on_vp vector const long tnode_id = thread_local_targets[ t_index ]; - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); if ( allow_autapses_ or snode_id != tnode_id ) @@ -1897,7 +2049,7 @@ nest::BernoulliBuilder::connect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -1909,7 +2061,7 @@ nest::BernoulliBuilder::connect_() for ( ; target_it < targets_->end(); ++target_it ) { const size_t tnode_id = ( *target_it ).node_id; - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); if ( target->is_proxy() ) { // skip array parameters handled in other virtual processes @@ -1923,7 +2075,7 @@ nest::BernoulliBuilder::connect_() else { - const SparseNodeArray& local_nodes = kernel().node_manager.get_local_nodes( tid ); + const SparseNodeArray& local_nodes = kernel::manager< NodeManager >.get_local_nodes( tid ); SparseNodeArray::const_iterator n; for ( n = local_nodes.begin(); n != local_nodes.end(); ++n ) { @@ -2015,7 +2167,7 @@ nest::PoissonBuilder::connect_() #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -2027,7 +2179,7 @@ nest::PoissonBuilder::connect_() for ( ; target_it < targets_->end(); ++target_it ) { const size_t tnode_id = ( *target_it ).node_id; - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); if ( target->is_proxy() ) { // skip parameters handled in other virtual processes @@ -2040,7 +2192,7 @@ nest::PoissonBuilder::connect_() } else { - const SparseNodeArray& local_nodes = kernel().node_manager.get_local_nodes( tid ); + const SparseNodeArray& local_nodes = kernel::manager< NodeManager >.get_local_nodes( tid ); SparseNodeArray::const_iterator n; for ( n = local_nodes.begin(); n != local_nodes.end(); ++n ) { @@ -2137,7 +2289,7 @@ nest::SymmetricBernoulliBuilder::connect_() { #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); // Use RNG generating same number sequence on all threads RngPtr synced_rng = get_vp_synced_rng( tid ); @@ -2165,7 +2317,7 @@ nest::SymmetricBernoulliBuilder::connect_() } assert( indegree < sources_->size() ); - target = kernel().node_manager.get_node_or_proxy( ( *tnode_id ).node_id, tid ); + target = kernel::manager< NodeManager >.get_node_or_proxy( ( *tnode_id ).node_id, tid ); target_thread = tid; // check whether the target is on this thread @@ -2191,7 +2343,7 @@ nest::SymmetricBernoulliBuilder::connect_() } previous_snode_ids.insert( snode_id ); - source = kernel().node_manager.get_node_or_proxy( snode_id, tid ); + source = kernel::manager< NodeManager >.get_node_or_proxy( snode_id, tid ); source_thread = tid; if ( source->is_proxy() ) @@ -2241,12 +2393,37 @@ nest::SPBuilder::SPBuilder( NodeCollectionPTR sources, } } +const std::string& +nest::SPBuilder::get_pre_synaptic_element_name() const +{ + return nest::SPBuilder::pre_synaptic_element_name_; +} + +const std::string& +nest::SPBuilder::get_post_synaptic_element_name() const +{ + return nest::SPBuilder::post_synaptic_element_name_; +} + +void +nest::SPBuilder::set_name( const std::string& name ) +{ + nest::SPBuilder::name_ = name; +} + +std::string +nest::SPBuilder::get_name() const +{ + return nest::SPBuilder::name_; +} + + void nest::SPBuilder::update_delay( long& d ) const { if ( get_default_delay() ) { - DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( get_synapse_model() ); + DictionaryDatum syn_defaults = kernel::manager< ModelManager >.get_connector_defaults( get_synapse_model() ); const double delay = getValue< double >( syn_defaults, "delay" ); d = Time( Time::ms( delay ) ).get_steps(); } @@ -2258,7 +2435,7 @@ nest::SPBuilder::sp_connect( const std::vector< size_t >& sources, const std::ve connect_( sources, targets ); // check if any exceptions have been raised - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { if ( exceptions_raised_.at( tid ).get() ) { @@ -2295,7 +2472,7 @@ nest::SPBuilder::connect_( const std::vector< size_t >& sources, const std::vect #pragma omp parallel { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -2317,7 +2494,7 @@ nest::SPBuilder::connect_( const std::vector< size_t >& sources, const std::vect skip_conn_parameter_( tid ); continue; } - Node* const target = kernel().node_manager.get_node_or_proxy( *tnode_id_it, tid ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( *tnode_id_it, tid ); single_connect_( *snode_id_it, *target, tid, rng ); } diff --git a/nestkernel/conn_builder.h b/nestkernel/conn_builder.h index 801d4bb355..0ae4009d33 100644 --- a/nestkernel/conn_builder.h +++ b/nestkernel/conn_builder.h @@ -39,13 +39,15 @@ #include "block_vector.h" // Includes from nestkernel: -#include "conn_parameter.h" -#include "nest_time.h" +// #include "conn_parameter.h" +// #include "kernel_manager.h" #include "node_collection.h" #include "parameter.h" +// #include "sp_manager.h" // Includes from sli: #include "dictdatum.h" +#include "nest_datums.h" #include "sliexceptions.h" namespace nest @@ -93,25 +95,9 @@ class BipartiteConnBuilder const std::vector< DictionaryDatum >& syn_specs ); virtual ~BipartiteConnBuilder(); - size_t - get_synapse_model() const - { - if ( synapse_model_id_.size() > 1 ) - { - throw KernelException( "Can only retrieve synapse model when one synapse per connection is used." ); - } - return synapse_model_id_[ 0 ]; - } + size_t get_synapse_model() const; - bool - get_default_delay() const - { - if ( synapse_model_id_.size() > 1 ) - { - throw KernelException( "Can only retrieve default delay when one synapse per connection is used." ); - } - return default_delay_[ 0 ]; - } + bool get_default_delay() const; void set_synaptic_element_names( const std::string& pre_name, const std::string& post_name ); @@ -127,37 +113,17 @@ class BipartiteConnBuilder bool change_connected_synaptic_elements( size_t snode_id, size_t tnode_id, const size_t tid, int update ); //! Return true if rule allows creation of symmetric connectivity - virtual bool - supports_symmetric() const - { - return false; - } + virtual bool supports_symmetric() const; //! Return true if rule automatically creates symmetric connectivity - virtual bool - is_symmetric() const - { - return false; - } + virtual bool is_symmetric() const; - bool - allows_autapses() const - { - return allow_autapses_; - } + bool allows_autapses() const; - bool - allows_multapses() const - { - return allow_multapses_; - } + bool allows_multapses() const; //! Return true if rule is applicable only to nodes with proxies - virtual bool - requires_proxies() const - { - return true; - } + virtual bool requires_proxies() const; protected: //! Implements the actual connection algorithm @@ -165,29 +131,17 @@ class BipartiteConnBuilder bool all_parameters_scalar_() const; - virtual void - sp_connect_() - { - throw NotImplemented( "This connection rule is not implemented for structural plasticity." ); - } + virtual void sp_connect_(); - virtual void - disconnect_() - { - throw NotImplemented( "This disconnection rule is not implemented." ); - } + virtual void disconnect_(); - virtual void - sp_disconnect_() - { - throw NotImplemented( "This connection rule is not implemented for structural plasticity." ); - } + virtual void sp_disconnect_(); void update_param_dict_( size_t snode_id, Node& target, size_t target_thread, RngPtr rng, size_t indx ); //! Create connection between given nodes, fill parameter values void single_connect_( size_t, Node&, size_t, RngPtr ); - void single_disconnect_( size_t, Node&, size_t ); + void single_disconnect_( size_t snode_id, Node& target, size_t target_thread ); /** * Moves pointer in parameter array. @@ -198,8 +152,7 @@ class BipartiteConnBuilder * node is not located on the current thread or MPI-process and read of an * array. */ - void skip_conn_parameter_( size_t, size_t n_skip = 1 ); - + void skip_conn_parameter_( size_t target_thread, size_t n_skip = 1 ); /** * Returns true if conventional looping over targets is indicated. * @@ -423,11 +376,7 @@ class ThirdOutBuilder : public BipartiteConnBuilder const std::vector< DictionaryDatum >& syn_specs ); //! Only call third_connect() on ThirdOutBuilder - void - connect() override final - { - assert( false ); - } + void connect() override final; /** * Create third-factor connection for given primary connection. @@ -520,11 +469,7 @@ class ThirdBernoulliWithPoolBuilder : public ThirdOutBuilder void third_connect( size_t source_gid, Node& target ) override; private: - void - connect_() override - { - assert( false ); - } //!< only call third_connect() + void connect_() override; //!< only call third_connect() /** * For block pool, return index of first pool element for given target node. @@ -570,17 +515,9 @@ class OneToOneBuilder : public BipartiteConnBuilder const DictionaryDatum& conn_spec, const std::vector< DictionaryDatum >& syn_specs ); - bool - supports_symmetric() const override - { - return true; - } + bool supports_symmetric() const override; - bool - requires_proxies() const override - { - return false; - } + bool requires_proxies() const override; protected: void connect_() override; @@ -621,17 +558,9 @@ class AllToAllBuilder : public BipartiteConnBuilder { } - bool - is_symmetric() const override - { - return sources_ == targets_ and all_parameters_scalar_(); - } + bool is_symmetric() const override; - bool - requires_proxies() const override - { - return false; - } + bool requires_proxies() const override; protected: void connect_() override; @@ -787,29 +716,13 @@ class SPBuilder : public BipartiteConnBuilder const DictionaryDatum& conn_spec, const std::vector< DictionaryDatum >& syn_spec ); - const std::string& - get_pre_synaptic_element_name() const - { - return pre_synaptic_element_name_; - } + const std::string& get_pre_synaptic_element_name() const; - const std::string& - get_post_synaptic_element_name() const - { - return post_synaptic_element_name_; - } + const std::string& get_post_synaptic_element_name() const; - void - set_name( const std::string& name ) - { - name_ = name; - } + void set_name( const std::string& name ); - std::string - get_name() const - { - return name_; - } + std::string get_name() const; /** * Writes the default delay of the connection model, if the SPBuilder only uses the default delay. @@ -839,27 +752,6 @@ class SPBuilder : public BipartiteConnBuilder */ void connect_( const std::vector< size_t >& sources, const std::vector< size_t >& targets ); }; - -inline void -BipartiteConnBuilder::register_parameters_requiring_skipping_( ConnParameter& param ) -{ - if ( param.is_array() ) - { - parameters_requiring_skipping_.push_back( ¶m ); - } -} - -inline void -BipartiteConnBuilder::skip_conn_parameter_( size_t target_thread, size_t n_skip ) -{ - for ( std::vector< ConnParameter* >::iterator it = parameters_requiring_skipping_.begin(); - it != parameters_requiring_skipping_.end(); - ++it ) - { - ( *it )->skip( target_thread, n_skip ); - } -} - } // namespace nest #endif diff --git a/nestkernel/conn_builder_conngen.cpp b/nestkernel/conn_builder_conngen.cpp index 7c0547ab34..f33948ec04 100644 --- a/nestkernel/conn_builder_conngen.cpp +++ b/nestkernel/conn_builder_conngen.cpp @@ -26,6 +26,8 @@ // Includes from nestkernel: #include "kernel_manager.h" +#include "nest.h" +#include "node_manager.h" // Includes from sli: #include "dictutils.h" @@ -89,7 +91,7 @@ ConnectionGeneratorBuilder::connect_() { // No need to check for locality of the target, as the mask // created by cg_set_masks() only contains local nodes. - Node* const target_node = kernel().node_manager.get_node_or_proxy( ( *targets_ )[ target ] ); + Node* const target_node = kernel::manager< NodeManager >.get_node_or_proxy( ( *targets_ )[ target ] ); const size_t target_thread = target_node->get_thread(); single_connect_( ( *sources_ )[ source ], *target_node, target_thread, rng ); } @@ -118,13 +120,13 @@ ConnectionGeneratorBuilder::connect_() { // No need to check for locality of the target node, as the mask // created by cg_set_masks() only contains local nodes. - Node* target_node = kernel().node_manager.get_node_or_proxy( ( *targets_ )[ target ] ); + Node* target_node = kernel::manager< NodeManager >.get_node_or_proxy( ( *targets_ )[ target ] ); const size_t target_thread = target_node->get_thread(); update_param_dict_( ( *sources_ )[ source ], *target_node, target_thread, rng, 0 ); // Use the low-level connect() here, as we need to pass a custom weight and delay - kernel().connection_manager.connect( ( *sources_ )[ source ], + kernel::manager< ConnectionManager >.connect( ( *sources_ )[ source ], target_node, target_thread, synapse_model_id_[ 0 ], @@ -143,7 +145,7 @@ ConnectionGeneratorBuilder::connect_() void ConnectionGeneratorBuilder::cg_set_masks() { - const size_t np = kernel().mpi_manager.get_num_processes(); + const size_t np = kernel::manager< MPIManager >.get_num_processes(); std::vector< ConnectionGenerator::Mask > masks( np, ConnectionGenerator::Mask( 1, np ) ); // The index of the left border of the currently looked at range @@ -203,7 +205,7 @@ ConnectionGeneratorBuilder::cg_set_masks() cg_idx_left += num_elements; } - cg_->setMask( masks, kernel().mpi_manager.get_rank() ); + cg_->setMask( masks, kernel::manager< MPIManager >.get_rank() ); } diff --git a/nestkernel/conn_builder_factory.cpp b/nestkernel/conn_builder_factory.cpp new file mode 100644 index 0000000000..c6666e4ebb --- /dev/null +++ b/nestkernel/conn_builder_factory.cpp @@ -0,0 +1,32 @@ +/* + * conn_builder_factory.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "conn_builder_factory.h" + +namespace nest +{ + +GenericBipartiteConnBuilderFactory::~GenericBipartiteConnBuilderFactory() = default; + +GenericThirdConnBuilderFactory::~GenericThirdConnBuilderFactory() = default; + +} // namespace nest diff --git a/nestkernel/conn_builder_factory.h b/nestkernel/conn_builder_factory.h index ccc62f0025..2a6af1720a 100644 --- a/nestkernel/conn_builder_factory.h +++ b/nestkernel/conn_builder_factory.h @@ -47,9 +47,7 @@ namespace nest class GenericBipartiteConnBuilderFactory { public: - virtual ~GenericBipartiteConnBuilderFactory() - { - } + virtual ~GenericBipartiteConnBuilderFactory(); /** * Factory method for builders for bipartite connection rules (the default). @@ -66,24 +64,6 @@ class GenericBipartiteConnBuilderFactory const std::vector< DictionaryDatum >& ) const = 0; }; -/** - * Factory class for bipartite ConnBuilders - */ -template < typename ConnBuilderType > -class BipartiteConnBuilderFactory : public GenericBipartiteConnBuilderFactory -{ -public: - BipartiteConnBuilder* - create( NodeCollectionPTR sources, - NodeCollectionPTR targets, - ThirdOutBuilder* third_out, - const DictionaryDatum& conn_spec, - const std::vector< DictionaryDatum >& syn_specs ) const override - { - return new ConnBuilderType( sources, targets, third_out, conn_spec, syn_specs ); - } -}; - /** * Generic factory class for tripartite ConnBuilder objects. * @@ -94,9 +74,7 @@ class BipartiteConnBuilderFactory : public GenericBipartiteConnBuilderFactory class GenericThirdConnBuilderFactory { public: - virtual ~GenericThirdConnBuilderFactory() - { - } + virtual ~GenericThirdConnBuilderFactory(); /** * Factory method for builders for tripartite connection rules. @@ -108,24 +86,6 @@ class GenericThirdConnBuilderFactory const std::vector< DictionaryDatum >& ) const = 0; }; -/** - * Factory class for Third-factor ConnBuilders - */ -template < typename ThirdConnBuilderType > -class ThirdConnBuilderFactory : public GenericThirdConnBuilderFactory -{ -public: - ThirdOutBuilder* - create( NodeCollectionPTR sources, - NodeCollectionPTR targets, - ThirdInBuilder* third_in, - const DictionaryDatum& conn_spec, - const std::vector< DictionaryDatum >& syn_specs ) const override - { - return new ThirdConnBuilderType( sources, targets, third_in, conn_spec, syn_specs ); - } -}; - } // namespace nest #endif diff --git a/nestkernel/conn_builder_factory_impl.h b/nestkernel/conn_builder_factory_impl.h new file mode 100644 index 0000000000..0f8a64f2f3 --- /dev/null +++ b/nestkernel/conn_builder_factory_impl.h @@ -0,0 +1,71 @@ +/* + * conn_builder_factory_impl.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef CONN_BUILDER_FACTORY_IMPL_H +#define CONN_BUILDER_FACTORY_IMPL_H + +#include "conn_builder_factory.h" + +namespace nest +{ + +/** + * Factory class for bipartite ConnBuilders + */ +template < typename ConnBuilderType > +class BipartiteConnBuilderFactory : public GenericBipartiteConnBuilderFactory +{ +public: + BipartiteConnBuilder* + create( NodeCollectionPTR sources, + NodeCollectionPTR targets, + ThirdOutBuilder* third_out, + const DictionaryDatum& conn_spec, + const std::vector< DictionaryDatum >& syn_specs ) const override + { + return new ConnBuilderType( sources, targets, third_out, conn_spec, syn_specs ); + } +}; + + +/** + * Factory class for Third-factor ConnBuilders + */ +template < typename ThirdConnBuilderType > +class ThirdConnBuilderFactory : public GenericThirdConnBuilderFactory +{ +public: + ThirdOutBuilder* + create( NodeCollectionPTR sources, + NodeCollectionPTR targets, + ThirdInBuilder* third_in, + const DictionaryDatum& conn_spec, + const std::vector< DictionaryDatum >& syn_specs ) const override + { + return new ThirdConnBuilderType( sources, targets, third_in, conn_spec, syn_specs ); + } +}; + + +} // namespace nest + +#endif // CONN_BUILDER_FACTORY_IMPL_H diff --git a/nestkernel/conn_parameter.cpp b/nestkernel/conn_parameter.cpp index 31d249a7c4..d4c5800e8a 100644 --- a/nestkernel/conn_parameter.cpp +++ b/nestkernel/conn_parameter.cpp @@ -84,3 +84,256 @@ nest::ParameterConnParameterWrapper::value_double( size_t, RngPtr rng, size_t, N { return parameter_->value( rng, target ); } + +void +nest::ArrayDoubleParameter::skip( size_t tid, size_t n_skip ) const +{ + if ( next_[ tid ] < values_->end() ) + { + next_[ tid ] += n_skip; + } + else + { + throw KernelException( "Parameter values exhausted." ); + } +} + +double +nest::ArrayDoubleParameter::value_double( size_t tid, RngPtr, size_t, Node* ) const +{ + if ( next_[ tid ] != values_->end() ) + { + return *next_[ tid ]++; + } + else + { + throw KernelException( "Parameter values exhausted." ); + } +} + +long +nest::ArrayDoubleParameter::value_int( size_t, RngPtr, size_t, Node* ) const +{ + throw KernelException( "ConnParameter calls value function with false return type." ); +} + +void +nest::ArrayDoubleParameter::reset() const +{ + for ( std::vector< std::vector< double >::const_iterator >::iterator it = next_.begin(); it != next_.end(); ++it ) + { + *it = values_->begin(); + } +} + +void +nest::ArrayIntegerParameter::skip( size_t tid, size_t n_skip ) const +{ + if ( next_[ tid ] < values_->end() ) + { + next_[ tid ] += n_skip; + } + else + { + throw KernelException( "Parameter values exhausted." ); + } +} + +long +nest::ArrayIntegerParameter::value_int( size_t tid, RngPtr, size_t, Node* ) const +{ + if ( next_[ tid ] != values_->end() ) + { + return *next_[ tid ]++; + } + else + { + throw KernelException( "Parameter values exhausted." ); + } +} + +double +nest::ArrayIntegerParameter::value_double( size_t tid, RngPtr, size_t, Node* ) const +{ + if ( next_[ tid ] != values_->end() ) + { + return static_cast< double >( *next_[ tid ]++ ); + } + else + { + throw KernelException( "Parameter values exhausted." ); + } +} + +void +nest::ArrayIntegerParameter::reset() const +{ + for ( std::vector< std::vector< long >::const_iterator >::iterator it = next_.begin(); it != next_.end(); ++it ) + { + *it = values_->begin(); + } +} +namespace nest +{ + +// ---- Base class: defaulted specials & defaults ---- +ConnParameter::ConnParameter() +{ +} +ConnParameter::~ConnParameter() +{ +} + +void +ConnParameter::skip( size_t, size_t ) const +{ +} +bool +ConnParameter::is_scalar() const +{ + return false; +} +bool +ConnParameter::provides_long() const +{ + return false; +} +void +ConnParameter::reset() const +{ + throw NotImplemented( "Symmetric connections require parameters that can be reset." ); +} +size_t +ConnParameter::number_of_values() const +{ + return 0; +} + +// ---- ScalarDoubleParameter ---- +ScalarDoubleParameter::ScalarDoubleParameter( double value, const size_t ) + : value_( value ) +{ +} +double +ScalarDoubleParameter::value_double( size_t, RngPtr, size_t, Node* ) const +{ + return value_; +} +long +ScalarDoubleParameter::value_int( size_t, RngPtr, size_t, Node* ) const +{ + throw KernelException( "ConnParameter calls value function with false return type." ); +} +bool +ScalarDoubleParameter::is_array() const +{ + return false; +} +void +ScalarDoubleParameter::reset() const +{ +} +bool +ScalarDoubleParameter::is_scalar() const +{ + return true; +} + +// ---- ScalarIntegerParameter ---- +ScalarIntegerParameter::ScalarIntegerParameter( long value, const size_t ) + : value_( value ) +{ +} +double +ScalarIntegerParameter::value_double( size_t, RngPtr, size_t, Node* ) const +{ + return static_cast< double >( value_ ); +} +long +ScalarIntegerParameter::value_int( size_t, RngPtr, size_t, Node* ) const +{ + return value_; +} +bool +ScalarIntegerParameter::is_array() const +{ + return false; +} +void +ScalarIntegerParameter::reset() const +{ +} +bool +ScalarIntegerParameter::is_scalar() const +{ + return true; +} +bool +ScalarIntegerParameter::provides_long() const +{ + return true; +} + +// ---- ArrayDoubleParameter ---- +ArrayDoubleParameter::ArrayDoubleParameter( const std::vector< double >& values, const size_t nthreads ) + : values_( &values ) + , next_( nthreads, values_->begin() ) +{ +} + +size_t +ArrayDoubleParameter::number_of_values() const +{ + return values_->size(); +} + +bool +ArrayDoubleParameter::is_array() const +{ + return true; +} + +// ---- ArrayIntegerParameter ---- +ArrayIntegerParameter::ArrayIntegerParameter( const std::vector< long >& values, const size_t nthreads ) + : values_( &values ) + , next_( nthreads, values_->begin() ) +{ +} + +size_t +ArrayIntegerParameter::number_of_values() const +{ + return values_->size(); +} + + +bool +ArrayIntegerParameter::is_array() const +{ + return true; +} +bool +ArrayIntegerParameter::provides_long() const +{ + return true; +} + + +// ---- ParameterConnParameterWrapper ---- +long +ParameterConnParameterWrapper::value_int( size_t tt, RngPtr rng, size_t sn, Node* tgt ) const +{ + return static_cast< long >( value_double( tt, rng, sn, tgt ) ); +} +bool +ParameterConnParameterWrapper::is_array() const +{ + return false; +} +bool +ParameterConnParameterWrapper::provides_long() const +{ + return parameter_->returns_int_only(); +} + +} // namespace nest diff --git a/nestkernel/conn_parameter.h b/nestkernel/conn_parameter.h index 08238339ba..bb04feac36 100644 --- a/nestkernel/conn_parameter.h +++ b/nestkernel/conn_parameter.h @@ -54,13 +54,9 @@ class ConnParameter { public: - ConnParameter() - { - } + ConnParameter(); - virtual ~ConnParameter() - { - } + virtual ~ConnParameter(); /** * Return parameter value. @@ -75,41 +71,19 @@ class ConnParameter */ virtual double value_double( size_t, RngPtr, size_t, Node* ) const = 0; virtual long value_int( size_t, RngPtr, size_t, Node* ) const = 0; - virtual void - skip( size_t, size_t ) const - { - } - virtual bool is_array() const = 0; - - virtual bool - is_scalar() const - { - return false; - } - virtual bool - provides_long() const - { - return false; - } - - virtual void - reset() const - { - throw NotImplemented( "Symmetric connections require parameters that can be reset." ); - } + virtual void skip( size_t, size_t ) const; + virtual bool is_array() const = 0; + virtual bool is_scalar() const; + virtual bool provides_long() const; + virtual void reset() const; /** * Returns number of values available. * * 0 indicates scalar/unlimited supply. */ - virtual size_t - number_of_values() const - { - return 0; - } - + virtual size_t number_of_values() const; /** * @param t parameter * type is established by casts to all acceptedpossibilities @@ -128,39 +102,13 @@ class ConnParameter class ScalarDoubleParameter : public ConnParameter { public: - ScalarDoubleParameter( double value, const size_t ) - : value_( value ) - { - } - - double - value_double( size_t, RngPtr, size_t, Node* ) const override - { - return value_; - } - - long - value_int( size_t, RngPtr, size_t, Node* ) const override - { - throw KernelException( "ConnParameter calls value function with false return type." ); - } - - inline bool - is_array() const override - { - return false; - } - - void - reset() const override - { - } - - bool - is_scalar() const override - { - return true; - } + ScalarDoubleParameter( double value, const size_t ); + + double value_double( size_t, RngPtr, size_t, Node* ) const override; + long value_int( size_t, RngPtr, size_t, Node* ) const override; + bool is_array() const override; + void reset() const override; + bool is_scalar() const override; private: double value_; @@ -174,45 +122,14 @@ class ScalarDoubleParameter : public ConnParameter class ScalarIntegerParameter : public ConnParameter { public: - ScalarIntegerParameter( long value, const size_t ) - : value_( value ) - { - } - - double - value_double( size_t, RngPtr, size_t, Node* ) const override - { - return static_cast< double >( value_ ); - } - - long - value_int( size_t, RngPtr, size_t, Node* ) const override - { - return value_; - } - - inline bool - is_array() const override - { - return false; - } - - void - reset() const override - { - } - - bool - is_scalar() const override - { - return true; - } - - bool - provides_long() const override - { - return true; - } + ScalarIntegerParameter( long value, const size_t ); + + double value_double( size_t, RngPtr, size_t, Node* ) const override; + long value_int( size_t, RngPtr, size_t, Node* ) const override; + bool is_array() const override; + void reset() const override; + bool is_scalar() const override; + bool provides_long() const override; private: long value_; @@ -237,64 +154,16 @@ class ScalarIntegerParameter : public ConnParameter class ArrayDoubleParameter : public ConnParameter { public: - ArrayDoubleParameter( const std::vector< double >& values, const size_t nthreads ) - : values_( &values ) - , next_( nthreads, values_->begin() ) - { - } - - void - skip( size_t tid, size_t n_skip ) const override - { - if ( next_[ tid ] < values_->end() ) - { - next_[ tid ] += n_skip; - } - else - { - throw KernelException( "Parameter values exhausted." ); - } - } - - size_t - number_of_values() const override - { - return values_->size(); - } - - double - value_double( size_t tid, RngPtr, size_t, Node* ) const override - { - if ( next_[ tid ] != values_->end() ) - { - return *next_[ tid ]++; - } - else - { - throw KernelException( "Parameter values exhausted." ); - } - } - - long - value_int( size_t, RngPtr, size_t, Node* ) const override - { - throw KernelException( "ConnParameter calls value function with false return type." ); - } - - inline bool - is_array() const override - { - return true; - } - - void - reset() const override - { - for ( std::vector< std::vector< double >::const_iterator >::iterator it = next_.begin(); it != next_.end(); ++it ) - { - *it = values_->begin(); - } - } + ArrayDoubleParameter( const std::vector< double >& values, const size_t nthreads ); + + void skip( size_t tid, size_t n_skip ) const override; + size_t number_of_values() const override; + + double value_double( size_t tid, RngPtr, size_t, Node* ) const override; + long value_int( size_t, RngPtr, size_t, Node* ) const override; + + bool is_array() const override; + void reset() const override; private: const std::vector< double >* values_; @@ -319,77 +188,17 @@ class ArrayDoubleParameter : public ConnParameter class ArrayIntegerParameter : public ConnParameter { public: - ArrayIntegerParameter( const std::vector< long >& values, const size_t nthreads ) - : values_( &values ) - , next_( nthreads, values_->begin() ) - { - } - - void - skip( size_t tid, size_t n_skip ) const override - { - if ( next_[ tid ] < values_->end() ) - { - next_[ tid ] += n_skip; - } - else - { - throw KernelException( "Parameter values exhausted." ); - } - } - - size_t - number_of_values() const override - { - return values_->size(); - } - - long - value_int( size_t tid, RngPtr, size_t, Node* ) const override - { - if ( next_[ tid ] != values_->end() ) - { - return *next_[ tid ]++; - } - else - { - throw KernelException( "Parameter values exhausted." ); - } - } - - double - value_double( size_t tid, RngPtr, size_t, Node* ) const override - { - if ( next_[ tid ] != values_->end() ) - { - return static_cast< double >( *next_[ tid ]++ ); - } - else - { - throw KernelException( "Parameter values exhausted." ); - } - } - - inline bool - is_array() const override - { - return true; - } - - bool - provides_long() const override - { - return true; - } - - void - reset() const override - { - for ( std::vector< std::vector< long >::const_iterator >::iterator it = next_.begin(); it != next_.end(); ++it ) - { - *it = values_->begin(); - } - } + ArrayIntegerParameter( const std::vector< long >& values, const size_t nthreads ); + + void skip( size_t tid, size_t n_skip ) const override; + size_t number_of_values() const override; + + long value_int( size_t tid, RngPtr, size_t, Node* ) const override; + double value_double( size_t tid, RngPtr, size_t, Node* ) const override; + + bool is_array() const override; + bool provides_long() const override; + void reset() const override; private: const std::vector< long >* values_; @@ -402,24 +211,10 @@ class ParameterConnParameterWrapper : public ConnParameter ParameterConnParameterWrapper( const ParameterDatum&, const size_t ); double value_double( size_t target_thread, RngPtr rng, size_t snode_id, Node* target ) const override; + long value_int( size_t target_thread, RngPtr rng, size_t snode_id, Node* target ) const override; - long - value_int( size_t target_thread, RngPtr rng, size_t snode_id, Node* target ) const override - { - return value_double( target_thread, rng, snode_id, target ); - } - - inline bool - is_array() const override - { - return false; - } - - bool - provides_long() const override - { - return parameter_->returns_int_only(); - } + bool is_array() const override; + bool provides_long() const override; private: Parameter* parameter_; diff --git a/nestkernel/connection.h b/nestkernel/connection.h index d3cb8f4cee..746b4ffe96 100644 --- a/nestkernel/connection.h +++ b/nestkernel/connection.h @@ -26,24 +26,14 @@ // Includes from nestkernel: #include "common_synapse_properties.h" #include "connection_label.h" -#include "connector_base_impl.h" -#include "delay_checker.h" #include "event.h" -#include "kernel_manager.h" -#include "nest.h" -#include "nest_names.h" #include "nest_time.h" -#include "nest_timeconverter.h" #include "nest_types.h" #include "node.h" #include "spikecounter.h" #include "syn_id_delay.h" -// Includes from sli: -#include "arraydatum.h" -#include "dict.h" -#include "dictutils.h" -#include "doubledatum.h" +#include namespace nest { @@ -314,98 +304,6 @@ class Connection SynIdDelay syn_id_delay_; }; -template < typename targetidentifierT > -constexpr ConnectionModelProperties Connection< targetidentifierT >::properties; - -template < typename targetidentifierT > -inline void -Connection< targetidentifierT >::check_connection_( Node& dummy_target, - Node& source, - Node& target, - const size_t receptor_type ) -{ - // 1. does this connection support the event type sent by source - // try to send event from source to dummy_target - // this line might throw an exception - source.send_test_event( dummy_target, receptor_type, get_syn_id(), true ); - - // 2. does the target accept the event type sent by source - // try to send event from source to target - // this returns the port of the incoming connection - // p must be stored in the base class connection - // this line might throw an exception - target_.set_rport( source.send_test_event( target, receptor_type, get_syn_id(), false ) ); - - // 3. do the events sent by source mean the same thing as they are - // interpreted in target? - // note that we here use a bitwise and operation (&), because we interpret - // each bit in the signal type as a collection of individual flags - if ( not( source.sends_signal() & target.receives_signal() ) ) - { - throw IllegalConnection( "Source and target neuron are not compatible (e.g., spiking vs binary neuron)." ); - } - - target_.set_target( &target ); -} - -template < typename targetidentifierT > -inline void -Connection< targetidentifierT >::get_status( DictionaryDatum& d ) const -{ - def< double >( d, names::delay, syn_id_delay_.get_delay_ms() ); - target_.get_status( d ); -} - -template < typename targetidentifierT > -inline void -Connection< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& ) -{ - double delay; - if ( updateValue< double >( d, names::delay, delay ) ) - { - kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( delay ); - syn_id_delay_.set_delay_ms( delay ); - } - // no call to target_.set_status() because target and rport cannot be changed -} - -template < typename targetidentifierT > -inline void -Connection< targetidentifierT >::check_synapse_params( const DictionaryDatum& ) const -{ -} - -template < typename targetidentifierT > -inline void -Connection< targetidentifierT >::calibrate( const TimeConverter& tc ) -{ - Time t = tc.from_old_steps( syn_id_delay_.delay ); - syn_id_delay_.delay = t.get_steps(); - - if ( syn_id_delay_.delay == 0 ) - { - syn_id_delay_.delay = 1; - } -} - -template < typename targetidentifierT > -inline void -Connection< targetidentifierT >::trigger_update_weight( const size_t, - const std::vector< spikecounter >&, - const double, - const CommonSynapseProperties& ) -{ - throw IllegalConnection( "Connection does not support updates that are triggered by a volume transmitter." ); -} - -template < typename targetidentifierT > -std::unique_ptr< SecondaryEvent > -Connection< targetidentifierT >::get_secondary_event() -{ - assert( false and "Non-primary connections have to provide get_secondary_event()" ); - return nullptr; -} - } // namespace nest #endif /* CONNECTION_H */ diff --git a/nestkernel/connection_creator.cpp b/nestkernel/connection_creator.cpp index 21b94e3153..7fcafd9068 100644 --- a/nestkernel/connection_creator.cpp +++ b/nestkernel/connection_creator.cpp @@ -22,6 +22,8 @@ #include "connection_creator.h" #include "dictutils.h" +#include "logging_manager.h" +#include "model_manager.h" namespace nest { @@ -95,7 +97,7 @@ ConnectionCreator::ConnectionCreator( DictionaryDatum dict ) { // If not, we have single synapses. param_dicts_.resize( 1 ); - param_dicts_[ 0 ].resize( kernel().vp_manager.get_num_threads() ); + param_dicts_[ 0 ].resize( kernel::manager< VPManager >.get_num_threads() ); extract_params_( dict, param_dicts_[ 0 ] ); } @@ -104,9 +106,9 @@ ConnectionCreator::ConnectionCreator( DictionaryDatum dict ) // Set default synapse_model, weight and delay if not given explicitly if ( synapse_model_.empty() ) { - synapse_model_ = { kernel().model_manager.get_synapse_model_id( "static_synapse" ) }; + synapse_model_ = { kernel::manager< ModelManager >.get_synapse_model_id( "static_synapse" ) }; } - DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( synapse_model_[ 0 ] ); + DictionaryDatum syn_defaults = kernel::manager< ModelManager >.get_connector_defaults( synapse_model_[ 0 ] ); if ( weight_.empty() ) { weight_ = { NestModule::create_parameter( ( *syn_defaults )[ names::weight ] ) }; @@ -167,10 +169,10 @@ ConnectionCreator::extract_params_( const DictionaryDatum& dict_datum, std::vect std::string syn_name = ( *dict_datum )[ names::synapse_model ]; // The following call will throw "UnknownSynapseType" if syn_name is not naming a known model - const size_t synapse_model_id = kernel().model_manager.get_synapse_model_id( syn_name ); + const size_t synapse_model_id = kernel::manager< ModelManager >.get_synapse_model_id( syn_name ); synapse_model_.push_back( synapse_model_id ); - DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( synapse_model_id ); + DictionaryDatum syn_defaults = kernel::manager< ModelManager >.get_connector_defaults( synapse_model_id ); if ( dict_datum->known( names::weight ) ) { weight_.push_back( NestModule::create_parameter( ( *dict_datum )[ names::weight ] ) ); @@ -209,10 +211,10 @@ ConnectionCreator::extract_params_( const DictionaryDatum& dict_datum, std::vect copy_long_if_known( names::synapse_label ); copy_long_if_known( names::receptor_type ); - params.resize( kernel().vp_manager.get_num_threads() ); + params.resize( kernel::manager< VPManager >.get_num_threads() ); #pragma omp parallel { - params.at( kernel().vp_manager.get_thread_id() ) = syn_dict; + params.at( kernel::manager< VPManager >.get_thread_id() ) = syn_dict; } } diff --git a/nestkernel/connection_creator.h b/nestkernel/connection_creator.h index 62d2671344..7747ba2645 100644 --- a/nestkernel/connection_creator.h +++ b/nestkernel/connection_creator.h @@ -27,9 +27,12 @@ #include // Includes from nestkernel: +#include "connection_manager.h" #include "kernel_manager.h" +#include "nest.h" #include "nest_names.h" #include "nestmodule.h" +#include "node_manager.h" // Includes from spatial: #include "mask.h" diff --git a/nestkernel/connection_creator_impl.h b/nestkernel/connection_creator_impl.h index e094ab59d5..5bf1578abc 100644 --- a/nestkernel/connection_creator_impl.h +++ b/nestkernel/connection_creator_impl.h @@ -25,15 +25,23 @@ #include "connection_creator.h" -// C++ includes: +#include +#include +#include +#include #include -// Includes from nestkernel: +#include "connection_manager.h" #include "kernel_manager.h" +#include "mask.h" #include "nest.h" +#include "nestmodule.h" +#include "node_manager.h" +#include "position.h" namespace nest { + template < int D > void ConnectionCreator::connect( Layer< D >& source, @@ -102,7 +110,7 @@ ConnectionCreator::connect_to_target_( Iterator from, { for ( size_t indx = 0; indx < synapse_model_.size(); ++indx ) { - kernel().connection_manager.connect( iter->second, + kernel::manager< ConnectionManager >.connect( iter->second, tgt_ptr, tgt_thread, synapse_model_[ indx ], @@ -114,6 +122,7 @@ ConnectionCreator::connect_to_target_( Iterator from, } } + template < typename Iterator, int D > void ConnectionCreator::connect_to_target_poisson_( Iterator from, @@ -147,7 +156,7 @@ ConnectionCreator::connect_to_target_poisson_( Iterator from, { for ( size_t indx = 0; indx < synapse_model_.size(); ++indx ) { - kernel().connection_manager.connect( iter->second, + kernel::manager< ConnectionManager >.connect( iter->second, tgt_ptr, tgt_thread, synapse_model_[ indx ], @@ -159,6 +168,7 @@ ConnectionCreator::connect_to_target_poisson_( Iterator from, } } + template < int D > ConnectionCreator::PoolWrapper_< D >::PoolWrapper_() : masked_layer_( 0 ) @@ -248,11 +258,12 @@ ConnectionCreator::pairwise_bernoulli_on_source_( Layer< D >& source, pool.define( source.get_global_positions_vector( source_nc ) ); } - std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( kernel().vp_manager.get_num_threads() ); + std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( + kernel::manager< VPManager >.get_num_threads() ); #pragma omp parallel { - const int thread_id = kernel().vp_manager.get_thread_id(); + const int thread_id = kernel::manager< VPManager >.get_thread_id(); try { NodeCollection::const_iterator target_begin = target_nc->begin(); @@ -260,7 +271,7 @@ ConnectionCreator::pairwise_bernoulli_on_source_( Layer< D >& source, for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it ) { - Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id, thread_id ); + Node* const tgt = kernel::manager< NodeManager >.get_node_or_proxy( ( *tgt_it ).node_id, thread_id ); if ( not tgt->is_proxy() ) { @@ -287,7 +298,7 @@ ConnectionCreator::pairwise_bernoulli_on_source_( Layer< D >& source, } } // omp parallel // check if any exceptions have been raised - for ( size_t thr = 0; thr < kernel().vp_manager.get_num_threads(); ++thr ) + for ( size_t thr = 0; thr < kernel::manager< VPManager >.get_num_threads(); ++thr ) { if ( exceptions_raised_.at( thr ).get() ) { @@ -325,10 +336,11 @@ ConnectionCreator::pairwise_bernoulli_on_target_( Layer< D >& source, pool.define( source.get_global_positions_vector( source_nc ) ); } - std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( kernel().vp_manager.get_num_threads() ); + std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( + kernel::manager< VPManager >.get_num_threads() ); // We only need to check the first in the NodeCollection - Node* const first_in_tgt = kernel().node_manager.get_node_or_proxy( target_nc->operator[]( 0 ) ); + Node* const first_in_tgt = kernel::manager< NodeManager >.get_node_or_proxy( target_nc->operator[]( 0 ) ); if ( not first_in_tgt->has_proxies() ) { throw IllegalConnection( "Spatial Connect with pairwise_bernoulli to devices is not possible." ); @@ -336,7 +348,7 @@ ConnectionCreator::pairwise_bernoulli_on_target_( Layer< D >& source, #pragma omp parallel { - const int thread_id = kernel().vp_manager.get_thread_id(); + const int thread_id = kernel::manager< VPManager >.get_thread_id(); try { NodeCollection::const_iterator target_begin = target_nc->thread_local_begin(); @@ -344,7 +356,7 @@ ConnectionCreator::pairwise_bernoulli_on_target_( Layer< D >& source, for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it ) { - Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id, thread_id ); + Node* const tgt = kernel::manager< NodeManager >.get_node_or_proxy( ( *tgt_it ).node_id, thread_id ); assert( not tgt->is_proxy() ); @@ -373,7 +385,7 @@ ConnectionCreator::pairwise_bernoulli_on_target_( Layer< D >& source, } } // omp parallel // check if any exceptions have been raised - for ( size_t thr = 0; thr < kernel().vp_manager.get_num_threads(); ++thr ) + for ( size_t thr = 0; thr < kernel::manager< VPManager >.get_num_threads(); ++thr ) { if ( exceptions_raised_.at( thr ).get() ) { @@ -407,11 +419,12 @@ ConnectionCreator::pairwise_poisson_( Layer< D >& source, pool.define( source.get_global_positions_vector( source_nc ) ); } - std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( kernel().vp_manager.get_num_threads() ); + std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( + kernel::manager< VPManager >.get_num_threads() ); #pragma omp parallel { - const int thread_id = kernel().vp_manager.get_thread_id(); + const int thread_id = kernel::manager< VPManager >.get_thread_id(); try { NodeCollection::const_iterator target_begin = target_nc->begin(); @@ -419,7 +432,7 @@ ConnectionCreator::pairwise_poisson_( Layer< D >& source, for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it ) { - Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id, thread_id ); + Node* const tgt = kernel::manager< NodeManager >.get_node_or_proxy( ( *tgt_it ).node_id, thread_id ); if ( not tgt->is_proxy() ) { @@ -446,7 +459,7 @@ ConnectionCreator::pairwise_poisson_( Layer< D >& source, } } // omp parallel // check if any exceptions have been raised - for ( size_t thr = 0; thr < kernel().vp_manager.get_num_threads(); ++thr ) + for ( size_t thr = 0; thr < kernel::manager< VPManager >.get_num_threads(); ++thr ) { if ( exceptions_raised_.at( thr ).get() ) { @@ -471,7 +484,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source, // 3. Draw source nodes and make connections // We only need to check the first in the NodeCollection - Node* const first_in_tgt = kernel().node_manager.get_node_or_proxy( target_nc->operator[]( 0 ) ); + Node* const first_in_tgt = kernel::manager< NodeManager >.get_node_or_proxy( target_nc->operator[]( 0 ) ); if ( not first_in_tgt->has_proxies() ) { throw IllegalConnection( "Spatial Connect with fixed_indegree to devices is not possible." ); @@ -485,9 +498,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source, // the network untouched if any target does not have proxies for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it ) { - Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id ); - - assert( not tgt->is_proxy() ); + assert( not kernel::manager< NodeManager >.get_node_or_proxy( ( *tgt_it ).node_id )->is_proxy() ); } if ( mask_.get() ) @@ -500,7 +511,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source, for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it ) { size_t target_id = ( *tgt_it ).node_id; - Node* const tgt = kernel().node_manager.get_node_or_proxy( target_id ); + Node* const tgt = kernel::manager< NodeManager >.get_node_or_proxy( target_id ); size_t target_thread = tgt->get_thread(); RngPtr rng = get_vp_specific_rng( target_thread ); @@ -575,7 +586,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source, { const double w = weight_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt ); const double d = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt ); - kernel().connection_manager.connect( + kernel::manager< ConnectionManager >.connect( source_id, tgt, target_thread, synapse_model_[ indx ], param_dicts_[ indx ][ target_thread ], d, w ); } @@ -614,7 +625,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source, { const double w = weight_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt ); const double d = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt ); - kernel().connection_manager.connect( + kernel::manager< ConnectionManager >.connect( source_id, tgt, target_thread, synapse_model_[ indx ], param_dicts_[ indx ][ target_thread ], d, w ); } @@ -634,7 +645,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source, for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it ) { size_t target_id = ( *tgt_it ).node_id; - Node* const tgt = kernel().node_manager.get_node_or_proxy( target_id ); + Node* const tgt = kernel::manager< NodeManager >.get_node_or_proxy( target_id ); size_t target_thread = tgt->get_thread(); RngPtr rng = get_vp_specific_rng( target_thread ); Position< D > target_pos = target.get_position( ( *tgt_it ).nc_index ); @@ -701,7 +712,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source, { const double w = weight_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt ); const double d = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt ); - kernel().connection_manager.connect( + kernel::manager< ConnectionManager >.connect( source_id, tgt, target_thread, synapse_model_[ indx ], param_dicts_[ indx ][ target_thread ], d, w ); } @@ -738,7 +749,7 @@ ConnectionCreator::fixed_indegree_( Layer< D >& source, { const double w = weight_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt ); const double d = delay_[ indx ]->value( rng, source_pos_vector, target_pos_vector, source, tgt ); - kernel().connection_manager.connect( + kernel::manager< ConnectionManager >.connect( source_id, tgt, target_thread, synapse_model_[ indx ], param_dicts_[ indx ][ target_thread ], d, w ); } @@ -763,7 +774,7 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source, // the network untouched if any target does not have proxies // We only need to check the first in the NodeCollection - Node* const first_in_tgt = kernel().node_manager.get_node_or_proxy( target_nc->operator[]( 0 ) ); + Node* const first_in_tgt = kernel::manager< NodeManager >.get_node_or_proxy( target_nc->operator[]( 0 ) ); if ( not first_in_tgt->has_proxies() ) { throw IllegalConnection( "Spatial Connect with fixed_outdegree to devices is not possible." ); @@ -774,9 +785,7 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source, for ( NodeCollection::const_iterator tgt_it = target_begin; tgt_it < target_end; ++tgt_it ) { - Node* const tgt = kernel().node_manager.get_node_or_proxy( ( *tgt_it ).node_id ); - - assert( not tgt->is_proxy() ); + assert( not kernel::manager< NodeManager >.get_node_or_proxy( ( *tgt_it ).node_id )->is_proxy() ); } // Fixed_outdegree connections (fixed fan out) @@ -800,7 +809,7 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source, { const Position< D > source_pos = source_pos_node_id_pair.first; const size_t source_id = source_pos_node_id_pair.second; - const auto src = kernel().node_manager.get_node_or_proxy( source_id ); + const auto src = kernel::manager< NodeManager >.get_node_or_proxy( source_id ); const std::vector< double > source_pos_vector = source_pos.get_vector(); // We create a target pos vector here that can be updated with the @@ -821,7 +830,7 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source, { // TODO: Why is probability calculated in source layer, but weight and delay in target layer? target_pos_node_id_pair.first.get_vector( target_pos_vector ); - const auto tgt = kernel().node_manager.get_node_or_proxy( target_pos_node_id_pair.second ); + const auto tgt = kernel::manager< NodeManager >.get_node_or_proxy( target_pos_node_id_pair.second ); probabilities.push_back( kernel_->value( grng, source_pos_vector, target_pos_vector, source, tgt ) ); } } @@ -871,7 +880,7 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source, std::vector< double > rng_delay_vec; for ( size_t indx = 0; indx < weight_.size(); ++indx ) { - const auto tgt = kernel().node_manager.get_node_or_proxy( target_pos_node_id_pairs[ indx ].second ); + const auto tgt = kernel::manager< NodeManager >.get_node_or_proxy( target_pos_node_id_pairs[ indx ].second ); rng_weight_vec.push_back( weight_[ indx ]->value( grng, source_pos_vector, target_pos_vector, target, tgt ) ); rng_delay_vec.push_back( delay_[ indx ]->value( grng, source_pos_vector, target_pos_vector, target, tgt ) ); } @@ -880,17 +889,17 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source, // required for it. Each VP thus counts the connection as created, but only the VP hosting the // target neuron actually creates the connection. --number_of_connections; - if ( not kernel().node_manager.is_local_node_id( target_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( target_id ) ) { continue; } - Node* target_ptr = kernel().node_manager.get_node_or_proxy( target_id ); + Node* target_ptr = kernel::manager< NodeManager >.get_node_or_proxy( target_id ); const size_t target_thread = target_ptr->get_thread(); for ( size_t indx = 0; indx < synapse_model_.size(); ++indx ) { - kernel().connection_manager.connect( source_id, + kernel::manager< ConnectionManager >.connect( source_id, target_ptr, target_thread, synapse_model_[ indx ], @@ -902,6 +911,7 @@ ConnectionCreator::fixed_outdegree_( Layer< D >& source, } } -} // namespace nest + +} #endif diff --git a/nestkernel/connection_id.cpp b/nestkernel/connection_id.cpp index bba8b60123..cf2363dd3d 100644 --- a/nestkernel/connection_id.cpp +++ b/nestkernel/connection_id.cpp @@ -53,6 +53,24 @@ ConnectionID::ConnectionID( long source_node_id, long target_thread, long synaps { } +ConnectionID::ConnectionID() + : source_node_id_( -1 ) + , target_node_id_( -1 ) + , target_thread_( -1 ) + , synapse_modelid_( -1 ) + , port_( -1 ) +{ +} + +ConnectionID::ConnectionID( const ConnectionID& cid ) + : source_node_id_( cid.source_node_id_ ) + , target_node_id_( cid.target_node_id_ ) + , target_thread_( cid.target_thread_ ) + , synapse_modelid_( cid.synapse_modelid_ ) + , port_( cid.port_ ) +{ +} + DictionaryDatum ConnectionID::get_dict() const { @@ -98,4 +116,35 @@ ConnectionID::print_me( std::ostream& out ) const << port_ << ">"; } +long +ConnectionID::get_source_node_id() const +{ + return source_node_id_; +} + +long +ConnectionID::get_target_node_id() const +{ + return target_node_id_; +} + +long +ConnectionID::get_target_thread() const +{ + return target_thread_; +} + +long +ConnectionID::get_synapse_model_id() const +{ + return synapse_modelid_; +} + +long +ConnectionID::get_port() const +{ + return port_; +} + + } // namespace diff --git a/nestkernel/connection_id.h b/nestkernel/connection_id.h index 44d26c89e3..25877a6bef 100644 --- a/nestkernel/connection_id.h +++ b/nestkernel/connection_id.h @@ -55,55 +55,6 @@ class ConnectionID long synapse_modelid_; long port_; }; - -inline ConnectionID::ConnectionID() - : source_node_id_( -1 ) - , target_node_id_( -1 ) - , target_thread_( -1 ) - , synapse_modelid_( -1 ) - , port_( -1 ) -{ -} - -inline ConnectionID::ConnectionID( const ConnectionID& cid ) - : source_node_id_( cid.source_node_id_ ) - , target_node_id_( cid.target_node_id_ ) - , target_thread_( cid.target_thread_ ) - , synapse_modelid_( cid.synapse_modelid_ ) - , port_( cid.port_ ) -{ -} - -inline long -ConnectionID::get_source_node_id() const -{ - return source_node_id_; -} - -inline long -ConnectionID::get_target_node_id() const -{ - return target_node_id_; -} - -inline long -ConnectionID::get_target_thread() const -{ - return target_thread_; -} - -inline long -ConnectionID::get_synapse_model_id() const -{ - return synapse_modelid_; -} - -inline long -ConnectionID::get_port() const -{ - return port_; -} - } // namespace #endif /* #ifndef CONNECTION_ID_H */ diff --git a/nestkernel/connection_impl.h b/nestkernel/connection_impl.h new file mode 100644 index 0000000000..39f933da6d --- /dev/null +++ b/nestkernel/connection_impl.h @@ -0,0 +1,125 @@ +/* + * connection_impl.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef CONNECTION_IMPL_H +#define CONNECTION_IMPL_H + +#include "connection.h" + +#include "connection_manager.h" +#include "delay_checker.h" +#include "nest_timeconverter.h" + +namespace nest +{ + +template < typename targetidentifierT > +void +Connection< targetidentifierT >::check_connection_( Node& dummy_target, + Node& source, + Node& target, + const size_t receptor_type ) +{ + // 1. does this connection support the event type sent by source + // try to send event from source to dummy_target + // this line might throw an exception + source.send_test_event( dummy_target, receptor_type, get_syn_id(), true ); + + // 2. does the target accept the event type sent by source + // try to send event from source to target + // this returns the port of the incoming connection + // p must be stored in the base class connection + // this line might throw an exception + target_.set_rport( source.send_test_event( target, receptor_type, get_syn_id(), false ) ); + + // 3. do the events sent by source mean the same thing as they are + // interpreted in target? + // note that we here use a bitwise and operation (&), because we interpret + // each bit in the signal type as a collection of individual flags + if ( not( source.sends_signal() & target.receives_signal() ) ) + { + throw IllegalConnection( "Source and target neuron are not compatible (e.g., spiking vs binary neuron)." ); + } + + target_.set_target( &target ); +} + +template < typename targetidentifierT > +void +Connection< targetidentifierT >::get_status( DictionaryDatum& d ) const +{ + def< double >( d, names::delay, syn_id_delay_.get_delay_ms() ); + target_.get_status( d ); +} + +template < typename targetidentifierT > +void +Connection< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& ) +{ + double delay; + if ( updateValue< double >( d, names::delay, delay ) ) + { + kernel::manager< ConnectionManager >.get_delay_checker().assert_valid_delay_ms( delay ); + syn_id_delay_.set_delay_ms( delay ); + } + // no call to target_.set_status() because target and rport cannot be changed +} + +template < typename targetidentifierT > +void +Connection< targetidentifierT >::check_synapse_params( const DictionaryDatum& ) const +{ +} + +template < typename targetidentifierT > +void +Connection< targetidentifierT >::calibrate( const TimeConverter& tc ) +{ + Time t = tc.from_old_steps( syn_id_delay_.delay ); + syn_id_delay_.delay = t.get_steps(); + + if ( syn_id_delay_.delay == 0 ) + { + syn_id_delay_.delay = 1; + } +} + +template < typename targetidentifierT > +void +Connection< targetidentifierT >::trigger_update_weight( const size_t, + const std::vector< spikecounter >&, + const double, + const CommonSynapseProperties& ) +{ + throw IllegalConnection( "Connection does not support updates that are triggered by a volume transmitter." ); +} + +template < typename targetidentifierT > +std::unique_ptr< SecondaryEvent > +Connection< targetidentifierT >::get_secondary_event() +{ + assert( false and "Non-primary connections have to provide get_secondary_event()" ); + return nullptr; +} +} // namespace nest + +#endif /* CONNECTION_IMPL_H */ diff --git a/nestkernel/connection_label.h b/nestkernel/connection_label.h index a20b55f850..5fa71b2a08 100644 --- a/nestkernel/connection_label.h +++ b/nestkernel/connection_label.h @@ -25,7 +25,7 @@ #include "dictdatum.h" #include "dictutils.h" -#include "nest.h" +#include "exceptions.h" #include "nest_names.h" namespace nest @@ -40,90 +40,6 @@ class ConnectorModel; */ const static long UNLABELED_CONNECTION = -1; -/** - * The class ConnectionLabel enables synapse model to be labeled by a positive - * integer. - * - * The label can be set / retrieved with the `names::synapse_label` - * property in the parameter dictionary of `Set/GetStatus` or `Connect`. - * Using the `GetConnections` function, synapses with the same label can be - * specified. - * - * The name of synapse models, which can be labeled, end with '_lbl'. - * @see nest::ConnectionManager::get_connections - */ -template < typename ConnectionT > -class ConnectionLabel : public ConnectionT -{ -public: - ConnectionLabel(); - - /** - * Get all properties of this connection and put them into a dictionary. - */ - void get_status( DictionaryDatum& d ) const; - - /** - * Set properties of this connection from the values given in dictionary. - * - * @note Target and Rport cannot be changed after a connection has been - * created. - */ - void set_status( const DictionaryDatum& d, ConnectorModel& cm ); - - long get_label() const; - -private: - long label_; -}; - -template < typename ConnectionT > -ConnectionLabel< ConnectionT >::ConnectionLabel() - : ConnectionT() - , label_( UNLABELED_CONNECTION ) -{ -} - -template < typename ConnectionT > -void -ConnectionLabel< ConnectionT >::get_status( DictionaryDatum& d ) const -{ - ConnectionT::get_status( d ); - def< long >( d, names::synapse_label, label_ ); - // override names::size_of from ConnectionT, - // as the size from ConnectionLabel< ConnectionT > is - // one long larger - def< long >( d, names::size_of, sizeof( *this ) ); -} - -template < typename ConnectionT > -void -ConnectionLabel< ConnectionT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) -{ - long lbl; - if ( updateValue< long >( d, names::synapse_label, lbl ) ) - { - if ( lbl >= 0 ) - { - label_ = lbl; - } - else - { - throw BadProperty( "Connection label must not be negative." ); - } - } - ConnectionT::set_status( d, cm ); -} - -template < typename ConnectionT > -inline long -ConnectionLabel< ConnectionT >::get_label() const -{ - return label_; -} - - } // namespace nest - #endif /* CONNECTION_LABEL_H */ diff --git a/nestkernel/connection_label_impl.h b/nestkernel/connection_label_impl.h new file mode 100644 index 0000000000..19e4facf16 --- /dev/null +++ b/nestkernel/connection_label_impl.h @@ -0,0 +1,121 @@ +/* + * connection_label_impl.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef CONNECTION_LABEL_IMPL_H +#define CONNECTION_LABEL_IMPL_H + +#include "dictdatum.h" +#include "dictutils.h" +#include "exceptions.h" +#include "nest_names.h" + +#include + +namespace nest +{ + + +/** + * The class ConnectionLabel enables synapse model to be labeled by a positive + * integer. + * + * The label can be set / retrieved with the `names::synapse_label` + * property in the parameter dictionary of `Set/GetStatus` or `Connect`. + * Using the `GetConnections` function, synapses with the same label can be + * specified. + * + * The name of synapse models, which can be labeled, end with '_lbl'. + * @see nest::ConnectionManager::get_connections + */ +template < typename ConnectionT > +class ConnectionLabel : public ConnectionT +{ +public: + ConnectionLabel(); + + /** + * Get all properties of this connection and put them into a dictionary. + */ + void get_status( DictionaryDatum& d ) const; + + /** + * Set properties of this connection from the values given in dictionary. + * + * @note Target and Rport cannot be changed after a connection has been + * created. + */ + void set_status( const DictionaryDatum& d, ConnectorModel& cm ); + + long get_label() const; + +private: + long label_; +}; + +template < typename ConnectionT > +ConnectionLabel< ConnectionT >::ConnectionLabel() + : ConnectionT() + , label_( UNLABELED_CONNECTION ) +{ +} + +template < typename ConnectionT > +void +ConnectionLabel< ConnectionT >::get_status( DictionaryDatum& d ) const +{ + ConnectionT::get_status( d ); + def< long >( d, names::synapse_label, label_ ); + // override names::size_of from ConnectionT, + // as the size from ConnectionLabel< ConnectionT > is + // one long larger + def< long >( d, names::size_of, sizeof( *this ) ); +} + +template < typename ConnectionT > +void +ConnectionLabel< ConnectionT >::set_status( const DictionaryDatum& d, ConnectorModel& cm ) +{ + long lbl; + if ( updateValue< long >( d, names::synapse_label, lbl ) ) + { + if ( lbl >= 0 ) + { + label_ = lbl; + } + else + { + throw BadProperty( "Connection label must not be negative." ); + } + } + ConnectionT::set_status( d, cm ); +} + +template < typename ConnectionT > +inline long +ConnectionLabel< ConnectionT >::get_label() const +{ + return label_; +} +} // namespace nest + + +#endif /* CONNECTION_LABEL_IMPL_H */ diff --git a/nestkernel/connection_manager.cpp b/nestkernel/connection_manager.cpp index de9307ce1a..c9a21a35a6 100644 --- a/nestkernel/connection_manager.cpp +++ b/nestkernel/connection_manager.cpp @@ -20,7 +20,7 @@ * */ -#include "connection_manager.h" +#include "connection_manager_impl.h" // Generated includes: #include "config.h" @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -41,26 +42,24 @@ // Includes from nestkernel: #include "clopath_archiving_node.h" #include "conn_builder.h" -#include "conn_builder_conngen.h" #include "conn_builder_factory.h" #include "connection_label.h" -#include "connection_manager_impl.h" #include "connector_base.h" -#include "connector_model.h" +#include "connector_model_impl.h" #include "delay_checker.h" -#include "eprop_archiving_node.h" #include "eprop_archiving_node_readout.h" #include "eprop_archiving_node_recurrent.h" #include "exceptions.h" #include "kernel_manager.h" -#include "mpi_manager_impl.h" +#include "logging_manager.h" +#include "model_manager.h" #include "nest_names.h" #include "nest_types.h" #include "node.h" +#include "node_manager.h" +#include "simulation_manager.h" #include "sonata_connector.h" -#include "stopwatch_impl.h" -#include "target_table_devices_impl.h" -#include "vp_manager_impl.h" +#include "sp_manager.h" // Includes from sli: #include "dictutils.h" @@ -68,8 +67,10 @@ #include "token.h" #include "tokenutils.h" +namespace nest +{ -nest::ConnectionManager::ConnectionManager() +ConnectionManager::ConnectionManager() : connruledict_( new Dictionary() ) , connbuilder_factories_() , thirdconnruledict_( new Dictionary() ) @@ -88,7 +89,7 @@ nest::ConnectionManager::ConnectionManager() { } -nest::ConnectionManager::~ConnectionManager() +ConnectionManager::~ConnectionManager() { // Memory leak on purpose! // The ConnectionManager is deleted, when the network is deleted, and @@ -99,7 +100,7 @@ nest::ConnectionManager::~ConnectionManager() } void -nest::ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_only ) +ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { if ( not adjust_number_of_threads_or_rng_only ) { @@ -126,7 +127,7 @@ nest::ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_ sw_construction_connect.reset(); } - const size_t num_threads = kernel().vp_manager.get_num_threads(); + const size_t num_threads = kernel::manager< VPManager >.get_num_threads(); connections_.resize( num_threads ); secondary_recv_buffer_pos_.resize( num_threads ); compressed_spike_data_.resize( 0 ); @@ -138,11 +139,11 @@ nest::ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_ // We need to obtain this while in serial context to avoid problems when // increasing the number of threads. - const size_t num_conn_models = kernel().model_manager.get_num_connection_models(); + const size_t num_conn_models = kernel::manager< ModelManager >.get_num_connection_models(); #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); connections_.at( tid ) = std::vector< ConnectorBase* >( num_conn_models ); secondary_recv_buffer_pos_.at( tid ) = std::vector< std::vector< size_t > >(); } // of omp parallel @@ -151,15 +152,15 @@ nest::ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_ target_table_.initialize(); target_table_devices_.initialize(); - std::vector< DelayChecker > tmp( kernel().vp_manager.get_num_threads() ); + std::vector< DelayChecker > tmp( kernel::manager< VPManager >.get_num_threads() ); delay_checkers_.swap( tmp ); - std::vector< std::vector< size_t > > tmp2( kernel().vp_manager.get_num_threads(), std::vector< size_t >() ); + std::vector< std::vector< size_t > > tmp2( kernel::manager< VPManager >.get_num_threads(), std::vector< size_t >() ); num_connections_.swap( tmp2 ); } void -nest::ConnectionManager::finalize( const bool adjust_number_of_threads_or_rng_only ) +ConnectionManager::finalize( const bool adjust_number_of_threads_or_rng_only ) { source_table_.finalize(); target_table_.finalize(); @@ -188,7 +189,7 @@ nest::ConnectionManager::finalize( const bool adjust_number_of_threads_or_rng_on } void -nest::ConnectionManager::set_status( const DictionaryDatum& d ) +ConnectionManager::set_status( const DictionaryDatum& d ) { for ( size_t i = 0; i < delay_checkers_.size(); ++i ) { @@ -196,7 +197,7 @@ nest::ConnectionManager::set_status( const DictionaryDatum& d ) } updateValue< bool >( d, names::keep_source_table, keep_source_table_ ); - if ( not keep_source_table_ and kernel().sp_manager.is_structural_plasticity_enabled() ) + if ( not keep_source_table_ and kernel::manager< SPManager >.is_structural_plasticity_enabled() ) { throw KernelException( "If structural plasticity is enabled, keep_source_table can not be set " @@ -212,14 +213,14 @@ nest::ConnectionManager::set_status( const DictionaryDatum& d ) } } -nest::DelayChecker& -nest::ConnectionManager::get_delay_checker() +DelayChecker& +ConnectionManager::get_delay_checker() { - return delay_checkers_[ kernel().vp_manager.get_thread_id() ]; + return delay_checkers_[ kernel::manager< VPManager >.get_thread_id() ]; } void -nest::ConnectionManager::get_status( DictionaryDatum& dict ) +ConnectionManager::get_status( DictionaryDatum& dict ) { update_delay_extrema_(); def< double >( dict, names::min_delay, Time( Time::step( min_delay_ ) ).get_ms() ); @@ -241,24 +242,24 @@ nest::ConnectionManager::get_status( DictionaryDatum& dict ) } DictionaryDatum -nest::ConnectionManager::get_synapse_status( const size_t source_node_id, +ConnectionManager::get_synapse_status( const size_t source_node_id, const size_t target_node_id, const size_t tid, const synindex syn_id, const size_t lcid ) const { - kernel().model_manager.assert_valid_syn_id( syn_id, kernel().vp_manager.get_thread_id() ); + kernel::manager< ModelManager >.assert_valid_syn_id( syn_id, kernel::manager< VPManager >.get_thread_id() ); DictionaryDatum dict( new Dictionary ); ( *dict )[ names::source ] = source_node_id; ( *dict )[ names::synapse_model ] = - LiteralDatum( kernel().model_manager.get_connection_model( syn_id, /* thread */ 0 ).get_name() ); + LiteralDatum( kernel::manager< ModelManager >.get_connection_model( syn_id, /* thread */ 0 ).get_name() ); ( *dict )[ names::target_thread ] = tid; ( *dict )[ names::synapse_id ] = syn_id; ( *dict )[ names::port ] = lcid; - const Node* source = kernel().node_manager.get_node_or_proxy( source_node_id, tid ); - const Node* target = kernel().node_manager.get_node_or_proxy( target_node_id, tid ); + const Node* source = kernel::manager< NodeManager >.get_node_or_proxy( source_node_id, tid ); + const Node* target = kernel::manager< NodeManager >.get_node_or_proxy( target_node_id, tid ); // synapses from neurons to neurons and from neurons to globally // receiving devices @@ -286,21 +287,21 @@ nest::ConnectionManager::get_synapse_status( const size_t source_node_id, } void -nest::ConnectionManager::set_synapse_status( const size_t source_node_id, +ConnectionManager::set_synapse_status( const size_t source_node_id, const size_t target_node_id, const size_t tid, const synindex syn_id, const size_t lcid, const DictionaryDatum& dict ) { - kernel().model_manager.assert_valid_syn_id( syn_id, kernel().vp_manager.get_thread_id() ); + kernel::manager< ModelManager >.assert_valid_syn_id( syn_id, kernel::manager< VPManager >.get_thread_id() ); - const Node* source = kernel().node_manager.get_node_or_proxy( source_node_id, tid ); - const Node* target = kernel().node_manager.get_node_or_proxy( target_node_id, tid ); + const Node* source = kernel::manager< NodeManager >.get_node_or_proxy( source_node_id, tid ); + const Node* target = kernel::manager< NodeManager >.get_node_or_proxy( target_node_id, tid ); try { - ConnectorModel& cm = kernel().model_manager.get_connection_model( syn_id, tid ); + ConnectorModel& cm = kernel::manager< ModelManager >.get_connection_model( syn_id, tid ); // synapses from neurons to neurons and from neurons to globally // receiving devices if ( ( source->has_proxies() and target->has_proxies() and connections_[ tid ][ syn_id ] ) @@ -327,7 +328,7 @@ nest::ConnectionManager::set_synapse_status( const size_t source_node_id, { throw BadProperty( String::compose( "Setting status of '%1' connecting from node ID %2 to node ID %3 via port %4: %5", - kernel().model_manager.get_connection_model( syn_id, tid ).get_name(), + kernel::manager< ModelManager >.get_connection_model( syn_id, tid ).get_name(), source_node_id, target_node_id, lcid, @@ -336,7 +337,7 @@ nest::ConnectionManager::set_synapse_status( const size_t source_node_id, } void -nest::ConnectionManager::delete_connections_() +ConnectionManager::delete_connections_() { for ( size_t tid = 0; tid < connections_.size(); ++tid ) { @@ -347,8 +348,8 @@ nest::ConnectionManager::delete_connections_() } } -const nest::Time -nest::ConnectionManager::get_min_delay_time_() const +const Time +ConnectionManager::get_min_delay_time_() const { Time min_delay = Time::pos_inf(); @@ -361,8 +362,8 @@ nest::ConnectionManager::get_min_delay_time_() const return min_delay; } -const nest::Time -nest::ConnectionManager::get_max_delay_time_() const +const Time +ConnectionManager::get_max_delay_time_() const { Time max_delay = Time::get_resolution(); @@ -376,7 +377,7 @@ nest::ConnectionManager::get_max_delay_time_() const } bool -nest::ConnectionManager::get_user_set_delay_extrema() const +ConnectionManager::get_user_set_delay_extrema() const { bool user_set_delay_extrema = false; @@ -389,8 +390,8 @@ nest::ConnectionManager::get_user_set_delay_extrema() const return user_set_delay_extrema; } -nest::BipartiteConnBuilder* -nest::ConnectionManager::get_conn_builder( const std::string& name, +BipartiteConnBuilder* +ConnectionManager::get_conn_builder( const std::string& name, NodeCollectionPTR sources, NodeCollectionPTR targets, ThirdOutBuilder* third_out, @@ -409,8 +410,8 @@ nest::ConnectionManager::get_conn_builder( const std::string& name, return cb; } -nest::ThirdOutBuilder* -nest::ConnectionManager::get_third_conn_builder( const std::string& name, +ThirdOutBuilder* +ConnectionManager::get_third_conn_builder( const std::string& name, NodeCollectionPTR sources, NodeCollectionPTR targets, ThirdInBuilder* third_in, @@ -430,21 +431,21 @@ nest::ConnectionManager::get_third_conn_builder( const std::string& name, } void -nest::ConnectionManager::calibrate( const TimeConverter& tc ) +ConnectionManager::calibrate( const TimeConverter& tc ) { - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { delay_checkers_[ tid ].calibrate( tc ); } } void -nest::ConnectionManager::connect( NodeCollectionPTR sources, +ConnectionManager::connect( NodeCollectionPTR sources, NodeCollectionPTR targets, const DictionaryDatum& conn_spec, const std::vector< DictionaryDatum >& syn_specs ) { - kernel().node_manager.update_thread_local_node_data(); + kernel::manager< NodeManager >.update_thread_local_node_data(); if ( sources->empty() ) { @@ -490,9 +491,9 @@ nest::ConnectionManager::connect( NodeCollectionPTR sources, void -nest::ConnectionManager::update_delay_extrema_() +ConnectionManager::update_delay_extrema_() { - if ( kernel().simulation_manager.has_been_simulated() ) + if ( kernel::manager< SimulationManager >.has_been_simulated() ) { // Once simulation has started, min/max_delay can no longer change, // so there is nothing to update. @@ -506,8 +507,8 @@ nest::ConnectionManager::update_delay_extrema_() { // If no min/max_delay is set explicitly, then the default delay used by the // SPBuilders have to be respected for min/max_delay. - min_delay_ = std::min( min_delay_, kernel().sp_manager.builder_min_delay() ); - max_delay_ = std::max( max_delay_, kernel().sp_manager.builder_max_delay() ); + min_delay_ = std::min( min_delay_, kernel::manager< SPManager >.builder_min_delay() ); + max_delay_ = std::max( max_delay_, kernel::manager< SPManager >.builder_max_delay() ); } // If the user explicitly set min/max_delay, this happend on all MPI ranks, @@ -515,17 +516,18 @@ nest::ConnectionManager::update_delay_extrema_() // explicitly, Connect() cannot induce new extrema. Thuse, we only need to communicate // with other ranks if the user has not set the extrema and connections may have // been created. - if ( not kernel().connection_manager.get_user_set_delay_extrema() - and kernel().connection_manager.connections_have_changed() and kernel().mpi_manager.get_num_processes() > 1 ) + if ( not kernel::manager< ConnectionManager >.get_user_set_delay_extrema() + and kernel::manager< ConnectionManager >.connections_have_changed() + and kernel::manager< MPIManager >.get_num_processes() > 1 ) { - std::vector< long > min_delays( kernel().mpi_manager.get_num_processes() ); - min_delays[ kernel().mpi_manager.get_rank() ] = min_delay_; - kernel().mpi_manager.communicate( min_delays ); + std::vector< long > min_delays( kernel::manager< MPIManager >.get_num_processes() ); + min_delays[ kernel::manager< MPIManager >.get_rank() ] = min_delay_; + kernel::manager< MPIManager >.communicate( min_delays ); min_delay_ = *std::min_element( min_delays.begin(), min_delays.end() ); - std::vector< long > max_delays( kernel().mpi_manager.get_num_processes() ); - max_delays[ kernel().mpi_manager.get_rank() ] = max_delay_; - kernel().mpi_manager.communicate( max_delays ); + std::vector< long > max_delays( kernel::manager< MPIManager >.get_num_processes() ); + max_delays[ kernel::manager< MPIManager >.get_rank() ] = max_delay_; + kernel::manager< MPIManager >.communicate( max_delays ); max_delay_ = *std::max_element( max_delays.begin(), max_delays.end() ); } @@ -537,7 +539,7 @@ nest::ConnectionManager::update_delay_extrema_() // node ID node thread syn_id dict delay weight void -nest::ConnectionManager::connect( const size_t snode_id, +ConnectionManager::connect( const size_t snode_id, Node* target, size_t target_thread, const synindex syn_id, @@ -545,9 +547,9 @@ nest::ConnectionManager::connect( const size_t snode_id, const double delay, const double weight ) { - kernel().model_manager.assert_valid_syn_id( syn_id, kernel().vp_manager.get_thread_id() ); + kernel::manager< ModelManager >.assert_valid_syn_id( syn_id, kernel::manager< VPManager >.get_thread_id() ); - Node* source = kernel().node_manager.get_node_or_proxy( snode_id, target_thread ); + Node* source = kernel::manager< NodeManager >.get_node_or_proxy( snode_id, target_thread ); ConnectionType connection_type = connection_required( source, target, target_thread ); @@ -569,23 +571,23 @@ nest::ConnectionManager::connect( const size_t snode_id, // node_id node_id dict syn_id bool -nest::ConnectionManager::connect( const size_t snode_id, +ConnectionManager::connect( const size_t snode_id, const size_t tnode_id, const DictionaryDatum& params, const synindex syn_id ) { - kernel().model_manager.assert_valid_syn_id( syn_id, kernel().vp_manager.get_thread_id() ); + kernel::manager< ModelManager >.assert_valid_syn_id( syn_id, kernel::manager< VPManager >.get_thread_id() ); - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); - if ( not kernel().node_manager.is_local_node_id( tnode_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( tnode_id ) ) { return false; } - Node* target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); - Node* source = kernel().node_manager.get_node_or_proxy( snode_id, target_thread ); + Node* source = kernel::manager< NodeManager >.get_node_or_proxy( snode_id, target_thread ); ConnectionType connection_type = connection_required( source, target, target_thread ); bool connected = true; @@ -610,7 +612,7 @@ nest::ConnectionManager::connect( const size_t snode_id, } void -nest::ConnectionManager::connect_arrays( long* sources, +ConnectionManager::connect_arrays( long* sources, long* targets, double* weights, double* delays, @@ -622,7 +624,7 @@ nest::ConnectionManager::connect_arrays( long* sources, // only place, where stopwatch sw_construction_connect is needed in addition to nestmodule.cpp sw_construction_connect.start(); - kernel().node_manager.update_thread_local_node_data(); + kernel::manager< NodeManager >.update_thread_local_node_data(); // Mapping pointers to the first parameter value of each parameter to their respective names. // The bool indicates whether the value is an integer or not, and is determined at a later point. @@ -638,13 +640,13 @@ nest::ConnectionManager::connect_arrays( long* sources, } } - const auto synapse_model_id = kernel().model_manager.get_synapse_model_id( syn_model ); - const auto syn_model_defaults = kernel().model_manager.get_connector_defaults( synapse_model_id ); + const auto synapse_model_id = kernel::manager< ModelManager >.get_synapse_model_id( syn_model ); + const auto syn_model_defaults = kernel::manager< ModelManager >.get_connector_defaults( synapse_model_id ); // Dictionary holding additional synapse parameters, passed to the connect call. std::vector< DictionaryDatum > param_dicts; - param_dicts.reserve( kernel().vp_manager.get_num_threads() ); - for ( size_t i = 0; i < kernel().vp_manager.get_num_threads(); ++i ) + param_dicts.reserve( kernel::manager< VPManager >.get_num_threads() ); + for ( size_t i = 0; i < kernel::manager< VPManager >.get_num_threads(); ++i ) { param_dicts.emplace_back( new Dictionary ); for ( auto& param_key : p_keys ) @@ -687,11 +689,12 @@ nest::ConnectionManager::connect_arrays( long* sources, set_connections_have_changed(); // Vector for storing exceptions raised by threads. - std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised( kernel().vp_manager.get_num_threads() ); + std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised( + kernel::manager< VPManager >.get_num_threads() ); #pragma omp parallel { - const auto tid = kernel().vp_manager.get_thread_id(); + const auto tid = kernel::manager< VPManager >.get_thread_id(); try { auto s = sources; @@ -704,15 +707,15 @@ nest::ConnectionManager::connect_arrays( long* sources, for ( ; s != sources + n; ++s, ++t, ++index_counter ) { - if ( 0 >= *s or static_cast< size_t >( *s ) > kernel().node_manager.size() ) + if ( 0 >= *s or static_cast< size_t >( *s ) > kernel::manager< NodeManager >.size() ) { throw UnknownNode( *s ); } - if ( 0 >= *t or static_cast< size_t >( *t ) > kernel().node_manager.size() ) + if ( 0 >= *t or static_cast< size_t >( *t ) > kernel::manager< NodeManager >.size() ) { throw UnknownNode( *t ); } - auto target_node = kernel().node_manager.get_node_or_proxy( *t, tid ); + auto target_node = kernel::manager< NodeManager >.get_node_or_proxy( *t, tid ); if ( target_node->is_proxy() ) { increment_wd( w, d ); @@ -775,7 +778,7 @@ nest::ConnectionManager::connect_arrays( long* sources, } } // check if any exceptions have been raised - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { if ( exceptions_raised.at( tid ).get() ) { @@ -787,10 +790,10 @@ nest::ConnectionManager::connect_arrays( long* sources, } void -nest::ConnectionManager::connect_sonata( const DictionaryDatum& graph_specs, const long hyberslab_size ) +ConnectionManager::connect_sonata( const DictionaryDatum& graph_specs, const long hyberslab_size ) { #ifdef HAVE_HDF5 - kernel().node_manager.update_thread_local_node_data(); + kernel::manager< NodeManager >.update_thread_local_node_data(); SonataConnector sonata_connector( graph_specs, hyberslab_size ); @@ -804,7 +807,7 @@ nest::ConnectionManager::connect_sonata( const DictionaryDatum& graph_specs, con } void -nest::ConnectionManager::connect_tripartite( NodeCollectionPTR sources, +ConnectionManager::connect_tripartite( NodeCollectionPTR sources, NodeCollectionPTR targets, NodeCollectionPTR third, const DictionaryDatum& conn_spec, @@ -845,7 +848,7 @@ nest::ConnectionManager::connect_tripartite( NodeCollectionPTR sources, 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 ] ); - kernel().node_manager.update_thread_local_node_data(); + kernel::manager< NodeManager >.update_thread_local_node_data(); ConnBuilder cb( primary_rule, third_rule, sources, targets, third, conn_spec, third_conn_spec, syn_specs ); @@ -867,7 +870,7 @@ nest::ConnectionManager::connect_tripartite( NodeCollectionPTR sources, void -nest::ConnectionManager::connect_( Node& source, +ConnectionManager::connect_( Node& source, Node& target, const size_t s_node_id, const size_t tid, @@ -876,7 +879,7 @@ nest::ConnectionManager::connect_( Node& source, const double delay, const double weight ) { - ConnectorModel& conn_model = kernel().model_manager.get_connection_model( syn_id, tid ); + ConnectorModel& conn_model = kernel::manager< ModelManager >.get_connection_model( syn_id, tid ); const bool clopath_archiving = conn_model.has_property( ConnectionModelProperties::REQUIRES_CLOPATH_ARCHIVING ); if ( clopath_archiving and not dynamic_cast< ClopathArchivingNode* >( &target ) ) @@ -923,7 +926,7 @@ nest::ConnectionManager::connect_( Node& source, } void -nest::ConnectionManager::connect_to_device_( Node& source, +ConnectionManager::connect_to_device_( Node& source, Node& target, const size_t s_node_id, const size_t tid, @@ -939,7 +942,7 @@ nest::ConnectionManager::connect_to_device_( Node& source, } void -nest::ConnectionManager::connect_from_device_( Node& source, +ConnectionManager::connect_from_device_( Node& source, Node& target, const size_t tid, const synindex syn_id, @@ -954,7 +957,7 @@ nest::ConnectionManager::connect_from_device_( Node& source, } void -nest::ConnectionManager::increase_connection_count( const size_t tid, const synindex syn_id ) +ConnectionManager::increase_connection_count( const size_t tid, const synindex syn_id ) { if ( num_connections_[ tid ].size() <= syn_id ) { @@ -972,7 +975,7 @@ nest::ConnectionManager::increase_connection_count( const size_t tid, const syni } size_t -nest::ConnectionManager::find_connection( const size_t tid, +ConnectionManager::find_connection( const size_t tid, const synindex syn_id, const size_t snode_id, const size_t tnode_id ) @@ -999,10 +1002,7 @@ nest::ConnectionManager::find_connection( const size_t tid, } void -nest::ConnectionManager::disconnect( const size_t tid, - const synindex syn_id, - const size_t snode_id, - const size_t tnode_id ) +ConnectionManager::disconnect( const size_t tid, const synindex syn_id, const size_t snode_id, const size_t tnode_id ) { assert( syn_id != invalid_synindex ); @@ -1021,11 +1021,11 @@ nest::ConnectionManager::disconnect( const size_t tid, } void -nest::ConnectionManager::trigger_update_weight( const long vt_id, +ConnectionManager::trigger_update_weight( const long vt_id, const std::vector< spikecounter >& dopa_spikes, const double t_trig ) { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); for ( std::vector< ConnectorBase* >::iterator it = connections_[ tid ].begin(); it != connections_[ tid ].end(); ++it ) @@ -1033,13 +1033,13 @@ nest::ConnectionManager::trigger_update_weight( const long vt_id, if ( *it ) { ( *it )->trigger_update_weight( - vt_id, tid, dopa_spikes, t_trig, kernel().model_manager.get_connection_models( tid ) ); + vt_id, tid, dopa_spikes, t_trig, kernel::manager< ModelManager >.get_connection_models( tid ) ); } } } size_t -nest::ConnectionManager::get_num_target_data( const size_t tid ) const +ConnectionManager::get_num_target_data( const size_t tid ) const { size_t num_connections = 0; for ( synindex syn_id = 0; syn_id < connections_[ tid ].size(); ++syn_id ) @@ -1053,7 +1053,7 @@ nest::ConnectionManager::get_num_target_data( const size_t tid ) const } size_t -nest::ConnectionManager::get_num_connections() const +ConnectionManager::get_num_connections() const { size_t num_connections = 0; for ( size_t t = 0; t < num_connections_.size(); ++t ) @@ -1068,7 +1068,7 @@ nest::ConnectionManager::get_num_connections() const } size_t -nest::ConnectionManager::get_num_connections( const synindex syn_id ) const +ConnectionManager::get_num_connections( const synindex syn_id ) const { size_t num_connections = 0; for ( size_t t = 0; t < num_connections_.size(); ++t ) @@ -1083,7 +1083,7 @@ nest::ConnectionManager::get_num_connections( const synindex syn_id ) const } ArrayDatum -nest::ConnectionManager::get_connections( const DictionaryDatum& params ) +ConnectionManager::get_connections( const DictionaryDatum& params ) { std::deque< ConnectionID > connectome; const Token& source_t = params->lookup( names::source ); @@ -1123,12 +1123,12 @@ nest::ConnectionManager::get_connections( const DictionaryDatum& params ) // Check whether waveform relaxation is used on any MPI process; // needs to be called before update_connection_infrastructure since // it resizes coefficient arrays for secondary events - kernel().node_manager.check_wfr_use(); + kernel::manager< NodeManager >.check_wfr_use(); #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); - kernel().simulation_manager.update_connection_infrastructure( tid ); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); + kernel::manager< SimulationManager >.update_connection_infrastructure( tid ); } } @@ -1138,12 +1138,12 @@ nest::ConnectionManager::get_connections( const DictionaryDatum& params ) { const std::string synmodel_name = getValue< std::string >( syn_model_t ); // The following throws UnknownSynapseType for invalid synmodel_name - syn_id = kernel().model_manager.get_synapse_model_id( synmodel_name ); + syn_id = kernel::manager< ModelManager >.get_synapse_model_id( synmodel_name ); get_connections( connectome, source_a, target_a, syn_id, synapse_label ); } else { - for ( syn_id = 0; syn_id < kernel().model_manager.get_num_connection_models(); ++syn_id ) + for ( syn_id = 0; syn_id < kernel::manager< ModelManager >.get_num_connection_models(); ++syn_id ) { get_connections( connectome, source_a, target_a, syn_id, synapse_label ); } @@ -1165,8 +1165,8 @@ nest::ConnectionManager::get_connections( const DictionaryDatum& params ) // Helper method which removes ConnectionIDs from input deque and // appends them to output deque. -static inline std::deque< nest::ConnectionID >& -extend_connectome( std::deque< nest::ConnectionID >& out, std::deque< nest::ConnectionID >& in ) +static inline std::deque< ConnectionID >& +extend_connectome( std::deque< ConnectionID >& out, std::deque< ConnectionID >& in ) { while ( not in.empty() ) { @@ -1178,7 +1178,7 @@ extend_connectome( std::deque< nest::ConnectionID >& out, std::deque< nest::Conn } void -nest::ConnectionManager::split_to_neuron_device_vectors_( const size_t tid, +ConnectionManager::split_to_neuron_device_vectors_( const size_t tid, NodeCollectionPTR nodecollection, std::vector< size_t >& neuron_node_ids, std::vector< size_t >& device_node_ids ) const @@ -1187,7 +1187,7 @@ nest::ConnectionManager::split_to_neuron_device_vectors_( const size_t tid, for ( ; t_id < nodecollection->end(); ++t_id ) { const size_t node_id = ( *t_id ).node_id; - const auto node = kernel().node_manager.get_node_or_proxy( node_id, tid ); + const auto node = kernel::manager< NodeManager >.get_node_or_proxy( node_id, tid ); // Normal neuron nodes have proxies. Globally receiving devices, e.g. volume transmitter, don't have a local // receiver, but are connected in the same way as normal neuron nodes. Therefore they have to be treated as such // here. @@ -1203,7 +1203,7 @@ nest::ConnectionManager::split_to_neuron_device_vectors_( const size_t tid, } void -nest::ConnectionManager::get_connections_( const size_t tid, +ConnectionManager::get_connections_( const size_t tid, std::deque< ConnectionID >& conns_in_thread, NodeCollectionPTR, NodeCollectionPTR, @@ -1354,7 +1354,7 @@ nest::ConnectionManager::get_connections( std::deque< ConnectionID >& connectome throw KernelException( "Invalid attempt to access connection information: source table was cleared." ); } - size_t tid = kernel().vp_manager.get_thread_id(); + size_t tid = kernel::manager< VPManager >.get_thread_id(); std::deque< ConnectionID > conns_in_thread; @@ -1382,7 +1382,7 @@ nest::ConnectionManager::get_connections( std::deque< ConnectionID >& connectome } void -nest::ConnectionManager::get_source_node_ids_( const size_t tid, +ConnectionManager::get_source_node_ids_( const size_t tid, const synindex syn_id, const size_t tnode_id, std::vector< size_t >& sources ) @@ -1396,7 +1396,7 @@ nest::ConnectionManager::get_source_node_ids_( const size_t tid, } void -nest::ConnectionManager::get_sources( const std::vector< size_t >& targets, +ConnectionManager::get_sources( const std::vector< size_t >& targets, const size_t syn_id, std::vector< std::vector< size_t > >& sources ) { @@ -1406,7 +1406,7 @@ nest::ConnectionManager::get_sources( const std::vector< size_t >& targets, ( *i ).clear(); } - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { for ( size_t i = 0; i < targets.size(); ++i ) { @@ -1416,7 +1416,7 @@ nest::ConnectionManager::get_sources( const std::vector< size_t >& targets, } void -nest::ConnectionManager::get_targets( const std::vector< size_t >& sources, +ConnectionManager::get_targets( const std::vector< size_t >& sources, const size_t syn_id, const std::string& post_synaptic_element, std::vector< std::vector< size_t > >& targets ) @@ -1427,7 +1427,7 @@ nest::ConnectionManager::get_targets( const std::vector< size_t >& sources, ( *i ).clear(); } - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { for ( size_t i = 0; i < sources.size(); ++i ) { @@ -1458,33 +1458,33 @@ nest::ConnectionManager::sort_connections( const size_t tid ) } void -nest::ConnectionManager::compute_target_data_buffer_size() +ConnectionManager::compute_target_data_buffer_size() { // Determine number of target data on this rank. Since each thread // has its own data structures, we need to count connections on every // thread separately to compute the total number of sources. size_t num_target_data = 0; - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { num_target_data += get_num_target_data( tid ); } // Determine maximum number of target data across all ranks, because // all ranks need identically sized buffers. - std::vector< long > global_num_target_data( kernel().mpi_manager.get_num_processes() ); - global_num_target_data[ kernel().mpi_manager.get_rank() ] = num_target_data; - kernel().mpi_manager.communicate( global_num_target_data ); + std::vector< long > global_num_target_data( kernel::manager< MPIManager >.get_num_processes() ); + global_num_target_data[ kernel::manager< MPIManager >.get_rank() ] = num_target_data; + kernel::manager< MPIManager >.communicate( global_num_target_data ); const size_t max_num_target_data = *std::max_element( global_num_target_data.begin(), global_num_target_data.end() ); // MPI buffers should have at least two entries per process - const size_t min_num_target_data = 2 * kernel().mpi_manager.get_num_processes(); + const size_t min_num_target_data = 2 * kernel::manager< MPIManager >.get_num_processes(); // Adjust target data buffers accordingly - kernel().mpi_manager.set_buffer_size_target_data( std::max( min_num_target_data, max_num_target_data ) ); + kernel::manager< MPIManager >.set_buffer_size_target_data( std::max( min_num_target_data, max_num_target_data ) ); } void -nest::ConnectionManager::compute_compressed_secondary_recv_buffer_positions( const size_t tid ) +ConnectionManager::compute_compressed_secondary_recv_buffer_positions( const size_t tid ) { #pragma omp single { @@ -1501,7 +1501,7 @@ nest::ConnectionManager::compute_compressed_secondary_recv_buffer_positions( con if ( connections_[ tid ][ syn_id ] ) { - ConnectorModel& conn_model = kernel().model_manager.get_connection_model( syn_id, tid ); + ConnectorModel& conn_model = kernel::manager< ModelManager >.get_connection_model( syn_id, tid ); const bool is_primary = conn_model.has_property( ConnectionModelProperties::IS_PRIMARY ); if ( not is_primary ) @@ -1516,25 +1516,25 @@ nest::ConnectionManager::compute_compressed_secondary_recv_buffer_positions( con { const size_t source_node_id = source_table_.get_node_id( tid, syn_id, lcid ); const size_t sg_s_id = source_table_.pack_source_node_id_and_syn_id( source_node_id, syn_id ); - const size_t source_rank = kernel().mpi_manager.get_process_id_of_node_id( source_node_id ); + const size_t source_rank = kernel::manager< MPIManager >.get_process_id_of_node_id( source_node_id ); positions[ lcid ] = buffer_pos_of_source_node_id_syn_id_[ sg_s_id ] - + kernel().mpi_manager.get_recv_displacement_secondary_events_in_int( source_rank ); + + kernel::manager< MPIManager >.get_recv_displacement_secondary_events_in_int( source_rank ); } } } } } -nest::ConnectionManager::ConnectionType -nest::ConnectionManager::connection_required( Node*& source, Node*& target, size_t tid ) +ConnectionManager::ConnectionType +ConnectionManager::connection_required( Node*& source, Node*& target, size_t tid ) { // The caller has to check and guarantee that the target is not a // proxy and that it is on thread tid. assert( not target->is_proxy() ); size_t target_vp = target->get_vp(); - assert( kernel().vp_manager.is_local_vp( target_vp ) ); - assert( kernel().vp_manager.vp_to_thread( target_vp ) == tid ); + assert( kernel::manager< VPManager >.is_local_vp( target_vp ) ); + assert( kernel::manager< VPManager >.vp_to_thread( target_vp ) == tid ); // Connections to nodes with proxies (neurons or devices with // proxies) which are local to tid have always to be @@ -1562,7 +1562,7 @@ nest::ConnectionManager::connection_required( Node*& source, Node*& target, size // source may be a proxy on tid. if ( target->one_node_per_process() ) { - if ( kernel().node_manager.is_local_node( source ) ) + if ( kernel::manager< NodeManager >.is_local_node( source ) ) { return CONNECT_TO_DEVICE; } @@ -1588,14 +1588,14 @@ nest::ConnectionManager::connection_required( Node*& source, Node*& target, size if ( not source->has_proxies() ) { const size_t target_node_id = target->get_node_id(); - target_vp = kernel().vp_manager.node_id_to_vp( target_node_id ); - const bool target_vp_local = kernel().vp_manager.is_local_vp( target_vp ); - const size_t target_thread = kernel().vp_manager.vp_to_thread( target_vp ); + target_vp = kernel::manager< VPManager >.node_id_to_vp( target_node_id ); + const bool target_vp_local = kernel::manager< VPManager >.is_local_vp( target_vp ); + const size_t target_thread = kernel::manager< VPManager >.vp_to_thread( target_vp ); if ( target_vp_local and target_thread == tid ) { const size_t source_node_id = source->get_node_id(); - source = kernel().node_manager.get_node_or_proxy( source_node_id, target_thread ); + source = kernel::manager< NodeManager >.get_node_or_proxy( source_node_id, target_thread ); return CONNECT_FROM_DEVICE; } } @@ -1608,7 +1608,7 @@ nest::ConnectionManager::connection_required( Node*& source, Node*& target, size { if ( source->has_proxies() ) { - target = kernel().node_manager.get_node_or_proxy( target->get_node_id(), tid ); + target = kernel::manager< NodeManager >.get_node_or_proxy( target->get_node_id(), tid ); return CONNECT; } @@ -1619,7 +1619,7 @@ nest::ConnectionManager::connection_required( Node*& source, Node*& target, size } void -nest::ConnectionManager::set_stdp_eps( const double stdp_eps ) +ConnectionManager::set_stdp_eps( const double stdp_eps ) { if ( not( stdp_eps < Time::get_resolution().get_ms() ) ) { @@ -1648,26 +1648,26 @@ nest::ConnectionManager::set_stdp_eps( const double stdp_eps ) // recv_buffer can not be a const reference as iterators used in // secondary events must not be const bool -nest::ConnectionManager::deliver_secondary_events( const size_t tid, +ConnectionManager::deliver_secondary_events( const size_t tid, const bool called_from_wfr_update, std::vector< unsigned int >& recv_buffer ) { - const std::vector< ConnectorModel* >& cm = kernel().model_manager.get_connection_models( tid ); - const Time stamp = - kernel().simulation_manager.get_slice_origin() + Time::step( 1 - kernel().connection_manager.get_min_delay() ); + const std::vector< ConnectorModel* >& cm = kernel::manager< ModelManager >.get_connection_models( tid ); + const Time stamp = kernel::manager< SimulationManager >.get_slice_origin() + + Time::step( 1 - kernel::manager< ConnectionManager >.get_min_delay() ); const std::vector< std::vector< size_t > >& positions_tid = secondary_recv_buffer_pos_[ tid ]; const synindex syn_id_end = positions_tid.size(); for ( synindex syn_id = 0; syn_id < syn_id_end; ++syn_id ) { - const ConnectorModel& conn_model = kernel().model_manager.get_connection_model( syn_id, tid ); + const ConnectorModel& conn_model = kernel::manager< ModelManager >.get_connection_model( syn_id, tid ); const bool supports_wfr = conn_model.has_property( ConnectionModelProperties::SUPPORTS_WFR ); if ( not called_from_wfr_update or supports_wfr ) { if ( positions_tid[ syn_id ].size() > 0 ) { std::unique_ptr< SecondaryEvent > prototype = - kernel().model_manager.get_secondary_event_prototype( syn_id, tid ); + kernel::manager< ModelManager >.get_secondary_event_prototype( syn_id, tid ); size_t lcid = 0; const size_t lcid_end = positions_tid[ syn_id ].size(); @@ -1688,22 +1688,22 @@ nest::ConnectionManager::deliver_secondary_events( const size_t tid, // Read waveform relaxation done marker from last position in every // chunk bool done = true; - for ( size_t rank = 0; rank < kernel().mpi_manager.get_num_processes(); ++rank ) + for ( size_t rank = 0; rank < kernel::manager< MPIManager >.get_num_processes(); ++rank ) { - done = - done and recv_buffer[ kernel().mpi_manager.get_done_marker_position_in_secondary_events_recv_buffer( rank ) ]; + done = done + and recv_buffer[ kernel::manager< MPIManager >.get_done_marker_position_in_secondary_events_recv_buffer( rank ) ]; } return done; } void -nest::ConnectionManager::compress_secondary_send_buffer_pos( const size_t tid ) +ConnectionManager::compress_secondary_send_buffer_pos( const size_t tid ) { target_table_.compress_secondary_send_buffer_pos( tid ); } void -nest::ConnectionManager::remove_disabled_connections_( const size_t tid ) +ConnectionManager::remove_disabled_connections_( const size_t tid ) { assert( use_compressed_spikes_ ); @@ -1729,32 +1729,33 @@ nest::ConnectionManager::remove_disabled_connections_( const size_t tid ) } void -nest::ConnectionManager::resize_connections() +ConnectionManager::resize_connections() { - kernel().vp_manager.assert_thread_parallel(); + kernel::manager< VPManager >.assert_thread_parallel(); - connections_.at( kernel().vp_manager.get_thread_id() ).resize( kernel().model_manager.get_num_connection_models() ); + connections_.at( kernel::manager< VPManager >.get_thread_id() ) + .resize( kernel::manager< ModelManager >.get_num_connection_models() ); source_table_.resize_sources(); target_table_devices_.resize_to_number_of_synapse_types(); } void -nest::ConnectionManager::sync_has_primary_connections() +ConnectionManager::sync_has_primary_connections() { - has_primary_connections_ = kernel().mpi_manager.any_true( has_primary_connections_ ); + has_primary_connections_ = kernel::manager< MPIManager >.any_true( has_primary_connections_ ); } void -nest::ConnectionManager::check_secondary_connections_exist() +ConnectionManager::check_secondary_connections_exist() { - secondary_connections_exist_ = kernel().mpi_manager.any_true( secondary_connections_exist_ ); + secondary_connections_exist_ = kernel::manager< MPIManager >.any_true( secondary_connections_exist_ ); } void -nest::ConnectionManager::set_connections_have_changed() +ConnectionManager::set_connections_have_changed() { - assert( kernel().vp_manager.get_thread_id() == 0 ); + assert( kernel::manager< VPManager >.get_thread_id() == 0 ); if ( get_connections_has_been_called_ ) { @@ -1769,14 +1770,14 @@ nest::ConnectionManager::set_connections_have_changed() } void -nest::ConnectionManager::unset_connections_have_changed() +ConnectionManager::unset_connections_have_changed() { connections_have_changed_ = false; } void -nest::ConnectionManager::collect_compressed_spike_data( const size_t tid ) +ConnectionManager::collect_compressed_spike_data( const size_t tid ) { if ( use_compressed_spikes_ ) { @@ -1787,9 +1788,9 @@ nest::ConnectionManager::collect_compressed_spike_data( const size_t tid ) } // of omp single; implicit barrier source_table_.collect_compressible_sources( tid ); - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); #pragma omp single { source_table_.fill_compressed_spike_data( compressed_spike_data_ ); @@ -1798,7 +1799,7 @@ nest::ConnectionManager::collect_compressed_spike_data( const size_t tid ) } bool -nest::ConnectionManager::fill_target_buffer( const size_t tid, +ConnectionManager::fill_target_buffer( const size_t tid, const size_t rank_start, const size_t rank_end, std::vector< TargetData >& send_buffer_target_data, @@ -1818,13 +1819,13 @@ nest::ConnectionManager::fill_target_buffer( const size_t tid, do { - const auto& conn_model = kernel().model_manager.get_connection_model( syn_id, tid ); + const auto& conn_model = kernel::manager< ModelManager >.get_connection_model( syn_id, tid ); const bool is_primary = conn_model.has_property( ConnectionModelProperties::IS_PRIMARY ); while ( source_2_idx != csd_maps.at( syn_id ).end() ) { const auto source_gid = source_2_idx->first; - const auto source_rank = kernel().mpi_manager.get_process_id_of_node_id( source_gid ); + const auto source_rank = kernel::manager< MPIManager >.get_process_id_of_node_id( source_gid ); if ( not( rank_start <= source_rank and source_rank < rank_end ) ) { // We are not responsible for this source. @@ -1849,8 +1850,8 @@ nest::ConnectionManager::fill_target_buffer( const size_t tid, next_target_data.set_is_primary( is_primary ); next_target_data.reset_marker(); next_target_data.set_source_tid( - kernel().vp_manager.vp_to_thread( kernel().vp_manager.node_id_to_vp( source_gid ) ) ); - next_target_data.set_source_lid( kernel().vp_manager.node_id_to_lid( source_gid ) ); + kernel::manager< VPManager >.vp_to_thread( kernel::manager< VPManager >.node_id_to_vp( source_gid ) ) ); + next_target_data.set_source_lid( kernel::manager< VPManager >.node_id_to_lid( source_gid ) ); if ( is_primary ) { @@ -1867,7 +1868,7 @@ nest::ConnectionManager::fill_target_buffer( const size_t tid, assert( target_thread == static_cast< unsigned long >( conn_info.get_tid() ) ); const size_t relative_recv_buffer_pos = get_secondary_recv_buffer_position( target_thread, syn_id, conn_info.get_lcid() ) - - kernel().mpi_manager.get_recv_displacement_secondary_events_in_int( source_rank ); + - kernel::manager< MPIManager >.get_recv_displacement_secondary_events_in_int( source_rank ); SecondaryTargetDataFields& secondary_fields = next_target_data.secondary_data; secondary_fields.set_recv_buffer_pos( relative_recv_buffer_pos ); @@ -1913,9 +1914,9 @@ nest::ConnectionManager::fill_target_buffer( const size_t tid, } void -nest::ConnectionManager::initialize_iteration_state() +ConnectionManager::initialize_iteration_state() { - const size_t num_threads = kernel().vp_manager.get_num_threads(); + const size_t num_threads = kernel::manager< VPManager >.get_num_threads(); iteration_state_.clear(); iteration_state_.reserve( num_threads ); @@ -1928,3 +1929,254 @@ nest::ConnectionManager::initialize_iteration_state() iteration_state_.push_back( std::pair< size_t, std::map< size_t, CSDMapEntry >::const_iterator >( 0, begin ) ); } } + +void +ConnectionManager::send_to_devices( const size_t tid, const size_t source_node_id, Event& e ) +{ + target_table_devices_.send_to_device( + tid, source_node_id, e, kernel::manager< ModelManager >.get_connection_models( tid ) ); +} + +void +ConnectionManager::send_to_devices( const size_t tid, const size_t source_node_id, SecondaryEvent& e ) +{ + target_table_devices_.send_to_device( + tid, source_node_id, e, kernel::manager< ModelManager >.get_connection_models( tid ) ); +} + +void +ConnectionManager::send_from_device( const size_t tid, const size_t ldid, Event& e ) +{ + target_table_devices_.send_from_device( tid, ldid, e, kernel::manager< ModelManager >.get_connection_models( tid ) ); +} + + +bool +ConnectionManager::valid_connection_rule( std::string rule_name ) +{ + return connruledict_->known( rule_name ); +} + +long +ConnectionManager::get_min_delay() const +{ + return min_delay_; +} + +long +ConnectionManager::get_max_delay() const +{ + return max_delay_; +} + +void +ConnectionManager::clean_source_table( const size_t tid ) +{ + if ( not keep_source_table_ ) + { + source_table_.clean( tid ); + } +} + +void +ConnectionManager::clear_source_table( const size_t tid ) +{ + if ( not keep_source_table_ ) + { + source_table_.clear( tid ); + } +} + +bool +ConnectionManager::get_keep_source_table() const +{ + return keep_source_table_; +} + +bool +ConnectionManager::is_source_table_cleared() const +{ + return source_table_.is_cleared(); +} + +void +ConnectionManager::resize_target_table_devices_to_number_of_neurons() +{ + target_table_devices_.resize_to_number_of_neurons(); +} + +void +ConnectionManager::resize_target_table_devices_to_number_of_synapse_types() +{ + target_table_devices_.resize_to_number_of_synapse_types(); +} + +void +ConnectionManager::reject_last_target_data( const size_t tid ) +{ + source_table_.reject_last_target_data( tid ); +} + +void +ConnectionManager::save_source_table_entry_point( const size_t tid ) +{ + source_table_.save_entry_point( tid ); +} + +void +ConnectionManager::no_targets_to_process( const size_t tid ) +{ + source_table_.no_targets_to_process( tid ); +} + +void +ConnectionManager::reset_source_table_entry_point( const size_t tid ) +{ + source_table_.reset_entry_point( tid ); +} + +void +ConnectionManager::restore_source_table_entry_point( const size_t tid ) +{ + source_table_.restore_entry_point( tid ); +} + +void +ConnectionManager::prepare_target_table( const size_t tid ) +{ + target_table_.prepare( tid ); +} + +const std::vector< Target >& +ConnectionManager::get_remote_targets_of_local_node( const size_t tid, const size_t lid ) const +{ + return target_table_.get_targets( tid, lid ); +} + +bool +ConnectionManager::connections_have_changed() const +{ + return connections_have_changed_; +} + +void +ConnectionManager::add_target( const size_t tid, const size_t target_rank, const TargetData& target_data ) +{ + target_table_.add_target( tid, target_rank, target_data ); +} + +bool +ConnectionManager::get_next_target_data( const size_t tid, + const size_t rank_start, + const size_t rank_end, + size_t& target_rank, + TargetData& next_target_data ) +{ + return source_table_.get_next_target_data( tid, rank_start, rank_end, target_rank, next_target_data ); +} + +const std::vector< size_t >& +ConnectionManager::get_secondary_send_buffer_positions( const size_t tid, + const size_t lid, + const synindex syn_id ) const +{ + return target_table_.get_secondary_send_buffer_positions( tid, lid, syn_id ); +} + +size_t +ConnectionManager::get_secondary_recv_buffer_position( const size_t tid, + const synindex syn_id, + const size_t lcid ) const +{ + return secondary_recv_buffer_pos_[ tid ][ syn_id ][ lcid ]; +} + +size_t +ConnectionManager::get_num_connections_( const size_t tid, const synindex syn_id ) const +{ + return connections_[ tid ][ syn_id ]->size(); +} + +size_t +ConnectionManager::get_source_node_id( const size_t tid, const synindex syn_index, const size_t lcid ) +{ + return source_table_.get_node_id( tid, syn_index, lcid ); +} + +bool +ConnectionManager::has_primary_connections() const +{ + return has_primary_connections_; +} + +bool +ConnectionManager::secondary_connections_exist() const +{ + return secondary_connections_exist_; +} + +bool +ConnectionManager::use_compressed_spikes() const +{ + return use_compressed_spikes_; +} + +double +ConnectionManager::get_stdp_eps() const +{ + return stdp_eps_; +} + +size_t +ConnectionManager::get_target_node_id( const size_t tid, const synindex syn_id, const size_t lcid ) const +{ + return connections_[ tid ][ syn_id ]->get_target_node_id( tid, lcid ); +} + +bool +ConnectionManager::get_device_connected( const size_t tid, const size_t lcid ) const +{ + return target_table_devices_.is_device_connected( tid, lcid ); +} + +void +ConnectionManager::send( const size_t tid, + const synindex syn_id, + const size_t lcid, + const std::vector< ConnectorModel* >& cm, + Event& e ) +{ + connections_[ tid ][ syn_id ]->send( tid, lcid, cm, e ); +} + +void +ConnectionManager::restructure_connection_tables( const size_t tid ) +{ + assert( not source_table_.is_cleared() ); + target_table_.clear( tid ); + source_table_.reset_processed_flags( tid ); +} + +void +ConnectionManager::set_source_has_more_targets( const size_t tid, + const synindex syn_id, + const size_t lcid, + const bool more_targets ) +{ + connections_[ tid ][ syn_id ]->set_source_has_more_targets( lcid, more_targets ); +} + +const std::vector< SpikeData >& +ConnectionManager::get_compressed_spike_data( const synindex syn_id, const size_t idx ) +{ + return compressed_spike_data_[ syn_id ][ idx ]; +} + +void +ConnectionManager::clear_compressed_spike_data_map() +{ + source_table_.clear_compressed_spike_data_map(); +} + + +} diff --git a/nestkernel/connection_manager.h b/nestkernel/connection_manager.h index d251263626..50c4853405 100644 --- a/nestkernel/connection_manager.h +++ b/nestkernel/connection_manager.h @@ -28,14 +28,13 @@ // Includes from libnestutil: #include "manager_interface.h" -#include "stopwatch.h" +#include "stopwatch_impl.h" // Includes from nestkernel: -#include "conn_builder.h" +#include "conn_builder_factory.h" #include "connection_id.h" #include "connector_base.h" #include "nest_time.h" -#include "nest_timeconverter.h" #include "nest_types.h" #include "node_collection.h" #include "per_thread_bool_indicator.h" @@ -54,13 +53,17 @@ namespace nest { class GenericBipartiteConnBuilderFactory; class GenericThirdConnBuilderFactory; -class spikecounter; class Node; class Event; class SecondaryEvent; class DelayChecker; class GrowthCurve; class SpikeData; +class BipartiteConnBuilder; +class ThirdOutBuilder; +class ThirdInBuilder; +class Time; +class TimeConverter; class ConnectionManager : public ManagerInterface { @@ -75,18 +78,25 @@ class ConnectionManager : public ManagerInterface }; ConnectionManager(); + ~ConnectionManager() override; void initialize( const bool ) override; + void finalize( const bool ) override; + void set_status( const DictionaryDatum& ) override; + void get_status( DictionaryDatum& ) override; bool valid_connection_rule( std::string ); void compute_target_data_buffer_size(); + void compute_compressed_secondary_recv_buffer_positions( const size_t tid ); + void collect_compressed_spike_data( const size_t tid ); + void clear_compressed_spike_data_map(); /** @@ -281,6 +291,7 @@ class ConnectionManager : public ManagerInterface size_t get_target_node_id( const size_t tid, const synindex syn_id, const size_t lcid ) const; bool get_device_connected( size_t tid, size_t lcid ) const; + /** * Triggered by volume transmitter in update. * @@ -314,6 +325,7 @@ class ConnectionManager : public ManagerInterface * Send event e to all device targets of source source_node_id */ void send_to_devices( const size_t tid, const size_t source_node_id, Event& e ); + void send_to_devices( const size_t tid, const size_t source_node_id, SecondaryEvent& e ); /** @@ -478,12 +490,14 @@ class ConnectionManager : public ManagerInterface NodeCollectionPTR target, synindex syn_id, long synapse_label ) const; + void get_connections_to_targets_( const size_t tid, std::deque< ConnectionID >& connectome, NodeCollectionPTR source, NodeCollectionPTR target, synindex syn_id, long synapse_label ) const; + void get_connections_from_sources_( const size_t tid, std::deque< ConnectionID >& connectome, NodeCollectionPTR source, @@ -722,233 +736,6 @@ class ConnectionManager : public ManagerInterface std::vector< std::pair< size_t, std::map< size_t, CSDMapEntry >::const_iterator > > iteration_state_; }; -inline bool -ConnectionManager::valid_connection_rule( std::string rule_name ) -{ - return connruledict_->known( rule_name ); -} - -inline long -ConnectionManager::get_min_delay() const -{ - return min_delay_; -} - -inline long -ConnectionManager::get_max_delay() const -{ - return max_delay_; -} - -inline void -ConnectionManager::clean_source_table( const size_t tid ) -{ - if ( not keep_source_table_ ) - { - source_table_.clean( tid ); - } -} - -inline void -ConnectionManager::clear_source_table( const size_t tid ) -{ - if ( not keep_source_table_ ) - { - source_table_.clear( tid ); - } -} - -inline bool -ConnectionManager::get_keep_source_table() const -{ - return keep_source_table_; -} - -inline bool -ConnectionManager::is_source_table_cleared() const -{ - return source_table_.is_cleared(); -} - -inline void -ConnectionManager::resize_target_table_devices_to_number_of_neurons() -{ - target_table_devices_.resize_to_number_of_neurons(); -} - -inline void -ConnectionManager::resize_target_table_devices_to_number_of_synapse_types() -{ - target_table_devices_.resize_to_number_of_synapse_types(); -} - -inline void -ConnectionManager::reject_last_target_data( const size_t tid ) -{ - source_table_.reject_last_target_data( tid ); -} - -inline void -ConnectionManager::save_source_table_entry_point( const size_t tid ) -{ - source_table_.save_entry_point( tid ); -} - -inline void -ConnectionManager::no_targets_to_process( const size_t tid ) -{ - source_table_.no_targets_to_process( tid ); -} - -inline void -ConnectionManager::reset_source_table_entry_point( const size_t tid ) -{ - source_table_.reset_entry_point( tid ); -} - -inline void -ConnectionManager::restore_source_table_entry_point( const size_t tid ) -{ - source_table_.restore_entry_point( tid ); -} - -inline void -ConnectionManager::prepare_target_table( const size_t tid ) -{ - target_table_.prepare( tid ); -} - -inline const std::vector< Target >& -ConnectionManager::get_remote_targets_of_local_node( const size_t tid, const size_t lid ) const -{ - return target_table_.get_targets( tid, lid ); -} - -inline bool -ConnectionManager::connections_have_changed() const -{ - return connections_have_changed_; -} - -inline void -ConnectionManager::add_target( const size_t tid, const size_t target_rank, const TargetData& target_data ) -{ - target_table_.add_target( tid, target_rank, target_data ); -} - -inline bool -ConnectionManager::get_next_target_data( const size_t tid, - const size_t rank_start, - const size_t rank_end, - size_t& target_rank, - TargetData& next_target_data ) -{ - return source_table_.get_next_target_data( tid, rank_start, rank_end, target_rank, next_target_data ); -} - -inline const std::vector< size_t >& -ConnectionManager::get_secondary_send_buffer_positions( const size_t tid, - const size_t lid, - const synindex syn_id ) const -{ - return target_table_.get_secondary_send_buffer_positions( tid, lid, syn_id ); -} - -inline size_t -ConnectionManager::get_secondary_recv_buffer_position( const size_t tid, - const synindex syn_id, - const size_t lcid ) const -{ - return secondary_recv_buffer_pos_[ tid ][ syn_id ][ lcid ]; -} - -inline size_t -ConnectionManager::get_num_connections_( const size_t tid, const synindex syn_id ) const -{ - return connections_[ tid ][ syn_id ]->size(); -} - -inline size_t -ConnectionManager::get_source_node_id( const size_t tid, const synindex syn_index, const size_t lcid ) -{ - return source_table_.get_node_id( tid, syn_index, lcid ); -} - -inline bool -ConnectionManager::has_primary_connections() const -{ - return has_primary_connections_; -} - -inline bool -ConnectionManager::secondary_connections_exist() const -{ - return secondary_connections_exist_; -} - -inline bool -ConnectionManager::use_compressed_spikes() const -{ - return use_compressed_spikes_; -} - -inline double -ConnectionManager::get_stdp_eps() const -{ - return stdp_eps_; -} - -inline size_t -ConnectionManager::get_target_node_id( const size_t tid, const synindex syn_id, const size_t lcid ) const -{ - return connections_[ tid ][ syn_id ]->get_target_node_id( tid, lcid ); -} - -inline bool -ConnectionManager::get_device_connected( const size_t tid, const size_t lcid ) const -{ - return target_table_devices_.is_device_connected( tid, lcid ); -} - -inline void -ConnectionManager::send( const size_t tid, - const synindex syn_id, - const size_t lcid, - const std::vector< ConnectorModel* >& cm, - Event& e ) -{ - connections_[ tid ][ syn_id ]->send( tid, lcid, cm, e ); -} - -inline void -ConnectionManager::restructure_connection_tables( const size_t tid ) -{ - assert( not source_table_.is_cleared() ); - target_table_.clear( tid ); - source_table_.reset_processed_flags( tid ); -} - -inline void -ConnectionManager::set_source_has_more_targets( const size_t tid, - const synindex syn_id, - const size_t lcid, - const bool more_targets ) -{ - connections_[ tid ][ syn_id ]->set_source_has_more_targets( lcid, more_targets ); -} - -inline const std::vector< SpikeData >& -ConnectionManager::get_compressed_spike_data( const synindex syn_id, const size_t idx ) -{ - return compressed_spike_data_[ syn_id ][ idx ]; -} - -inline void -ConnectionManager::clear_compressed_spike_data_map() -{ - source_table_.clear_compressed_spike_data_map(); -} - } // namespace nest #endif /* CONNECTION_MANAGER_H */ diff --git a/nestkernel/connection_manager_impl.h b/nestkernel/connection_manager_impl.h index 3c8d74034c..18e83e301a 100644 --- a/nestkernel/connection_manager_impl.h +++ b/nestkernel/connection_manager_impl.h @@ -24,16 +24,12 @@ #define CONNECTION_MANAGER_IMPL_H #include "connection_manager.h" - -// C++ includes: +#include #include -// Includes from nestkernel: -#include "conn_builder.h" #include "conn_builder_factory.h" -#include "connector_base.h" -#include "kernel_manager.h" -#include "target_table_devices_impl.h" +#include "conn_builder_factory_impl.h" +#include "dictdatum.h" namespace nest { @@ -62,24 +58,7 @@ ConnectionManager::register_third_conn_builder( const std::string& name ) thirdconnruledict_->insert( name, id ); } -inline void -ConnectionManager::send_to_devices( const size_t tid, const size_t source_node_id, Event& e ) -{ - target_table_devices_.send_to_device( tid, source_node_id, e, kernel().model_manager.get_connection_models( tid ) ); -} - -inline void -ConnectionManager::send_to_devices( const size_t tid, const size_t source_node_id, SecondaryEvent& e ) -{ - target_table_devices_.send_to_device( tid, source_node_id, e, kernel().model_manager.get_connection_models( tid ) ); -} - -inline void -ConnectionManager::send_from_device( const size_t tid, const size_t ldid, Event& e ) -{ - target_table_devices_.send_from_device( tid, ldid, e, kernel().model_manager.get_connection_models( tid ) ); -} - } // namespace nest + #endif /* CONNECTION_MANAGER_IMPL_H */ diff --git a/nestkernel/connector_base.cpp b/nestkernel/connector_base.cpp new file mode 100644 index 0000000000..22e2bfb4ff --- /dev/null +++ b/nestkernel/connector_base.cpp @@ -0,0 +1,51 @@ +/* + * connector_base.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "connector_base.h" + +#include "connection_manager.h" + +namespace nest +{ + +void +ConnectorBase::prepare_weight_recorder_event( WeightRecorderEvent& wr_e, + const size_t tid, + const synindex syn_id, + const unsigned int lcid, + const Event& e, + const CommonSynapseProperties& cp ) +{ + wr_e.set_port( e.get_port() ); + wr_e.set_rport( e.get_rport() ); + wr_e.set_stamp( e.get_stamp() ); + // Sender is not available for SecondaryEvents, and not needed, so we do not set it to avoid undefined behavior. + // wr_e.set_sender_node_id( kernel::manager< ConnectionManager >.get_source_node_id( tid, syn_id, lcid ) ); + wr_e.set_sender_node_id( kernel::manager< ConnectionManager >.get_source_node_id( tid, syn_id, lcid ) ); + wr_e.set_weight( e.get_weight() ); + wr_e.set_delay_steps( e.get_delay_steps() ); + wr_e.set_receiver( *static_cast< Node* >( cp.get_weight_recorder() ) ); + // Set the node_id of the postsynaptic node as receiver node ID + wr_e.set_receiver_node_id( e.get_receiver_node_id() ); +} + +} // namespace nest diff --git a/nestkernel/connector_base.h b/nestkernel/connector_base.h index 1ac334b5d1..aaa6198b12 100644 --- a/nestkernel/connector_base.h +++ b/nestkernel/connector_base.h @@ -27,33 +27,35 @@ #include "config.h" // C++ includes: -#include +#include #include -// Includes from libnestutil: -#include "compose.hpp" -#include "sort.h" -#include "vector_util.h" +// Includes from models: +#include "weight_recorder.h" + +#ifdef HAVE_SIONLIB +#include +#endif // Includes from nestkernel: #include "common_synapse_properties.h" #include "connection_label.h" -#include "connector_model.h" #include "event.h" -#include "nest_datums.h" -#include "nest_names.h" #include "node.h" #include "source.h" #include "source_table.h" #include "spikecounter.h" -// Includes from sli: -#include "arraydatum.h" -#include "dictutils.h" +#include "block_vector.h" + namespace nest { +class ConnectorModel; +template < typename ConnectionT > +class GenericConnectorModel; + /** * Base class to allow storing Connectors for different synapse types * in vectors. We define the interface here to avoid casting. @@ -64,7 +66,6 @@ namespace nest */ class ConnectorBase { - public: // Destructor needs to be declared virtual to avoid undefined // behavior, avoid possible memory leak and needs to be defined to @@ -214,314 +215,90 @@ class ConnectorBase * Remove disabled connections from the connector. */ virtual void remove_disabled_connections( const size_t first_disabled_index ) = 0; + +protected: + static void prepare_weight_recorder_event( WeightRecorderEvent& wr_e, + const size_t tid, + const synindex syn_id, + const unsigned int lcid, + const Event& e, + const CommonSynapseProperties& cp ); }; -/** - * Homogeneous connector, contains synapses of one particular type (syn_id_). - */ +// --- Template connector (declarations only) --- + template < typename ConnectionT > class Connector : public ConnectorBase { -private: BlockVector< ConnectionT > C_; const synindex syn_id_; public: - explicit Connector( const synindex syn_id ) - : syn_id_( syn_id ) - { - } - - ~Connector() override - { - C_.clear(); - } - - synindex - get_syn_id() const override - { - return syn_id_; - } - - size_t - size() const override - { - return C_.size(); - } - - void - get_synapse_status( const size_t tid, const size_t lcid, DictionaryDatum& dict ) const override - { - assert( lcid < C_.size() ); - - C_[ lcid ].get_status( dict ); - - // get target node ID here, where tid is available - // necessary for hpc synapses using TargetIdentifierIndex - def< long >( dict, names::target, C_[ lcid ].get_target( tid )->get_node_id() ); - } - - void - set_synapse_status( const size_t lcid, const DictionaryDatum& dict, ConnectorModel& cm ) override - { - assert( lcid < C_.size() ); - - C_[ lcid ].set_status( dict, static_cast< GenericConnectorModel< ConnectionT >& >( cm ) ); - } - - void - push_back( const ConnectionT& c ) - { - C_.push_back( c ); - } - - void - push_back( ConnectionT&& c ) - { - C_.push_back( std::move( c ) ); - } - - void - get_connection( const size_t source_node_id, - const size_t target_node_id, - const size_t tid, - const size_t lcid, - const long synapse_label, - std::deque< ConnectionID >& conns ) const override - { - if ( not C_[ lcid ].is_disabled() ) - { - if ( synapse_label == UNLABELED_CONNECTION or C_[ lcid ].get_label() == synapse_label ) - { - const size_t current_target_node_id = C_[ lcid ].get_target( tid )->get_node_id(); - if ( current_target_node_id == target_node_id or target_node_id == 0 ) - { - conns.push_back( - ConnectionDatum( ConnectionID( source_node_id, current_target_node_id, tid, syn_id_, lcid ) ) ); - } - } - } - } - - void - get_connection_with_specified_targets( const size_t source_node_id, + explicit Connector( synindex syn_id ); + ~Connector() override; + + synindex get_syn_id() const override; + size_t size() const override; + + void get_synapse_status( size_t tid, size_t lcid, DictionaryDatum& dict ) const override; + void set_synapse_status( size_t lcid, const DictionaryDatum& dict, ConnectorModel& cm ) override; + + void push_back( const ConnectionT& c ); + void push_back( ConnectionT&& c ); + + void get_connection( size_t source_node_id, + size_t target_node_id, + size_t tid, + size_t lcid, + long synapse_label, + std::deque< ConnectionID >& conns ) const override; + + void get_connection_with_specified_targets( size_t source_node_id, const std::vector< size_t >& target_neuron_node_ids, - const size_t tid, - const size_t lcid, - const long synapse_label, - std::deque< ConnectionID >& conns ) const override - { - if ( not C_[ lcid ].is_disabled() ) - { - if ( synapse_label == UNLABELED_CONNECTION or C_[ lcid ].get_label() == synapse_label ) - { - const size_t current_target_node_id = C_[ lcid ].get_target( tid )->get_node_id(); - if ( std::find( target_neuron_node_ids.begin(), target_neuron_node_ids.end(), current_target_node_id ) - != target_neuron_node_ids.end() ) - { - conns.push_back( - ConnectionDatum( ConnectionID( source_node_id, current_target_node_id, tid, syn_id_, lcid ) ) ); - } - } - } - } - - void - get_all_connections( const size_t source_node_id, - const size_t target_node_id, - const size_t tid, - const long synapse_label, - std::deque< ConnectionID >& conns ) const override - { - for ( size_t lcid = 0; lcid < C_.size(); ++lcid ) - { - get_connection( source_node_id, target_node_id, tid, lcid, synapse_label, conns ); - } - } - - void - get_source_lcids( const size_t tid, const size_t target_node_id, std::vector< size_t >& source_lcids ) const override - { - for ( size_t lcid = 0; lcid < C_.size(); ++lcid ) - { - const size_t current_target_node_id = C_[ lcid ].get_target( tid )->get_node_id(); - if ( current_target_node_id == target_node_id and not C_[ lcid ].is_disabled() ) - { - source_lcids.push_back( lcid ); - } - } - } - - void - get_target_node_ids( const size_t tid, - const size_t start_lcid, + size_t tid, + size_t lcid, + long synapse_label, + std::deque< ConnectionID >& conns ) const override; + + void get_all_connections( size_t source_node_id, + size_t target_node_id, + size_t tid, + long synapse_label, + std::deque< ConnectionID >& conns ) const override; + + void get_source_lcids( size_t tid, size_t target_node_id, std::vector< size_t >& source_lcids ) const override; + + void get_target_node_ids( size_t tid, + size_t start_lcid, const std::string& post_synaptic_element, - std::vector< size_t >& target_node_ids ) const override - { - size_t lcid = start_lcid; - while ( true ) - { - if ( C_[ lcid ].get_target( tid )->get_synaptic_elements( post_synaptic_element ) != 0.0 - and not C_[ lcid ].is_disabled() ) - { - target_node_ids.push_back( C_[ lcid ].get_target( tid )->get_node_id() ); - } - - if ( not C_[ lcid ].source_has_more_targets() ) - { - break; - } - - ++lcid; - } - } - - size_t - get_target_node_id( const size_t tid, const unsigned int lcid ) const override - { - return C_[ lcid ].get_target( tid )->get_node_id(); - } - - void - send_to_all( const size_t tid, const std::vector< ConnectorModel* >& cm, Event& e ) override - { - auto const& cp = static_cast< GenericConnectorModel< ConnectionT >* >( cm[ syn_id_ ] )->get_common_properties(); - - for ( size_t lcid = 0; lcid < C_.size(); ++lcid ) - { - e.set_port( lcid ); - assert( not C_[ lcid ].is_disabled() ); - C_[ lcid ].send( e, tid, cp ); - } - } - - size_t - send( const size_t tid, const size_t lcid, const std::vector< ConnectorModel* >& cm, Event& e ) override - { - typename ConnectionT::CommonPropertiesType const& cp = - static_cast< GenericConnectorModel< ConnectionT >* >( cm[ syn_id_ ] )->get_common_properties(); - - size_t lcid_offset = 0; - - while ( true ) - { - assert( lcid + lcid_offset < C_.size() ); - ConnectionT& conn = C_[ lcid + lcid_offset ]; - - e.set_port( lcid + lcid_offset ); - if ( not conn.is_disabled() ) - { - // Some synapses, e.g., bernoulli_synapse, may not send an event after all - const bool event_sent = conn.send( e, tid, cp ); - if ( event_sent ) - { - send_weight_event( tid, lcid + lcid_offset, e, cp ); - } - } - if ( not conn.source_has_more_targets() ) - { - break; - } - ++lcid_offset; - } - - return 1 + lcid_offset; // event was delivered to at least one target - } - - // Implemented in connector_base_impl.h - void - send_weight_event( const size_t tid, const unsigned int lcid, Event& e, const CommonSynapseProperties& cp ) override; - - void - trigger_update_weight( const long vt_node_id, - const size_t tid, + std::vector< size_t >& target_node_ids ) const override; + + size_t get_target_node_id( size_t tid, unsigned int lcid ) const override; + + void send_to_all( size_t tid, const std::vector< ConnectorModel* >& cm, Event& e ) override; + size_t send( size_t tid, size_t lcid, const std::vector< ConnectorModel* >& cm, Event& e ) override; + + void send_weight_event( size_t tid, unsigned int lcid, Event& e, const CommonSynapseProperties& cp ) override; + + void trigger_update_weight( long vt_node_id, + size_t tid, const std::vector< spikecounter >& dopa_spikes, - const double t_trig, - const std::vector< ConnectorModel* >& cm ) override - { - for ( size_t i = 0; i < C_.size(); ++i ) - { - if ( static_cast< GenericConnectorModel< ConnectionT >* >( cm[ syn_id_ ] ) - ->get_common_properties() - .get_vt_node_id() - == vt_node_id ) - { - C_[ i ].trigger_update_weight( tid, - dopa_spikes, - t_trig, - static_cast< GenericConnectorModel< ConnectionT >* >( cm[ syn_id_ ] )->get_common_properties() ); - } - } - } - - void - sort_connections( BlockVector< Source >& sources ) override - { - nest::sort( sources, C_ ); - } - - void - set_source_has_more_targets( const size_t lcid, const bool has_more_targets ) override - { - C_[ lcid ].set_source_has_more_targets( has_more_targets ); - } - - size_t - find_first_target( const size_t tid, const size_t start_lcid, const size_t target_node_id ) const override - { - // TODO: Once #3544 is merged, activate this assertion. It is currently - // commented out to avoid circular inclusions. - // assert( kernel().connection_manager.use_compressed_spikes() ); - - size_t lcid = start_lcid; - while ( true ) - { - if ( C_[ lcid ].get_target( tid )->get_node_id() == target_node_id and not C_[ lcid ].is_disabled() ) - { - return lcid; - } - - if ( not C_[ lcid ].source_has_more_targets() ) - { - return invalid_index; - } - - ++lcid; - } - } - - size_t - find_enabled_connection( const size_t tid, + double t_trig, + const std::vector< ConnectorModel* >& cm ) override; + + void sort_connections( BlockVector< Source >& sources ) override; + void set_source_has_more_targets( size_t lcid, bool has_more_targets ) override; + + size_t find_first_target( size_t tid, size_t start_lcid, size_t target_node_id ) const override; + + size_t find_enabled_connection( const size_t tid, const size_t syn_id, const size_t source_node_id, const size_t target_node_id, - const SourceTable& source_table ) const override - { - for ( size_t lcid = 0; lcid < C_.size(); ++lcid ) - { - if ( source_table.get_node_id( tid, syn_id, lcid ) == source_node_id - and C_[ lcid ].get_target( tid )->get_node_id() == target_node_id and not C_[ lcid ].is_disabled() ) - { - return lcid; - } - } - - return invalid_index; - } - - void - disable_connection( const size_t lcid ) override - { - assert( not C_[ lcid ].is_disabled() ); - C_[ lcid ].disable(); - } - - void - remove_disabled_connections( const size_t first_disabled_index ) override - { - assert( C_[ first_disabled_index ].is_disabled() ); - C_.erase( C_.begin() + first_disabled_index, C_.end() ); - } + const SourceTable& source_table ) const override; + + void disable_connection( size_t lcid ) override; + void remove_disabled_connections( size_t first_disabled_index ) override; }; } // of namespace nest diff --git a/nestkernel/connector_base_impl.h b/nestkernel/connector_base_impl.h index a322b2e336..0dc05f4b01 100644 --- a/nestkernel/connector_base_impl.h +++ b/nestkernel/connector_base_impl.h @@ -20,20 +20,251 @@ * */ +#ifndef CONNECTOR_BASE_IMPL_H +#define CONNECTOR_BASE_IMPL_H + #include "connector_base.h" -// Includes from nestkernel: -#include "kernel_manager.h" +#include +#include -// Includes from models: +#include "common_synapse_properties.h" +#include "connector_model.h" +#include "event.h" +#include "nest_names.h" +#include "node.h" +#include "sort.h" +#include "spikecounter.h" #include "weight_recorder.h" -#ifndef CONNECTOR_BASE_IMPL_H -#define CONNECTOR_BASE_IMPL_H - namespace nest { +/** + * Homogeneous connector, contains synapses of one particular type (syn_id_). + */ +template < typename ConnectionT > +Connector< ConnectionT >::Connector( const synindex syn_id ) + : syn_id_( syn_id ) +{ +} + +template < typename ConnectionT > +Connector< ConnectionT >::~Connector() +{ + C_.clear(); +} + +template < typename ConnectionT > +synindex +Connector< ConnectionT >::get_syn_id() const +{ + return syn_id_; +} + +template < typename ConnectionT > +size_t +Connector< ConnectionT >::size() const +{ + return C_.size(); +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::get_synapse_status( const size_t tid, const size_t lcid, DictionaryDatum& dict ) const +{ + assert( lcid < C_.size() ); + + C_[ lcid ].get_status( dict ); + + // get target node ID here, where tid is available + // necessary for hpc synapses using TargetIdentifierIndex + def< long >( dict, names::target, C_[ lcid ].get_target( tid )->get_node_id() ); +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::set_synapse_status( const size_t lcid, const DictionaryDatum& dict, ConnectorModel& cm ) +{ + assert( lcid < C_.size() ); + + C_[ lcid ].set_status( dict, static_cast< GenericConnectorModel< ConnectionT >& >( cm ) ); +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::push_back( const ConnectionT& c ) +{ + C_.push_back( c ); +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::push_back( ConnectionT&& c ) +{ + C_.push_back( std::move( c ) ); +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::get_connection( const size_t source_node_id, + const size_t target_node_id, + const size_t tid, + const size_t lcid, + const long synapse_label, + std::deque< ConnectionID >& conns ) const +{ + if ( not C_[ lcid ].is_disabled() ) + { + if ( synapse_label == UNLABELED_CONNECTION or C_[ lcid ].get_label() == synapse_label ) + { + const size_t current_target_node_id = C_[ lcid ].get_target( tid )->get_node_id(); + if ( current_target_node_id == target_node_id or target_node_id == 0 ) + { + conns.push_back( + ConnectionDatum( ConnectionID( source_node_id, current_target_node_id, tid, syn_id_, lcid ) ) ); + } + } + } +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::get_connection_with_specified_targets( const size_t source_node_id, + const std::vector< size_t >& target_neuron_node_ids, + const size_t tid, + const size_t lcid, + const long synapse_label, + std::deque< ConnectionID >& conns ) const +{ + if ( not C_[ lcid ].is_disabled() ) + { + if ( synapse_label == UNLABELED_CONNECTION or C_[ lcid ].get_label() == synapse_label ) + { + const size_t current_target_node_id = C_[ lcid ].get_target( tid )->get_node_id(); + if ( std::find( target_neuron_node_ids.begin(), target_neuron_node_ids.end(), current_target_node_id ) + != target_neuron_node_ids.end() ) + { + conns.push_back( + ConnectionDatum( ConnectionID( source_node_id, current_target_node_id, tid, syn_id_, lcid ) ) ); + } + } + } +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::get_all_connections( const size_t source_node_id, + const size_t target_node_id, + const size_t tid, + const long synapse_label, + std::deque< ConnectionID >& conns ) const +{ + for ( size_t lcid = 0; lcid < C_.size(); ++lcid ) + { + get_connection( source_node_id, target_node_id, tid, lcid, synapse_label, conns ); + } +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::get_source_lcids( const size_t tid, + const size_t target_node_id, + std::vector< size_t >& source_lcids ) const +{ + for ( size_t lcid = 0; lcid < C_.size(); ++lcid ) + { + const size_t current_target_node_id = C_[ lcid ].get_target( tid )->get_node_id(); + if ( current_target_node_id == target_node_id and not C_[ lcid ].is_disabled() ) + { + source_lcids.push_back( lcid ); + } + } +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::get_target_node_ids( const size_t tid, + const size_t start_lcid, + const std::string& post_synaptic_element, + std::vector< size_t >& target_node_ids ) const +{ + size_t lcid = start_lcid; + while ( true ) + { + if ( C_[ lcid ].get_target( tid )->get_synaptic_elements( post_synaptic_element ) != 0.0 + and not C_[ lcid ].is_disabled() ) + { + target_node_ids.push_back( C_[ lcid ].get_target( tid )->get_node_id() ); + } + + if ( not C_[ lcid ].source_has_more_targets() ) + { + break; + } + + ++lcid; + } +} + +template < typename ConnectionT > +size_t +Connector< ConnectionT >::get_target_node_id( const size_t tid, const unsigned int lcid ) const +{ + return C_[ lcid ].get_target( tid )->get_node_id(); +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::send_to_all( const size_t tid, const std::vector< ConnectorModel* >& cm, Event& e ) +{ + auto const& cp = static_cast< GenericConnectorModel< ConnectionT >* >( cm[ syn_id_ ] )->get_common_properties(); + + for ( size_t lcid = 0; lcid < C_.size(); ++lcid ) + { + e.set_port( lcid ); + assert( not C_[ lcid ].is_disabled() ); + C_[ lcid ].send( e, tid, cp ); + } +} + +template < typename ConnectionT > +size_t +Connector< ConnectionT >::send( const size_t tid, + const size_t lcid, + const std::vector< ConnectorModel* >& cm, + Event& e ) +{ + typename ConnectionT::CommonPropertiesType const& cp = + static_cast< GenericConnectorModel< ConnectionT >* >( cm[ syn_id_ ] )->get_common_properties(); + + size_t lcid_offset = 0; + + while ( true ) + { + assert( lcid + lcid_offset < C_.size() ); + ConnectionT& conn = C_[ lcid + lcid_offset ]; + + e.set_port( lcid + lcid_offset ); + if ( not conn.is_disabled() ) + { + // Some synapses, e.g., bernoulli_synapse, may not send an event after all + const bool event_sent = conn.send( e, tid, cp ); + if ( event_sent ) + { + send_weight_event( tid, lcid + lcid_offset, e, cp ); + } + } + if ( not conn.source_has_more_targets() ) + { + break; + } + ++lcid_offset; + } + + return 1 + lcid_offset; // event was delivered to at least one target +} + template < typename ConnectionT > void Connector< ConnectionT >::send_weight_event( const size_t tid, @@ -47,21 +278,107 @@ Connector< ConnectionT >::send_weight_event( const size_t tid, { // Create new event to record the weight and copy relevant content. WeightRecorderEvent wr_e; - wr_e.set_port( e.get_port() ); - wr_e.set_rport( e.get_rport() ); - wr_e.set_stamp( e.get_stamp() ); - // Sender is not available for SecondaryEvents, and not needed, so we do not - // set it to avoid undefined behavior. - wr_e.set_sender_node_id( kernel().connection_manager.get_source_node_id( tid, syn_id_, lcid ) ); - wr_e.set_weight( e.get_weight() ); - wr_e.set_delay_steps( e.get_delay_steps() ); - wr_e.set_receiver( *static_cast< Node* >( cp.get_weight_recorder() ) ); - // Set the node_id of the postsynaptic node as receiver node ID - wr_e.set_receiver_node_id( e.get_receiver_node_id() ); + prepare_weight_recorder_event( wr_e, tid, syn_id_, lcid, e, cp ); wr_e(); } } -} // of namespace nest +template < typename ConnectionT > +void +Connector< ConnectionT >::trigger_update_weight( const long vt_node_id, + const size_t tid, + const std::vector< spikecounter >& dopa_spikes, + const double t_trig, + const std::vector< ConnectorModel* >& cm ) +{ + for ( size_t i = 0; i < C_.size(); ++i ) + { + if ( static_cast< GenericConnectorModel< ConnectionT >* >( cm[ syn_id_ ] )->get_common_properties().get_vt_node_id() + == vt_node_id ) + { + C_[ i ].trigger_update_weight( tid, + dopa_spikes, + t_trig, + static_cast< GenericConnectorModel< ConnectionT >* >( cm[ syn_id_ ] )->get_common_properties() ); + } + } +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::sort_connections( BlockVector< Source >& sources ) +{ + nest::sort( sources, C_ ); +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::set_source_has_more_targets( const size_t lcid, const bool has_more_targets ) +{ + C_[ lcid ].set_source_has_more_targets( has_more_targets ); +} + +template < typename ConnectionT > +size_t +Connector< ConnectionT >::find_first_target( const size_t tid, + const size_t start_lcid, + const size_t target_node_id ) const +{ + assert( kernel::manager< ConnectionManager >.use_compressed_spikes() ); + + size_t lcid = start_lcid; + while ( true ) + { + if ( C_[ lcid ].get_target( tid )->get_node_id() == target_node_id and not C_[ lcid ].is_disabled() ) + { + return lcid; + } + + if ( not C_[ lcid ].source_has_more_targets() ) + { + return invalid_index; + } + + ++lcid; + } +} + +template < typename ConnectionT > +size_t +Connector< ConnectionT >::find_enabled_connection( const size_t tid, + const size_t syn_id, + const size_t source_node_id, + const size_t target_node_id, + const SourceTable& source_table ) const +{ + for ( size_t lcid = 0; lcid < C_.size(); ++lcid ) + { + if ( source_table.get_node_id( tid, syn_id, lcid ) == source_node_id + and C_[ lcid ].get_target( tid )->get_node_id() == target_node_id and not C_[ lcid ].is_disabled() ) + { + return lcid; + } + } + + return invalid_index; +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::disable_connection( const size_t lcid ) +{ + assert( not C_[ lcid ].is_disabled() ); + C_[ lcid ].disable(); +} + +template < typename ConnectionT > +void +Connector< ConnectionT >::remove_disabled_connections( const size_t first_disabled_index ) +{ + assert( C_[ first_disabled_index ].is_disabled() ); + C_.erase( C_.begin() + first_disabled_index, C_.end() ); +} + +} // namespace nest #endif diff --git a/nestkernel/connector_model.cpp b/nestkernel/connector_model.cpp index 6e3bb9f078..0ae28ab589 100644 --- a/nestkernel/connector_model.cpp +++ b/nestkernel/connector_model.cpp @@ -21,6 +21,7 @@ */ #include "connector_model.h" +#include "model_manager.h" namespace nest { @@ -39,4 +40,10 @@ ConnectorModel::ConnectorModel( const ConnectorModel& cm, const std::string name { } +size_t +ConnectorModel::get_synapse_model_id( const std::string& name ) +{ + return kernel::manager< ModelManager >.get_synapse_model_id( name ); +} + } // namespace nest diff --git a/nestkernel/connector_model.h b/nestkernel/connector_model.h index 0884b44312..d7f13eeaf0 100644 --- a/nestkernel/connector_model.h +++ b/nestkernel/connector_model.h @@ -28,17 +28,15 @@ #include // Includes from libnestutil: +#include "enum_bitfield.h" #include "numerics.h" // Includes from nestkernel: -#include "enum_bitfield.h" #include "event.h" -#include "nest_time.h" #include "nest_types.h" #include "secondary_event.h" +#include "simulation_manager.h" -// Includes from sli: -#include "dictutils.h" namespace nest { @@ -143,6 +141,9 @@ class ConnectorModel } protected: + // helper function to avoid circular dependency + static size_t get_synapse_model_id( const std::string& name ); + std::string name_; //!< name of the ConnectorModel bool default_delay_needs_check_; //!< indicates whether the default delay must be checked ConnectionModelProperties properties_; //!< connection properties @@ -199,11 +200,7 @@ class GenericConnectorModel : public ConnectorModel void check_synapse_params( const DictionaryDatum& syn_spec ) const override; - std::unique_ptr< SecondaryEvent > - get_secondary_event() override - { - return default_connection_.get_secondary_event(); - } + std::unique_ptr< SecondaryEvent > get_secondary_event() override; ConnectionT const& get_default_connection() const diff --git a/nestkernel/connector_model_impl.h b/nestkernel/connector_model_impl.h index fc831cb916..fea64aee7d 100644 --- a/nestkernel/connector_model_impl.h +++ b/nestkernel/connector_model_impl.h @@ -19,29 +19,14 @@ * along with NEST. If not, see . * */ - #ifndef CONNECTOR_MODEL_IMPL_H #define CONNECTOR_MODEL_IMPL_H +#include "connection_impl.h" +#include "connection_manager.h" +#include "connector_base_impl.h" #include "connector_model.h" - -// Generated includes: -#include "config.h" - -// Includes from libnestutil: -#include "compose.hpp" -#include "enum_bitfield.h" - -// Includes from nestkernel: -#include "connector_base.h" #include "delay_checker.h" -#include "kernel_manager.h" -#include "nest_time.h" -#include "nest_timeconverter.h" -#include "secondary_event_impl.h" - -// Includes from sli: -#include "dictutils.h" namespace nest { @@ -62,6 +47,13 @@ namespace nest // return cm.get_default_connection().get_syn_id_delay(); // } +template < typename ConnectionT > +std::unique_ptr< SecondaryEvent > +GenericConnectorModel< ConnectionT >::get_secondary_event() +{ + return default_connection_.get_secondary_event(); +} + template < typename ConnectionT > ConnectorModel* GenericConnectorModel< ConnectionT >::clone( std::string name, synindex syn_id ) const @@ -105,7 +97,7 @@ GenericConnectorModel< ConnectionT >::get_status( DictionaryDatum& d ) const ( *d )[ names::receptor_type ] = receptor_type_; ( *d )[ names::synapse_model ] = LiteralDatum( name_ ); - ( *d )[ names::synapse_modelid ] = kernel().model_manager.get_synapse_model_id( name_ ); + ( *d )[ names::synapse_modelid ] = get_synapse_model_id( name_ ); ( *d )[ names::requires_symmetric ] = has_property( ConnectionModelProperties::REQUIRES_SYMMETRIC ); ( *d )[ names::has_delay ] = has_property( ConnectionModelProperties::HAS_DELAY ); } @@ -126,12 +118,12 @@ GenericConnectorModel< ConnectionT >::set_status( const DictionaryDatum& d ) // set_status calls on common properties and default connection may // modify min/max delay, we need to freeze the min/max_delay checking. - kernel().connection_manager.get_delay_checker().freeze_delay_update(); + kernel::manager< ConnectionManager >.get_delay_checker().freeze_delay_update(); cp_.set_status( d, *this ); default_connection_.set_status( d, *this ); - kernel().connection_manager.get_delay_checker().enable_delay_update(); + kernel::manager< ConnectionManager >.get_delay_checker().enable_delay_update(); // we've possibly just got a new default delay. So enforce checking next time // it is used @@ -176,7 +168,7 @@ GenericConnectorModel< ConnectionT >::used_default_delay() if ( has_property( ConnectionModelProperties::HAS_DELAY ) ) { const double d = default_connection_.get_delay(); - kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( d ); + kernel::manager< ConnectionManager >.get_delay_checker().assert_valid_delay_ms( d ); } // Let connections without delay contribute to the delay extrema with // wfr_comm_interval. For those connections the min_delay is important @@ -186,8 +178,8 @@ GenericConnectorModel< ConnectionT >::used_default_delay() // without delay is created. else { - const double wfr_comm_interval = kernel().simulation_manager.get_wfr_comm_interval(); - kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( wfr_comm_interval ); + const double wfr_comm_interval = kernel::manager< SimulationManager >.get_wfr_comm_interval(); + kernel::manager< ConnectionManager >.get_delay_checker().assert_valid_delay_ms( wfr_comm_interval ); } } catch ( BadDelay& e ) @@ -196,8 +188,8 @@ GenericConnectorModel< ConnectionT >::used_default_delay() String::compose( "Default delay of '%1' must be between min_delay %2 " "and max_delay %3.", get_name(), - Time::delay_steps_to_ms( kernel().connection_manager.get_min_delay() ), - Time::delay_steps_to_ms( kernel().connection_manager.get_max_delay() ) ) ); + Time::delay_steps_to_ms( kernel::manager< ConnectionManager >.get_min_delay() ), + Time::delay_steps_to_ms( kernel::manager< ConnectionManager >.get_max_delay() ) ) ); } default_delay_needs_check_ = false; } @@ -231,7 +223,7 @@ GenericConnectorModel< ConnectionT >::add_connection( Node& src, { if ( has_property( ConnectionModelProperties::HAS_DELAY ) ) { - kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( delay ); + kernel::manager< ConnectionManager >.get_delay_checker().assert_valid_delay_ms( delay ); } if ( p->known( names::delay ) ) @@ -244,13 +236,13 @@ GenericConnectorModel< ConnectionT >::add_connection( Node& src, else { // check delay - double delay = 0.0; + double delay_in = 0.0; - if ( updateValue< double >( p, names::delay, delay ) ) + if ( updateValue< double >( p, names::delay, delay_in ) ) { if ( has_property( ConnectionModelProperties::HAS_DELAY ) ) { - kernel().connection_manager.get_delay_checker().assert_valid_delay_ms( delay ); + kernel::manager< ConnectionManager >.get_delay_checker().assert_valid_delay_ms( delay_in ); } } else @@ -322,5 +314,4 @@ GenericConnectorModel< ConnectionT >::add_connection_( Node& src, } } // namespace nest - -#endif +#endif // CONNECTOR_MODEL_IMPL_H diff --git a/nestkernel/delay_checker.cpp b/nestkernel/delay_checker.cpp index 8a1776c98e..474f46781a 100644 --- a/nestkernel/delay_checker.cpp +++ b/nestkernel/delay_checker.cpp @@ -30,6 +30,18 @@ #include "kernel_manager.h" #include "nest_timeconverter.h" +#include "compose.hpp" +#include "connection_manager.h" +#include "dictdatum.h" +#include "dictutils.h" +#include "logging.h" +#include "logging_manager.h" +#include "nest_names.h" +#include "nest_time.h" + +#include + + nest::DelayChecker::DelayChecker() : min_delay_( Time::pos_inf() ) , max_delay_( Time::neg_inf() ) @@ -130,7 +142,7 @@ nest::DelayChecker::set_status( const DictionaryDatum& d ) if ( min_delay_updated and max_delay_updated ) { - if ( kernel().connection_manager.get_num_connections() > 0 ) + if ( kernel::manager< ConnectionManager >.get_num_connections() > 0 ) { throw BadProperty( "Connections already exist. Please call ResetKernel first" ); } @@ -155,10 +167,10 @@ nest::DelayChecker::assert_valid_delay_ms( double requested_new_delay ) // if already simulated, the new delay has to be checked against the // min_delay and the max_delay which have been used during simulation - if ( kernel().simulation_manager.has_been_simulated() ) + if ( kernel::manager< SimulationManager >.has_been_simulated() ) { - const bool bad_min_delay = new_delay < kernel().connection_manager.get_min_delay(); - const bool bad_max_delay = new_delay > kernel().connection_manager.get_max_delay(); + const bool bad_min_delay = new_delay < kernel::manager< ConnectionManager >.get_min_delay(); + const bool bad_max_delay = new_delay > kernel::manager< ConnectionManager >.get_max_delay(); if ( bad_min_delay or bad_max_delay ) { throw BadDelay( new_delay_ms, @@ -216,10 +228,10 @@ nest::DelayChecker::assert_two_valid_delays_steps( long new_delay1, long new_del throw BadDelay( Time::delay_steps_to_ms( ldelay ), "Delay must be greater than or equal to resolution" ); } - if ( kernel().simulation_manager.has_been_simulated() ) + if ( kernel::manager< SimulationManager >.has_been_simulated() ) { - const bool bad_min_delay = ldelay < kernel().connection_manager.get_min_delay(); - const bool bad_max_delay = hdelay > kernel().connection_manager.get_max_delay(); + const bool bad_min_delay = ldelay < kernel::manager< ConnectionManager >.get_min_delay(); + const bool bad_max_delay = hdelay > kernel::manager< ConnectionManager >.get_max_delay(); if ( bad_min_delay ) { throw BadDelay( @@ -269,3 +281,38 @@ nest::DelayChecker::assert_two_valid_delays_steps( long new_delay1, long new_del } } } + +void +nest::DelayChecker::enable_delay_update() +{ + + freeze_delay_update_ = false; +} + +void +nest::DelayChecker::DelayChecker::freeze_delay_update() +{ + + freeze_delay_update_ = true; +} + +bool +nest::DelayChecker::DelayChecker::get_user_set_delay_extrema() const +{ + + return user_set_delay_extrema_; +} + +const nest::Time& +nest::DelayChecker::DelayChecker::get_max_delay() const +{ + + return max_delay_; +} + +const nest::Time& +nest::DelayChecker::DelayChecker::get_min_delay() const +{ + + return min_delay_; +} diff --git a/nestkernel/delay_checker.h b/nestkernel/delay_checker.h index 294378a8c7..bc496f1fad 100644 --- a/nestkernel/delay_checker.h +++ b/nestkernel/delay_checker.h @@ -99,35 +99,7 @@ class DelayChecker void set_min_max_delay_( const double, const double ); }; -inline const Time& -DelayChecker::get_min_delay() const -{ - return min_delay_; -} -inline const Time& -DelayChecker::get_max_delay() const -{ - return max_delay_; -} - -inline bool -DelayChecker::get_user_set_delay_extrema() const -{ - return user_set_delay_extrema_; -} - -inline void -DelayChecker::freeze_delay_update() -{ - freeze_delay_update_ = true; -} - -inline void -DelayChecker::enable_delay_update() -{ - freeze_delay_update_ = false; -} } diff --git a/nestkernel/deprecation_warning.cpp b/nestkernel/deprecation_warning.cpp index a00690d7b5..091bde2fa3 100644 --- a/nestkernel/deprecation_warning.cpp +++ b/nestkernel/deprecation_warning.cpp @@ -30,6 +30,12 @@ namespace nest { +void +DeprecationWarning::set_deprecated( std::string name ) +{ + deprecated_functions_[ name ] = true; +} + void DeprecationWarning::deprecation_warning( std::string name ) { diff --git a/nestkernel/deprecation_warning.h b/nestkernel/deprecation_warning.h index c931551b8c..2ce650dd1f 100644 --- a/nestkernel/deprecation_warning.h +++ b/nestkernel/deprecation_warning.h @@ -69,11 +69,7 @@ class DeprecationWarning /** * Set parameter name to be deprecated. */ - void - set_deprecated( std::string name ) - { - deprecated_functions_[ name ] = true; - } + void set_deprecated( std::string name ); /** * Issue a deprecation warning. diff --git a/nestkernel/device.cpp b/nestkernel/device.cpp index d844381cdd..e70767a699 100644 --- a/nestkernel/device.cpp +++ b/nestkernel/device.cpp @@ -149,3 +149,71 @@ nest::Device::pre_run_hook() V_.t_min_ = ( P_.origin_ + P_.start_ ).get_steps(); V_.t_max_ = ( P_.origin_ + P_.stop_ ).get_steps(); } + + +long +nest::Device::get_t_max_() const +{ + + return V_.t_max_; +} + +long +nest::Device::get_t_min_() const +{ + + return V_.t_min_; +} + +nest::Time const& +nest::Device::get_stop() const +{ + + return P_.stop_; +} + +nest::Time const& +nest::Device::get_start() const +{ + + return P_.start_; +} + +nest::Time const& +nest::Device::get_origin() const +{ + + return P_.origin_; +} + +void +nest::Device::set_status( const DictionaryDatum& d ) +{ + + Parameters_ ptmp = P_; // temporary copy in case of errors + ptmp.set( d ); // throws if BadProperty + + // if we get here, temporaries contain consistent set of properties + P_ = ptmp; +} + +void +nest::Device::get_status( DictionaryDatum& d ) const +{ + + P_.get( d ); +} + +void +nest::Device::init_buffers() +{ +} + +void +nest::Device::init_state() +{ +} + +nest::Device::~Device() +{ +} diff --git a/nestkernel/device.h b/nestkernel/device.h index 6d22482d0d..9933c905ce 100644 --- a/nestkernel/device.h +++ b/nestkernel/device.h @@ -63,21 +63,13 @@ class Device public: Device(); Device( const Device& n ); - virtual ~Device() - { - } + virtual ~Device(); /** Reset dynamic state to that of model. */ - virtual void - init_state() - { - } + void init_state(); /** Reset buffers. */ - virtual void - init_buffers() - { - } + void init_buffers(); /** Set internal variables before calls to SimulationManager::run() */ virtual void pre_run_hook(); @@ -179,50 +171,4 @@ class Device } // namespace -inline void -nest::Device::get_status( DictionaryDatum& d ) const -{ - P_.get( d ); -} - -inline void -nest::Device::set_status( const DictionaryDatum& d ) -{ - Parameters_ ptmp = P_; // temporary copy in case of errors - ptmp.set( d ); // throws if BadProperty - - // if we get here, temporaries contain consistent set of properties - P_ = ptmp; -} - -inline nest::Time const& -nest::Device::get_origin() const -{ - return P_.origin_; -} - -inline nest::Time const& -nest::Device::get_start() const -{ - return P_.start_; -} - -inline nest::Time const& -nest::Device::get_stop() const -{ - return P_.stop_; -} - -inline long -nest::Device::get_t_min_() const -{ - return V_.t_min_; -} - -inline long -nest::Device::get_t_max_() const -{ - return V_.t_max_; -} - #endif /* DEVICE_H */ diff --git a/nestkernel/device_node.cpp b/nestkernel/device_node.cpp new file mode 100644 index 0000000000..57a42a8a7a --- /dev/null +++ b/nestkernel/device_node.cpp @@ -0,0 +1,52 @@ +/* + * device_node.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "device_node.h" + +namespace nest +{ + +DeviceNode::DeviceNode() + : Node() + , local_device_id_( invalid_index ) +{ +} + +DeviceNode::DeviceNode( DeviceNode const& dn ) + : Node( dn ) + , local_device_id_( invalid_index ) +{ +} + +void +DeviceNode::set_local_device_id( const size_t ldid ) +{ + local_device_id_ = ldid; +} + +size_t +DeviceNode::get_local_device_id() const +{ + return local_device_id_; +} + +} // namespace nest diff --git a/nestkernel/device_node.h b/nestkernel/device_node.h index 9d8aebfc49..7ebedb368b 100644 --- a/nestkernel/device_node.h +++ b/nestkernel/device_node.h @@ -36,17 +36,9 @@ class DeviceNode : public Node { public: - DeviceNode() - : Node() - , local_device_id_( invalid_index ) - { - } + DeviceNode(); - DeviceNode( DeviceNode const& dn ) - : Node( dn ) - , local_device_id_( invalid_index ) - { - } + DeviceNode( DeviceNode const& dn ); void set_local_device_id( const size_t ldid ) override; size_t get_local_device_id() const override; @@ -55,18 +47,6 @@ class DeviceNode : public Node size_t local_device_id_; }; -inline void -DeviceNode::set_local_device_id( const size_t ldid ) -{ - local_device_id_ = ldid; -} - -inline size_t -DeviceNode::get_local_device_id() const -{ - return local_device_id_; -} - } // namespace #endif /* #ifndef DEVICE_NODE_H */ diff --git a/nestkernel/eprop_archiving_node.h b/nestkernel/eprop_archiving_node.h index 04cfc2d3ba..1d0b2a1960 100644 --- a/nestkernel/eprop_archiving_node.h +++ b/nestkernel/eprop_archiving_node.h @@ -25,8 +25,6 @@ // nestkernel #include "histentry.h" -#include "nest_time.h" -#include "nest_types.h" #include "node.h" // sli @@ -57,14 +55,21 @@ class EpropArchivingNode : public Node /** * Constructs a new EpropArchivingNode object. */ - EpropArchivingNode(); + EpropArchivingNode() + : eprop_indegree_( 0 ) + { + } /** * Constructs a new EpropArchivingNode object by copying another EpropArchivingNode object. * * @param other The other object to copy. */ - EpropArchivingNode( const EpropArchivingNode& other ); + EpropArchivingNode( const EpropArchivingNode& other ) + : Node( other ) + , eprop_indegree_( other.eprop_indegree_ ) + { + } void register_eprop_connection() override; diff --git a/nestkernel/eprop_archiving_node_impl.h b/nestkernel/eprop_archiving_node_impl.h index 7c4c60a52e..00189dda69 100644 --- a/nestkernel/eprop_archiving_node_impl.h +++ b/nestkernel/eprop_archiving_node_impl.h @@ -25,29 +25,9 @@ #include "eprop_archiving_node.h" -// Includes from nestkernel: -#include "kernel_manager.h" - -// Includes from sli: -#include "dictutils.h" - namespace nest { -template < typename HistEntryT > -EpropArchivingNode< HistEntryT >::EpropArchivingNode() - : Node() - , eprop_indegree_( 0 ) -{ -} - -template < typename HistEntryT > -EpropArchivingNode< HistEntryT >::EpropArchivingNode( const EpropArchivingNode& n ) - : Node( n ) - , eprop_indegree_( n.eprop_indegree_ ) -{ -} - template < typename HistEntryT > void EpropArchivingNode< HistEntryT >::register_eprop_connection() @@ -135,7 +115,7 @@ EpropArchivingNode< HistEntryT >::erase_used_eprop_history() return; } - const long update_interval = kernel().simulation_manager.get_eprop_update_interval().get_steps(); + const long update_interval = kernel::manager< SimulationManager >.get_eprop_update_interval().get_steps(); auto it_update_hist = update_history_.begin(); diff --git a/nestkernel/eprop_archiving_node_readout.h b/nestkernel/eprop_archiving_node_readout.h index 97fd67ca27..e3c3d9d73d 100644 --- a/nestkernel/eprop_archiving_node_readout.h +++ b/nestkernel/eprop_archiving_node_readout.h @@ -24,16 +24,10 @@ #define EPROP_ARCHIVING_NODE_READOUT_H // models -#include "eprop_archiving_node.h" +#include "eprop_archiving_node_impl.h" // nestkernel #include "histentry.h" -#include "nest_time.h" -#include "nest_types.h" -#include "node.h" - -// sli -#include "dictdatum.h" namespace nest { @@ -82,64 +76,6 @@ class EpropArchivingNodeReadout : public EpropArchivingNode< HistEntryEpropReado long model_dependent_history_shift_() const override; bool history_shift_required_() const override; }; - -template < bool hist_shift_required > -void -EpropArchivingNodeReadout< hist_shift_required >::append_new_eprop_history_entry( long time_step ) -{ - if ( eprop_indegree_ == 0 ) - { - return; - } - - if constexpr ( hist_shift_required ) - { - time_step -= delay_out_norm_; - } - - eprop_history_.emplace_back( time_step, 0.0 ); -} - -template < bool hist_shift_required > -void -EpropArchivingNodeReadout< hist_shift_required >::write_error_signal_to_history( long time_step, - const double error_signal ) -{ - if ( eprop_indegree_ == 0 ) - { - return; - } - - if constexpr ( hist_shift_required ) - { - time_step -= delay_out_norm_; - } - - auto it_hist = get_eprop_history( time_step ); - it_hist->error_signal_ = error_signal; -} - -template < bool hist_shift_required > -long -EpropArchivingNodeReadout< hist_shift_required >::model_dependent_history_shift_() const -{ - if constexpr ( hist_shift_required ) - { - return get_shift(); - } - else - { - return -delay_rec_out_; - } -} - -template < bool hist_shift_required > -bool -EpropArchivingNodeReadout< hist_shift_required >::history_shift_required_() const -{ - return hist_shift_required; -} - } #endif diff --git a/nestkernel/eprop_archiving_node_readout_impl.h b/nestkernel/eprop_archiving_node_readout_impl.h new file mode 100644 index 0000000000..d115a18334 --- /dev/null +++ b/nestkernel/eprop_archiving_node_readout_impl.h @@ -0,0 +1,92 @@ +/* + * eprop_archiving_node_readout_impl.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef EPROP_ARCHIVING_NODE_READOUT_IMPL_H +#define EPROP_ARCHIVING_NODE_READOUT_IMPL_H + +// models +#include "eprop_archiving_node_readout.h" + +namespace nest +{ + +template < bool hist_shift_required > +void +EpropArchivingNodeReadout< hist_shift_required >::append_new_eprop_history_entry( long time_step ) +{ + if ( eprop_indegree_ == 0 ) + { + return; + } + + if constexpr ( hist_shift_required ) + { + time_step -= delay_out_norm_; + } + + eprop_history_.emplace_back( time_step, 0.0 ); +} + +template < bool hist_shift_required > +void +EpropArchivingNodeReadout< hist_shift_required >::write_error_signal_to_history( long time_step, + const double error_signal ) +{ + if ( eprop_indegree_ == 0 ) + { + return; + } + + if constexpr ( hist_shift_required ) + { + time_step -= delay_out_norm_; + } + + auto it_hist = get_eprop_history( time_step ); + it_hist->error_signal_ = error_signal; +} + +template < bool hist_shift_required > +long +EpropArchivingNodeReadout< hist_shift_required >::model_dependent_history_shift_() const +{ + if constexpr ( hist_shift_required ) + { + return get_shift(); + } + else + { + return -delay_rec_out_; + } +} + +template < bool hist_shift_required > +bool +EpropArchivingNodeReadout< hist_shift_required >::history_shift_required_() const +{ + return hist_shift_required; +} + + +} + +#endif diff --git a/nestkernel/eprop_archiving_node_recurrent.h b/nestkernel/eprop_archiving_node_recurrent.h index a8872e3297..b2c8fd7c91 100644 --- a/nestkernel/eprop_archiving_node_recurrent.h +++ b/nestkernel/eprop_archiving_node_recurrent.h @@ -24,13 +24,10 @@ #define EPROP_ARCHIVING_NODE_RECURRENT_H // models -#include "eprop_archiving_node.h" +#include "eprop_archiving_node_impl.h" // nestkernel #include "histentry.h" -#include "nest_time.h" -#include "nest_types.h" -#include "node.h" // sli #include "dictdatum.h" @@ -269,42 +266,6 @@ class EpropArchivingNodeRecurrent : public EpropArchivingNode< HistEntryEpropRec static std::map< std::string, surrogate_gradient_function > surrogate_gradient_funcs_; }; -template < bool hist_shift_required > -inline void -EpropArchivingNodeRecurrent< hist_shift_required >::count_spike() -{ - ++n_spikes_; -} - -template < bool hist_shift_required > -inline void -EpropArchivingNodeRecurrent< hist_shift_required >::reset_spike_count() -{ - n_spikes_ = 0; -} - -template < bool hist_shift_required > -long -EpropArchivingNodeRecurrent< hist_shift_required >::model_dependent_history_shift_() const -{ - if constexpr ( hist_shift_required ) - { - return get_shift(); - } - else - { - return -delay_rec_out_; - } -} - -template < bool hist_shift_required > -bool -EpropArchivingNodeRecurrent< hist_shift_required >::history_shift_required_() const -{ - return hist_shift_required; -} - - } #endif diff --git a/nestkernel/eprop_archiving_node_recurrent_impl.h b/nestkernel/eprop_archiving_node_recurrent_impl.h index 58dde7a87e..83714faadc 100644 --- a/nestkernel/eprop_archiving_node_recurrent_impl.h +++ b/nestkernel/eprop_archiving_node_recurrent_impl.h @@ -20,18 +20,50 @@ * */ -// nestkernel -#include "eprop_archiving_node.h" -#include "eprop_archiving_node_impl.h" -#include "eprop_archiving_node_recurrent.h" -#include "kernel_manager.h" +#ifndef EPROP_ARCHIVING_NODE_RECURRENT_IMPL_H +#define EPROP_ARCHIVING_NODE_RECURRENT_IMPL_H -// sli -#include "dictutils.h" +#include "eprop_archiving_node_recurrent.h" namespace nest { + +template < bool hist_shift_required > +inline void +EpropArchivingNodeRecurrent< hist_shift_required >::count_spike() +{ + ++n_spikes_; +} + +template < bool hist_shift_required > +inline void +EpropArchivingNodeRecurrent< hist_shift_required >::reset_spike_count() +{ + n_spikes_ = 0; +} + +template < bool hist_shift_required > +long +EpropArchivingNodeRecurrent< hist_shift_required >::model_dependent_history_shift_() const +{ + if constexpr ( hist_shift_required ) + { + return get_shift(); + } + else + { + return -delay_rec_out_; + } +} + +template < bool hist_shift_required > +bool +EpropArchivingNodeRecurrent< hist_shift_required >::history_shift_required_() const +{ + return hist_shift_required; +} + template < bool hist_shift_required > std::map< std::string, typename EpropArchivingNodeRecurrent< hist_shift_required >::surrogate_gradient_function > EpropArchivingNodeRecurrent< hist_shift_required >::surrogate_gradient_funcs_ = { @@ -212,7 +244,7 @@ EpropArchivingNodeRecurrent< hist_shift_required >::write_firing_rate_reg_to_his return; } - const double update_interval = kernel().simulation_manager.get_eprop_update_interval().get_steps(); + const double update_interval = kernel::manager< SimulationManager >.get_eprop_update_interval().get_steps(); const double dt = Time::get_resolution().get_ms(); const long shift = Time::get_resolution().get_steps(); @@ -300,4 +332,7 @@ EpropArchivingNodeRecurrent< hist_shift_required >::erase_used_firing_rate_reg_h } -} // namespace nest +} + + +#endif diff --git a/nestkernel/event.cpp b/nestkernel/event.cpp index 6d33a5f615..0231d86bff 100644 --- a/nestkernel/event.cpp +++ b/nestkernel/event.cpp @@ -23,9 +23,9 @@ #include "event.h" // Includes from nestkernel: +#include "connection_manager.h" #include "kernel_manager.h" #include "node.h" -#include "secondary_event_impl.h" namespace nest { @@ -55,7 +55,7 @@ Event::retrieve_sender_node_id_from_source_table() const } else { - const size_t node_id = kernel().connection_manager.get_source_node_id( + const size_t node_id = kernel::manager< ConnectionManager >.get_source_node_id( sender_spike_data_.get_tid(), sender_spike_data_.get_syn_id(), sender_spike_data_.get_lcid() ); return node_id; } @@ -163,4 +163,392 @@ SICEvent::operator()() receiver_->handle( *this ); } +void +Event::set_rport( size_t rp ) +{ + + rp_ = rp; +} + +void +Event::set_port( size_t p ) +{ + + p_ = p; +} + +size_t +Event::get_rport() const +{ + + return rp_; +} + +size_t +Event::get_port() const +{ + + return p_; +} + +void +Event::set_offset( double t ) +{ + + offset_ = t; +} + +double +Event::get_offset() const +{ + + return offset_; +} + +void +Event::set_delay_steps( long d ) +{ + + d_ = d; +} + +long +Event::get_rel_delivery_steps( const Time& t ) const +{ + + if ( stamp_steps_ == 0 ) + { + stamp_steps_ = stamp_.get_steps(); + } + return stamp_steps_ + d_ - 1 - t.get_steps(); +} + +long +Event::get_delay_steps() const +{ + + return d_; +} + +void +Event::set_stamp( Time const& s ) +{ + + stamp_ = s; + stamp_steps_ = 0; // setting stamp_steps to zero indicates + // stamp_steps needs to be recalculated from + // stamp_ next time it is needed (e.g., in + // get_rel_delivery_steps) +} + +Time const& +Event::get_stamp() const +{ + + return stamp_; +} + +void +Event::set_weight( double w ) +{ + + w_ = w; +} + +double +Event::get_weight() const +{ + + return w_; +} + +size_t +Event::get_sender_node_id() const +{ + + assert( sender_node_id_ > 0 ); + return sender_node_id_; +} + +Node& +Event::get_sender() const +{ + + assert( sender_ ); + return *sender_; +} + +Node& +Event::get_receiver() const +{ + + assert( receiver_ ); + return *receiver_; +} + +void +Event::set_sender_node_id_info( const size_t tid, const synindex syn_id, const size_t lcid ) +{ + + // lag and offset of SpikeData are not used here + sender_spike_data_.set( tid, syn_id, lcid, 0, 0.0 ); +} + +void +Event::set_sender_node_id( const size_t node_id ) +{ + + sender_node_id_ = node_id; +} + +void +Event::set_sender( Node& s ) +{ + + sender_ = &s; +} + +void +Event::set_receiver( Node& r ) +{ + + receiver_ = &r; +} + +bool +Event::is_valid() const +{ + + return ( sender_is_valid() and receiver_is_valid() and d_ > 0 ); +} + +bool +Event::receiver_is_valid() const +{ + + return receiver_; +} + +bool +Event::sender_is_valid() const +{ + + return sender_; +} + +DoubleDataEvent* +DoubleDataEvent::clone() const +{ + + return new DoubleDataEvent( *this ); +} + + +double +ConductanceEvent::get_conductance() const +{ + + return g_; +} + +void +ConductanceEvent::set_conductance( double g ) +{ + + g_ = g; +} + +ConductanceEvent* +ConductanceEvent::clone() const +{ + + return new ConductanceEvent( *this ); +} + + +const std::vector< Name >& +DataLoggingRequest::record_from() const +{ + + // During simulation, events are created without recordables + // information. On these, record_from() must not be called. + assert( record_from_ ); + + return *record_from_; +} + +const Time& +DataLoggingRequest::get_recording_offset() const +{ + + assert( recording_offset_.is_finite() ); + return recording_offset_; +} + +const Time& +DataLoggingRequest::get_recording_interval() const +{ + + // During simulation, events are created without recording interval + // information. On these, get_recording_interval() must not be called. + assert( recording_interval_.is_finite() ); + + return recording_interval_; +} + +DataLoggingRequest* +DataLoggingRequest::clone() const +{ + + return new DataLoggingRequest( *this ); +} + +DataLoggingRequest::DataLoggingRequest( const Time& rec_int, const Time& rec_offset, const std::vector< Name >& recs ) + : Event() + , recording_interval_( rec_int ) + , recording_offset_( rec_offset ) + , record_from_( &recs ) +{ +} + +DataLoggingRequest::DataLoggingRequest( const Time& rec_int, const std::vector< Name >& recs ) + : Event() + , recording_interval_( rec_int ) + , record_from_( &recs ) +{ +} + +DataLoggingRequest::DataLoggingRequest() + : Event() + , recording_interval_( Time::neg_inf() ) + , recording_offset_( Time::ms( 0. ) ) + , record_from_( nullptr ) +{ +} + +double +CurrentEvent::get_current() const +{ + + return c_; +} + +void +CurrentEvent::set_current( double c ) +{ + + c_ = c; +} + +CurrentEvent* +CurrentEvent::clone() const +{ + + return new CurrentEvent( *this ); +} + +double +RateEvent::get_rate() const +{ + + return r_; +} + +void +RateEvent::set_rate( double r ) +{ + + r_ = r; +} + +RateEvent* +RateEvent::clone() const +{ + + return new RateEvent( *this ); +} + +size_t +WeightRecorderEvent::get_receiver_node_id() const +{ + + return receiver_node_id_; +} + +void +WeightRecorderEvent::set_receiver_node_id( size_t node_id ) +{ + + receiver_node_id_ = node_id; +} + +WeightRecorderEvent* +WeightRecorderEvent::clone() const +{ + + return new WeightRecorderEvent( *this ); +} + +WeightRecorderEvent::WeightRecorderEvent() + : receiver_node_id_( 0 ) +{ +} + +size_t +SpikeEvent::get_multiplicity() const +{ + + return multiplicity_; +} + +void +SpikeEvent::set_multiplicity( size_t multiplicity ) +{ + + multiplicity_ = multiplicity; +} + +SpikeEvent* +SpikeEvent::clone() const +{ + + return new SpikeEvent( *this ); +} + +SpikeEvent::SpikeEvent() + : multiplicity_( 1 ) +{ +} + +DataLoggingReply* +DataLoggingReply::clone() const +{ + + assert( false ); + return nullptr; +} + + +const DataLoggingReply::Container& +DataLoggingReply::get_info() const +{ + + return info_; +} + + +void +Event::set_drift_factor( double ) +{ +} + +Event::~Event() +{ +} + +DataLoggingReply::DataLoggingReply( const DataLoggingReply::Container& info ) + : info_( info ) +{ +} + } // namespace nest diff --git a/nestkernel/event.h b/nestkernel/event.h index 780234b4d5..c0b1595359 100644 --- a/nestkernel/event.h +++ b/nestkernel/event.h @@ -107,9 +107,7 @@ class Event public: Event(); - virtual ~Event() - { - } + virtual ~Event(); virtual Event* clone() const = 0; @@ -289,7 +287,7 @@ class Event /** * Set drift_factor of the event (see DiffusionConnectionEvent). */ - virtual void set_drift_factor( double ) {}; + virtual void set_drift_factor( double ); /** * Set diffusion_factor of the event (see DiffusionConnectionEvent). @@ -420,29 +418,6 @@ class SpikeEvent : public Event size_t multiplicity_; }; -inline SpikeEvent::SpikeEvent() - : multiplicity_( 1 ) -{ -} - -inline SpikeEvent* -SpikeEvent::clone() const -{ - return new SpikeEvent( *this ); -} - -inline void -SpikeEvent::set_multiplicity( size_t multiplicity ) -{ - multiplicity_ = multiplicity; -} - -inline size_t -SpikeEvent::get_multiplicity() const -{ - return multiplicity_; -} - /** * Event for recording the weight of a spike. @@ -469,29 +444,6 @@ class WeightRecorderEvent : public Event size_t receiver_node_id_; //!< node ID of receiver or 0. }; -inline WeightRecorderEvent::WeightRecorderEvent() - : receiver_node_id_( 0 ) -{ -} - -inline WeightRecorderEvent* -WeightRecorderEvent::clone() const -{ - return new WeightRecorderEvent( *this ); -} - -inline void -WeightRecorderEvent::set_receiver_node_id( size_t node_id ) -{ - receiver_node_id_ = node_id; -} - -inline size_t -WeightRecorderEvent::get_receiver_node_id() const -{ - return receiver_node_id_; -} - /** * "Callback request event" for use in Device. @@ -535,23 +487,6 @@ class RateEvent : public Event double get_rate() const; }; -inline RateEvent* -RateEvent::clone() const -{ - return new RateEvent( *this ); -} - -inline void -RateEvent::set_rate( double r ) -{ - r_ = r; -} - -inline double -RateEvent::get_rate() const -{ - return r_; -} /** * Event for electrical currents. @@ -569,23 +504,6 @@ class CurrentEvent : public Event double get_current() const; }; -inline CurrentEvent* -CurrentEvent::clone() const -{ - return new CurrentEvent( *this ); -} - -inline void -CurrentEvent::set_current( double c ) -{ - c_ = c; -} - -inline double -CurrentEvent::get_current() const -{ - return c_; -} /** * "Callback request event" for use in Device. @@ -663,64 +581,6 @@ class DataLoggingRequest : public Event std::vector< Name > const* const record_from_; }; -inline DataLoggingRequest::DataLoggingRequest() - : Event() - , recording_interval_( Time::neg_inf() ) - , recording_offset_( Time::ms( 0. ) ) - , record_from_( nullptr ) -{ -} - -inline DataLoggingRequest::DataLoggingRequest( const Time& rec_int, const std::vector< Name >& recs ) - : Event() - , recording_interval_( rec_int ) - , record_from_( &recs ) -{ -} - -inline DataLoggingRequest::DataLoggingRequest( const Time& rec_int, - const Time& rec_offset, - const std::vector< Name >& recs ) - : Event() - , recording_interval_( rec_int ) - , recording_offset_( rec_offset ) - , record_from_( &recs ) -{ -} - - -inline DataLoggingRequest* -DataLoggingRequest::clone() const -{ - return new DataLoggingRequest( *this ); -} - -inline const Time& -DataLoggingRequest::get_recording_interval() const -{ - // During simulation, events are created without recording interval - // information. On these, get_recording_interval() must not be called. - assert( recording_interval_.is_finite() ); - - return recording_interval_; -} - -inline const Time& -DataLoggingRequest::get_recording_offset() const -{ - assert( recording_offset_.is_finite() ); - return recording_offset_; -} - -inline const std::vector< Name >& -DataLoggingRequest::record_from() const -{ - // During simulation, events are created without recordables - // information. On these, record_from() must not be called. - assert( record_from_ ); - - return *record_from_; -} /** * Provide logged data through request transmitting reference. @@ -763,33 +623,19 @@ class DataLoggingReply : public Event void operator()() override; //! Access referenced data - const Container& - get_info() const - { - return info_; - } + const Container& get_info() const; private: //! Prohibit copying DataLoggingReply( const DataLoggingReply& ); //! Prohibit cloning - DataLoggingReply* - clone() const override - { - assert( false ); - return nullptr; - } + DataLoggingReply* clone() const override; //! data to be transmitted, with time stamps const Container& info_; }; -inline DataLoggingReply::DataLoggingReply( const Container& d ) - : Event() - , info_( d ) -{ -} /** * Event for electrical conductances. @@ -809,24 +655,6 @@ class ConductanceEvent : public Event double get_conductance() const; }; -inline ConductanceEvent* -ConductanceEvent::clone() const -{ - return new ConductanceEvent( *this ); -} - -inline void -ConductanceEvent::set_conductance( double g ) -{ - g_ = g; -} - -inline double -ConductanceEvent::get_conductance() const -{ - return g_; -} - /** * Event for transmitting arbitrary data. @@ -875,164 +703,11 @@ class DoubleDataEvent : public DataEvent< double > DoubleDataEvent* clone() const override; }; -inline DoubleDataEvent* -DoubleDataEvent::clone() const -{ - return new DoubleDataEvent( *this ); -} //************************************************************* // Inline implementations. -inline bool -Event::sender_is_valid() const -{ - return sender_; -} - -inline bool -Event::receiver_is_valid() const -{ - return receiver_; -} - -inline bool -Event::is_valid() const -{ - return ( sender_is_valid() and receiver_is_valid() and d_ > 0 ); -} -inline void -Event::set_receiver( Node& r ) -{ - receiver_ = &r; -} - -inline void -Event::set_sender( Node& s ) -{ - sender_ = &s; -} - -inline void -Event::set_sender_node_id( const size_t node_id ) -{ - sender_node_id_ = node_id; -} - -inline void -Event::set_sender_node_id_info( const size_t tid, const synindex syn_id, const size_t lcid ) -{ - // lag and offset of SpikeData are not used here - sender_spike_data_.set( tid, syn_id, lcid, 0, 0.0 ); -} - -inline Node& -Event::get_receiver() const -{ - assert( receiver_ ); - return *receiver_; -} - -inline Node& -Event::get_sender() const -{ - assert( sender_ ); - return *sender_; -} - -inline size_t -Event::get_sender_node_id() const -{ - assert( sender_node_id_ > 0 ); - return sender_node_id_; -} - -inline double -Event::get_weight() const -{ - return w_; -} - -inline void -Event::set_weight( double w ) -{ - w_ = w; -} - -inline Time const& -Event::get_stamp() const -{ - return stamp_; -} - -inline void -Event::set_stamp( Time const& s ) -{ - stamp_ = s; - stamp_steps_ = 0; // setting stamp_steps to zero indicates - // stamp_steps needs to be recalculated from - // stamp_ next time it is needed (e.g., in - // get_rel_delivery_steps) -} - -inline long -Event::get_delay_steps() const -{ - return d_; -} - -inline long -Event::get_rel_delivery_steps( const Time& t ) const -{ - if ( stamp_steps_ == 0 ) - { - stamp_steps_ = stamp_.get_steps(); - } - return stamp_steps_ + d_ - 1 - t.get_steps(); -} - -inline void -Event::set_delay_steps( long d ) -{ - d_ = d; -} - -inline double -Event::get_offset() const -{ - return offset_; -} - -inline void -Event::set_offset( double t ) -{ - offset_ = t; -} - -inline size_t -Event::get_port() const -{ - return p_; -} - -inline size_t -Event::get_rport() const -{ - return rp_; -} - -inline void -Event::set_port( size_t p ) -{ - p_ = p; -} - -inline void -Event::set_rport( size_t rp ) -{ - rp_ = rp; -} } #endif /* EVENT_H */ diff --git a/nestkernel/event_delivery_manager.cpp b/nestkernel/event_delivery_manager.cpp index 8ba790b740..c992f61e61 100644 --- a/nestkernel/event_delivery_manager.cpp +++ b/nestkernel/event_delivery_manager.cpp @@ -28,15 +28,12 @@ // Includes from nestkernel: #include "connection_manager.h" -#include "connection_manager_impl.h" -#include "event_delivery_manager_impl.h" #include "kernel_manager.h" +#include "model_manager.h" #include "mpi_manager_impl.h" #include "send_buffer_position.h" -#include "source.h" -#include "stopwatch_impl.h" +#include "simulation_manager.h" #include "vp_manager.h" -#include "vp_manager_impl.h" // Includes from sli: #include "dictutils.h" @@ -92,7 +89,7 @@ EventDeliveryManager::initialize( const bool adjust_number_of_threads_or_rng_onl send_recv_buffer_resize_log_.clear(); } - const size_t num_threads = kernel().vp_manager.get_num_threads(); + const size_t num_threads = kernel::manager< VPManager >.get_num_threads(); local_spike_counter_.resize( num_threads, 0 ); reset_counters(); @@ -102,7 +99,7 @@ EventDeliveryManager::initialize( const bool adjust_number_of_threads_or_rng_onl #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); if ( not emitted_spikes_register_[ tid ] ) { @@ -201,26 +198,26 @@ void EventDeliveryManager::resize_send_recv_buffers_target_data() { // compute send receive counts and allocate memory for buffers - send_buffer_target_data_.resize( kernel().mpi_manager.get_buffer_size_target_data() ); - recv_buffer_target_data_.resize( kernel().mpi_manager.get_buffer_size_target_data() ); + send_buffer_target_data_.resize( kernel::manager< MPIManager >.get_buffer_size_target_data() ); + recv_buffer_target_data_.resize( kernel::manager< MPIManager >.get_buffer_size_target_data() ); } void EventDeliveryManager::resize_send_recv_buffers_spike_data_() { - if ( kernel().mpi_manager.get_buffer_size_spike_data() > send_buffer_spike_data_.size() ) + if ( kernel::manager< MPIManager >.get_buffer_size_spike_data() > send_buffer_spike_data_.size() ) { - send_buffer_spike_data_.resize( kernel().mpi_manager.get_buffer_size_spike_data() ); - recv_buffer_spike_data_.resize( kernel().mpi_manager.get_buffer_size_spike_data() ); - send_buffer_off_grid_spike_data_.resize( kernel().mpi_manager.get_buffer_size_spike_data() ); - recv_buffer_off_grid_spike_data_.resize( kernel().mpi_manager.get_buffer_size_spike_data() ); + send_buffer_spike_data_.resize( kernel::manager< MPIManager >.get_buffer_size_spike_data() ); + recv_buffer_spike_data_.resize( kernel::manager< MPIManager >.get_buffer_size_spike_data() ); + send_buffer_off_grid_spike_data_.resize( kernel::manager< MPIManager >.get_buffer_size_spike_data() ); + recv_buffer_off_grid_spike_data_.resize( kernel::manager< MPIManager >.get_buffer_size_spike_data() ); } } void EventDeliveryManager::configure_spike_data_buffers() { - assert( kernel().connection_manager.get_min_delay() != 0 ); + assert( kernel::manager< ConnectionManager >.get_min_delay() != 0 ); configure_spike_register(); @@ -235,7 +232,7 @@ EventDeliveryManager::configure_spike_register() { #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); reset_spike_register_( tid ); } } @@ -244,16 +241,16 @@ void EventDeliveryManager::configure_secondary_buffers() { send_buffer_secondary_events_.clear(); - send_buffer_secondary_events_.resize( kernel().mpi_manager.get_send_buffer_size_secondary_events_in_int() ); + send_buffer_secondary_events_.resize( kernel::manager< MPIManager >.get_send_buffer_size_secondary_events_in_int() ); recv_buffer_secondary_events_.clear(); - recv_buffer_secondary_events_.resize( kernel().mpi_manager.get_recv_buffer_size_secondary_events_in_int() ); + recv_buffer_secondary_events_.resize( kernel::manager< MPIManager >.get_recv_buffer_size_secondary_events_in_int() ); } void EventDeliveryManager::init_moduli() { - long min_delay = kernel().connection_manager.get_min_delay(); - long max_delay = kernel().connection_manager.get_max_delay(); + long min_delay = kernel::manager< ConnectionManager >.get_min_delay(); + long max_delay = kernel::manager< ConnectionManager >.get_max_delay(); assert( min_delay != 0 ); assert( max_delay != 0 ); @@ -265,7 +262,7 @@ EventDeliveryManager::init_moduli() for ( long d = 0; d < min_delay + max_delay; ++d ) { - moduli_[ d ] = ( kernel().simulation_manager.get_clock().get_steps() + d ) % ( min_delay + max_delay ); + moduli_[ d ] = ( kernel::manager< SimulationManager >.get_clock().get_steps() + d ) % ( min_delay + max_delay ); } // Slice-based ring-buffers have one bin per min_delay steps, @@ -275,15 +272,15 @@ EventDeliveryManager::init_moduli() slice_moduli_.resize( min_delay + max_delay ); for ( long d = 0; d < min_delay + max_delay; ++d ) { - slice_moduli_[ d ] = ( ( kernel().simulation_manager.get_clock().get_steps() + d ) / min_delay ) % nbuff; + slice_moduli_[ d ] = ( ( kernel::manager< SimulationManager >.get_clock().get_steps() + d ) / min_delay ) % nbuff; } } void EventDeliveryManager::update_moduli() { - long min_delay = kernel().connection_manager.get_min_delay(); - long max_delay = kernel().connection_manager.get_max_delay(); + long min_delay = kernel::manager< ConnectionManager >.get_min_delay(); + long max_delay = kernel::manager< ConnectionManager >.get_max_delay(); assert( min_delay != 0 ); assert( max_delay != 0 ); @@ -300,7 +297,7 @@ EventDeliveryManager::update_moduli() const size_t nbuff = static_cast< size_t >( std::ceil( static_cast< double >( min_delay + max_delay ) / min_delay ) ); for ( long d = 0; d < min_delay + max_delay; ++d ) { - slice_moduli_[ d ] = ( ( kernel().simulation_manager.get_clock().get_steps() + d ) / min_delay ) % nbuff; + slice_moduli_[ d ] = ( ( kernel::manager< SimulationManager >.get_clock().get_steps() + d ) / min_delay ) % nbuff; } } @@ -330,10 +327,10 @@ void EventDeliveryManager::write_done_marker_secondary_events_( const bool done ) { // write done marker at last position in every chunk - for ( size_t rank = 0; rank < kernel().mpi_manager.get_num_processes(); ++rank ) + for ( size_t rank = 0; rank < kernel::manager< MPIManager >.get_num_processes(); ++rank ) { - send_buffer_secondary_events_[ kernel().mpi_manager.get_done_marker_position_in_secondary_events_send_buffer( - rank ) ] = done; + send_buffer_secondary_events_ + [ kernel::manager< MPIManager >.get_done_marker_position_in_secondary_events_send_buffer( rank ) ] = done; } } @@ -341,14 +338,14 @@ void EventDeliveryManager::gather_secondary_events( const bool done ) { write_done_marker_secondary_events_( done ); - kernel().mpi_manager.communicate_secondary_events_Alltoallv( + kernel::manager< MPIManager >.communicate_secondary_events_Alltoallv( send_buffer_secondary_events_, recv_buffer_secondary_events_ ); } bool EventDeliveryManager::deliver_secondary_events( const size_t tid, const bool called_from_wfr_update ) { - return kernel().connection_manager.deliver_secondary_events( + return kernel::manager< ConnectionManager >.deliver_secondary_events( tid, called_from_wfr_update, recv_buffer_secondary_events_ ); } @@ -373,14 +370,14 @@ EventDeliveryManager::gather_spike_data_( std::vector< SpikeDataT >& send_buffer // NOTE: For meaning and logic of SpikeData flags for detecting complete transmission // and information for shrink/grow, see comment in spike_data.h. - const size_t old_buff_size_per_rank = kernel().mpi_manager.get_send_recv_count_spike_data_per_rank(); + const size_t old_buff_size_per_rank = kernel::manager< MPIManager >.get_send_recv_count_spike_data_per_rank(); if ( global_max_spikes_per_rank_ < send_recv_buffer_shrink_limit_ * old_buff_size_per_rank ) { const size_t new_buff_size_per_rank = std::max( 2UL, static_cast< size_t >( ( 1 + send_recv_buffer_shrink_spare_ ) * global_max_spikes_per_rank_ ) ); - kernel().mpi_manager.set_buffer_size_spike_data( - kernel().mpi_manager.get_num_processes() * new_buff_size_per_rank ); + kernel::manager< MPIManager >.set_buffer_size_spike_data( + kernel::manager< MPIManager >.get_num_processes() * new_buff_size_per_rank ); resize_send_recv_buffers_spike_data_(); send_recv_buffer_resize_log_.add_entry( global_max_spikes_per_rank_, new_buff_size_per_rank ); } @@ -399,7 +396,7 @@ EventDeliveryManager::gather_spike_data_( std::vector< SpikeDataT >& send_buffer // Set marker at end of each chunk to DEFAULT reset_complete_marker_spike_data_( send_buffer_position, send_buffer ); - std::vector< size_t > num_spikes_per_rank( kernel().mpi_manager.get_num_processes(), 0 ); + std::vector< size_t > num_spikes_per_rank( kernel::manager< MPIManager >.get_num_processes(), 0 ); // Collocate spikes to send buffer collocate_spike_data_buffers_( send_buffer_position, emitted_spikes_register_, send_buffer, num_spikes_per_rank ); @@ -423,19 +420,19 @@ EventDeliveryManager::gather_spike_data_( std::vector< SpikeDataT >& send_buffer // We introduce an explicit barrier at this point to measure how long each process idles until all other processes // reached this point as well. This barrier is directly followed by another implicit barrier due to global // communication. - kernel().get_mpi_synchronization_stopwatch().start(); - kernel().mpi_manager.synchronize(); - kernel().get_mpi_synchronization_stopwatch().stop(); + kernel::manager< SimulationManager >.get_mpi_synchronization_stopwatch().start(); + kernel::manager< MPIManager >.synchronize(); + kernel::manager< SimulationManager >.get_mpi_synchronization_stopwatch().stop(); #endif // Given that we templatize by plain vs offgrid, this if should not be necessary, but ... if ( off_grid_spiking_ ) { - kernel().mpi_manager.communicate_off_grid_spike_data_Alltoall( send_buffer, recv_buffer ); + kernel::manager< MPIManager >.communicate_off_grid_spike_data_Alltoall( send_buffer, recv_buffer ); } else { - kernel().mpi_manager.communicate_spike_data_Alltoall( send_buffer, recv_buffer ); + kernel::manager< MPIManager >.communicate_spike_data_Alltoall( send_buffer, recv_buffer ); } sw_communicate_spike_data_.stop(); @@ -443,15 +440,15 @@ EventDeliveryManager::gather_spike_data_( std::vector< SpikeDataT >& send_buffer global_max_spikes_per_rank_ = get_global_max_spikes_per_rank_( send_buffer_position, recv_buffer ); all_spikes_transmitted = - global_max_spikes_per_rank_ <= kernel().mpi_manager.get_send_recv_count_spike_data_per_rank(); + global_max_spikes_per_rank_ <= kernel::manager< MPIManager >.get_send_recv_count_spike_data_per_rank(); if ( not all_spikes_transmitted ) { const size_t new_buff_size_per_rank = static_cast< size_t >( ( 1 + send_recv_buffer_grow_extra_ ) * global_max_spikes_per_rank_ ); - kernel().mpi_manager.set_buffer_size_spike_data( - kernel().mpi_manager.get_num_processes() * new_buff_size_per_rank ); + kernel::manager< MPIManager >.set_buffer_size_spike_data( + kernel::manager< MPIManager >.get_num_processes() * new_buff_size_per_rank ); resize_send_recv_buffers_spike_data_(); send_recv_buffer_resize_log_.add_entry( global_max_spikes_per_rank_, new_buff_size_per_rank ); } @@ -506,9 +503,9 @@ EventDeliveryManager::set_end_marker_( const SendBufferPosition& send_buffer_pos { // See comment in spike_data.h for logic. const bool collocate_complete = local_max_spikes_per_rank - <= static_cast< size_t >( kernel().mpi_manager.get_send_recv_count_spike_data_per_rank() ); + <= static_cast< size_t >( kernel::manager< MPIManager >.get_send_recv_count_spike_data_per_rank() ); - for ( size_t rank = 0; rank < kernel().mpi_manager.get_num_processes(); ++rank ) + for ( size_t rank = 0; rank < kernel::manager< MPIManager >.get_num_processes(); ++rank ) { const size_t end_idx = send_buffer_position.end( rank ) - 1; if ( not collocate_complete ) @@ -549,7 +546,7 @@ void EventDeliveryManager::reset_complete_marker_spike_data_( const SendBufferPosition& send_buffer_position, std::vector< SpikeDataT >& send_buffer ) const { - for ( size_t rank = 0; rank < kernel().mpi_manager.get_num_processes(); ++rank ) + for ( size_t rank = 0; rank < kernel::manager< MPIManager >.get_num_processes(); ++rank ) { const size_t idx = send_buffer_position.end( rank ) - 1; send_buffer[ idx ].reset_marker(); @@ -564,7 +561,7 @@ EventDeliveryManager::get_global_max_spikes_per_rank_( const SendBufferPosition& // TODO: send_buffer_position not needed here, only used to get endpoint of each per-rank section of buffer size_t maximum = 0; - for ( size_t target_rank = 0; target_rank < kernel().mpi_manager.get_num_processes(); ++target_rank ) + for ( size_t target_rank = 0; target_rank < kernel::manager< MPIManager >.get_num_processes(); ++target_rank ) { const auto& end_entry = recv_buffer[ send_buffer_position.end( target_rank ) - 1 ]; size_t max_per_thread_max_spikes_per_rank = 0; @@ -575,7 +572,7 @@ EventDeliveryManager::get_global_max_spikes_per_rank_( const SendBufferPosition& else { assert( end_entry.is_end_marker() ); - max_per_thread_max_spikes_per_rank = kernel().mpi_manager.get_send_recv_count_spike_data_per_rank(); + max_per_thread_max_spikes_per_rank = kernel::manager< MPIManager >.get_send_recv_count_spike_data_per_rank(); } maximum = std::max( max_per_thread_max_spikes_per_rank, maximum ); } @@ -601,25 +598,25 @@ void EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< SpikeDataT >& recv_buffer ) { // deliver only at beginning of time slice - if ( kernel().simulation_manager.get_from_step() > 0 ) + if ( kernel::manager< SimulationManager >.get_from_step() > 0 ) { return; } - const size_t spike_buffer_size_per_rank = kernel().mpi_manager.get_send_recv_count_spike_data_per_rank(); - const std::vector< ConnectorModel* >& cm = kernel().model_manager.get_connection_models( tid ); + const size_t spike_buffer_size_per_rank = kernel::manager< MPIManager >.get_send_recv_count_spike_data_per_rank(); + const std::vector< ConnectorModel* >& cm = kernel::manager< ModelManager >.get_connection_models( tid ); // prepare Time objects for every possible time stamp within min_delay_ - std::vector< Time > prepared_timestamps( kernel().connection_manager.get_min_delay() ); - for ( size_t lag = 0; lag < static_cast< size_t >( kernel().connection_manager.get_min_delay() ); ++lag ) + std::vector< Time > prepared_timestamps( kernel::manager< ConnectionManager >.get_min_delay() ); + for ( size_t lag = 0; lag < static_cast< size_t >( kernel::manager< ConnectionManager >.get_min_delay() ); ++lag ) { // Subtract min_delay because spikes were emitted in previous time slice and we use current clock. - prepared_timestamps[ lag ] = - kernel().simulation_manager.get_clock() + Time::step( lag + 1 - kernel().connection_manager.get_min_delay() ); + prepared_timestamps[ lag ] = kernel::manager< SimulationManager >.get_clock() + + Time::step( lag + 1 - kernel::manager< ConnectionManager >.get_min_delay() ); } // Deliver spikes sent by each rank in order - for ( size_t rank = 0; rank < kernel().mpi_manager.get_num_processes(); ++rank ) + for ( size_t rank = 0; rank < kernel::manager< MPIManager >.get_num_processes(); ++rank ) { // Continue with next rank if no spikes were sent by current rank if ( recv_buffer[ rank * spike_buffer_size_per_rank ].is_invalid_marker() ) @@ -651,7 +648,7 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik size_t syn_id_batch[ SPIKES_PER_BATCH ]; size_t lcid_batch[ SPIKES_PER_BATCH ]; - if ( not kernel().connection_manager.use_compressed_spikes() ) + if ( not kernel::manager< ConnectionManager >.use_compressed_spikes() ) { for ( size_t i = 0; i < num_batches; ++i ) { @@ -669,7 +666,8 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik { if ( tid_batch[ j ] == tid ) { - kernel().connection_manager.send( tid_batch[ j ], syn_id_batch[ j ], lcid_batch[ j ], cm, se_batch[ j ] ); + kernel::manager< ConnectionManager >.send( + tid_batch[ j ], syn_id_batch[ j ], lcid_batch[ j ], cm, se_batch[ j ] ); } } } @@ -690,7 +688,8 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik { if ( tid_batch[ j ] == tid ) { - kernel().connection_manager.send( tid_batch[ j ], syn_id_batch[ j ], lcid_batch[ j ], cm, se_batch[ j ] ); + kernel::manager< ConnectionManager >.send( + tid_batch[ j ], syn_id_batch[ j ], lcid_batch[ j ], cm, se_batch[ j ] ); } } } @@ -714,7 +713,7 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik { // find the spike-data entry for this thread const std::vector< SpikeData >& compressed_spike_data = - kernel().connection_manager.get_compressed_spike_data( syn_id_batch[ j ], lcid_batch[ j ] ); + kernel::manager< ConnectionManager >.get_compressed_spike_data( syn_id_batch[ j ], lcid_batch[ j ] ); lcid_batch[ j ] = compressed_spike_data[ tid ].get_lcid(); } for ( size_t j = 0; j < SPIKES_PER_BATCH; ++j ) @@ -730,7 +729,7 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik { if ( lcid_batch[ j ] != invalid_lcid ) { - kernel().connection_manager.send( tid, syn_id_batch[ j ], lcid_batch[ j ], cm, se_batch[ j ] ); + kernel::manager< ConnectionManager >.send( tid, syn_id_batch[ j ], lcid_batch[ j ], cm, se_batch[ j ] ); } } } @@ -751,7 +750,7 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik { // find the spike-data entry for this thread const std::vector< SpikeData >& compressed_spike_data = - kernel().connection_manager.get_compressed_spike_data( syn_id_batch[ j ], lcid_batch[ j ] ); + kernel::manager< ConnectionManager >.get_compressed_spike_data( syn_id_batch[ j ], lcid_batch[ j ] ); lcid_batch[ j ] = compressed_spike_data[ tid ].get_lcid(); } for ( size_t j = 0; j < num_remaining_entries; ++j ) @@ -767,27 +766,64 @@ EventDeliveryManager::deliver_events_( const size_t tid, const std::vector< Spik { if ( lcid_batch[ j ] != invalid_lcid ) { - kernel().connection_manager.send( tid, syn_id_batch[ j ], lcid_batch[ j ], cm, se_batch[ j ] ); + kernel::manager< ConnectionManager >.send( tid, syn_id_batch[ j ], lcid_batch[ j ], cm, se_batch[ j ] ); } } } // if-else not compressed } // for rank } +template <> +void +EventDeliveryManager::send< SpikeEvent >( Node& source, SpikeEvent& e, const long lag ) +{ + const size_t tid = source.get_thread(); + const size_t source_node_id = source.get_node_id(); + e.set_sender_node_id( source_node_id ); + if ( source.has_proxies() ) + { + local_spike_counter_[ tid ] += e.get_multiplicity(); + + e.set_stamp( kernel::manager< SimulationManager >.get_slice_origin() + Time::step( lag + 1 ) ); + e.set_sender( source ); + + if ( source.is_off_grid() ) + { + send_off_grid_remote( tid, e, lag ); + } + else + { + send_remote( tid, e, lag ); + } + kernel::manager< ConnectionManager >.send_to_devices( tid, source_node_id, e ); + } + else + { + send_local_( source, e, lag ); + } +} + +template <> +void +EventDeliveryManager::send< DSSpikeEvent >( Node& source, DSSpikeEvent& e, const long lag ) +{ + e.set_sender_node_id( source.get_node_id() ); + send_local_( source, e, lag ); +} void EventDeliveryManager::gather_target_data( const size_t tid ) { - assert( not kernel().connection_manager.is_source_table_cleared() ); + assert( not kernel::manager< ConnectionManager >.is_source_table_cleared() ); // assume all threads have some work to do gather_completed_checker_.set_false( tid ); assert( gather_completed_checker_.all_false() ); - const AssignedRanks assigned_ranks = kernel().vp_manager.get_assigned_ranks( tid ); + const AssignedRanks assigned_ranks = kernel::manager< VPManager >.get_assigned_ranks( tid ); - kernel().connection_manager.prepare_target_table( tid ); - kernel().connection_manager.reset_source_table_entry_point( tid ); + kernel::manager< ConnectionManager >.prepare_target_table( tid ); + kernel::manager< ConnectionManager >.reset_source_table_entry_point( tid ); while ( gather_completed_checker_.any_false() ) { @@ -797,19 +833,19 @@ EventDeliveryManager::gather_target_data( const size_t tid ) #pragma omp master { - if ( kernel().mpi_manager.adaptive_target_buffers() and buffer_size_target_data_has_changed_ ) + if ( kernel::manager< MPIManager >.adaptive_target_buffers() and buffer_size_target_data_has_changed_ ) { resize_send_recv_buffers_target_data(); } } // of omp master; (no barrier) - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); - kernel().connection_manager.restore_source_table_entry_point( tid ); + kernel::manager< ConnectionManager >.restore_source_table_entry_point( tid ); TargetSendBufferPosition send_buffer_position( - assigned_ranks, kernel().mpi_manager.get_send_recv_count_target_data_per_rank() ); + assigned_ranks, kernel::manager< MPIManager >.get_send_recv_count_target_data_per_rank() ); const bool gather_completed = collocate_target_data_buffers_( tid, assigned_ranks, send_buffer_position ); gather_completed_checker_.logical_and( tid, gather_completed ); @@ -818,16 +854,17 @@ EventDeliveryManager::gather_target_data( const size_t tid ) { set_complete_marker_target_data_( assigned_ranks, send_buffer_position ); } - kernel().connection_manager.save_source_table_entry_point( tid ); - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< ConnectionManager >.save_source_table_entry_point( tid ); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); - kernel().connection_manager.clean_source_table( tid ); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< ConnectionManager >.clean_source_table( tid ); #pragma omp master { sw_communicate_target_data_.start(); - kernel().mpi_manager.communicate_target_data_Alltoall( send_buffer_target_data_, recv_buffer_target_data_ ); + kernel::manager< MPIManager >.communicate_target_data_Alltoall( + send_buffer_target_data_, recv_buffer_target_data_ ); sw_communicate_target_data_.stop(); } // of omp master (no barriers!) #pragma omp barrier @@ -836,31 +873,31 @@ EventDeliveryManager::gather_target_data( const size_t tid ) gather_completed_checker_.logical_and( tid, distribute_completed ); // resize mpi buffers, if necessary and allowed - if ( gather_completed_checker_.any_false() and kernel().mpi_manager.adaptive_target_buffers() ) + if ( gather_completed_checker_.any_false() and kernel::manager< MPIManager >.adaptive_target_buffers() ) { #pragma omp master { - buffer_size_target_data_has_changed_ = kernel().mpi_manager.increase_buffer_size_target_data(); + buffer_size_target_data_has_changed_ = kernel::manager< MPIManager >.increase_buffer_size_target_data(); } #pragma omp barrier } } // of while - kernel().connection_manager.clear_source_table( tid ); + kernel::manager< ConnectionManager >.clear_source_table( tid ); } void EventDeliveryManager::gather_target_data_compressed( const size_t tid ) { - assert( not kernel().connection_manager.is_source_table_cleared() ); + assert( not kernel::manager< ConnectionManager >.is_source_table_cleared() ); // assume all threads have some work to do gather_completed_checker_.set_false( tid ); assert( gather_completed_checker_.all_false() ); - const AssignedRanks assigned_ranks = kernel().vp_manager.get_assigned_ranks( tid ); + const AssignedRanks assigned_ranks = kernel::manager< VPManager >.get_assigned_ranks( tid ); - kernel().connection_manager.prepare_target_table( tid ); + kernel::manager< ConnectionManager >.prepare_target_table( tid ); while ( gather_completed_checker_.any_false() ) { @@ -869,17 +906,17 @@ EventDeliveryManager::gather_target_data_compressed( const size_t tid ) #pragma omp master { - if ( kernel().mpi_manager.adaptive_target_buffers() and buffer_size_target_data_has_changed_ ) + if ( kernel::manager< MPIManager >.adaptive_target_buffers() and buffer_size_target_data_has_changed_ ) { resize_send_recv_buffers_target_data(); } } // of omp master; no barrier - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); TargetSendBufferPosition send_buffer_position( - assigned_ranks, kernel().mpi_manager.get_send_recv_count_target_data_per_rank() ); + assigned_ranks, kernel::manager< MPIManager >.get_send_recv_count_target_data_per_rank() ); const bool gather_completed = collocate_target_data_buffers_compressed_( tid, assigned_ranks, send_buffer_position ); @@ -891,14 +928,15 @@ EventDeliveryManager::gather_target_data_compressed( const size_t tid ) set_complete_marker_target_data_( assigned_ranks, send_buffer_position ); } - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); #pragma omp master { sw_communicate_target_data_.start(); - kernel().mpi_manager.communicate_target_data_Alltoall( send_buffer_target_data_, recv_buffer_target_data_ ); + kernel::manager< MPIManager >.communicate_target_data_Alltoall( + send_buffer_target_data_, recv_buffer_target_data_ ); sw_communicate_target_data_.stop(); } // of omp master (no barrier) #pragma omp barrier @@ -910,20 +948,20 @@ EventDeliveryManager::gather_target_data_compressed( const size_t tid ) gather_completed_checker_.logical_and( tid, distribute_completed ); // resize mpi buffers, if necessary and allowed - if ( gather_completed_checker_.any_false() and kernel().mpi_manager.adaptive_target_buffers() ) + if ( gather_completed_checker_.any_false() and kernel::manager< MPIManager >.adaptive_target_buffers() ) { #pragma omp master { - buffer_size_target_data_has_changed_ = kernel().mpi_manager.increase_buffer_size_target_data(); + buffer_size_target_data_has_changed_ = kernel::manager< MPIManager >.increase_buffer_size_target_data(); } // of omp master (no barrier) - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); } } // of while - kernel().connection_manager.clear_source_table( tid ); + kernel::manager< ConnectionManager >.clear_source_table( tid ); } bool @@ -939,7 +977,7 @@ EventDeliveryManager::collocate_target_data_buffers_( const size_t tid, // no ranks to process for this thread if ( assigned_ranks.begin == assigned_ranks.end ) { - kernel().connection_manager.no_targets_to_process( tid ); + kernel::manager< ConnectionManager >.no_targets_to_process( tid ); return is_source_table_read; } @@ -956,7 +994,7 @@ EventDeliveryManager::collocate_target_data_buffers_( const size_t tid, while ( true ) { - valid_next_target_data = kernel().connection_manager.get_next_target_data( + valid_next_target_data = kernel::manager< ConnectionManager >.get_next_target_data( tid, assigned_ranks.begin, assigned_ranks.end, source_rank, next_target_data ); if ( valid_next_target_data ) // add valid entry to MPI buffer { @@ -964,11 +1002,11 @@ EventDeliveryManager::collocate_target_data_buffers_( const size_t tid, { // entry does not fit in this part of the MPI buffer any more, // so we need to reject it - kernel().connection_manager.reject_last_target_data( tid ); + kernel::manager< ConnectionManager >.reject_last_target_data( tid ); // after rejecting the last target, we need to save the // position to start at this point again next communication // round - kernel().connection_manager.save_source_table_entry_point( tid ); + kernel::manager< ConnectionManager >.save_source_table_entry_point( tid ); // we have just rejected an entry, so source table can not be // fully read is_source_table_read = false; @@ -1028,7 +1066,7 @@ EventDeliveryManager::collocate_target_data_buffers_compressed_( const size_t ti send_buffer_target_data_[ send_buffer_position.begin( rank ) ].set_invalid_marker(); } - const bool is_source_table_read = kernel().connection_manager.fill_target_buffer( + const bool is_source_table_read = kernel::manager< ConnectionManager >.fill_target_buffer( tid, assigned_ranks.begin, assigned_ranks.end, send_buffer_target_data_, send_buffer_position ); return is_source_table_read; @@ -1051,9 +1089,9 @@ nest::EventDeliveryManager::distribute_target_data_buffers_( const size_t tid ) { bool are_others_completed = true; const unsigned int send_recv_count_target_data_per_rank = - kernel().mpi_manager.get_send_recv_count_target_data_per_rank(); + kernel::manager< MPIManager >.get_send_recv_count_target_data_per_rank(); - for ( size_t rank = 0; rank < kernel().mpi_manager.get_num_processes(); ++rank ) + for ( size_t rank = 0; rank < kernel::manager< MPIManager >.get_num_processes(); ++rank ) { // Check last entry for completed marker if ( not recv_buffer_target_data_[ ( rank + 1 ) * send_recv_count_target_data_per_rank - 1 ].is_complete_marker() ) @@ -1072,7 +1110,7 @@ nest::EventDeliveryManager::distribute_target_data_buffers_( const size_t tid ) const TargetData& target_data = recv_buffer_target_data_[ rank * send_recv_count_target_data_per_rank + i ]; if ( target_data.get_source_tid() == tid ) { - kernel().connection_manager.add_target( tid, rank, target_data ); + kernel::manager< ConnectionManager >.add_target( tid, rank, target_data ); } // Is this the last target from this rank? @@ -1086,4 +1124,161 @@ nest::EventDeliveryManager::distribute_target_data_buffers_( const size_t tid ) return are_others_completed; } +size_t +EventDeliveryManager::write_toggle() const +{ + + return kernel::manager< SimulationManager >.get_slice() % 2; +} + +void +EventDeliveryManager::send_secondary( Node& source, SecondaryEvent& e ) +{ + + const size_t tid = kernel::manager< VPManager >.get_thread_id(); + const size_t source_node_id = source.get_node_id(); + const size_t lid = kernel::manager< VPManager >.node_id_to_lid( source_node_id ); + + if ( source.has_proxies() ) + { + + // We need to consider every synapse type this event supports to + // make sure also labeled and connection created by CopyModel are + // considered. + const std::set< synindex >& supported_syn_ids = e.get_supported_syn_ids(); + for ( const auto& syn_id : supported_syn_ids ) + { + const std::vector< size_t >& positions = + kernel::manager< ConnectionManager >.get_secondary_send_buffer_positions( tid, lid, syn_id ); + + for ( size_t i = 0; i < positions.size(); ++i ) + { + std::vector< unsigned int >::iterator it = send_buffer_secondary_events_.begin() + positions[ i ]; + e >> it; + } + } + kernel::manager< ConnectionManager >.send_to_devices( tid, source_node_id, e ); + } + else + { + send_local_( source, e, 0 ); // need to pass lag (last argument), but not + // used in template specialization, so pass + // zero as dummy value + } +} + +void +EventDeliveryManager::send_off_grid_remote( size_t tid, SpikeEvent& e, const long lag ) +{ + + // Put the spike in a buffer for the remote machines + const size_t lid = kernel::manager< VPManager >.node_id_to_lid( e.get_sender().get_node_id() ); + const auto& targets = kernel::manager< ConnectionManager >.get_remote_targets_of_local_node( tid, lid ); + + for ( const auto& target : targets ) + { + // Unroll spike multiplicity as plastic synapses only handle individual spikes. + for ( size_t i = 0; i < e.get_multiplicity(); ++i ) + { + ( *off_grid_emitted_spikes_register_[ tid ] ).emplace_back( target, lag, e.get_offset() ); + } + } +} + +void +EventDeliveryManager::send_remote( size_t tid, SpikeEvent& e, const long lag ) +{ + + // Put the spike in a buffer for the remote machines + const size_t lid = kernel::manager< VPManager >.node_id_to_lid( e.get_sender().get_node_id() ); + const auto& targets = kernel::manager< ConnectionManager >.get_remote_targets_of_local_node( tid, lid ); + + for ( const auto& target : targets ) + { + // Unroll spike multiplicity as plastic synapses only handle individual spikes. + for ( size_t i = 0; i < e.get_multiplicity(); ++i ) + { + ( *emitted_spikes_register_[ tid ] ).emplace_back( target, lag ); + } + } +} + +void +EventDeliveryManager::send_local_( Node& source, SecondaryEvent& e, const long ) +{ + + assert( not source.has_proxies() ); + e.set_stamp( kernel::manager< SimulationManager >.get_slice_origin() + Time::step( 1 ) ); + e.set_sender( source ); + const size_t t = source.get_thread(); + const size_t ldid = source.get_local_device_id(); + kernel::manager< ConnectionManager >.send_from_device( t, ldid, e ); +} + +long +EventDeliveryManager::get_slice_modulo( long d ) +{ + + // Note, here d may be 0, since bin 0 represents the "current" time + // when all events due are read out. + assert( static_cast< std::vector< long >::size_type >( d ) < slice_moduli_.size() ); + + return slice_moduli_[ d ]; +} + +long +EventDeliveryManager::get_modulo( long d ) +{ + + // Note, here d may be 0, since bin 0 represents the "current" time + // when all events due are read out. + assert( static_cast< std::vector< long >::size_type >( d ) < moduli_.size() ); + + return moduli_[ d ]; +} + +size_t +EventDeliveryManager::read_toggle() const +{ + + // define in terms of write_toggle() to ensure consistency + return 1 - write_toggle(); +} + +void +EventDeliveryManager::set_off_grid_communication( bool off_grid_spiking ) +{ + + off_grid_spiking_ = off_grid_spiking; +} + +bool +EventDeliveryManager::get_off_grid_communication() const +{ + + return off_grid_spiking_; +} + +void +EventDeliveryManager::send_to_node( Event& e ) +{ + + e(); +} + +bool +EventDeliveryManager::is_marked_for_removal_( const Target& target ) +{ + + return target.is_processed(); +} + +void +EventDeliveryManager::reset_spike_register_( const size_t tid ) +{ + + emitted_spikes_register_[ tid ]->clear(); + off_grid_emitted_spikes_register_[ tid ]->clear(); +} + } // of namespace nest diff --git a/nestkernel/event_delivery_manager.h b/nestkernel/event_delivery_manager.h index dbdbe1483b..8e6edb5f26 100644 --- a/nestkernel/event_delivery_manager.h +++ b/nestkernel/event_delivery_manager.h @@ -24,21 +24,17 @@ #define EVENT_DELIVERY_MANAGER_H // C++ includes: -#include -#include #include // Includes from libnestutil: #include "manager_interface.h" -#include "stopwatch.h" +#include "stopwatch_impl.h" // Includes from nestkernel: #include "buffer_resize_log.h" +#include "connection_manager.h" #include "event.h" #include "mpi_manager.h" // OffGridSpike -#include "nest_time.h" -#include "nest_types.h" -#include "node.h" #include "per_thread_bool_indicator.h" #include "secondary_event.h" #include "spike_data.h" @@ -473,64 +469,6 @@ class EventDeliveryManager : public ManagerInterface Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::MasterOnly > sw_communicate_target_data_; }; -inline void -EventDeliveryManager::reset_spike_register_( const size_t tid ) -{ - emitted_spikes_register_[ tid ]->clear(); - off_grid_emitted_spikes_register_[ tid ]->clear(); -} - -inline bool -EventDeliveryManager::is_marked_for_removal_( const Target& target ) -{ - return target.is_processed(); -} - -inline void -EventDeliveryManager::send_to_node( Event& e ) -{ - e(); -} - -inline bool -EventDeliveryManager::get_off_grid_communication() const -{ - return off_grid_spiking_; -} - -inline void -EventDeliveryManager::set_off_grid_communication( bool off_grid_spiking ) -{ - off_grid_spiking_ = off_grid_spiking; -} - -inline size_t -EventDeliveryManager::read_toggle() const -{ - // define in terms of write_toggle() to ensure consistency - return 1 - write_toggle(); -} - -inline long -EventDeliveryManager::get_modulo( long d ) -{ - // Note, here d may be 0, since bin 0 represents the "current" time - // when all events due are read out. - assert( static_cast< std::vector< long >::size_type >( d ) < moduli_.size() ); - - return moduli_[ d ]; -} - -inline long -EventDeliveryManager::get_slice_modulo( long d ) -{ - // Note, here d may be 0, since bin 0 represents the "current" time - // when all events due are read out. - assert( static_cast< std::vector< long >::size_type >( d ) < slice_moduli_.size() ); - - return slice_moduli_[ d ]; -} - } // namespace nest #endif /* EVENT_DELIVERY_MANAGER_H */ diff --git a/nestkernel/event_delivery_manager_impl.h b/nestkernel/event_delivery_manager_impl.h index 55310a24bd..4d33d41f88 100644 --- a/nestkernel/event_delivery_manager_impl.h +++ b/nestkernel/event_delivery_manager_impl.h @@ -20,162 +20,36 @@ * */ + #ifndef EVENT_DELIVERY_MANAGER_IMPL_H #define EVENT_DELIVERY_MANAGER_IMPL_H #include "event_delivery_manager.h" - -// Includes from nestkernel: -#include "connection_manager_impl.h" -#include "kernel_manager.h" +#include "simulation_manager.h" namespace nest { template < class EventT > -inline void +void EventDeliveryManager::send_local_( Node& source, EventT& e, const long lag ) { assert( not source.has_proxies() ); - e.set_stamp( kernel().simulation_manager.get_slice_origin() + Time::step( lag + 1 ) ); + e.set_stamp( kernel::manager< SimulationManager >.get_slice_origin() + Time::step( lag + 1 ) ); e.set_sender( source ); const size_t t = source.get_thread(); const size_t ldid = source.get_local_device_id(); - kernel().connection_manager.send_from_device( t, ldid, e ); + kernel::manager< ConnectionManager >.send_from_device( t, ldid, e ); } -inline void -EventDeliveryManager::send_local_( Node& source, SecondaryEvent& e, const long ) -{ - assert( not source.has_proxies() ); - e.set_stamp( kernel().simulation_manager.get_slice_origin() + Time::step( 1 ) ); - e.set_sender( source ); - const size_t t = source.get_thread(); - const size_t ldid = source.get_local_device_id(); - kernel().connection_manager.send_from_device( t, ldid, e ); -} template < class EventT > -inline void +void EventDeliveryManager::send( Node& source, EventT& e, const long lag ) { send_local_( source, e, lag ); } -template <> -inline void -EventDeliveryManager::send< SpikeEvent >( Node& source, SpikeEvent& e, const long lag ) -{ - const size_t tid = source.get_thread(); - const size_t source_node_id = source.get_node_id(); - e.set_sender_node_id( source_node_id ); - if ( source.has_proxies() ) - { - local_spike_counter_[ tid ] += e.get_multiplicity(); - - e.set_stamp( kernel().simulation_manager.get_slice_origin() + Time::step( lag + 1 ) ); - e.set_sender( source ); - - if ( source.is_off_grid() ) - { - send_off_grid_remote( tid, e, lag ); - } - else - { - send_remote( tid, e, lag ); - } - kernel().connection_manager.send_to_devices( tid, source_node_id, e ); - } - else - { - send_local_( source, e, lag ); - } -} - -template <> -inline void -EventDeliveryManager::send< DSSpikeEvent >( Node& source, DSSpikeEvent& e, const long lag ) -{ - e.set_sender_node_id( source.get_node_id() ); - send_local_( source, e, lag ); -} - -inline void -EventDeliveryManager::send_remote( size_t tid, SpikeEvent& e, const long lag ) -{ - // Put the spike in a buffer for the remote machines - const size_t lid = kernel().vp_manager.node_id_to_lid( e.get_sender().get_node_id() ); - const auto& targets = kernel().connection_manager.get_remote_targets_of_local_node( tid, lid ); - - for ( const auto& target : targets ) - { - // Unroll spike multiplicity as plastic synapses only handle individual spikes. - for ( size_t i = 0; i < e.get_multiplicity(); ++i ) - { - ( *emitted_spikes_register_[ tid ] ).emplace_back( target, lag ); - } - } -} - -inline void -EventDeliveryManager::send_off_grid_remote( size_t tid, SpikeEvent& e, const long lag ) -{ - // Put the spike in a buffer for the remote machines - const size_t lid = kernel().vp_manager.node_id_to_lid( e.get_sender().get_node_id() ); - const auto& targets = kernel().connection_manager.get_remote_targets_of_local_node( tid, lid ); - - for ( const auto& target : targets ) - { - // Unroll spike multiplicity as plastic synapses only handle individual spikes. - for ( size_t i = 0; i < e.get_multiplicity(); ++i ) - { - ( *off_grid_emitted_spikes_register_[ tid ] ).emplace_back( target, lag, e.get_offset() ); - } - } -} - -inline void -EventDeliveryManager::send_secondary( Node& source, SecondaryEvent& e ) -{ - const size_t tid = kernel().vp_manager.get_thread_id(); - const size_t source_node_id = source.get_node_id(); - const size_t lid = kernel().vp_manager.node_id_to_lid( source_node_id ); - - if ( source.has_proxies() ) - { - - // We need to consider every synapse type this event supports to - // make sure also labeled and connection created by CopyModel are - // considered. - const std::set< synindex >& supported_syn_ids = e.get_supported_syn_ids(); - for ( const auto& syn_id : supported_syn_ids ) - { - const std::vector< size_t >& positions = - kernel().connection_manager.get_secondary_send_buffer_positions( tid, lid, syn_id ); - - for ( size_t i = 0; i < positions.size(); ++i ) - { - std::vector< unsigned int >::iterator it = send_buffer_secondary_events_.begin() + positions[ i ]; - e >> it; - } - } - kernel().connection_manager.send_to_devices( tid, source_node_id, e ); - } - else - { - send_local_( source, e, 0 ); // need to pass lag (last argument), but not - // used in template specialization, so pass - // zero as dummy value - } -} - -inline size_t -EventDeliveryManager::write_toggle() const -{ - return kernel().simulation_manager.get_slice() % 2; -} - - -} // of namespace nest +} // namespace nest -#endif +#endif /* EVENT_DELIVERY_MANAGER_IMPL_H */ diff --git a/nestkernel/free_layer.h b/nestkernel/free_layer.h index 40b1c972cc..7dc507537f 100644 --- a/nestkernel/free_layer.h +++ b/nestkernel/free_layer.h @@ -30,13 +30,13 @@ // Includes from nestkernel: #include "nest_names.h" +#include "node_manager.h" // Includes from sli: #include "dictutils.h" // Includes from spatial: #include "layer.h" -#include "ntree_impl.h" namespace nest { @@ -111,303 +111,6 @@ class FreeLayer : public Layer< D > }; }; -template < int D > -void -FreeLayer< D >::set_status( const DictionaryDatum& d ) -{ - Layer< D >::set_status( d ); - - Position< D > max_point; // for each dimension, the largest value of the positions, aka upper right - - for ( int d = 0; d < D; ++d ) - { - this->lower_left_[ d ] = std::numeric_limits< double >::infinity(); - max_point[ d ] = -std::numeric_limits< double >::infinity(); - } - - num_local_nodes_ = std::accumulate( this->node_collection_->begin(), - this->node_collection_->end(), - 0, - []( size_t a, NodeIDTriple b ) - { - const auto node = kernel().node_manager.get_mpi_local_node_or_device_head( b.node_id ); - return node->is_proxy() ? a : a + 1; - } ); - - // Read positions from dictionary - if ( d->known( names::positions ) ) - { - const Token& tkn = d->lookup( names::positions ); - if ( tkn.is_a< TokenArray >() ) - { - TokenArray pos = getValue< TokenArray >( tkn ); - - positions_.clear(); - positions_.reserve( num_local_nodes_ ); - - auto nc_it = this->node_collection_->begin(); - for ( Token* it = pos.begin(); it != pos.end(); ++it, ++nc_it ) - { - assert( nc_it != this->node_collection_->end() ); - Position< D > point = getValue< std::vector< double > >( *it ); - const auto node = kernel().node_manager.get_mpi_local_node_or_device_head( ( *nc_it ).node_id ); - assert( node ); - if ( not node->is_proxy() ) - { - positions_.push_back( point ); - } - // We do the calculation for lower_left_ and max_point even if we don't add the position, to keep the size of - // the layer consistent over processes. - for ( int d = 0; d < D; ++d ) - { - if ( point[ d ] < this->lower_left_[ d ] ) - { - this->lower_left_[ d ] = point[ d ]; - } - if ( point[ d ] > max_point[ d ] ) - { - max_point[ d ] = point[ d ]; - } - } - } - assert( positions_.size() == num_local_nodes_ ); - } - else if ( tkn.is_a< ParameterDatum >() ) - { - auto pd = dynamic_cast< ParameterDatum* >( tkn.datum() ); - auto pos = dynamic_cast< DimensionParameter* >( pd->get() ); - - positions_.clear(); - positions_.reserve( num_local_nodes_ ); - - RngPtr rng = get_rank_synced_rng(); - - for ( auto nc_it = this->node_collection_->begin(); nc_it < this->node_collection_->end(); ++nc_it ) - { - // We generate the position here, even if we do not store it, to do the same calculations of lower_left_ and - // max_point on all processes. - Position< D > point = pos->get_values( rng ); - - const auto node = kernel().node_manager.get_mpi_local_node_or_device_head( ( *nc_it ).node_id ); - assert( node ); - if ( not node->is_proxy() ) - { - positions_.push_back( point ); - } - // We do the calculation for lower_left_ and max_point even if we don't add the position, to keep the size of - // the layer consistent over processes. - for ( int d = 0; d < D; ++d ) - { - if ( point[ d ] < this->lower_left_[ d ] ) - { - this->lower_left_[ d ] = point[ d ]; - } - if ( point[ d ] > max_point[ d ] ) - { - max_point[ d ] = point[ d ]; - } - } - } - assert( positions_.size() == num_local_nodes_ ); - } - else - { - throw KernelException( "'positions' must be an array or a DimensionParameter." ); - } - } - if ( d->known( names::extent ) ) - { - this->extent_ = getValue< std::vector< double > >( d, names::extent ); - - Position< D > center = ( max_point + this->lower_left_ ) / 2; - auto lower_left_point = this->lower_left_; // save lower-left-most point - this->lower_left_ = center - this->extent_ / 2; - - // check if all points are inside the specified layer extent - auto upper_right_limit = center + this->extent_ / 2; - for ( int d = 0; d < D; ++d ) - { - if ( lower_left_point[ d ] < this->lower_left_[ d ] or max_point[ d ] > upper_right_limit[ d ] ) - { - throw BadProperty( "Node position outside of layer" ); - } - } - } - else - { - if ( this->node_collection_->size() <= 1 ) - { - throw KernelException( "If only one node is created, 'extent' must be specified." ); - } - - const auto positional_extent = max_point - this->lower_left_; - const auto center = ( max_point + this->lower_left_ ) / 2; - for ( int d = 0; d < D; ++d ) - { - // Set extent to be extent of the points, rounded up in each dimension. - this->extent_[ d ] = std::ceil( positional_extent[ d ] ); - } - - // Adjust lower_left relative to the rounded center with the rounded up extent. - this->lower_left_ = center - this->extent_ / 2; - } -} - -template < int D > -void -FreeLayer< D >::get_status( DictionaryDatum& d, NodeCollection const* nc ) const -{ - Layer< D >::get_status( d, nc ); - - TokenArray points; - - if ( not nc ) - { - // This is needed by NodeCollectionMetadata::operator==() which does not have access to the node collection - for ( const auto& pos : positions_ ) - { - points.push_back( pos.getToken() ); - } - } - else - { - // Selecting the right positions - // - Coordinates for all nodes in the underlying primitive node collection - // which belong to this rank are stored in positions_ - // - nc has information on which nodes actually belong to it, especially - // important for sliced collections with step > 1. - // - Use the rank-local iterator over the node collection to pick the right - // nodes, then step in lockstep through the positions_ array. - auto nc_it = nc->rank_local_begin(); - const auto nc_end = nc->end(); - if ( nc_it < nc_end ) - { - // Node index in node collection is global to NEST, so we need to scale down - // to get right indices into positions_, which has only rank-local data. - const size_t n_procs = kernel().mpi_manager.get_num_processes(); - size_t pos_idx = ( *nc_it ).nc_index / n_procs; - size_t step = nc_it.get_step_size() / n_procs; - - for ( ; nc_it < nc->end(); pos_idx += step, ++nc_it ) - { - points.push_back( positions_.at( pos_idx ).getToken() ); - } - } - } - - def2< TokenArray, ArrayDatum >( d, names::positions, points ); -} - -template < int D > -Position< D > -FreeLayer< D >::get_position( size_t lid ) const -{ - return positions_.at( lid_to_position_id_( lid ) ); -} - -template < int D > -template < class Ins > -void -FreeLayer< D >::communicate_positions_( Ins iter, NodeCollectionPTR node_collection ) -{ - // This array will be filled with node ID,pos_x,pos_y[,pos_z] for local nodes: - std::vector< double > local_node_id_pos; - - // If the NodeCollection has proxies, nodes and positions are distributed over MPI processes, - // and we must iterate only the local nodes. If not, all nodes and positions are on all MPI processes. - // All models in a layer are the same, so if has_proxies() for the NodeCollection returns true, we - // know that all nodes in the NodeCollection have proxies. Likewise, if it returns false we know that - // no nodes have proxies. - NodeCollection::const_iterator nc_begin = - node_collection->has_proxies() ? node_collection->rank_local_begin() : node_collection->begin(); - NodeCollection::const_iterator nc_end = node_collection->end(); - - // Reserve capacity in the vector based on number of local nodes. If the NodeCollection is sliced, - // it may need less than the reserved capacity. - local_node_id_pos.reserve( ( D + 1 ) * num_local_nodes_ ); - for ( NodeCollection::const_iterator nc_it = nc_begin; nc_it < nc_end; ++nc_it ) - { - // Push node ID into array to communicate - local_node_id_pos.push_back( ( *nc_it ).node_id ); - // Push coordinates one by one - const auto pos = get_position( ( *nc_it ).nc_index ); - for ( int j = 0; j < D; ++j ) - { - local_node_id_pos.push_back( pos[ j ] ); - } - } - - // This array will be filled with node ID,pos_x,pos_y[,pos_z] for global nodes: - std::vector< double > global_node_id_pos; - std::vector< int > displacements; - kernel().mpi_manager.communicate( local_node_id_pos, global_node_id_pos, displacements ); - - // To avoid copying the vector one extra time in order to sort, we - // sneakishly use reinterpret_cast - NodePositionData* pos_ptr; - NodePositionData* pos_end; - pos_ptr = reinterpret_cast< NodePositionData* >( &global_node_id_pos[ 0 ] ); - pos_end = pos_ptr + global_node_id_pos.size() / ( D + 1 ); - - // Get rid of any multiple entries - std::sort( pos_ptr, pos_end ); - pos_end = std::unique( pos_ptr, pos_end ); - - // Unpack node IDs and coordinates - for ( ; pos_ptr < pos_end; pos_ptr++ ) - { - *iter++ = std::pair< Position< D >, size_t >( pos_ptr->get_position(), pos_ptr->get_node_id() ); - } -} - -template < int D > -void -FreeLayer< D >::insert_global_positions_ntree_( Ntree< D, size_t >& tree, NodeCollectionPTR node_collection ) -{ - - communicate_positions_( std::inserter( tree, tree.end() ), node_collection ); -} - -// Helper function to compare node IDs used for sorting (Position,node ID) pairs -template < int D > -static bool -node_id_less( const std::pair< Position< D >, size_t >& a, const std::pair< Position< D >, size_t >& b ) -{ - return a.second < b.second; -} - -template < int D > -void -FreeLayer< D >::insert_global_positions_vector_( std::vector< std::pair< Position< D >, size_t > >& vec, - NodeCollectionPTR node_collection ) -{ - - communicate_positions_( std::back_inserter( vec ), node_collection ); - - // Sort vector to ensure consistent results - std::sort( vec.begin(), vec.end(), node_id_less< D > ); -} - -template < int D > -size_t -FreeLayer< D >::lid_to_position_id_( size_t lid ) const -{ - // If the NodeCollection has proxies, nodes and positions are distributed over MPI processes, - // and we must iterate only the local nodes. If not, all nodes and positions are on all MPI processes. - // All models in a layer are the same, so if has_proxies() for the NodeCollection returns true, we - // know that all nodes in the NodeCollection have proxies. Likewise, if it returns false we know that - // no nodes have proxies. - if ( not this->node_collection_->has_proxies() ) - { - return lid; - } - else - { - const auto num_procs = kernel().mpi_manager.get_num_processes(); - return lid / num_procs; - } -} - } // namespace nest #endif diff --git a/nestkernel/free_layer_impl.h b/nestkernel/free_layer_impl.h new file mode 100644 index 0000000000..56ba3d841a --- /dev/null +++ b/nestkernel/free_layer_impl.h @@ -0,0 +1,330 @@ +/* + * free_layer_impl.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef FREE_LAYER_IMPL_H +#define FREE_LAYER_IMPL_H + +#include "free_layer.h" + + +namespace nest +{ + +template < int D > +void +FreeLayer< D >::set_status( const DictionaryDatum& d ) +{ + Layer< D >::set_status( d ); + + Position< D > max_point; // for each dimension, the largest value of the positions, aka upper right + + for ( int d = 0; d < D; ++d ) + { + this->lower_left_[ d ] = std::numeric_limits< double >::infinity(); + max_point[ d ] = -std::numeric_limits< double >::infinity(); + } + + num_local_nodes_ = std::accumulate( this->node_collection_->begin(), + this->node_collection_->end(), + 0, + []( size_t a, NodeIDTriple b ) + { + const auto node = kernel::manager< NodeManager >.get_mpi_local_node_or_device_head( b.node_id ); + return node->is_proxy() ? a : a + 1; + } ); + + // Read positions from dictionary + if ( d->known( names::positions ) ) + { + const Token& tkn = d->lookup( names::positions ); + if ( tkn.is_a< TokenArray >() ) + { + TokenArray pos = getValue< TokenArray >( tkn ); + + positions_.clear(); + positions_.reserve( num_local_nodes_ ); + + auto nc_it = this->node_collection_->begin(); + for ( Token* it = pos.begin(); it != pos.end(); ++it, ++nc_it ) + { + assert( nc_it != this->node_collection_->end() ); + Position< D > point = getValue< std::vector< double > >( *it ); + const auto node = kernel::manager< NodeManager >.get_mpi_local_node_or_device_head( ( *nc_it ).node_id ); + assert( node ); + if ( not node->is_proxy() ) + { + positions_.push_back( point ); + } + // We do the calculation for lower_left_ and max_point even if we don't add the position, to keep the size of + // the layer consistent over processes. + for ( int d = 0; d < D; ++d ) + { + if ( point[ d ] < this->lower_left_[ d ] ) + { + this->lower_left_[ d ] = point[ d ]; + } + if ( point[ d ] > max_point[ d ] ) + { + max_point[ d ] = point[ d ]; + } + } + } + assert( positions_.size() == num_local_nodes_ ); + } + else if ( tkn.is_a< ParameterDatum >() ) + { + auto pd = dynamic_cast< ParameterDatum* >( tkn.datum() ); + auto pos = dynamic_cast< DimensionParameter* >( pd->get() ); + + positions_.clear(); + positions_.reserve( num_local_nodes_ ); + + RngPtr rng = get_rank_synced_rng(); + + for ( auto nc_it = this->node_collection_->begin(); nc_it < this->node_collection_->end(); ++nc_it ) + { + // We generate the position here, even if we do not store it, to do the same calculations of lower_left_ and + // max_point on all processes. + Position< D > point = pos->get_values( rng ); + + const auto node = kernel::manager< NodeManager >.get_mpi_local_node_or_device_head( ( *nc_it ).node_id ); + assert( node ); + if ( not node->is_proxy() ) + { + positions_.push_back( point ); + } + // We do the calculation for lower_left_ and max_point even if we don't add the position, to keep the size of + // the layer consistent over processes. + for ( int d = 0; d < D; ++d ) + { + if ( point[ d ] < this->lower_left_[ d ] ) + { + this->lower_left_[ d ] = point[ d ]; + } + if ( point[ d ] > max_point[ d ] ) + { + max_point[ d ] = point[ d ]; + } + } + } + assert( positions_.size() == num_local_nodes_ ); + } + else + { + throw KernelException( "'positions' must be an array or a DimensionParameter." ); + } + } + if ( d->known( names::extent ) ) + { + this->extent_ = getValue< std::vector< double > >( d, names::extent ); + + Position< D > center = ( max_point + this->lower_left_ ) / 2; + auto lower_left_point = this->lower_left_; // save lower-left-most point + this->lower_left_ = center - this->extent_ / 2; + + // check if all points are inside the specified layer extent + auto upper_right_limit = center + this->extent_ / 2; + for ( int d = 0; d < D; ++d ) + { + if ( lower_left_point[ d ] < this->lower_left_[ d ] or max_point[ d ] > upper_right_limit[ d ] ) + { + throw BadProperty( "Node position outside of layer" ); + } + } + } + else + { + if ( this->node_collection_->size() <= 1 ) + { + throw KernelException( "If only one node is created, 'extent' must be specified." ); + } + + const auto positional_extent = max_point - this->lower_left_; + const auto center = ( max_point + this->lower_left_ ) / 2; + for ( int d = 0; d < D; ++d ) + { + // Set extent to be extent of the points, rounded up in each dimension. + this->extent_[ d ] = std::ceil( positional_extent[ d ] ); + } + + // Adjust lower_left relative to the rounded center with the rounded up extent. + this->lower_left_ = center - this->extent_ / 2; + } +} + +template < int D > +void +FreeLayer< D >::get_status( DictionaryDatum& d, NodeCollection const* nc ) const +{ + Layer< D >::get_status( d, nc ); + + TokenArray points; + + if ( not nc ) + { + // This is needed by NodeCollectionMetadata::operator==() which does not have access to the node collection + for ( const auto& pos : positions_ ) + { + points.push_back( pos.getToken() ); + } + } + else + { + // Selecting the right positions + // - Coordinates for all nodes in the underlying primitive node collection + // which belong to this rank are stored in positions_ + // - nc has information on which nodes actually belong to it, especially + // important for sliced collections with step > 1. + // - Use the rank-local iterator over the node collection to pick the right + // nodes, then step in lockstep through the positions_ array. + auto nc_it = nc->rank_local_begin(); + const auto nc_end = nc->end(); + if ( nc_it < nc_end ) + { + // Node index in node collection is global to NEST, so we need to scale down + // to get right indices into positions_, which has only rank-local data. + const size_t n_procs = kernel::manager< MPIManager >.get_num_processes(); + size_t pos_idx = ( *nc_it ).nc_index / n_procs; + size_t step = nc_it.get_step_size() / n_procs; + + for ( ; nc_it < nc->end(); pos_idx += step, ++nc_it ) + { + points.push_back( positions_.at( pos_idx ).getToken() ); + } + } + } + + def2< TokenArray, ArrayDatum >( d, names::positions, points ); +} + +template < int D > +Position< D > +FreeLayer< D >::get_position( size_t lid ) const +{ + return positions_.at( lid_to_position_id_( lid ) ); +} + +template < int D > +template < class Ins > +void +FreeLayer< D >::communicate_positions_( Ins iter, NodeCollectionPTR node_collection ) +{ + // This array will be filled with node ID,pos_x,pos_y[,pos_z] for local nodes: + std::vector< double > local_node_id_pos; + + // If the NodeCollection has proxies, nodes and positions are distributed over MPI processes, + // and we must iterate only the local nodes. If not, all nodes and positions are on all MPI processes. + // All models in a layer are the same, so if has_proxies() for the NodeCollection returns true, we + // know that all nodes in the NodeCollection have proxies. Likewise, if it returns false we know that + // no nodes have proxies. + NodeCollection::const_iterator nc_begin = + node_collection->has_proxies() ? node_collection->rank_local_begin() : node_collection->begin(); + NodeCollection::const_iterator nc_end = node_collection->end(); + + // Reserve capacity in the vector based on number of local nodes. If the NodeCollection is sliced, + // it may need less than the reserved capacity. + local_node_id_pos.reserve( ( D + 1 ) * num_local_nodes_ ); + for ( NodeCollection::const_iterator nc_it = nc_begin; nc_it < nc_end; ++nc_it ) + { + // Push node ID into array to communicate + local_node_id_pos.push_back( ( *nc_it ).node_id ); + // Push coordinates one by one + const auto pos = get_position( ( *nc_it ).nc_index ); + for ( int j = 0; j < D; ++j ) + { + local_node_id_pos.push_back( pos[ j ] ); + } + } + + // This array will be filled with node ID,pos_x,pos_y[,pos_z] for global nodes: + std::vector< double > global_node_id_pos; + std::vector< int > displacements; + kernel::manager< MPIManager >.communicate( local_node_id_pos, global_node_id_pos, displacements ); + + // To avoid copying the vector one extra time in order to sort, we + // sneakishly use reinterpret_cast + NodePositionData* pos_ptr; + NodePositionData* pos_end; + pos_ptr = reinterpret_cast< NodePositionData* >( &global_node_id_pos[ 0 ] ); + pos_end = pos_ptr + global_node_id_pos.size() / ( D + 1 ); + + // Get rid of any multiple entries + std::sort( pos_ptr, pos_end ); + pos_end = std::unique( pos_ptr, pos_end ); + + // Unpack node IDs and coordinates + for ( ; pos_ptr < pos_end; pos_ptr++ ) + { + *iter++ = std::pair< Position< D >, size_t >( pos_ptr->get_position(), pos_ptr->get_node_id() ); + } +} + +template < int D > +void +FreeLayer< D >::insert_global_positions_ntree_( Ntree< D, size_t >& tree, NodeCollectionPTR node_collection ) +{ + + communicate_positions_( std::inserter( tree, tree.end() ), node_collection ); +} + +// Helper function to compare node IDs used for sorting (Position,node ID) pairs +template < int D > +static bool +node_id_less( const std::pair< Position< D >, size_t >& a, const std::pair< Position< D >, size_t >& b ) +{ + return a.second < b.second; +} + +template < int D > +void +FreeLayer< D >::insert_global_positions_vector_( std::vector< std::pair< Position< D >, size_t > >& vec, + NodeCollectionPTR node_collection ) +{ + + communicate_positions_( std::back_inserter( vec ), node_collection ); + + // Sort vector to ensure consistent results + std::sort( vec.begin(), vec.end(), node_id_less< D > ); +} + +template < int D > +size_t +FreeLayer< D >::lid_to_position_id_( size_t lid ) const +{ + // If the NodeCollection has proxies, nodes and positions are distributed over MPI processes, + // and we must iterate only the local nodes. If not, all nodes and positions are on all MPI processes. + // All models in a layer are the same, so if has_proxies() for the NodeCollection returns true, we + // know that all nodes in the NodeCollection have proxies. Likewise, if it returns false we know that + // no nodes have proxies. + if ( not this->node_collection_->has_proxies() ) + { + return lid; + } + else + { + const auto num_procs = kernel::manager< MPIManager >.get_num_processes(); + return lid / num_procs; + } +} +} // namespace nest + +#endif diff --git a/nestkernel/generic_factory.h b/nestkernel/generic_factory.h index 1df0f1483f..630e8d6ef8 100644 --- a/nestkernel/generic_factory.h +++ b/nestkernel/generic_factory.h @@ -89,41 +89,6 @@ class GenericFactory AssocMap associations_; }; -template < class BaseT > -inline BaseT* -GenericFactory< BaseT >::create( const Name& name, const DictionaryDatum& d ) const -{ - typename AssocMap::const_iterator i = associations_.find( name ); - if ( i != associations_.end() ) - { - return ( i->second )( d ); - } - throw UndefinedName( name.toString() ); -} - -template < class BaseT > -template < class T > -inline bool -GenericFactory< BaseT >::register_subtype( const Name& name ) -{ - return register_subtype( name, new_from_dict_< T > ); -} - -template < class BaseT > -inline bool -GenericFactory< BaseT >::register_subtype( const Name& name, CreatorFunction creator ) -{ - return associations_.insert( std::pair< Name, CreatorFunction >( name, creator ) ).second; -} - -template < class BaseT > -template < class T > -BaseT* -GenericFactory< BaseT >::new_from_dict_( const DictionaryDatum& d ) -{ - return new T( d ); -} - } // namespace nest #endif diff --git a/nestkernel/generic_factory_impl.h b/nestkernel/generic_factory_impl.h new file mode 100644 index 0000000000..14afa34dff --- /dev/null +++ b/nestkernel/generic_factory_impl.h @@ -0,0 +1,69 @@ +/* + * generic_factory_impl.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef GENERIC_FACTORY_IMPL_H +#define GENERIC_FACTORY_IMPL_H + +#include "generic_factory.h" + +namespace nest +{ + +template < class BaseT > +inline BaseT* +GenericFactory< BaseT >::create( const Name& name, const DictionaryDatum& d ) const +{ + typename AssocMap::const_iterator i = associations_.find( name ); + if ( i != associations_.end() ) + { + return ( i->second )( d ); + } + throw UndefinedName( name.toString() ); +} + +template < class BaseT > +template < class T > +inline bool +GenericFactory< BaseT >::register_subtype( const Name& name ) +{ + return register_subtype( name, new_from_dict_< T > ); +} + +template < class BaseT > +inline bool +GenericFactory< BaseT >::register_subtype( const Name& name, CreatorFunction creator ) +{ + return associations_.insert( std::pair< Name, CreatorFunction >( name, creator ) ).second; +} + +template < class BaseT > +template < class T > +BaseT* +GenericFactory< BaseT >::new_from_dict_( const DictionaryDatum& d ) +{ + return new T( d ); +} + + +} // namespace nest + +#endif diff --git a/nestkernel/genericmodel.h b/nestkernel/genericmodel.h index a6f5ddc9cb..3029f13587 100644 --- a/nestkernel/genericmodel.h +++ b/nestkernel/genericmodel.h @@ -23,10 +23,8 @@ #ifndef GENERICMODEL_H #define GENERICMODEL_H -// C++ includes: -#include - // Includes from nestkernel: +#include "logging_manager.h" #include "model.h" namespace nest @@ -118,169 +116,6 @@ class GenericModel : public Model bool deprecation_warning_issued_; }; -template < typename ElementT > -GenericModel< ElementT >::GenericModel( const std::string& name, const std::string& deprecation_info ) - : Model( name ) - , proto_() - , deprecation_info_( deprecation_info ) - , deprecation_warning_issued_( false ) -{ - set_threads(); -} - -template < typename ElementT > -GenericModel< ElementT >::GenericModel( const GenericModel& oldmod, const std::string& newname ) - : Model( newname ) - , proto_( oldmod.proto_ ) - , deprecation_info_( oldmod.deprecation_info_ ) - , deprecation_warning_issued_( false ) -{ - set_type_id( oldmod.get_type_id() ); - set_threads(); -} - -template < typename ElementT > -Model* -GenericModel< ElementT >::clone( const std::string& newname ) const -{ - return new GenericModel( *this, newname ); -} - -template < typename ElementT > -Node* -GenericModel< ElementT >::create_() -{ - Node* n = new ElementT( proto_ ); - return n; -} - -template < typename ElementT > -inline bool -GenericModel< ElementT >::has_proxies() -{ - return proto_.has_proxies(); -} - -template < typename ElementT > -inline bool -GenericModel< ElementT >::one_node_per_process() -{ - return proto_.one_node_per_process(); -} - -template < typename ElementT > -inline bool -GenericModel< ElementT >::is_off_grid() -{ - return proto_.is_off_grid(); -} - -template < typename ElementT > -inline void -GenericModel< ElementT >::calibrate_time( const TimeConverter& tc ) -{ - proto_.calibrate_time( tc ); -} - -template < typename ElementT > -inline size_t -GenericModel< ElementT >::send_test_event( Node& target, size_t receptor, synindex syn_id, bool dummy_target ) -{ - return proto_.send_test_event( target, receptor, syn_id, dummy_target ); -} - -template < typename ElementT > -inline void -GenericModel< ElementT >::sends_secondary_event( GapJunctionEvent& ge ) -{ - return proto_.sends_secondary_event( ge ); -} - -template < typename ElementT > -inline void -GenericModel< ElementT >::sends_secondary_event( InstantaneousRateConnectionEvent& re ) -{ - return proto_.sends_secondary_event( re ); -} - -template < typename ElementT > -inline void -GenericModel< ElementT >::sends_secondary_event( DiffusionConnectionEvent& de ) -{ - return proto_.sends_secondary_event( de ); -} - -template < typename ElementT > -inline void -GenericModel< ElementT >::sends_secondary_event( DelayedRateConnectionEvent& re ) -{ - return proto_.sends_secondary_event( re ); -} - -template < typename ElementT > -inline void -GenericModel< ElementT >::sends_secondary_event( LearningSignalConnectionEvent& re ) -{ - return proto_.sends_secondary_event( re ); -} - -template < typename ElementT > -inline void -GenericModel< ElementT >::sends_secondary_event( SICEvent& sic ) -{ - return proto_.sends_secondary_event( sic ); -} - -template < typename ElementT > -inline nest::SignalType -GenericModel< ElementT >::sends_signal() const -{ - return proto_.sends_signal(); -} - -template < typename ElementT > -void -GenericModel< ElementT >::set_status_( DictionaryDatum d ) -{ - proto_.set_status( d ); -} - -template < typename ElementT > -DictionaryDatum -GenericModel< ElementT >::get_status_() -{ - DictionaryDatum d = proto_.get_status_base(); - ( *d )[ names::elementsize ] = sizeof( ElementT ); - return d; -} - -template < typename ElementT > -size_t -GenericModel< ElementT >::get_element_size() const -{ - return sizeof( ElementT ); -} - -template < typename ElementT > -Node const& -GenericModel< ElementT >::get_prototype() const -{ - return proto_; -} - -template < typename ElementT > -void -GenericModel< ElementT >::set_model_id( int i ) -{ - proto_.set_model_id( i ); -} - -template < typename ElementT > -int -GenericModel< ElementT >::get_model_id() -{ - return proto_.get_model_id(); -} -} +} // namespace nest #endif diff --git a/nestkernel/genericmodel_impl.h b/nestkernel/genericmodel_impl.h index db1d0edc3f..541ab91385 100644 --- a/nestkernel/genericmodel_impl.h +++ b/nestkernel/genericmodel_impl.h @@ -25,13 +25,173 @@ #include "genericmodel.h" -// Includes from nestkernel: -#include "kernel_manager.h" -#include "logging_manager.h" - namespace nest { +template < typename ElementT > +GenericModel< ElementT >::GenericModel( const std::string& name, const std::string& deprecation_info ) + : Model( name ) + , proto_() + , deprecation_info_( deprecation_info ) + , deprecation_warning_issued_( false ) +{ + set_threads(); +} + +template < typename ElementT > +GenericModel< ElementT >::GenericModel( const GenericModel& oldmod, const std::string& newname ) + : Model( newname ) + , proto_( oldmod.proto_ ) + , deprecation_info_( oldmod.deprecation_info_ ) + , deprecation_warning_issued_( false ) +{ + set_type_id( oldmod.get_type_id() ); + set_threads(); +} + +template < typename ElementT > +Model* +GenericModel< ElementT >::clone( const std::string& newname ) const +{ + return new GenericModel( *this, newname ); +} + +template < typename ElementT > +Node* +GenericModel< ElementT >::create_() +{ + Node* n = new ElementT( proto_ ); + return n; +} + +template < typename ElementT > +inline bool +GenericModel< ElementT >::has_proxies() +{ + return proto_.has_proxies(); +} + +template < typename ElementT > +inline bool +GenericModel< ElementT >::one_node_per_process() +{ + return proto_.one_node_per_process(); +} + +template < typename ElementT > +inline bool +GenericModel< ElementT >::is_off_grid() +{ + return proto_.is_off_grid(); +} + +template < typename ElementT > +inline void +GenericModel< ElementT >::calibrate_time( const TimeConverter& tc ) +{ + proto_.calibrate_time( tc ); +} + +template < typename ElementT > +inline size_t +GenericModel< ElementT >::send_test_event( Node& target, size_t receptor, synindex syn_id, bool dummy_target ) +{ + return proto_.send_test_event( target, receptor, syn_id, dummy_target ); +} + +template < typename ElementT > +inline void +GenericModel< ElementT >::sends_secondary_event( GapJunctionEvent& ge ) +{ + return proto_.sends_secondary_event( ge ); +} + +template < typename ElementT > +inline void +GenericModel< ElementT >::sends_secondary_event( InstantaneousRateConnectionEvent& re ) +{ + return proto_.sends_secondary_event( re ); +} + +template < typename ElementT > +inline void +GenericModel< ElementT >::sends_secondary_event( DiffusionConnectionEvent& de ) +{ + return proto_.sends_secondary_event( de ); +} + +template < typename ElementT > +inline void +GenericModel< ElementT >::sends_secondary_event( DelayedRateConnectionEvent& re ) +{ + return proto_.sends_secondary_event( re ); +} + +template < typename ElementT > +inline void +GenericModel< ElementT >::sends_secondary_event( LearningSignalConnectionEvent& re ) +{ + return proto_.sends_secondary_event( re ); +} + +template < typename ElementT > +inline void +GenericModel< ElementT >::sends_secondary_event( SICEvent& sic ) +{ + return proto_.sends_secondary_event( sic ); +} + +template < typename ElementT > +inline nest::SignalType +GenericModel< ElementT >::sends_signal() const +{ + return proto_.sends_signal(); +} + +template < typename ElementT > +void +GenericModel< ElementT >::set_status_( DictionaryDatum d ) +{ + proto_.set_status( d ); +} + +template < typename ElementT > +DictionaryDatum +GenericModel< ElementT >::get_status_() +{ + DictionaryDatum d = proto_.get_status_base(); + ( *d )[ names::elementsize ] = sizeof( ElementT ); + return d; +} + +template < typename ElementT > +size_t +GenericModel< ElementT >::get_element_size() const +{ + return sizeof( ElementT ); +} + +template < typename ElementT > +Node const& +GenericModel< ElementT >::get_prototype() const +{ + return proto_; +} + +template < typename ElementT > +void +GenericModel< ElementT >::set_model_id( int i ) +{ + proto_.set_model_id( i ); +} + +template < typename ElementT > +int +GenericModel< ElementT >::get_model_id() +{ + return proto_.get_model_id(); +} + template < typename ElementT > void GenericModel< ElementT >::deprecation_warning( const std::string& caller ) @@ -48,5 +208,7 @@ GenericModel< ElementT >::deprecation_warning( const std::string& caller ) deprecation_warning_issued_ = true; } -} + +} // namespace nest + #endif diff --git a/nestkernel/grid_layer.h b/nestkernel/grid_layer.h index 75fc467fb5..2edd28a5fa 100644 --- a/nestkernel/grid_layer.h +++ b/nestkernel/grid_layer.h @@ -161,263 +161,6 @@ class GridLayer : public Layer< D > NodeCollectionPTR node_collection ) override; }; -template < int D > -Position< D, size_t > -GridLayer< D >::get_dims() const -{ - return dims_; -} - -template < int D > -void -GridLayer< D >::set_status( const DictionaryDatum& d ) -{ - std::vector< long > new_dims( D ); - - updateValue< std::vector< long > >( d, names::shape, new_dims ); - - size_t new_size = 1; - for ( int i = 0; i < D; ++i ) - { - new_size *= new_dims[ i ]; - - this->dims_[ i ] = static_cast< size_t >( new_dims[ i ] ); - } - - if ( new_size != this->node_collection_->size() ) - { - throw BadProperty( "Total size of layer must be unchanged." ); - } - - if ( d->known( names::extent ) ) - { - Position< D > center = this->get_center(); - this->extent_ = getValue< std::vector< double > >( d, names::extent ); - this->lower_left_ = center - this->extent_ / 2; - } - if ( d->known( names::center ) ) - { - this->lower_left_ = getValue< std::vector< double > >( d, names::center ); - this->lower_left_ -= this->extent_ / 2; - } - - Layer< D >::set_status( d ); -} - -template < int D > -void -GridLayer< D >::get_status( DictionaryDatum& d, NodeCollection const* nc ) const -{ - Layer< D >::get_status( d, nc ); - - ( *d )[ names::shape ] = std::vector< size_t >( dims_.get_vector() ); -} - -template < int D > -Position< D > -GridLayer< D >::lid_to_position( size_t lid ) const -{ - Position< D, int > gridpos; - for ( int i = D - 1; i > 0; --i ) - { - gridpos[ i ] = lid % dims_[ i ]; - lid = lid / dims_[ i ]; - } - assert( lid < dims_[ 0 ] ); - gridpos[ 0 ] = lid; - return gridpos_to_position( gridpos ); -} - -template < int D > -Position< D > -GridLayer< D >::gridpos_to_position( Position< D, int > gridpos ) const -{ - // grid layer uses "matrix convention", i.e. reversed y axis - Position< D > ext = this->extent_; - Position< D > upper_left = this->lower_left_; - if ( D > 1 ) - { - upper_left[ 1 ] += ext[ 1 ]; - ext[ 1 ] = -ext[ 1 ]; - } - return upper_left + ext / dims_ * gridpos + ext / dims_ * 0.5; -} - -template < int D > -Position< D > -GridLayer< D >::get_position( size_t lid ) const -{ - return lid_to_position( lid ); -} - -template < int D > -size_t -GridLayer< D >::gridpos_to_lid( Position< D, int > pos ) const -{ - size_t lid = 0; - - // In case of periodic boundaries, allow grid positions outside layer - for ( int i = 0; i < D; ++i ) - { - if ( this->periodic_[ i ] ) - { - pos[ i ] %= int( dims_[ i ] ); - if ( pos[ i ] < 0 ) - { - pos[ i ] += dims_[ i ]; - } - } - } - - for ( int i = 0; i < D; ++i ) - { - lid *= dims_[ i ]; - lid += pos[ i ]; - } - - return lid; -} - -template < int D > -template < class Ins > -void -GridLayer< D >::insert_global_positions_( Ins iter, NodeCollectionPTR node_collection ) -{ - for ( auto gi = node_collection->begin(); gi < node_collection->end(); ++gi ) - { - const auto triple = *gi; - *iter++ = std::pair< Position< D >, size_t >( lid_to_position( triple.nc_index ), triple.node_id ); - } -} - -template < int D > -void -GridLayer< D >::insert_global_positions_ntree_( Ntree< D, size_t >& tree, NodeCollectionPTR node_collection ) -{ - insert_global_positions_( std::inserter( tree, tree.end() ), node_collection ); -} - -template < int D > -void -GridLayer< D >::insert_global_positions_vector_( std::vector< std::pair< Position< D >, size_t > >& vec, - NodeCollectionPTR node_collection ) -{ - insert_global_positions_( std::back_inserter( vec ), node_collection ); -} - -template < int D > -inline typename GridLayer< D >::masked_iterator -GridLayer< D >::masked_begin( const Mask< D >& mask, const Position< D >& anchor ) -{ - return masked_iterator( *this, mask, anchor ); -} - -template < int D > -inline typename GridLayer< D >::masked_iterator -GridLayer< D >::masked_end() -{ - return masked_iterator( *this ); -} - -template < int D > -GridLayer< D >::masked_iterator::masked_iterator( const GridLayer< D >& layer, - const Mask< D >& mask, - const Position< D >& anchor ) - : layer_( layer ) - , mask_( &mask ) - , anchor_( anchor ) -{ - layer_size_ = layer.global_size(); - - Position< D, int > lower_left; - Position< D, int > upper_right; - Box< D > bbox = mask.get_bbox(); - bbox.lower_left += anchor; - bbox.upper_right += anchor; - for ( int i = 0; i < D; ++i ) - { - if ( layer.periodic_[ i ] ) - { - lower_left[ i ] = - ceil( ( bbox.lower_left[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] - 0.5 ); - upper_right[ i ] = - round( ( bbox.upper_right[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] ); - } - else - { - lower_left[ i ] = std::min( - size_t( std::max( - ceil( ( bbox.lower_left[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] - 0.5 ), - 0.0 ) ), - layer.dims_[ i ] ); - upper_right[ i ] = std::min( - size_t( std::max( - round( ( bbox.upper_right[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] ), 0.0 ) ), - layer.dims_[ i ] ); - } - } - if ( D > 1 ) - { - // grid layer uses "matrix convention", i.e. reversed y axis - int tmp = lower_left[ 1 ]; - lower_left[ 1 ] = layer.dims_[ 1 ] - upper_right[ 1 ]; - upper_right[ 1 ] = layer.dims_[ 1 ] - tmp; - } - - node_ = MultiIndex< D >( lower_left, upper_right ); - - if ( not mask_->inside( layer_.gridpos_to_position( node_ ) - anchor_ ) ) - { - ++( *this ); - } -} - -template < int D > -inline std::pair< Position< D >, size_t > -GridLayer< D >::masked_iterator::operator*() -{ - return std::pair< Position< D >, size_t >( - layer_.gridpos_to_position( node_ ), layer_.node_collection_->operator[]( layer_.gridpos_to_lid( node_ ) ) ); -} - -template < int D > -typename GridLayer< D >::masked_iterator& -GridLayer< D >::masked_iterator::operator++() -{ - do - { - ++node_; - - if ( node_ == node_.get_upper_right() ) - { - // Mark as invalid - node_ = MultiIndex< D >(); - return *this; - } - - } while ( not mask_->inside( layer_.gridpos_to_position( node_ ) - anchor_ ) ); - - return *this; -} - -template < int D > -std::vector< std::pair< Position< D >, size_t > > -GridLayer< D >::get_global_positions_vector( const AbstractMask& mask, - const Position< D >& anchor, - bool, - NodeCollectionPTR ) -{ - std::vector< std::pair< Position< D >, size_t > > positions; - - const Mask< D >& mask_d = dynamic_cast< const Mask< D >& >( mask ); - for ( typename GridLayer< D >::masked_iterator mi = masked_begin( mask_d, anchor ); mi != masked_end(); ++mi ) - { - positions.push_back( *mi ); - } - - return positions; -} - } // namespace nest #endif diff --git a/nestkernel/grid_layer_impl.h b/nestkernel/grid_layer_impl.h new file mode 100644 index 0000000000..2783433dad --- /dev/null +++ b/nestkernel/grid_layer_impl.h @@ -0,0 +1,293 @@ +/* + * grid_layer_impl.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef GRID_LAYER_IMPL_H +#define GRID_LAYER_IMPL_H + +// Includes from spatial: +#include "grid_layer.h" + +namespace nest +{ + + +template < int D > +Position< D, size_t > +GridLayer< D >::get_dims() const +{ + return dims_; +} + +template < int D > +void +GridLayer< D >::set_status( const DictionaryDatum& d ) +{ + std::vector< long > new_dims( D ); + + updateValue< std::vector< long > >( d, names::shape, new_dims ); + + size_t new_size = 1; + for ( int i = 0; i < D; ++i ) + { + new_size *= new_dims[ i ]; + + this->dims_[ i ] = static_cast< size_t >( new_dims[ i ] ); + } + + if ( new_size != this->node_collection_->size() ) + { + throw BadProperty( "Total size of layer must be unchanged." ); + } + + if ( d->known( names::extent ) ) + { + Position< D > center = this->get_center(); + this->extent_ = getValue< std::vector< double > >( d, names::extent ); + this->lower_left_ = center - this->extent_ / 2; + } + if ( d->known( names::center ) ) + { + this->lower_left_ = getValue< std::vector< double > >( d, names::center ); + this->lower_left_ -= this->extent_ / 2; + } + + Layer< D >::set_status( d ); +} + +template < int D > +void +GridLayer< D >::get_status( DictionaryDatum& d, NodeCollection const* nc ) const +{ + Layer< D >::get_status( d, nc ); + + ( *d )[ names::shape ] = std::vector< size_t >( dims_.get_vector() ); +} + +template < int D > +Position< D > +GridLayer< D >::lid_to_position( size_t lid ) const +{ + Position< D, int > gridpos; + for ( int i = D - 1; i > 0; --i ) + { + gridpos[ i ] = lid % dims_[ i ]; + lid = lid / dims_[ i ]; + } + assert( lid < dims_[ 0 ] ); + gridpos[ 0 ] = lid; + return gridpos_to_position( gridpos ); +} + +template < int D > +Position< D > +GridLayer< D >::gridpos_to_position( Position< D, int > gridpos ) const +{ + // grid layer uses "matrix convention", i.e. reversed y axis + Position< D > ext = this->extent_; + Position< D > upper_left = this->lower_left_; + if ( D > 1 ) + { + upper_left[ 1 ] += ext[ 1 ]; + ext[ 1 ] = -ext[ 1 ]; + } + return upper_left + ext / dims_ * gridpos + ext / dims_ * 0.5; +} + +template < int D > +Position< D > +GridLayer< D >::get_position( size_t lid ) const +{ + return lid_to_position( lid ); +} + +template < int D > +size_t +GridLayer< D >::gridpos_to_lid( Position< D, int > pos ) const +{ + size_t lid = 0; + + // In case of periodic boundaries, allow grid positions outside layer + for ( int i = 0; i < D; ++i ) + { + if ( this->periodic_[ i ] ) + { + pos[ i ] %= int( dims_[ i ] ); + if ( pos[ i ] < 0 ) + { + pos[ i ] += dims_[ i ]; + } + } + } + + for ( int i = 0; i < D; ++i ) + { + lid *= dims_[ i ]; + lid += pos[ i ]; + } + + return lid; +} + +template < int D > +template < class Ins > +void +GridLayer< D >::insert_global_positions_( Ins iter, NodeCollectionPTR node_collection ) +{ + for ( auto gi = node_collection->begin(); gi < node_collection->end(); ++gi ) + { + const auto triple = *gi; + *iter++ = std::pair< Position< D >, size_t >( lid_to_position( triple.nc_index ), triple.node_id ); + } +} + +template < int D > +void +GridLayer< D >::insert_global_positions_ntree_( Ntree< D, size_t >& tree, NodeCollectionPTR node_collection ) +{ + insert_global_positions_( std::inserter( tree, tree.end() ), node_collection ); +} + +template < int D > +void +GridLayer< D >::insert_global_positions_vector_( std::vector< std::pair< Position< D >, size_t > >& vec, + NodeCollectionPTR node_collection ) +{ + insert_global_positions_( std::back_inserter( vec ), node_collection ); +} + +template < int D > +inline typename GridLayer< D >::masked_iterator +GridLayer< D >::masked_begin( const Mask< D >& mask, const Position< D >& anchor ) +{ + return masked_iterator( *this, mask, anchor ); +} + +template < int D > +inline typename GridLayer< D >::masked_iterator +GridLayer< D >::masked_end() +{ + return masked_iterator( *this ); +} + +template < int D > +GridLayer< D >::masked_iterator::masked_iterator( const GridLayer< D >& layer, + const Mask< D >& mask, + const Position< D >& anchor ) + : layer_( layer ) + , mask_( &mask ) + , anchor_( anchor ) +{ + layer_size_ = layer.global_size(); + + Position< D, int > lower_left; + Position< D, int > upper_right; + Box< D > bbox = mask.get_bbox(); + bbox.lower_left += anchor; + bbox.upper_right += anchor; + for ( int i = 0; i < D; ++i ) + { + if ( layer.periodic_[ i ] ) + { + lower_left[ i ] = + ceil( ( bbox.lower_left[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] - 0.5 ); + upper_right[ i ] = + round( ( bbox.upper_right[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] ); + } + else + { + lower_left[ i ] = std::min( + size_t( std::max( + ceil( ( bbox.lower_left[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] - 0.5 ), + 0.0 ) ), + layer.dims_[ i ] ); + upper_right[ i ] = std::min( + size_t( std::max( + round( ( bbox.upper_right[ i ] - layer.lower_left_[ i ] ) * layer_.dims_[ i ] / layer.extent_[ i ] ), 0.0 ) ), + layer.dims_[ i ] ); + } + } + if ( D > 1 ) + { + // grid layer uses "matrix convention", i.e. reversed y axis + int tmp = lower_left[ 1 ]; + lower_left[ 1 ] = layer.dims_[ 1 ] - upper_right[ 1 ]; + upper_right[ 1 ] = layer.dims_[ 1 ] - tmp; + } + + node_ = MultiIndex< D >( lower_left, upper_right ); + + if ( not mask_->inside( layer_.gridpos_to_position( node_ ) - anchor_ ) ) + { + ++( *this ); + } +} + +template < int D > +inline std::pair< Position< D >, size_t > +GridLayer< D >::masked_iterator::operator*() +{ + return std::pair< Position< D >, size_t >( + layer_.gridpos_to_position( node_ ), layer_.node_collection_->operator[]( layer_.gridpos_to_lid( node_ ) ) ); +} + +template < int D > +typename GridLayer< D >::masked_iterator& +GridLayer< D >::masked_iterator::operator++() +{ + do + { + ++node_; + + if ( node_ == node_.get_upper_right() ) + { + // Mark as invalid + node_ = MultiIndex< D >(); + return *this; + } + + } while ( not mask_->inside( layer_.gridpos_to_position( node_ ) - anchor_ ) ); + + return *this; +} + +template < int D > +std::vector< std::pair< Position< D >, size_t > > +GridLayer< D >::get_global_positions_vector( const AbstractMask& mask, + const Position< D >& anchor, + bool, + NodeCollectionPTR ) +{ + std::vector< std::pair< Position< D >, size_t > > positions; + + const Mask< D >& mask_d = dynamic_cast< const Mask< D >& >( mask ); + for ( typename GridLayer< D >::masked_iterator mi = masked_begin( mask_d, anchor ); mi != masked_end(); ++mi ) + { + positions.push_back( *mi ); + } + + return positions; +} + + +} // namespace nest + +#endif diff --git a/nestkernel/grid_mask.h b/nestkernel/grid_mask.h index 7c76c0abe4..0d421e1521 100644 --- a/nestkernel/grid_mask.h +++ b/nestkernel/grid_mask.h @@ -109,69 +109,6 @@ class GridMask : public AbstractMask Position< D, int > lower_right_; }; -template < int D > -GridMask< D >::GridMask( const DictionaryDatum& d ) -{ - std::vector< long > shape = getValue< std::vector< long > >( d, names::shape ); - - if ( D == 2 ) - { - lower_right_ = Position< D, int >( shape[ 0 ], shape[ 1 ] ); - } - else if ( D == 3 ) - { - lower_right_ = Position< D, int >( shape[ 0 ], shape[ 1 ], shape[ 2 ] ); - } - else - { - throw BadProperty( "Grid mask must be 2- or 3-dimensional." ); - } -} - -template <> -inline Name -GridMask< 2 >::get_name() -{ - return names::grid; -} - -template <> -inline Name -GridMask< 3 >::get_name() -{ - return names::grid3d; -} - -template < int D > -DictionaryDatum -GridMask< D >::get_dict() const -{ - DictionaryDatum d( new Dictionary ); - DictionaryDatum maskd( new Dictionary ); - def< DictionaryDatum >( d, get_name(), maskd ); - - long shape_x = lower_right_[ 0 ] - upper_left_[ 0 ]; - long shape_y = lower_right_[ 1 ] - upper_left_[ 1 ]; - std::vector< long > shape_dim { shape_x, shape_y }; - - if ( D == 3 ) - { - long shape_z = lower_right_[ 2 ] - upper_left_[ 2 ]; - shape_dim.push_back( shape_z ); - } - def< std::vector< long > >( maskd, names::shape, shape_dim ); - - return d; -} - -template < int D > -void -GridMask< D >::set_anchor( const Position< D, int >& anchor ) -{ - lower_right_ = lower_right_ - upper_left_ - anchor; - upper_left_ = -anchor; -} - } // namespace nest #endif diff --git a/nestkernel/grid_mask_impl.h b/nestkernel/grid_mask_impl.h new file mode 100644 index 0000000000..f8cb4d08bf --- /dev/null +++ b/nestkernel/grid_mask_impl.h @@ -0,0 +1,96 @@ +/* + * grid_mask_impl.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef GRID_MASK_IMPL_H +#define GRID_MASK_IMPL_H + +#include "grid_mask.h" + +namespace nest +{ + +template < int D > +GridMask< D >::GridMask( const DictionaryDatum& d ) +{ + std::vector< long > shape = getValue< std::vector< long > >( d, names::shape ); + + if ( D == 2 ) + { + lower_right_ = Position< D, int >( shape[ 0 ], shape[ 1 ] ); + } + else if ( D == 3 ) + { + lower_right_ = Position< D, int >( shape[ 0 ], shape[ 1 ], shape[ 2 ] ); + } + else + { + throw BadProperty( "Grid mask must be 2- or 3-dimensional." ); + } +} + +template <> +inline Name +GridMask< 2 >::get_name() +{ + return names::grid; +} + +template <> +inline Name +GridMask< 3 >::get_name() +{ + return names::grid3d; +} + +template < int D > +DictionaryDatum +GridMask< D >::get_dict() const +{ + DictionaryDatum d( new Dictionary ); + DictionaryDatum maskd( new Dictionary ); + def< DictionaryDatum >( d, get_name(), maskd ); + + long shape_x = lower_right_[ 0 ] - upper_left_[ 0 ]; + long shape_y = lower_right_[ 1 ] - upper_left_[ 1 ]; + std::vector< long > shape_dim { shape_x, shape_y }; + + if ( D == 3 ) + { + long shape_z = lower_right_[ 2 ] - upper_left_[ 2 ]; + shape_dim.push_back( shape_z ); + } + def< std::vector< long > >( maskd, names::shape, shape_dim ); + + return d; +} + +template < int D > +void +GridMask< D >::set_anchor( const Position< D, int >& anchor ) +{ + lower_right_ = lower_right_ - upper_left_ - anchor; + upper_left_ = -anchor; +} + +} + +#endif diff --git a/nestkernel/io_manager.cpp b/nestkernel/io_manager.cpp index 2d6bdf27e5..6b2b2e5293 100644 --- a/nestkernel/io_manager.cpp +++ b/nestkernel/io_manager.cpp @@ -38,14 +38,17 @@ #include "logging.h" // Includes from nestkernel: -#include "io_manager_impl.h" #include "kernel_manager.h" +#include "logging_manager.h" #include "recording_backend_ascii.h" #include "recording_backend_memory.h" #include "recording_backend_screen.h" + #ifdef HAVE_MPI #include "recording_backend_mpi.h" #include "stimulation_backend_mpi.h" +#else +#include "stimulation_backend.h" #endif #ifdef HAVE_SIONLIB #include "recording_backend_sionlib.h" @@ -392,4 +395,22 @@ IOManager::get_recording_backend_device_status( const Name backend_name, recording_backends_[ backend_name ]->get_device_status( device, d ); } +const std::string& +IOManager::get_data_path() const +{ + return data_path_; +} + +const std::string& +IOManager::get_data_prefix() const +{ + return data_prefix_; +} + +bool +IOManager::overwrite_files() const +{ + return overwrite_files_; +} + } // namespace nest diff --git a/nestkernel/io_manager.h b/nestkernel/io_manager.h index ea4be311bd..35193bfc3b 100644 --- a/nestkernel/io_manager.h +++ b/nestkernel/io_manager.h @@ -24,16 +24,23 @@ #define IO_MANAGER_H // C++ includes: +#include #include +#include // Includes from libnestutil: +#include "exceptions.h" #include "manager_interface.h" -#include "recording_backend.h" -#include "stimulation_backend.h" +// NOTE: Use forward declarations to avoid circular dependencies namespace nest { +class RecordingBackend; +class StimulationBackend; +class RecordingDevice; +class StimulationDevice; +class Event; /** * Manager to handle everything related to input and output. @@ -166,24 +173,34 @@ class IOManager : public ManagerInterface std::map< Name, StimulationBackend* > stimulation_backends_; }; -} // namespace nest - -inline const std::string& -nest::IOManager::get_data_path() const +template < class RecordingBackendT > +void +IOManager::register_recording_backend( const Name name ) { - return data_path_; + if ( recording_backends_.find( name ) != recording_backends_.end() ) + { + throw BackendAlreadyRegistered( name.toString() ); + } + + RecordingBackendT* recording_backend = new RecordingBackendT(); + recording_backend->pre_run_hook(); + recording_backends_.insert( std::make_pair( name, recording_backend ) ); } -inline const std::string& -nest::IOManager::get_data_prefix() const +template < class StimulationBackendT > +void +IOManager::register_stimulation_backend( const Name name ) { - return data_prefix_; + if ( stimulation_backends_.find( name ) != stimulation_backends_.end() ) + { + throw BackendAlreadyRegistered( name.toString() ); + } + + StimulationBackendT* stimulation_backend = new StimulationBackendT(); + stimulation_backend->pre_run_hook(); + stimulation_backends_.insert( std::make_pair( name, stimulation_backend ) ); } -inline bool -nest::IOManager::overwrite_files() const -{ - return overwrite_files_; -} +} // namespace nest #endif /* #ifndef IO_MANAGER_H */ diff --git a/nestkernel/io_manager_impl.h b/nestkernel/io_manager_impl.h deleted file mode 100644 index 9c631b4345..0000000000 --- a/nestkernel/io_manager_impl.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * io_manager_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - */ - -#ifndef IO_MANAGER_IMPL_H -#define IO_MANAGER_IMPL_H - -#include "io_manager.h" - -namespace nest -{ - -template < class RecordingBackendT > -void -IOManager::register_recording_backend( const Name name ) -{ - if ( recording_backends_.find( name ) != recording_backends_.end() ) - { - throw BackendAlreadyRegistered( name.toString() ); - } - - RecordingBackendT* recording_backend = new RecordingBackendT(); - recording_backend->pre_run_hook(); - recording_backends_.insert( std::make_pair( name, recording_backend ) ); -} - -template < class StimulationBackendT > -void -IOManager::register_stimulation_backend( const Name name ) -{ - if ( stimulation_backends_.find( name ) != stimulation_backends_.end() ) - { - throw BackendAlreadyRegistered( name.toString() ); - } - - StimulationBackendT* stimulation_backend = new StimulationBackendT(); - stimulation_backend->pre_run_hook(); - stimulation_backends_.insert( std::make_pair( name, stimulation_backend ) ); -} - -} // namespace nest - -#endif /* #ifndef IO_MANAGER_IMPL_H */ diff --git a/nestkernel/kernel_manager.cpp b/nestkernel/kernel_manager.cpp index e31cea89b4..3974676346 100644 --- a/nestkernel/kernel_manager.cpp +++ b/nestkernel/kernel_manager.cpp @@ -21,81 +21,62 @@ */ #include "kernel_manager.h" -#include "stopwatch_impl.h" -nest::KernelManager* nest::KernelManager::kernel_manager_instance_ = nullptr; - -void -nest::KernelManager::create_kernel_manager() +// Include concrete manager headers only in the implementation. +#include "connection_manager.h" +#include "event_delivery_manager.h" +#include "io_manager.h" +#include "logging_manager.h" +#include "model_manager.h" +#include "modelrange_manager.h" +#include "module_manager.h" +#include "mpi_manager.h" +#include "music_manager.h" +#include "node_manager.h" +#include "random_manager.h" +#include "simulation_manager.h" +#include "sp_manager.h" +#include "vp_manager.h" + +namespace nest { -#pragma omp master - { - if ( not kernel_manager_instance_ ) - { - kernel_manager_instance_ = new KernelManager(); - assert( kernel_manager_instance_ ); - } - } -#pragma omp barrier -} -void -nest::KernelManager::destroy_kernel_manager() -{ - kernel_manager_instance_->logging_manager.set_logging_level( M_QUIET ); - delete kernel_manager_instance_; -} - -nest::KernelManager::KernelManager() +KernelManager::KernelManager() : fingerprint_( 0 ) - , logging_manager() - , mpi_manager() - , vp_manager() - , module_manager() - , random_manager() - , simulation_manager() - , modelrange_manager() - , connection_manager() - , sp_manager() - , event_delivery_manager() - , io_manager() - , model_manager() - , music_manager() - , node_manager() - , managers( { &logging_manager, - &mpi_manager, - &vp_manager, - &module_manager, - &random_manager, - &simulation_manager, - &modelrange_manager, - &connection_manager, - &sp_manager, - &event_delivery_manager, - &io_manager, - &model_manager, - &music_manager, - &node_manager } ) + , managers( { &kernel::manager< LoggingManager >, + &kernel::manager< MPIManager >, + &kernel::manager< VPManager >, + &kernel::manager< ModuleManager >, + &kernel::manager< RandomManager >, + &kernel::manager< SimulationManager >, + &kernel::manager< ModelRangeManager >, + &kernel::manager< ConnectionManager >, + &kernel::manager< SPManager >, + &kernel::manager< EventDeliveryManager >, + &kernel::manager< IOManager >, + &kernel::manager< ModelManager >, + &kernel::manager< MUSICManager >, + &kernel::manager< NodeManager > } ) , initialized_( false ) { } -nest::KernelManager::~KernelManager() +KernelManager::~KernelManager() { + if ( initialized_ ) + { + KernelManager::finalize(); + } } void -nest::KernelManager::initialize() +KernelManager::initialize( const bool ) { for ( auto& manager : managers ) { manager->initialize( /* adjust_number_of_threads_or_rng_only */ false ); } - sw_omp_synchronization_construction_.reset(); - sw_omp_synchronization_simulation_.reset(); - sw_mpi_synchronization_.reset(); - ++fingerprint_; initialized_ = true; FULL_LOGGING_ONLY( dump_.open( @@ -103,62 +84,58 @@ nest::KernelManager::initialize() } void -nest::KernelManager::prepare() +KernelManager::prepare() { - for ( auto& manager : managers ) + for ( auto manager : managers ) { manager->prepare(); } - - sw_omp_synchronization_simulation_.reset(); - sw_mpi_synchronization_.reset(); } void -nest::KernelManager::cleanup() +KernelManager::cleanup() { - for ( auto&& m_it = managers.rbegin(); m_it != managers.rend(); ++m_it ) + for ( auto it = managers.rbegin(); it != managers.rend(); ++it ) { - ( *m_it )->cleanup(); + ( *it )->cleanup(); } } void -nest::KernelManager::finalize() +KernelManager::finalize( const bool ) { FULL_LOGGING_ONLY( dump_.close(); ) - for ( auto&& m_it = managers.rbegin(); m_it != managers.rend(); ++m_it ) + for ( auto it = managers.rbegin(); it != managers.rend(); ++it ) { - ( *m_it )->finalize( /* adjust_number_of_threads_or_rng_only */ false ); + ( *it )->finalize( /* adjust_number_of_threads_or_rng_only */ false ); } initialized_ = false; } void -nest::KernelManager::reset() +KernelManager::reset() { finalize(); initialize(); } void -nest::KernelManager::change_number_of_threads( size_t new_num_threads ) +KernelManager::change_number_of_threads( size_t new_num_threads ) { // Inputs are checked in VPManager::set_status(). // Just double check here that all values are legal. - assert( node_manager.size() == 0 ); - assert( not connection_manager.get_user_set_delay_extrema() ); - assert( not simulation_manager.has_been_simulated() ); - assert( not sp_manager.is_structural_plasticity_enabled() or new_num_threads == 1 ); + assert( kernel::manager< NodeManager >.size() == 0 ); + assert( not kernel::manager< ConnectionManager >.get_user_set_delay_extrema() ); + assert( not kernel::manager< SimulationManager >.has_been_simulated() ); + assert( not kernel::manager< SPManager >.is_structural_plasticity_enabled() or new_num_threads == 1 ); - // Finalize in reverse order of initialization with old thread number set - for ( auto mgr_it = managers.rbegin(); mgr_it != managers.rend(); ++mgr_it ) + for ( auto it = managers.rbegin(); it != managers.rend(); ++it ) { - ( *mgr_it )->finalize( /* adjust_number_of_threads_or_rng_only */ true ); + ( *it )->finalize( /* adjust_number_of_threads_or_rng_only */ true ); } - vp_manager.set_num_threads( new_num_threads ); + kernel::manager< VPManager >.set_num_threads( new_num_threads ); // Initialize in original order with new number of threads set for ( auto& manager : managers ) @@ -169,21 +146,17 @@ nest::KernelManager::change_number_of_threads( size_t new_num_threads ) // Finalizing deleted all register components. Now that all infrastructure // is in place again, we can tell modules to re-register the components // they provide. - module_manager.reinitialize_dynamic_modules(); + kernel::manager< ModuleManager >.reinitialize_dynamic_modules(); // Prepare timers and set the number of threads for multi-threaded timers - kernel().simulation_manager.reset_timers_for_preparation(); - kernel().simulation_manager.reset_timers_for_dynamics(); - kernel().event_delivery_manager.reset_timers_for_preparation(); - kernel().event_delivery_manager.reset_timers_for_dynamics(); - - sw_omp_synchronization_construction_.reset(); - sw_omp_synchronization_simulation_.reset(); - sw_mpi_synchronization_.reset(); + kernel::manager< SimulationManager >.reset_timers_for_preparation(); + kernel::manager< SimulationManager >.reset_timers_for_dynamics(); + kernel::manager< EventDeliveryManager >.reset_timers_for_preparation(); + kernel::manager< EventDeliveryManager >.reset_timers_for_dynamics(); } void -nest::KernelManager::set_status( const DictionaryDatum& dict ) +KernelManager::set_status( const DictionaryDatum& dict ) { assert( is_initialized() ); @@ -194,7 +167,7 @@ nest::KernelManager::set_status( const DictionaryDatum& dict ) } void -nest::KernelManager::get_status( DictionaryDatum& dict ) +KernelManager::get_status( DictionaryDatum& dict ) { assert( is_initialized() ); @@ -202,16 +175,10 @@ nest::KernelManager::get_status( DictionaryDatum& dict ) { manager->get_status( dict ); } - - sw_omp_synchronization_construction_.get_status( - dict, names::time_omp_synchronization_construction, names::time_omp_synchronization_construction_cpu ); - sw_omp_synchronization_simulation_.get_status( - dict, names::time_omp_synchronization_simulation, names::time_omp_synchronization_simulation_cpu ); - sw_mpi_synchronization_.get_status( dict, names::time_mpi_synchronization, names::time_mpi_synchronization_cpu ); } void -nest::KernelManager::write_to_dump( const std::string& msg ) +KernelManager::write_to_dump( const std::string& msg ) { #pragma omp critical // In critical section to avoid any garbling of output. @@ -219,3 +186,17 @@ nest::KernelManager::write_to_dump( const std::string& msg ) dump_ << msg << std::endl << std::flush; } } + +bool +KernelManager::is_initialized() const +{ + return initialized_; +} + +unsigned long +KernelManager::get_fingerprint() const +{ + return fingerprint_; +} + +} // namespace nest diff --git a/nestkernel/kernel_manager.h b/nestkernel/kernel_manager.h index abd225e836..5c49d7827a 100644 --- a/nestkernel/kernel_manager.h +++ b/nestkernel/kernel_manager.h @@ -23,31 +23,13 @@ #ifndef KERNEL_MANAGER_H #define KERNEL_MANAGER_H -// Includes from libnestutil -#include "config.h" - -// Includes from nestkernel: -#include "connection_manager.h" -#include "event_delivery_manager.h" -#include "io_manager.h" -#include "logging_manager.h" -#include "model_manager.h" -#include "modelrange_manager.h" -#include "module_manager.h" -#include "mpi_manager.h" -#include "music_manager.h" -#include "node_manager.h" -#include "random_manager.h" -#include "simulation_manager.h" -#include "sp_manager.h" -#include "vp_manager.h" - // Includes from sli: #include "dictdatum.h" -#include "compose.hpp" #include +#include "manager_interface.h" + /** @BeginDocumentation Name: kernel - Global properties of the simulation kernel. @@ -188,26 +170,16 @@ namespace nest { -class KernelManager +class KernelManager : public ManagerInterface { -private: - KernelManager(); - ~KernelManager(); - unsigned long fingerprint_; - static KernelManager* kernel_manager_instance_; - KernelManager( KernelManager const& ); // do not implement void operator=( KernelManager const& ); // do not implement public: - /** - * Create/destroy and access the KernelManager singleton. - */ - static void create_kernel_manager(); - static void destroy_kernel_manager(); - static KernelManager& get_kernel_manager(); + KernelManager(); + ~KernelManager() override; /** * Prepare kernel for operation. @@ -217,7 +189,7 @@ class KernelManager * * @see finalize(), reset() */ - void initialize(); + void initialize( const bool adjust_number_of_threads_or_rng_only = false ) override; /** * Take down kernel after operation. @@ -227,7 +199,7 @@ class KernelManager * * @see initialize(), reset() */ - void finalize(); + void finalize( const bool adjust_number_of_threads_or_rng_only = false ) override; /** * Reset kernel. @@ -241,16 +213,15 @@ class KernelManager /** * Change number of threads. * - * Set the new number of threads on all managers by calling - * change_number_of_threads() on each of them. + * Set the new number of threads on all managers by calling change_number_of_threads() on each of them. */ void change_number_of_threads( size_t new_num_threads ); - void set_status( const DictionaryDatum& ); - void get_status( DictionaryDatum& ); + void set_status( const DictionaryDatum& ) override; + void get_status( DictionaryDatum& ) override; - void prepare(); - void cleanup(); + void prepare() override; + void cleanup() override; //! Returns true if kernel is initialized bool is_initialized() const; @@ -264,89 +235,22 @@ class KernelManager */ void write_to_dump( const std::string& msg ); - /** - * \defgroup Manager components in NEST kernel - * - * The managers are defined below in the order in which they need to be initialized. - * - * NodeManager is last to ensure all model structures are in place before it is initialized. - * @{ - */ - LoggingManager logging_manager; - MPIManager mpi_manager; - VPManager vp_manager; - ModuleManager module_manager; - RandomManager random_manager; - SimulationManager simulation_manager; - ModelRangeManager modelrange_manager; - ConnectionManager connection_manager; - SPManager sp_manager; - EventDeliveryManager event_delivery_manager; - IOManager io_manager; - ModelManager model_manager; - MUSICManager music_manager; - NodeManager node_manager; - /**@}*/ - - //! Get the stopwatch to measure the time each thread is idle during network construction. - Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded >& - get_omp_synchronization_construction_stopwatch() - { - return sw_omp_synchronization_construction_; - } - - //! Get the stopwatch to measure the time each thread is idle during simulation. - Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded >& - get_omp_synchronization_simulation_stopwatch() - { - return sw_omp_synchronization_simulation_; - } - - Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::MasterOnly >& - get_mpi_synchronization_stopwatch() - { - return sw_mpi_synchronization_; - } - private: //! All managers, order determines initialization and finalization order (latter backwards) std::vector< ManagerInterface* > managers; bool initialized_; //!< true if the kernel is initialized std::ofstream dump_; //!< for FULL_LOGGING output - - Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded > sw_omp_synchronization_construction_; - Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded > sw_omp_synchronization_simulation_; - Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::MasterOnly > sw_mpi_synchronization_; }; -KernelManager& kernel(); - -} // namespace nest - -inline nest::KernelManager& -nest::KernelManager::get_kernel_manager() +namespace kernel { - assert( kernel_manager_instance_ ); - return *kernel_manager_instance_; -} -inline nest::KernelManager& -nest::kernel() -{ - return KernelManager::get_kernel_manager(); -} +template < class T > +inline T manager; -inline bool -nest::KernelManager::is_initialized() const -{ - return initialized_; } -inline unsigned long -nest::KernelManager::get_fingerprint() const -{ - return fingerprint_; -} +} // namespace nest #endif /* KERNEL_MANAGER_H */ diff --git a/nestkernel/layer.cpp b/nestkernel/layer.cpp index d8236b26a7..f6ee30a48a 100644 --- a/nestkernel/layer.cpp +++ b/nestkernel/layer.cpp @@ -20,11 +20,12 @@ * */ -#include "layer.h" +#include "layer_impl.h" // Includes from nestkernel: #include "exceptions.h" #include "kernel_manager.h" +#include "model_manager.h" #include "nest_names.h" #include "node_collection.h" #include "parameter.h" @@ -34,11 +35,8 @@ #include "integerdatum.h" // Includes from spatial: -#include "connection_creator_impl.h" -#include "free_layer.h" -#include "grid_layer.h" -#include "layer_impl.h" -#include "mask_impl.h" +#include "free_layer_impl.h" +#include "grid_layer_impl.h" #include "spatial.h" namespace nest @@ -58,7 +56,7 @@ AbstractLayer::create_layer( const DictionaryDatum& layer_dict ) AbstractLayer* layer_local = nullptr; auto element_name = getValue< std::string >( layer_dict, names::elements ); - auto element_id = kernel().model_manager.get_node_model_id( element_name ); + auto element_id = kernel::manager< ModelManager >.get_node_model_id( element_name ); if ( layer_dict->known( names::positions ) ) { @@ -146,7 +144,7 @@ AbstractLayer::create_layer( const DictionaryDatum& layer_dict ) NodeCollectionMetadataPTR layer_meta( new LayerMetadata( layer_safe ) ); // We have at least one element, create a NodeCollection for it - NodeCollectionPTR node_collection = kernel().node_manager.add_node( element_id, length ); + NodeCollectionPTR node_collection = kernel::manager< NodeManager >.add_node( element_id, length ); node_collection->set_metadata( layer_meta ); @@ -165,4 +163,17 @@ AbstractLayer::get_metadata() const return node_collection_->get_metadata(); } +// Define the tiny accessors (moved from header) +void +AbstractLayer::set_node_collection( NodeCollectionPTR node_collection ) +{ + node_collection_ = node_collection; +} + +NodeCollectionPTR +AbstractLayer::get_node_collection() +{ + return node_collection_; +} + } // namespace nest diff --git a/nestkernel/layer.h b/nestkernel/layer.h index 7adf212118..b67e90d56b 100644 --- a/nestkernel/layer.h +++ b/nestkernel/layer.h @@ -25,25 +25,22 @@ // C++ includes: #include -#include #include -// Includes from nestkernel: -#include "kernel_manager.h" -#include "nest_names.h" -#include "nest_types.h" - // Includes from sli: #include "dictutils.h" // Includes from spatial: #include "connection_creator.h" -#include "ntree.h" +#include "ntree_impl.h" #include "position.h" namespace nest { +template < int D > +class GridLayer; + class AbstractLayer; typedef std::shared_ptr< AbstractLayer > AbstractLayerPTR; @@ -522,174 +519,6 @@ class MaskedLayer MaskDatum mask_; }; -inline void -AbstractLayer::set_node_collection( NodeCollectionPTR node_collection ) -{ - node_collection_ = node_collection; -} - - -inline NodeCollectionPTR -AbstractLayer::get_node_collection() -{ - return node_collection_; -} - -template < int D > -inline MaskedLayer< D >::MaskedLayer( Layer< D >& layer, - const MaskDatum& maskd, - bool allow_oversized, - NodeCollectionPTR node_collection ) - : mask_( maskd ) -{ - ntree_ = layer.get_global_positions_ntree( node_collection ); - - check_mask_( layer, allow_oversized ); -} - -template < int D > -inline MaskedLayer< D >::MaskedLayer( Layer< D >& layer, - const MaskDatum& maskd, - bool allow_oversized, - Layer< D >& target, - NodeCollectionPTR node_collection ) - : mask_( maskd ) -{ - ntree_ = layer.get_global_positions_ntree( - target.get_periodic_mask(), target.get_lower_left(), target.get_extent(), node_collection ); - - check_mask_( target, allow_oversized ); - mask_ = new ConverseMask< D >( dynamic_cast< const Mask< D >& >( *mask_ ) ); -} - -template < int D > -inline MaskedLayer< D >::~MaskedLayer() -{ -} - -template < int D > -inline typename Ntree< D, size_t >::masked_iterator -MaskedLayer< D >::begin( const Position< D >& anchor ) -{ - try - { - return ntree_->masked_begin( dynamic_cast< const Mask< D >& >( *mask_ ), anchor ); - } - catch ( std::bad_cast& e ) - { - throw BadProperty( "Mask is incompatible with layer." ); - } -} - -template < int D > -inline typename Ntree< D, size_t >::masked_iterator -MaskedLayer< D >::end() -{ - return ntree_->masked_end(); -} - -template < int D > -inline Layer< D >::Layer() -{ - // Default center (0,0) and extent (1,1) - for ( int i = 0; i < D; ++i ) - { - lower_left_[ i ] = -0.5; - extent_[ i ] = 1.0; - } -} - -template < int D > -inline Layer< D >::Layer( const Layer& other_layer ) - : AbstractLayer( other_layer ) - , lower_left_( other_layer.lower_left_ ) - , extent_( other_layer.extent_ ) - , periodic_( other_layer.periodic_ ) -{ -} - -template < int D > -inline Layer< D >::~Layer() -{ - if ( cached_ntree_md_ == get_metadata() ) - { - clear_ntree_cache_(); - } - - if ( cached_vector_md_ == get_metadata() ) - { - clear_vector_cache_(); - } -} - -template < int D > -inline Position< D > -Layer< D >::compute_displacement( const Position< D >& from_pos, const size_t to_lid ) const -{ - return compute_displacement( from_pos, get_position( to_lid ) ); -} - -template < int D > -inline std::vector< double > -Layer< D >::compute_displacement( const std::vector< double >& from_pos, const size_t to_lid ) const -{ - return std::vector< double >( compute_displacement( Position< D >( from_pos ), to_lid ).get_vector() ); -} - -template < int D > -inline double -Layer< D >::compute_distance( const Position< D >& from_pos, const size_t lid ) const -{ - return compute_displacement( from_pos, lid ).length(); -} - -template < int D > -inline double -Layer< D >::compute_distance( const std::vector< double >& from_pos, const size_t lid ) const -{ - return compute_displacement( Position< D >( from_pos ), lid ).length(); -} - -template < int D > -inline double -Layer< D >::compute_distance( const std::vector< double >& from_pos, const std::vector< double >& to_pos ) const -{ - double squared_displacement = 0; - for ( unsigned int i = 0; i < D; ++i ) - { - const double displacement = compute_displacement( from_pos, to_pos, i ); - squared_displacement += displacement * displacement; - } - return std::sqrt( squared_displacement ); -} - -template < int D > -inline std::vector< double > -Layer< D >::get_position_vector( const size_t sind ) const -{ - return get_position( sind ).get_vector(); -} - -template < int D > -inline void -Layer< D >::clear_ntree_cache_() const -{ - cached_ntree_ = std::shared_ptr< Ntree< D, size_t > >(); - cached_ntree_md_ = NodeCollectionMetadataPTR( nullptr ); -} - -template < int D > -inline void -Layer< D >::clear_vector_cache_() const -{ - if ( cached_vector_ != 0 ) - { - delete cached_vector_; - } - cached_vector_ = 0; - cached_vector_md_ = NodeCollectionMetadataPTR( nullptr ); -} - } // namespace nest #endif diff --git a/nestkernel/layer_impl.h b/nestkernel/layer_impl.h index e24f571d08..fc136235b4 100644 --- a/nestkernel/layer_impl.h +++ b/nestkernel/layer_impl.h @@ -19,24 +19,260 @@ * along with NEST. If not, see . * */ - #ifndef LAYER_IMPL_H #define LAYER_IMPL_H +#include "connection_creator_impl.h" +#include "free_layer_impl.h" +#include "grid_layer_impl.h" +#include "grid_mask_impl.h" #include "layer.h" +#include "mask_impl.h" -// Includes from nestkernel: -#include "booldatum.h" -#include "nest_datums.h" -#include "node_collection.h" - -// Includes from spatial: -#include "grid_layer.h" -#include "grid_mask.h" +#include namespace nest { +template < int D > +void +MaskedLayer< D >::check_mask_( Layer< D >& layer, bool allow_oversized ) +{ + if ( not mask_.get() ) + { + mask_ = new AllMask< D >(); + return; + } + + try // Try to cast to GridMask + { + const GridMask< D >& grid_mask = dynamic_cast< const GridMask< D >& >( *mask_ ); + + // If the above cast succeeds, then this is a grid mask + + GridLayer< D >* grid_layer = dynamic_cast< GridLayer< D >* >( &layer ); + if ( grid_layer == 0 ) + { + throw BadProperty( "Grid masks can only be used with grid layers." ); + } + + Position< D > ext = grid_layer->get_extent(); + Position< D, size_t > dims = grid_layer->get_dims(); + + if ( not allow_oversized ) + { + bool oversize = false; + for ( int i = 0; i < D; ++i ) + { + oversize |= layer.get_periodic_mask()[ i ] + and ( grid_mask.get_lower_right()[ i ] - grid_mask.get_upper_left()[ i ] ) > static_cast< int >( dims[ i ] ); + } + if ( oversize ) + { + throw BadProperty( + "Mask size must not exceed layer size; set allow_oversized_mask to " + "override." ); + } + } + + Position< D > lower_left = ext / dims * grid_mask.get_upper_left() - ext / dims * 0.5; + Position< D > upper_right = ext / dims * grid_mask.get_lower_right() - ext / dims * 0.5; + + double y = lower_left[ 1 ]; + lower_left[ 1 ] = -upper_right[ 1 ]; + upper_right[ 1 ] = -y; + + mask_ = new BoxMask< D >( lower_left, upper_right ); + } + catch ( std::bad_cast& ) + { + + // Not a grid mask + + try // Try to cast to correct dimension Mask + { + const Mask< D >& mask = dynamic_cast< const Mask< D >& >( *mask_ ); + + if ( not allow_oversized ) + { + const Box< D > bb = mask.get_bbox(); + bool oversize = false; + for ( int i = 0; i < D; ++i ) + { + oversize |= + layer.get_periodic_mask()[ i ] and bb.upper_right[ i ] - bb.lower_left[ i ] > layer.get_extent()[ i ]; + } + if ( oversize ) + { + throw BadProperty( + "Mask size must not exceed layer size; set allow_oversized_mask to " + "override." ); + } + } + } + catch ( std::bad_cast& ) + { + throw BadProperty( "Mask is incompatible with layer." ); + } + } +} + + +template < int D > +inline MaskedLayer< D >::MaskedLayer( Layer< D >& layer, + const MaskDatum& maskd, + bool allow_oversized, + NodeCollectionPTR node_collection ) + : mask_( maskd ) +{ + ntree_ = layer.get_global_positions_ntree( node_collection ); + + check_mask_( layer, allow_oversized ); +} + +template < int D > +inline MaskedLayer< D >::MaskedLayer( Layer< D >& layer, + const MaskDatum& maskd, + bool allow_oversized, + Layer< D >& target, + NodeCollectionPTR node_collection ) + : mask_( maskd ) +{ + ntree_ = layer.get_global_positions_ntree( + target.get_periodic_mask(), target.get_lower_left(), target.get_extent(), node_collection ); + + check_mask_( target, allow_oversized ); + mask_ = new ConverseMask< D >( dynamic_cast< const Mask< D >& >( *mask_ ) ); +} + +template < int D > +inline MaskedLayer< D >::~MaskedLayer() +{ +} + +template < int D > +inline typename Ntree< D, size_t >::masked_iterator +MaskedLayer< D >::begin( const Position< D >& anchor ) +{ + try + { + return ntree_->masked_begin( dynamic_cast< const Mask< D >& >( *mask_ ), anchor ); + } + catch ( std::bad_cast& e ) + { + throw BadProperty( "Mask is incompatible with layer." ); + } +} + +template < int D > +inline typename Ntree< D, size_t >::masked_iterator +MaskedLayer< D >::end() +{ + return ntree_->masked_end(); +} + +template < int D > +inline Layer< D >::Layer() +{ + // Default center (0,0) and extent (1,1) + for ( int i = 0; i < D; ++i ) + { + lower_left_[ i ] = -0.5; + extent_[ i ] = 1.0; + } +} + +template < int D > +inline Layer< D >::Layer( const Layer& other_layer ) + : AbstractLayer( other_layer ) + , lower_left_( other_layer.lower_left_ ) + , extent_( other_layer.extent_ ) + , periodic_( other_layer.periodic_ ) +{ +} + +template < int D > +inline Layer< D >::~Layer() +{ + if ( cached_ntree_md_ == get_metadata() ) + { + clear_ntree_cache_(); + } + + if ( cached_vector_md_ == get_metadata() ) + { + clear_vector_cache_(); + } +} + +template < int D > +inline Position< D > +Layer< D >::compute_displacement( const Position< D >& from_pos, const size_t to_lid ) const +{ + return compute_displacement( from_pos, get_position( to_lid ) ); +} + +template < int D > +inline std::vector< double > +Layer< D >::compute_displacement( const std::vector< double >& from_pos, const size_t to_lid ) const +{ + return std::vector< double >( compute_displacement( Position< D >( from_pos ), to_lid ).get_vector() ); +} + +template < int D > +inline double +Layer< D >::compute_distance( const Position< D >& from_pos, const size_t lid ) const +{ + return compute_displacement( from_pos, lid ).length(); +} + +template < int D > +inline double +Layer< D >::compute_distance( const std::vector< double >& from_pos, const size_t lid ) const +{ + return compute_displacement( Position< D >( from_pos ), lid ).length(); +} + +template < int D > +inline double +Layer< D >::compute_distance( const std::vector< double >& from_pos, const std::vector< double >& to_pos ) const +{ + double squared_displacement = 0; + for ( unsigned int i = 0; i < D; ++i ) + { + const double displacement = compute_displacement( from_pos, to_pos, i ); + squared_displacement += displacement * displacement; + } + return std::sqrt( squared_displacement ); +} + +template < int D > +inline std::vector< double > +Layer< D >::get_position_vector( const size_t sind ) const +{ + return get_position( sind ).get_vector(); +} + +template < int D > +inline void +Layer< D >::clear_ntree_cache_() const +{ + cached_ntree_ = std::shared_ptr< Ntree< D, size_t > >(); + cached_ntree_md_ = NodeCollectionMetadataPTR( nullptr ); +} + +template < int D > +inline void +Layer< D >::clear_vector_cache_() const +{ + if ( cached_vector_ != 0 ) + { + delete cached_vector_; + } + cached_vector_ = 0; + cached_vector_md_ = NodeCollectionMetadataPTR( nullptr ); +} + template < int D > std::shared_ptr< Ntree< D, size_t > > Layer< D >::cached_ntree_; @@ -315,7 +551,7 @@ Layer< D >::dump_connections( std::ostream& out, def( conn_filter, names::source, NodeCollectionDatum( node_collection ) ); def( conn_filter, names::target, NodeCollectionDatum( target_layer->get_node_collection() ) ); def( conn_filter, names::synapse_model, syn_model ); - ArrayDatum connectome = kernel().connection_manager.get_connections( conn_filter ); + ArrayDatum connectome = kernel::manager< ConnectionManager >.get_connections( conn_filter ); // Get positions of remote nodes std::vector< std::pair< Position< D >, size_t > >* src_vec = get_global_positions_vector( node_collection ); @@ -340,7 +576,7 @@ Layer< D >::dump_connections( std::ostream& out, previous_source_node_id = source_node_id; } - DictionaryDatum result_dict = kernel().connection_manager.get_synapse_status( source_node_id, + DictionaryDatum result_dict = kernel::manager< ConnectionManager >.get_synapse_status( source_node_id, conn.get_target_node_id(), conn.get_target_thread(), conn.get_synapse_model_id(), @@ -359,88 +595,6 @@ Layer< D >::dump_connections( std::ostream& out, } } -template < int D > -void -MaskedLayer< D >::check_mask_( Layer< D >& layer, bool allow_oversized ) -{ - if ( not mask_.get() ) - { - mask_ = new AllMask< D >(); - return; - } - - try // Try to cast to GridMask - { - const GridMask< D >& grid_mask = dynamic_cast< const GridMask< D >& >( *mask_ ); - - // If the above cast succeeds, then this is a grid mask - - GridLayer< D >* grid_layer = dynamic_cast< GridLayer< D >* >( &layer ); - if ( grid_layer == 0 ) - { - throw BadProperty( "Grid masks can only be used with grid layers." ); - } - - Position< D > ext = grid_layer->get_extent(); - Position< D, size_t > dims = grid_layer->get_dims(); - - if ( not allow_oversized ) - { - bool oversize = false; - for ( int i = 0; i < D; ++i ) - { - oversize |= layer.get_periodic_mask()[ i ] - and ( grid_mask.get_lower_right()[ i ] - grid_mask.get_upper_left()[ i ] ) > static_cast< int >( dims[ i ] ); - } - if ( oversize ) - { - throw BadProperty( - "Mask size must not exceed layer size; set allow_oversized_mask to " - "override." ); - } - } - - Position< D > lower_left = ext / dims * grid_mask.get_upper_left() - ext / dims * 0.5; - Position< D > upper_right = ext / dims * grid_mask.get_lower_right() - ext / dims * 0.5; - - double y = lower_left[ 1 ]; - lower_left[ 1 ] = -upper_right[ 1 ]; - upper_right[ 1 ] = -y; - - mask_ = new BoxMask< D >( lower_left, upper_right ); - } - catch ( std::bad_cast& ) - { - - // Not a grid mask - - try // Try to cast to correct dimension Mask - { - const Mask< D >& mask = dynamic_cast< const Mask< D >& >( *mask_ ); - - if ( not allow_oversized ) - { - const Box< D > bb = mask.get_bbox(); - bool oversize = false; - for ( int i = 0; i < D; ++i ) - { - oversize |= - layer.get_periodic_mask()[ i ] and bb.upper_right[ i ] - bb.lower_left[ i ] > layer.get_extent()[ i ]; - } - if ( oversize ) - { - throw BadProperty( - "Mask size must not exceed layer size; set allow_oversized_mask to " - "override." ); - } - } - } - catch ( std::bad_cast& ) - { - throw BadProperty( "Mask is incompatible with layer." ); - } - } -} } // namespace nest diff --git a/nestkernel/mask.h b/nestkernel/mask.h index 33b4c20c3b..d1bb340df3 100644 --- a/nestkernel/mask.h +++ b/nestkernel/mask.h @@ -29,7 +29,6 @@ // Includes from nestkernel: #include "exceptions.h" #include "nest_names.h" -#include "nest_types.h" #include "nestmodule.h" // Includes from sli: @@ -37,7 +36,7 @@ #include "dictutils.h" // Includes from spatial: -#include "position.h" +#include "position_impl.h" namespace nest { @@ -719,295 +718,6 @@ class AnchoredMask : public Mask< D > Position< D > anchor_; }; -template <> -inline Name -BoxMask< 2 >::get_name() -{ - return names::rectangular; -} - -template <> -inline Name -BoxMask< 3 >::get_name() -{ - return names::box; -} - -template < int D > -BoxMask< D >::BoxMask( const DictionaryDatum& d ) -{ - lower_left_ = getValue< std::vector< double > >( d, names::lower_left ); - upper_right_ = getValue< std::vector< double > >( d, names::upper_right ); - - if ( not( lower_left_ < upper_right_ ) ) - { - throw BadProperty( - "nest::BoxMask: " - "Upper right must be strictly to the right and above lower left." ); - } - - if ( d->known( names::azimuth_angle ) ) - { - azimuth_angle_ = getValue< double >( d, names::azimuth_angle ); - } - else - { - azimuth_angle_ = 0.0; - } - - if ( d->known( names::polar_angle ) ) - { - if ( D == 2 ) - { - throw BadProperty( - "nest::BoxMask: " - "polar_angle not defined in 2D." ); - } - polar_angle_ = getValue< double >( d, names::polar_angle ); - } - else - { - polar_angle_ = 0.0; - } - - azimuth_cos_ = std::cos( azimuth_angle_ * numerics::pi / 180. ); - azimuth_sin_ = std::sin( azimuth_angle_ * numerics::pi / 180. ); - polar_cos_ = std::cos( polar_angle_ * numerics::pi / 180. ); - polar_sin_ = std::sin( polar_angle_ * numerics::pi / 180. ); - - cntr_ = ( upper_right_ + lower_left_ ) * 0.5; - for ( int i = 0; i != D; ++i ) - { - eps_[ i ] = 1e-12; - } - - cntr_x_az_cos_ = cntr_[ 0 ] * azimuth_cos_; - cntr_x_az_sin_ = cntr_[ 0 ] * azimuth_sin_; - cntr_y_az_cos_ = cntr_[ 1 ] * azimuth_cos_; - cntr_y_az_sin_ = cntr_[ 1 ] * azimuth_sin_; - if ( D == 3 ) - { - cntr_z_pol_cos_ = cntr_[ 2 ] * polar_cos_; - cntr_z_pol_sin_ = cntr_[ 2 ] * polar_sin_; - cntr_x_az_cos_pol_cos_ = cntr_x_az_cos_ * polar_cos_; - cntr_x_az_cos_pol_sin_ = cntr_x_az_cos_ * polar_sin_; - cntr_y_az_sin_pol_cos_ = cntr_y_az_sin_ * polar_cos_; - cntr_y_az_sin_pol_sin_ = cntr_y_az_sin_ * polar_sin_; - az_cos_pol_cos_ = azimuth_cos_ * polar_cos_; - az_cos_pol_sin_ = azimuth_cos_ * polar_sin_; - az_sin_pol_cos_ = azimuth_sin_ * polar_cos_; - az_sin_pol_sin_ = azimuth_sin_ * polar_sin_; - } - else - { - cntr_z_pol_cos_ = 0.0; - cntr_z_pol_sin_ = 0.0; - cntr_x_az_cos_pol_cos_ = 0.0; - cntr_x_az_cos_pol_sin_ = 0.0; - cntr_y_az_sin_pol_cos_ = 0.0; - cntr_y_az_sin_pol_sin_ = 0.0; - az_cos_pol_cos_ = 0.0; - az_cos_pol_sin_ = 0.0; - az_sin_pol_cos_ = 0.0; - az_sin_pol_sin_ = 0.0; - } - - is_rotated_ = azimuth_angle_ != 0.0 or polar_angle_ != 0.0; - - calculate_min_max_values_(); -} - -template < int D > -inline BoxMask< D >::BoxMask( const Position< D >& lower_left, - const Position< D >& upper_right, - const double azimuth_angle, - const double polar_angle ) - : lower_left_( lower_left ) - , upper_right_( upper_right ) - , azimuth_angle_( azimuth_angle ) - , polar_angle_( polar_angle ) - , azimuth_cos_( std::cos( azimuth_angle_ * numerics::pi / 180. ) ) - , azimuth_sin_( std::sin( azimuth_angle_ * numerics::pi / 180. ) ) - , polar_cos_( std::cos( polar_angle_ * numerics::pi / 180. ) ) - , polar_sin_( std::sin( polar_angle_ * numerics::pi / 180. ) ) - , cntr_( ( upper_right_ + lower_left_ ) * 0.5 ) - , cntr_x_az_cos_( cntr_[ 0 ] * azimuth_cos_ ) - , cntr_x_az_sin_( cntr_[ 0 ] * azimuth_sin_ ) - , cntr_y_az_cos_( cntr_[ 1 ] * azimuth_cos_ ) - , cntr_y_az_sin_( cntr_[ 1 ] * azimuth_sin_ ) -{ - if ( D == 2 and not( polar_angle_ == 0.0 ) ) - { - throw BadProperty( - "nest::BoxMask: " - "polar_angle not defined in 2D." ); - } - - for ( int i = 0; i != D; ++i ) - { - eps_[ i ] = 1e-12; - } - - if ( D == 3 ) - { - cntr_z_pol_cos_ = cntr_[ 2 ] * polar_cos_; - cntr_z_pol_sin_ = cntr_[ 2 ] * polar_sin_; - cntr_x_az_cos_pol_cos_ = cntr_x_az_cos_ * polar_cos_; - cntr_x_az_cos_pol_sin_ = cntr_x_az_cos_ * polar_sin_; - cntr_y_az_sin_pol_cos_ = cntr_y_az_sin_ * polar_cos_; - cntr_y_az_sin_pol_sin_ = cntr_y_az_sin_ * polar_sin_; - az_cos_pol_cos_ = azimuth_cos_ * polar_cos_; - az_cos_pol_sin_ = azimuth_cos_ * polar_sin_; - az_sin_pol_cos_ = azimuth_sin_ * polar_cos_; - az_sin_pol_sin_ = azimuth_sin_ * polar_sin_; - } - else - { - cntr_z_pol_cos_ = 0.0; - cntr_z_pol_sin_ = 0.0; - cntr_x_az_cos_pol_cos_ = 0.0; - cntr_x_az_cos_pol_sin_ = 0.0; - cntr_y_az_sin_pol_cos_ = 0.0; - cntr_y_az_sin_pol_sin_ = 0.0; - az_cos_pol_cos_ = 0.0; - az_cos_pol_sin_ = 0.0; - az_sin_pol_cos_ = 0.0; - az_sin_pol_sin_ = 0.0; - } - - is_rotated_ = azimuth_angle_ != 0.0 or polar_angle_ != 0.0; - - calculate_min_max_values_(); -} - -template <> -inline Name -BallMask< 2 >::get_name() -{ - return names::circular; -} - -template <> -inline Name -BallMask< 3 >::get_name() -{ - return names::spherical; -} - -template < int D > -BallMask< D >::BallMask( const DictionaryDatum& d ) -{ - radius_ = getValue< double >( d, names::radius ); - if ( radius_ <= 0 ) - { - throw BadProperty( - "nest::BallMask: " - "radius > 0 required." ); - } - - if ( d->known( names::anchor ) ) - { - center_ = getValue< std::vector< double > >( d, names::anchor ); - } -} - -template <> -inline Name -EllipseMask< 2 >::get_name() -{ - return names::elliptical; -} - -template <> -inline Name -EllipseMask< 3 >::get_name() -{ - return names::ellipsoidal; -} - -template < int D > -EllipseMask< D >::EllipseMask( const DictionaryDatum& d ) -{ - major_axis_ = getValue< double >( d, names::major_axis ); - minor_axis_ = getValue< double >( d, names::minor_axis ); - if ( major_axis_ <= 0 or minor_axis_ <= 0 ) - { - throw BadProperty( - "nest::EllipseMask: " - "All axis > 0 required." ); - } - if ( major_axis_ < minor_axis_ ) - { - throw BadProperty( - "nest::EllipseMask: " - "major_axis greater than minor_axis required." ); - } - - x_scale_ = 4.0 / ( major_axis_ * major_axis_ ); - y_scale_ = 4.0 / ( minor_axis_ * minor_axis_ ); - - if ( d->known( names::polar_axis ) ) - { - if ( D == 2 ) - { - throw BadProperty( - "nest::EllipseMask: " - "polar_axis not defined in 2D." ); - } - polar_axis_ = getValue< double >( d, names::polar_axis ); - - if ( polar_axis_ <= 0 ) - { - throw BadProperty( - "nest::EllipseMask: " - "All axis > 0 required." ); - } - - z_scale_ = 4.0 / ( polar_axis_ * polar_axis_ ); - } - else - { - polar_axis_ = 0.0; - z_scale_ = 0.0; - } - - if ( d->known( names::anchor ) ) - { - center_ = getValue< std::vector< double > >( d, names::anchor ); - } - - if ( d->known( names::azimuth_angle ) ) - { - azimuth_angle_ = getValue< double >( d, names::azimuth_angle ); - } - else - { - azimuth_angle_ = 0.0; - } - - if ( d->known( names::polar_angle ) ) - { - if ( D == 2 ) - { - throw BadProperty( - "nest::EllipseMask: " - "polar_angle not defined in 2D." ); - } - polar_angle_ = getValue< double >( d, names::polar_angle ); - } - else - { - polar_angle_ = 0.0; - } - - azimuth_cos_ = std::cos( azimuth_angle_ * numerics::pi / 180. ); - azimuth_sin_ = std::sin( azimuth_angle_ * numerics::pi / 180. ); - polar_cos_ = std::cos( polar_angle_ * numerics::pi / 180. ); - polar_sin_ = std::sin( polar_angle_ * numerics::pi / 180. ); - - create_bbox_(); -} - } // namespace nest #endif diff --git a/nestkernel/mask_impl.h b/nestkernel/mask_impl.h index d62bab2e58..0d960f5a60 100644 --- a/nestkernel/mask_impl.h +++ b/nestkernel/mask_impl.h @@ -24,10 +24,301 @@ #define MASK_IMPL_H #include "mask.h" +#include "nest_names.h" +#include "position.h" namespace nest { +template <> +inline Name +BoxMask< 2 >::get_name() +{ + return names::rectangular; +} + +template <> +inline Name +BoxMask< 3 >::get_name() +{ + return names::box; +} + +template < int D > +BoxMask< D >::BoxMask( const DictionaryDatum& d ) +{ + lower_left_ = getValue< std::vector< double > >( d, names::lower_left ); + upper_right_ = getValue< std::vector< double > >( d, names::upper_right ); + + if ( not( lower_left_ < upper_right_ ) ) + { + throw BadProperty( + "nest::BoxMask: " + "Upper right must be strictly to the right and above lower left." ); + } + + if ( d->known( names::azimuth_angle ) ) + { + azimuth_angle_ = getValue< double >( d, names::azimuth_angle ); + } + else + { + azimuth_angle_ = 0.0; + } + + if ( d->known( names::polar_angle ) ) + { + if ( D == 2 ) + { + throw BadProperty( + "nest::BoxMask: " + "polar_angle not defined in 2D." ); + } + polar_angle_ = getValue< double >( d, names::polar_angle ); + } + else + { + polar_angle_ = 0.0; + } + + azimuth_cos_ = std::cos( azimuth_angle_ * numerics::pi / 180. ); + azimuth_sin_ = std::sin( azimuth_angle_ * numerics::pi / 180. ); + polar_cos_ = std::cos( polar_angle_ * numerics::pi / 180. ); + polar_sin_ = std::sin( polar_angle_ * numerics::pi / 180. ); + + cntr_ = ( upper_right_ + lower_left_ ) * 0.5; + for ( int i = 0; i != D; ++i ) + { + eps_[ i ] = 1e-12; + } + + cntr_x_az_cos_ = cntr_[ 0 ] * azimuth_cos_; + cntr_x_az_sin_ = cntr_[ 0 ] * azimuth_sin_; + cntr_y_az_cos_ = cntr_[ 1 ] * azimuth_cos_; + cntr_y_az_sin_ = cntr_[ 1 ] * azimuth_sin_; + if ( D == 3 ) + { + cntr_z_pol_cos_ = cntr_[ 2 ] * polar_cos_; + cntr_z_pol_sin_ = cntr_[ 2 ] * polar_sin_; + cntr_x_az_cos_pol_cos_ = cntr_x_az_cos_ * polar_cos_; + cntr_x_az_cos_pol_sin_ = cntr_x_az_cos_ * polar_sin_; + cntr_y_az_sin_pol_cos_ = cntr_y_az_sin_ * polar_cos_; + cntr_y_az_sin_pol_sin_ = cntr_y_az_sin_ * polar_sin_; + az_cos_pol_cos_ = azimuth_cos_ * polar_cos_; + az_cos_pol_sin_ = azimuth_cos_ * polar_sin_; + az_sin_pol_cos_ = azimuth_sin_ * polar_cos_; + az_sin_pol_sin_ = azimuth_sin_ * polar_sin_; + } + else + { + cntr_z_pol_cos_ = 0.0; + cntr_z_pol_sin_ = 0.0; + cntr_x_az_cos_pol_cos_ = 0.0; + cntr_x_az_cos_pol_sin_ = 0.0; + cntr_y_az_sin_pol_cos_ = 0.0; + cntr_y_az_sin_pol_sin_ = 0.0; + az_cos_pol_cos_ = 0.0; + az_cos_pol_sin_ = 0.0; + az_sin_pol_cos_ = 0.0; + az_sin_pol_sin_ = 0.0; + } + + is_rotated_ = azimuth_angle_ != 0.0 or polar_angle_ != 0.0; + + calculate_min_max_values_(); +} + +template < int D > +inline BoxMask< D >::BoxMask( const Position< D >& lower_left, + const Position< D >& upper_right, + const double azimuth_angle, + const double polar_angle ) + : lower_left_( lower_left ) + , upper_right_( upper_right ) + , azimuth_angle_( azimuth_angle ) + , polar_angle_( polar_angle ) + , azimuth_cos_( std::cos( azimuth_angle_ * numerics::pi / 180. ) ) + , azimuth_sin_( std::sin( azimuth_angle_ * numerics::pi / 180. ) ) + , polar_cos_( std::cos( polar_angle_ * numerics::pi / 180. ) ) + , polar_sin_( std::sin( polar_angle_ * numerics::pi / 180. ) ) + , cntr_( ( upper_right_ + lower_left_ ) * 0.5 ) + , cntr_x_az_cos_( cntr_[ 0 ] * azimuth_cos_ ) + , cntr_x_az_sin_( cntr_[ 0 ] * azimuth_sin_ ) + , cntr_y_az_cos_( cntr_[ 1 ] * azimuth_cos_ ) + , cntr_y_az_sin_( cntr_[ 1 ] * azimuth_sin_ ) +{ + if ( D == 2 and not( polar_angle_ == 0.0 ) ) + { + throw BadProperty( + "nest::BoxMask: " + "polar_angle not defined in 2D." ); + } + + for ( int i = 0; i != D; ++i ) + { + eps_[ i ] = 1e-12; + } + + if ( D == 3 ) + { + cntr_z_pol_cos_ = cntr_[ 2 ] * polar_cos_; + cntr_z_pol_sin_ = cntr_[ 2 ] * polar_sin_; + cntr_x_az_cos_pol_cos_ = cntr_x_az_cos_ * polar_cos_; + cntr_x_az_cos_pol_sin_ = cntr_x_az_cos_ * polar_sin_; + cntr_y_az_sin_pol_cos_ = cntr_y_az_sin_ * polar_cos_; + cntr_y_az_sin_pol_sin_ = cntr_y_az_sin_ * polar_sin_; + az_cos_pol_cos_ = azimuth_cos_ * polar_cos_; + az_cos_pol_sin_ = azimuth_cos_ * polar_sin_; + az_sin_pol_cos_ = azimuth_sin_ * polar_cos_; + az_sin_pol_sin_ = azimuth_sin_ * polar_sin_; + } + else + { + cntr_z_pol_cos_ = 0.0; + cntr_z_pol_sin_ = 0.0; + cntr_x_az_cos_pol_cos_ = 0.0; + cntr_x_az_cos_pol_sin_ = 0.0; + cntr_y_az_sin_pol_cos_ = 0.0; + cntr_y_az_sin_pol_sin_ = 0.0; + az_cos_pol_cos_ = 0.0; + az_cos_pol_sin_ = 0.0; + az_sin_pol_cos_ = 0.0; + az_sin_pol_sin_ = 0.0; + } + + is_rotated_ = azimuth_angle_ != 0.0 or polar_angle_ != 0.0; + + calculate_min_max_values_(); +} + +template <> +inline Name +BallMask< 2 >::get_name() +{ + return names::circular; +} + +template <> +inline Name +BallMask< 3 >::get_name() +{ + return names::spherical; +} + +template < int D > +BallMask< D >::BallMask( const DictionaryDatum& d ) +{ + radius_ = getValue< double >( d, names::radius ); + if ( radius_ <= 0 ) + { + throw BadProperty( + "nest::BallMask: " + "radius > 0 required." ); + } + + if ( d->known( names::anchor ) ) + { + center_ = getValue< std::vector< double > >( d, names::anchor ); + } +} + +template <> +inline Name +EllipseMask< 2 >::get_name() +{ + return names::elliptical; +} + +template <> +inline Name +EllipseMask< 3 >::get_name() +{ + return names::ellipsoidal; +} + +template < int D > +EllipseMask< D >::EllipseMask( const DictionaryDatum& d ) +{ + major_axis_ = getValue< double >( d, names::major_axis ); + minor_axis_ = getValue< double >( d, names::minor_axis ); + if ( major_axis_ <= 0 or minor_axis_ <= 0 ) + { + throw BadProperty( + "nest::EllipseMask: " + "All axis > 0 required." ); + } + if ( major_axis_ < minor_axis_ ) + { + throw BadProperty( + "nest::EllipseMask: " + "major_axis greater than minor_axis required." ); + } + + x_scale_ = 4.0 / ( major_axis_ * major_axis_ ); + y_scale_ = 4.0 / ( minor_axis_ * minor_axis_ ); + + if ( d->known( names::polar_axis ) ) + { + if ( D == 2 ) + { + throw BadProperty( + "nest::EllipseMask: " + "polar_axis not defined in 2D." ); + } + polar_axis_ = getValue< double >( d, names::polar_axis ); + + if ( polar_axis_ <= 0 ) + { + throw BadProperty( + "nest::EllipseMask: " + "All axis > 0 required." ); + } + + z_scale_ = 4.0 / ( polar_axis_ * polar_axis_ ); + } + else + { + polar_axis_ = 0.0; + z_scale_ = 0.0; + } + + if ( d->known( names::anchor ) ) + { + center_ = getValue< std::vector< double > >( d, names::anchor ); + } + + if ( d->known( names::azimuth_angle ) ) + { + azimuth_angle_ = getValue< double >( d, names::azimuth_angle ); + } + else + { + azimuth_angle_ = 0.0; + } + + if ( d->known( names::polar_angle ) ) + { + if ( D == 2 ) + { + throw BadProperty( + "nest::EllipseMask: " + "polar_angle not defined in 2D." ); + } + polar_angle_ = getValue< double >( d, names::polar_angle ); + } + else + { + polar_angle_ = 0.0; + } + + azimuth_cos_ = std::cos( azimuth_angle_ * numerics::pi / 180. ); + azimuth_sin_ = std::sin( azimuth_angle_ * numerics::pi / 180. ); + polar_cos_ = std::cos( polar_angle_ * numerics::pi / 180. ); + polar_sin_ = std::sin( polar_angle_ * numerics::pi / 180. ); + + create_bbox_(); +} + template < int D > AbstractMask* Mask< D >::intersect_mask( const AbstractMask& other ) const @@ -509,7 +800,7 @@ AnchoredMask< D >::get_dict() const def< std::vector< double > >( d, names::anchor, anchor_.get_vector() ); return d; } +} -} // namespace nest #endif diff --git a/nestkernel/model.cpp b/nestkernel/model.cpp index 08d2a342a3..19f28786f5 100644 --- a/nestkernel/model.cpp +++ b/nestkernel/model.cpp @@ -31,6 +31,7 @@ // Includes from nestkernel: #include "exceptions.h" #include "kernel_manager.h" +#include "model_manager.h" // Includes from sli: #include "dictutils.h" @@ -48,7 +49,7 @@ Model::Model( const std::string& name ) void Model::set_threads() { - set_threads_( kernel().vp_manager.get_num_threads() ); + set_threads_( kernel::manager< VPManager >.get_num_threads() ); } void @@ -129,7 +130,7 @@ Model::get_status() } ( *d )[ names::instantiations ] = Token( tmp ); - ( *d )[ names::type_id ] = LiteralDatum( kernel().model_manager.get_node_model( type_id_ )->get_name() ); + ( *d )[ names::type_id ] = LiteralDatum( kernel::manager< ModelManager >.get_node_model( type_id_ )->get_name() ); for ( size_t t = 0; t < tmp.size(); ++t ) { @@ -149,4 +150,35 @@ Model::get_status() return d; } +std::string +Model::get_name() const +{ + + return name_; +} + +Node* +Model::create( size_t t ) +{ + + assert( t < memory_.size() ); + Node* n = create_(); + memory_[ t ].emplace_back( n ); + return n; +} + +size_t +Model::get_type_id() const +{ + + return type_id_; +} + +void +Model::set_type_id( size_t id ) +{ + + type_id_ = id; +} + } // namespace diff --git a/nestkernel/model.h b/nestkernel/model.h index 19372e9a6a..e4479cf8d2 100644 --- a/nestkernel/model.h +++ b/nestkernel/model.h @@ -24,13 +24,9 @@ #define MODEL_H // C++ includes: -#include #include #include -// Includes from libnestutil: -#include "allocator.h" - // Includes from nestkernel: #include "node.h" @@ -201,17 +197,9 @@ class Model /** * Set the model id on the prototype. */ - void - set_type_id( size_t id ) - { - type_id_ = id; - } + void set_type_id( size_t id ); - size_t - get_type_id() const - { - return type_id_; - } + size_t get_type_id() const; private: virtual void set_status_( DictionaryDatum ) = 0; @@ -253,20 +241,5 @@ class Model std::vector< std::vector< Node* > > memory_; }; - -inline Node* -Model::create( size_t t ) -{ - assert( t < memory_.size() ); - Node* n = create_(); - memory_[ t ].emplace_back( n ); - return n; -} - -inline std::string -Model::get_name() const -{ - return name_; -} } #endif diff --git a/nestkernel/model_manager.cpp b/nestkernel/model_manager.cpp index 1ab616ffce..03b8fa1d21 100644 --- a/nestkernel/model_manager.cpp +++ b/nestkernel/model_manager.cpp @@ -31,16 +31,17 @@ #include "compose.hpp" // Includes from nestkernel: +#include "connection_manager.h" #include "connector_model_impl.h" #include "genericmodel_impl.h" #include "kernel_manager.h" #include "model_manager_impl.h" #include "proxynode.h" -#include "vp_manager_impl.h" // Includes from models: #include "models.h" +#include "modelrange_manager.h" namespace nest { @@ -70,7 +71,7 @@ ModelManager::initialize( const bool ) proxynode_model_->set_type_id( 1 ); proxynode_model_->set_threads(); - const size_t num_threads = kernel().vp_manager.get_num_threads(); + const size_t num_threads = kernel::manager< VPManager >.get_num_threads(); // Make space for one vector of connection models per thread connection_models_.resize( num_threads ); @@ -102,7 +103,7 @@ ModelManager::get_num_connection_models() const return 0; } - return connection_models_.at( kernel().vp_manager.get_thread_id() ).size(); + return connection_models_.at( kernel::manager< VPManager >.get_thread_id() ).size(); } void @@ -177,7 +178,7 @@ ModelManager::register_node_model_( Model* model ) #pragma omp parallel { - const size_t t = kernel().vp_manager.get_thread_id(); + const size_t t = kernel::manager< VPManager >.get_thread_id(); proxy_nodes_.at( t ).push_back( create_proxynode_( t, id ) ); } @@ -201,7 +202,7 @@ ModelManager::copy_node_model_( const size_t old_id, Name new_name, DictionaryDa #pragma omp parallel { - const size_t t = kernel().vp_manager.get_thread_id(); + const size_t t = kernel::manager< VPManager >.get_thread_id(); proxy_nodes_.at( t ).push_back( create_proxynode_( t, new_id ) ); } } @@ -209,9 +210,9 @@ ModelManager::copy_node_model_( const size_t old_id, Name new_name, DictionaryDa void ModelManager::copy_connection_model_( const size_t old_id, Name new_name, DictionaryDatum params ) { - kernel().vp_manager.assert_single_threaded(); + kernel::manager< VPManager >.assert_single_threaded(); - const size_t new_id = connection_models_.at( kernel().vp_manager.get_thread_id() ).size(); + const size_t new_id = connection_models_.at( kernel::manager< VPManager >.get_thread_id() ).size(); if ( new_id == invalid_synindex ) { @@ -225,11 +226,11 @@ ModelManager::copy_connection_model_( const size_t old_id, Name new_name, Dictio #pragma omp parallel { - const size_t thread_id = kernel().vp_manager.get_thread_id(); + const size_t thread_id = kernel::manager< VPManager >.get_thread_id(); connection_models_.at( thread_id ) .push_back( get_connection_model( old_id, thread_id ).clone( new_name.toString(), new_id ) ); - kernel().connection_manager.resize_connections(); + kernel::manager< ConnectionManager >.resize_connections(); } set_synapse_defaults_( new_id, params ); // handles parallelism internally @@ -277,15 +278,16 @@ void ModelManager::set_synapse_defaults_( size_t model_id, const DictionaryDatum& params ) { params->clear_access_flags(); - assert_valid_syn_id( model_id, kernel().vp_manager.get_thread_id() ); + assert_valid_syn_id( model_id, kernel::manager< VPManager >.get_thread_id() ); - std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( kernel().vp_manager.get_num_threads() ); + std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( + kernel::manager< VPManager >.get_num_threads() ); // We have to run this in parallel to set the status on nodes that exist on each // thread, such as volume_transmitter. #pragma omp parallel { - size_t tid = kernel().vp_manager.get_thread_id(); + size_t tid = kernel::manager< VPManager >.get_thread_id(); try { @@ -299,7 +301,7 @@ ModelManager::set_synapse_defaults_( size_t model_id, const DictionaryDatum& par } } - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { if ( exceptions_raised_.at( tid ).get() ) { @@ -342,17 +344,17 @@ ModelManager::get_synapse_model_id( std::string model_name ) DictionaryDatum ModelManager::get_connector_defaults( synindex syn_id ) const { - assert_valid_syn_id( syn_id, kernel().vp_manager.get_thread_id() ); + assert_valid_syn_id( syn_id, kernel::manager< VPManager >.get_thread_id() ); DictionaryDatum dict( new Dictionary() ); - for ( size_t t = 0; t < static_cast< size_t >( kernel().vp_manager.get_num_threads() ); ++t ) + for ( size_t t = 0; t < static_cast< size_t >( kernel::manager< VPManager >.get_num_threads() ); ++t ) { // each call adds to num_connections connection_models_[ t ][ syn_id ]->get_status( dict ); } - ( *dict )[ names::num_connections ] = kernel().connection_manager.get_num_connections( syn_id ); + ( *dict )[ names::num_connections ] = kernel::manager< ConnectionManager >.get_num_connections( syn_id ); ( *dict )[ names::element_type ] = "synapse"; return dict; @@ -420,7 +422,7 @@ ModelManager::calibrate( const TimeConverter& tc ) { model->calibrate_time( tc ); } - for ( size_t t = 0; t < static_cast< size_t >( kernel().vp_manager.get_num_threads() ); ++t ) + for ( size_t t = 0; t < static_cast< size_t >( kernel::manager< VPManager >.get_num_threads() ); ++t ) { for ( auto&& connection_model : connection_models_[ t ] ) { @@ -436,8 +438,8 @@ ModelManager::calibrate( const TimeConverter& tc ) bool ModelManager::compare_model_by_id_( const int a, const int b ) { - return kernel().model_manager.get_node_model( a )->get_name() - < kernel().model_manager.get_node_model( b )->get_name(); + return kernel::manager< ModelManager >.get_node_model( a )->get_name() + < kernel::manager< ModelManager >.get_node_model( b )->get_name(); } void @@ -484,4 +486,62 @@ ModelManager::create_proxynode_( size_t t, int model_id ) return proxy; } +Node* +ModelManager::get_proxy_node( size_t tid, size_t node_id ) +{ + + const int model_id = kernel::manager< ModelRangeManager >.get_model_id( node_id ); + Node* proxy = proxy_nodes_[ tid ].at( model_id ); + proxy->set_node_id_( node_id ); + proxy->set_vp( kernel::manager< VPManager >.node_id_to_vp( node_id ) ); + return proxy; +} + +std::unique_ptr< SecondaryEvent > +ModelManager::get_secondary_event_prototype( const synindex syn_id, const size_t tid ) +{ + assert_valid_syn_id( syn_id, tid ); + return get_connection_model( syn_id, tid ).get_secondary_event(); +} + +void +ModelManager::assert_valid_syn_id( synindex syn_id, size_t t ) const +{ + + if ( syn_id >= connection_models_[ t ].size() or not connection_models_[ t ][ syn_id ] ) + { + throw UnknownSynapseType( syn_id ); + } +} + +const std::vector< ConnectorModel* >& +ModelManager::get_connection_models( size_t tid ) +{ + + return connection_models_[ tid ]; +} + +ConnectorModel& +ModelManager::get_connection_model( synindex syn_id, size_t thread_id ) +{ + + assert_valid_syn_id( syn_id, thread_id ); + return *( connection_models_[ thread_id ][ syn_id ] ); +} + +bool +ModelManager::are_model_defaults_modified() const +{ + + return model_defaults_modified_; +} + +Model* +ModelManager::get_node_model( size_t m ) const +{ + + assert( m < node_models_.size() ); + return node_models_[ m ]; +} + } // namespace nest diff --git a/nestkernel/model_manager.h b/nestkernel/model_manager.h index 58c5ceafb2..55988d2ddf 100644 --- a/nestkernel/model_manager.h +++ b/nestkernel/model_manager.h @@ -27,18 +27,13 @@ #include // Includes from nestkernel: -#include "connector_model.h" -#include "genericmodel.h" +#include "connection_manager.h" #include "manager_interface.h" #include "model.h" -#include "nest.h" #include "nest_time.h" -#include "nest_timeconverter.h" #include "nest_types.h" #include "node.h" -// Includes from sli: -#include "dictutils.h" namespace nest { @@ -284,48 +279,6 @@ class ModelManager : public ManagerInterface }; -inline Model* -ModelManager::get_node_model( size_t m ) const -{ - assert( m < node_models_.size() ); - return node_models_[ m ]; -} - -inline bool -ModelManager::are_model_defaults_modified() const -{ - return model_defaults_modified_; -} - -inline ConnectorModel& -ModelManager::get_connection_model( synindex syn_id, size_t thread_id ) -{ - assert_valid_syn_id( syn_id, thread_id ); - return *( connection_models_[ thread_id ][ syn_id ] ); -} - -inline const std::vector< ConnectorModel* >& -ModelManager::get_connection_models( size_t tid ) -{ - return connection_models_[ tid ]; -} - -inline void -ModelManager::assert_valid_syn_id( synindex syn_id, size_t t ) const -{ - if ( syn_id >= connection_models_[ t ].size() or not connection_models_[ t ][ syn_id ] ) - { - throw UnknownSynapseType( syn_id ); - } -} - -inline std::unique_ptr< SecondaryEvent > -ModelManager::get_secondary_event_prototype( const synindex syn_id, const size_t tid ) -{ - assert_valid_syn_id( syn_id, tid ); - return get_connection_model( syn_id, tid ).get_secondary_event(); -} - } // namespace nest #endif /* MODEL_MANAGER_H */ diff --git a/nestkernel/model_manager_impl.h b/nestkernel/model_manager_impl.h index d9e8d8e6c7..485d12db3c 100644 --- a/nestkernel/model_manager_impl.h +++ b/nestkernel/model_manager_impl.h @@ -23,19 +23,13 @@ #ifndef MODEL_MANAGER_IMPL_H #define MODEL_MANAGER_IMPL_H +#include "connection_label_impl.h" #include "model_manager.h" -// Includes from libnestutil: -#include "compose.hpp" -#include "string_utils.h" - -// Includes from nestkernel: -#include "connection_label.h" -#include "kernel_manager.h" -#include "nest.h" +#include "connector_model_impl.h" +#include "genericmodel.h" #include "target_identifier.h" - namespace nest { @@ -78,7 +72,7 @@ template < typename CompleteConnectionT > void ModelManager::register_specific_connection_model_( const std::string& name ) { - kernel().vp_manager.assert_single_threaded(); + kernel::manager< VPManager >.assert_single_threaded(); if ( synapsedict_->known( name ) ) { @@ -106,21 +100,12 @@ ModelManager::register_specific_connection_model_( const std::string& name ) { conn_model->get_secondary_event()->add_syn_id( new_syn_id ); } - connection_models_.at( kernel().vp_manager.get_thread_id() ).push_back( conn_model ); - kernel().connection_manager.resize_connections(); + connection_models_.at( kernel::manager< VPManager >.get_thread_id() ).push_back( conn_model ); + kernel::manager< ConnectionManager >.resize_connections(); } // end of parallel section } -inline Node* -ModelManager::get_proxy_node( size_t tid, size_t node_id ) -{ - const int model_id = kernel().modelrange_manager.get_model_id( node_id ); - Node* proxy = proxy_nodes_[ tid ].at( model_id ); - proxy->set_node_id_( node_id ); - proxy->set_vp( kernel().vp_manager.node_id_to_vp( node_id ) ); - return proxy; -} - } // namespace nest -#endif /* #ifndef MODEL_MANAGER_IMPL_H */ + +#endif diff --git a/nestkernel/modelrange.cpp b/nestkernel/modelrange.cpp index dc006d750d..dd91384899 100644 --- a/nestkernel/modelrange.cpp +++ b/nestkernel/modelrange.cpp @@ -34,3 +34,30 @@ nest::modelrange::extend_range( size_t new_last_node_id ) { last_node_id_ = new_last_node_id; } +size_t +nest::modelrange::get_last_node_id() const +{ + + return last_node_id_; +} + +size_t +nest::modelrange::get_first_node_id() const +{ + + return first_node_id_; +} + +size_t +nest::modelrange::get_model_id() const +{ + + return model_; +} + +bool +nest::modelrange::is_in_range( size_t node_id ) const +{ + + return ( node_id >= first_node_id_ and node_id <= last_node_id_ ); +} diff --git a/nestkernel/modelrange.h b/nestkernel/modelrange.h index ce905a72da..a3798461f9 100644 --- a/nestkernel/modelrange.h +++ b/nestkernel/modelrange.h @@ -33,26 +33,10 @@ class modelrange { public: modelrange( size_t model, size_t first_node_id, size_t last_node_id ); - bool - is_in_range( size_t node_id ) const - { - return ( node_id >= first_node_id_ and node_id <= last_node_id_ ); - } - size_t - get_model_id() const - { - return model_; - } - size_t - get_first_node_id() const - { - return first_node_id_; - } - size_t - get_last_node_id() const - { - return last_node_id_; - } + bool is_in_range( size_t node_id ) const; + size_t get_model_id() const; + size_t get_first_node_id() const; + size_t get_last_node_id() const; void extend_range( size_t new_last_node_id ); private: diff --git a/nestkernel/modelrange_manager.cpp b/nestkernel/modelrange_manager.cpp index 9b33323a87..5181c42e20 100644 --- a/nestkernel/modelrange_manager.cpp +++ b/nestkernel/modelrange_manager.cpp @@ -28,6 +28,7 @@ // Includes from nestkernel: #include "kernel_manager.h" #include "model.h" +#include "model_manager.h" namespace nest @@ -112,7 +113,7 @@ ModelRangeManager::get_model_id( size_t node_id ) const nest::Model* nest::ModelRangeManager::get_model_of_node_id( size_t node_id ) { - return kernel().model_manager.get_node_model( get_model_id( node_id ) ); + return kernel::manager< ModelManager >.get_node_model( get_model_id( node_id ) ); } const modelrange& @@ -134,4 +135,35 @@ ModelRangeManager::get_contiguous_node_id_range( size_t node_id ) const throw UnknownNode( node_id ); } +std::vector< modelrange >::const_iterator +nest::ModelRangeManager::end() const +{ + + return modelranges_.end(); +} + +std::vector< modelrange >::const_iterator +nest::ModelRangeManager::begin() const +{ + + return modelranges_.begin(); +} + +bool +nest::ModelRangeManager::is_in_range( size_t node_id ) const +{ + + return ( node_id > 0 and node_id <= last_node_id_ and node_id >= first_node_id_ ); +} + +void +nest::ModelRangeManager::get_status( DictionaryDatum& ) +{ +} + +void +nest::ModelRangeManager::set_status( const DictionaryDatum& ) +{ +} + } // namespace nest diff --git a/nestkernel/modelrange_manager.h b/nestkernel/modelrange_manager.h index c25941325f..646ad32e9a 100644 --- a/nestkernel/modelrange_manager.h +++ b/nestkernel/modelrange_manager.h @@ -86,33 +86,6 @@ class ModelRangeManager : public ManagerInterface size_t last_node_id_; }; -inline void -nest::ModelRangeManager::set_status( const DictionaryDatum& ) -{ -} - -inline void -nest::ModelRangeManager::get_status( DictionaryDatum& ) -{ -} - -inline bool -nest::ModelRangeManager::is_in_range( size_t node_id ) const -{ - return ( node_id > 0 and node_id <= last_node_id_ and node_id >= first_node_id_ ); -} - -inline std::vector< modelrange >::const_iterator -nest::ModelRangeManager::begin() const -{ - return modelranges_.begin(); -} - -inline std::vector< modelrange >::const_iterator -nest::ModelRangeManager::end() const -{ - return modelranges_.end(); -} } // namespace nest end diff --git a/nestkernel/module_manager.cpp b/nestkernel/module_manager.cpp index 57c668da9b..f00055d9ec 100644 --- a/nestkernel/module_manager.cpp +++ b/nestkernel/module_manager.cpp @@ -37,6 +37,8 @@ // Includes from thirdparty: #include "compose.hpp" +#include + namespace nest { @@ -116,7 +118,7 @@ ModuleManager::install( const std::string& name ) { // We cannot have connections without network elements, so we only need to check nodes. // Simulating an empty network causes no problems, so we don't have to check for that. - if ( kernel().node_manager.size() > 0 ) + if ( kernel::manager< NodeManager >.size() > 0 ) { throw KernelException( "Network elements have been created, so external modules can no longer be imported. " diff --git a/nestkernel/mpi_manager.cpp b/nestkernel/mpi_manager.cpp index 3f97911320..59cccb7e35 100644 --- a/nestkernel/mpi_manager.cpp +++ b/nestkernel/mpi_manager.cpp @@ -20,22 +20,30 @@ * */ -#include "mpi_manager.h" +#include "mpi_manager_impl.h" // C++ includes: #include -// Includes from libnestutil: -#include "stopwatch_impl.h" - // Includes from nestkernel: #include "kernel_manager.h" -#include "mpi_manager_impl.h" #include "nest_types.h" +#include "logging.h" +#include "logging_manager.h" +#include "music_manager.h" +#include "nest_names.h" +#include "stopwatch_impl.h" + // Includes from sli: #include "dictutils.h" +#include +#include + +namespace nest +{ + #ifdef HAVE_MPI template <> @@ -51,7 +59,7 @@ MPI_Datatype MPI_Type< unsigned long >::type = MPI_UNSIGNED_LONG; #endif /* #ifdef HAVE_MPI */ -nest::MPIManager::MPIManager() +MPIManager::MPIManager() : num_processes_( 1 ) , rank_( 0 ) , send_buffer_size_( 0 ) @@ -78,14 +86,14 @@ nest::MPIManager::MPIManager() #ifndef HAVE_MPI void -nest::MPIManager::init_mpi( int*, char*** ) +MPIManager::init_mpi( int*, char*** ) { // if ! HAVE_MPI, initialize process entries for 1 rank // use 2 processes entries (need at least two // entries per process to use flag of first entry as validity and // last entry to communicate end of communication) - kernel().mpi_manager.set_buffer_size_target_data( 2 ); - kernel().mpi_manager.set_buffer_size_spike_data( 2 ); + kernel::manager< MPIManager >.set_buffer_size_target_data( 2 ); + kernel::manager< MPIManager >.set_buffer_size_spike_data( 2 ); recv_counts_secondary_events_in_int_per_rank_.resize( 1, 0 ); recv_displacements_secondary_events_in_int_per_rank_.resize( 1, 0 ); @@ -96,7 +104,7 @@ nest::MPIManager::init_mpi( int*, char*** ) #else /* HAVE_MPI */ void -nest::MPIManager::set_communicator( MPI_Comm global_comm ) +MPIManager::set_communicator( MPI_Comm global_comm ) { comm = global_comm; MPI_Comm_size( comm, &num_processes_ ); @@ -106,12 +114,12 @@ nest::MPIManager::set_communicator( MPI_Comm global_comm ) // use at least 2 * number of processes entries (need at least two // entries per process to use flag of first entry as validity and // last entry to communicate end of communication) - kernel().mpi_manager.set_buffer_size_target_data( 2 * kernel().mpi_manager.get_num_processes() ); - kernel().mpi_manager.set_buffer_size_spike_data( 2 * kernel().mpi_manager.get_num_processes() ); + kernel::manager< MPIManager >.set_buffer_size_target_data( 2 * kernel::manager< MPIManager >.get_num_processes() ); + kernel::manager< MPIManager >.set_buffer_size_spike_data( 2 * kernel::manager< MPIManager >.get_num_processes() ); } void -nest::MPIManager::init_mpi( int* argc, char** argv[] ) +MPIManager::init_mpi( int* argc, char** argv[] ) { int init; MPI_Initialized( &init ); @@ -119,9 +127,9 @@ nest::MPIManager::init_mpi( int* argc, char** argv[] ) if ( init == 0 ) { #ifdef HAVE_MUSIC - kernel().music_manager.init_music( argc, argv ); + kernel::manager< MUSICManager >.init_music( argc, argv ); // get a communicator from MUSIC - set_communicator( static_cast< MPI_Comm >( kernel().music_manager.communicator() ) ); + set_communicator( static_cast< MPI_Comm >( kernel::manager< MUSICManager >.communicator() ) ); #else /* #ifdef HAVE_MUSIC */ int provided_thread_level; MPI_Init_thread( argc, argv, MPI_THREAD_FUNNELED, &provided_thread_level ); @@ -178,7 +186,7 @@ nest::MPIManager::init_mpi( int* argc, char** argv[] ) #endif /* #ifdef HAVE_MPI */ void -nest::MPIManager::initialize( const bool adjust_number_of_threads_or_rng_only ) +MPIManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { if ( adjust_number_of_threads_or_rng_only ) { @@ -216,12 +224,12 @@ nest::MPIManager::initialize( const bool adjust_number_of_threads_or_rng_only ) } void -nest::MPIManager::finalize( const bool ) +MPIManager::finalize( const bool ) { } void -nest::MPIManager::set_status( const DictionaryDatum& dict ) +MPIManager::set_status( const DictionaryDatum& dict ) { updateValue< bool >( dict, names::adaptive_target_buffers, adaptive_target_buffers_ ); @@ -249,7 +257,7 @@ nest::MPIManager::set_status( const DictionaryDatum& dict ) } void -nest::MPIManager::get_status( DictionaryDatum& dict ) +MPIManager::get_status( DictionaryDatum& dict ) { def< long >( dict, names::num_processes, num_processes_ ); def< bool >( dict, names::adaptive_target_buffers, adaptive_target_buffers_ ); @@ -265,7 +273,7 @@ nest::MPIManager::get_status( DictionaryDatum& dict ) #ifdef HAVE_MPI void -nest::MPIManager::mpi_finalize( int exitcode ) +MPIManager::mpi_finalize( int exitcode ) { MPI_Type_free( &MPI_OFFGRID_SPIKE ); @@ -279,7 +287,7 @@ nest::MPIManager::mpi_finalize( int exitcode ) { if ( exitcode == 0 ) { - kernel().music_manager.music_finalize(); // calls MPI_Finalize() + kernel::manager< MUSICManager >.music_finalize(); // calls MPI_Finalize() } else { @@ -292,7 +300,7 @@ nest::MPIManager::mpi_finalize( int exitcode ) #else /* #ifdef HAVE_MPI */ void -nest::MPIManager::mpi_finalize( int ) +MPIManager::mpi_finalize( int ) { } @@ -301,14 +309,14 @@ nest::MPIManager::mpi_finalize( int ) #ifdef HAVE_MPI void -nest::MPIManager::mpi_abort( int exitcode ) +MPIManager::mpi_abort( int exitcode ) const { MPI_Abort( comm, exitcode ); } std::string -nest::MPIManager::get_processor_name() +MPIManager::get_processor_name() { char name[ 1024 ]; int len; @@ -318,7 +326,7 @@ nest::MPIManager::get_processor_name() } void -nest::MPIManager::communicate( std::vector< long >& local_nodes, std::vector< long >& global_nodes ) +MPIManager::communicate( std::vector< long >& local_nodes, std::vector< long >& global_nodes ) { const size_t num_procs = get_num_processes(); @@ -359,7 +367,7 @@ nest::MPIManager::communicate( std::vector< long >& local_nodes, std::vector< lo } void -nest::MPIManager::communicate( std::vector< unsigned int >& send_buffer, +MPIManager::communicate( std::vector< unsigned int >& send_buffer, std::vector< unsigned int >& recv_buffer, std::vector< int >& displacements ) { @@ -381,7 +389,7 @@ nest::MPIManager::communicate( std::vector< unsigned int >& send_buffer, } void -nest::MPIManager::communicate_Allgather( std::vector< unsigned int >& send_buffer, +MPIManager::communicate_Allgather( std::vector< unsigned int >& send_buffer, std::vector< unsigned int >& recv_buffer, std::vector< int >& displacements ) { @@ -446,7 +454,7 @@ nest::MPIManager::communicate_Allgather( std::vector< unsigned int >& send_buffe template < typename T > void -nest::MPIManager::communicate_Allgather( std::vector< T >& send_buffer, +MPIManager::communicate_Allgather( std::vector< T >& send_buffer, std::vector< T >& recv_buffer, std::vector< int >& displacements ) { @@ -515,7 +523,7 @@ nest::MPIManager::communicate_Allgather( std::vector< T >& send_buffer, } void -nest::MPIManager::communicate( std::vector< OffGridSpike >& send_buffer, +MPIManager::communicate( std::vector< OffGridSpike >& send_buffer, std::vector< OffGridSpike >& recv_buffer, std::vector< int >& displacements ) { @@ -537,7 +545,7 @@ nest::MPIManager::communicate( std::vector< OffGridSpike >& send_buffer, } void -nest::MPIManager::communicate_Allgather( std::vector< OffGridSpike >& send_buffer, +MPIManager::communicate_Allgather( std::vector< OffGridSpike >& send_buffer, std::vector< OffGridSpike >& recv_buffer, std::vector< int >& displacements ) { @@ -605,7 +613,7 @@ nest::MPIManager::communicate_Allgather( std::vector< OffGridSpike >& send_buffe } void -nest::MPIManager::communicate( std::vector< double >& send_buffer, +MPIManager::communicate( std::vector< double >& send_buffer, std::vector< double >& recv_buffer, std::vector< int >& displacements ) { @@ -635,7 +643,7 @@ nest::MPIManager::communicate( std::vector< double >& send_buffer, } void -nest::MPIManager::communicate( std::vector< unsigned long >& send_buffer, +MPIManager::communicate( std::vector< unsigned long >& send_buffer, std::vector< unsigned long >& recv_buffer, std::vector< int >& displacements ) { @@ -665,7 +673,7 @@ nest::MPIManager::communicate( std::vector< unsigned long >& send_buffer, } void -nest::MPIManager::communicate( std::vector< int >& send_buffer, +MPIManager::communicate( std::vector< int >& send_buffer, std::vector< int >& recv_buffer, std::vector< int >& displacements ) { @@ -695,7 +703,7 @@ nest::MPIManager::communicate( std::vector< int >& send_buffer, } void -nest::MPIManager::communicate( double send_val, std::vector< double >& recv_buffer ) +MPIManager::communicate( double send_val, std::vector< double >& recv_buffer ) const { recv_buffer.resize( get_num_processes() ); MPI_Allgather( &send_val, 1, MPI_DOUBLE, &recv_buffer[ 0 ], 1, MPI_DOUBLE, comm ); @@ -706,19 +714,19 @@ nest::MPIManager::communicate( double send_val, std::vector< double >& recv_buff * communicate function for sending set-up information */ void -nest::MPIManager::communicate( std::vector< int >& buffer ) +MPIManager::communicate( std::vector< int >& buffer ) { communicate_Allgather( buffer ); } void -nest::MPIManager::communicate( std::vector< long >& buffer ) +MPIManager::communicate( std::vector< long >& buffer ) { communicate_Allgather( buffer ); } void -nest::MPIManager::communicate_Allgather( std::vector< int >& buffer ) +MPIManager::communicate_Allgather( std::vector< int >& buffer ) const { // avoid aliasing, see http://www.mpi-forum.org/docs/mpi-11-html/node10.html int my_val = buffer[ get_rank() ]; @@ -726,32 +734,32 @@ nest::MPIManager::communicate_Allgather( std::vector< int >& buffer ) } void -nest::MPIManager::communicate_Allreduce_sum_in_place( double buffer ) +MPIManager::communicate_Allreduce_sum_in_place( double buffer ) const { MPI_Allreduce( MPI_IN_PLACE, &buffer, 1, MPI_Type< double >::type, MPI_SUM, comm ); } void -nest::MPIManager::communicate_Allreduce_sum_in_place( std::vector< double >& buffer ) +MPIManager::communicate_Allreduce_sum_in_place( std::vector< double >& buffer ) const { MPI_Allreduce( MPI_IN_PLACE, &buffer[ 0 ], buffer.size(), MPI_Type< double >::type, MPI_SUM, comm ); } void -nest::MPIManager::communicate_Allreduce_sum_in_place( std::vector< int >& buffer ) +MPIManager::communicate_Allreduce_sum_in_place( std::vector< int >& buffer ) const { MPI_Allreduce( MPI_IN_PLACE, &buffer[ 0 ], buffer.size(), MPI_Type< int >::type, MPI_SUM, comm ); } void -nest::MPIManager::communicate_Allreduce_sum( std::vector< double >& send_buffer, std::vector< double >& recv_buffer ) +MPIManager::communicate_Allreduce_sum( std::vector< double >& send_buffer, std::vector< double >& recv_buffer ) const { assert( recv_buffer.size() == send_buffer.size() ); MPI_Allreduce( &send_buffer[ 0 ], &recv_buffer[ 0 ], send_buffer.size(), MPI_Type< double >::type, MPI_SUM, comm ); } bool -nest::MPIManager::equal_cross_ranks( const double value ) +MPIManager::equal_cross_ranks( const double value ) const { // Flipping the sign of one argument to check both min and max values. double values[ 2 ]; @@ -762,7 +770,7 @@ nest::MPIManager::equal_cross_ranks( const double value ) } void -nest::MPIManager::communicate_Allgather( std::vector< long >& buffer ) +MPIManager::communicate_Allgather( std::vector< long >& buffer ) const { // avoid aliasing, see http://www.mpi-forum.org/docs/mpi-11-html/node10.html long my_val = buffer[ get_rank() ]; @@ -770,18 +778,18 @@ nest::MPIManager::communicate_Allgather( std::vector< long >& buffer ) } void -nest::MPIManager::communicate_Alltoall_( void* send_buffer, void* recv_buffer, const unsigned int send_recv_count ) +MPIManager::communicate_Alltoall_( void* send_buffer, void* recv_buffer, const unsigned int send_recv_count ) const { MPI_Alltoall( send_buffer, send_recv_count, MPI_UNSIGNED, recv_buffer, send_recv_count, MPI_UNSIGNED, comm ); } void -nest::MPIManager::communicate_Alltoallv_( void* send_buffer, +MPIManager::communicate_Alltoallv_( void* send_buffer, const int* send_counts, const int* send_displacements, void* recv_buffer, const int* recv_counts, - const int* recv_displacements ) + const int* recv_displacements ) const { MPI_Alltoallv( send_buffer, send_counts, @@ -795,7 +803,7 @@ nest::MPIManager::communicate_Alltoallv_( void* send_buffer, } void -nest::MPIManager::communicate_recv_counts_secondary_events() +MPIManager::communicate_recv_counts_secondary_events() { communicate_Alltoall( @@ -807,7 +815,7 @@ nest::MPIManager::communicate_recv_counts_secondary_events() } void -nest::MPIManager::synchronize() +MPIManager::synchronize() const { MPI_Barrier( comm ); } @@ -816,7 +824,7 @@ nest::MPIManager::synchronize() // any_true: takes a single bool, exchanges with all other processes, // and returns "true" if one or more processes provide "true" bool -nest::MPIManager::any_true( const bool my_bool ) +MPIManager::any_true( const bool my_bool ) const { if ( get_num_processes() == 1 ) { @@ -831,7 +839,7 @@ nest::MPIManager::any_true( const bool my_bool ) // average communication time for a packet size of num_bytes using Allgather double -nest::MPIManager::time_communicate( int num_bytes, int samples ) +MPIManager::time_communicate( int num_bytes, int samples ) const { if ( get_num_processes() == 1 ) { @@ -859,7 +867,7 @@ nest::MPIManager::time_communicate( int num_bytes, int samples ) // average communication time for a packet size of num_bytes using Allgatherv double -nest::MPIManager::time_communicatev( int num_bytes, int samples ) +MPIManager::time_communicatev( int num_bytes, int samples ) { if ( get_num_processes() == 1 ) { @@ -895,7 +903,7 @@ nest::MPIManager::time_communicatev( int num_bytes, int samples ) // average communication time for a packet size of num_bytes double -nest::MPIManager::time_communicate_offgrid( int num_bytes, int samples ) +MPIManager::time_communicate_offgrid( int num_bytes, int samples ) const { if ( get_num_processes() == 1 ) { @@ -928,7 +936,7 @@ nest::MPIManager::time_communicate_offgrid( int num_bytes, int samples ) // average communication time for a packet size of num_bytes using Alltoall double -nest::MPIManager::time_communicate_alltoall( int num_bytes, int samples ) +MPIManager::time_communicate_alltoall( int num_bytes, int samples ) const { if ( get_num_processes() == 1 ) { @@ -957,7 +965,7 @@ nest::MPIManager::time_communicate_alltoall( int num_bytes, int samples ) // average communication time for a packet size of num_bytes using Alltoallv double -nest::MPIManager::time_communicate_alltoallv( int num_bytes, int samples ) +MPIManager::time_communicate_alltoallv( int num_bytes, int samples ) const { if ( get_num_processes() == 1 ) { @@ -1003,7 +1011,7 @@ nest::MPIManager::time_communicate_alltoallv( int num_bytes, int samples ) // communicate (on-grid) if compiled without MPI void -nest::MPIManager::communicate( std::vector< unsigned int >& send_buffer, +MPIManager::communicate( std::vector< unsigned int >& send_buffer, std::vector< unsigned int >& recv_buffer, std::vector< int >& displacements ) { @@ -1019,7 +1027,7 @@ nest::MPIManager::communicate( std::vector< unsigned int >& send_buffer, // communicate (off-grid) if compiled without MPI void -nest::MPIManager::communicate( std::vector< OffGridSpike >& send_buffer, +MPIManager::communicate( std::vector< OffGridSpike >& send_buffer, std::vector< OffGridSpike >& recv_buffer, std::vector< int >& displacements ) { @@ -1034,7 +1042,7 @@ nest::MPIManager::communicate( std::vector< OffGridSpike >& send_buffer, } void -nest::MPIManager::communicate( std::vector< double >& send_buffer, +MPIManager::communicate( std::vector< double >& send_buffer, std::vector< double >& recv_buffer, std::vector< int >& displacements ) { @@ -1044,7 +1052,7 @@ nest::MPIManager::communicate( std::vector< double >& send_buffer, } void -nest::MPIManager::communicate( std::vector< unsigned long >& send_buffer, +MPIManager::communicate( std::vector< unsigned long >& send_buffer, std::vector< unsigned long >& recv_buffer, std::vector< int >& displacements ) { @@ -1054,7 +1062,7 @@ nest::MPIManager::communicate( std::vector< unsigned long >& send_buffer, } void -nest::MPIManager::communicate( std::vector< int >& send_buffer, +MPIManager::communicate( std::vector< int >& send_buffer, std::vector< int >& recv_buffer, std::vector< int >& displacements ) { @@ -1064,46 +1072,46 @@ nest::MPIManager::communicate( std::vector< int >& send_buffer, } void -nest::MPIManager::communicate( double send_val, std::vector< double >& recv_buffer ) +MPIManager::communicate( double send_val, std::vector< double >& recv_buffer ) const { recv_buffer.resize( 1 ); recv_buffer[ 0 ] = send_val; } void -nest::MPIManager::communicate( std::vector< long >&, std::vector< long >& ) +MPIManager::communicate( std::vector< long >&, std::vector< long >& ) { } void -nest::MPIManager::communicate_Allreduce_sum_in_place( double ) +MPIManager::communicate_Allreduce_sum_in_place( double ) const { } void -nest::MPIManager::communicate_Allreduce_sum_in_place( std::vector< double >& ) +MPIManager::communicate_Allreduce_sum_in_place( std::vector< double >& ) const { } void -nest::MPIManager::communicate_Allreduce_sum_in_place( std::vector< int >& ) +MPIManager::communicate_Allreduce_sum_in_place( std::vector< int >& ) const { } void -nest::MPIManager::communicate_Allreduce_sum( std::vector< double >& send_buffer, std::vector< double >& recv_buffer ) +MPIManager::communicate_Allreduce_sum( std::vector< double >& send_buffer, std::vector< double >& recv_buffer ) const { recv_buffer.swap( send_buffer ); } bool -nest::MPIManager::equal_cross_ranks( const double ) +MPIManager::equal_cross_ranks( const double ) const { return true; } void -nest::MPIManager::communicate_recv_counts_secondary_events() +MPIManager::communicate_recv_counts_secondary_events() { // since we only have one process, the send count is equal to the recv count send_counts_secondary_events_in_int_per_rank_ = recv_counts_secondary_events_in_int_per_rank_; @@ -1114,3 +1122,306 @@ nest::MPIManager::communicate_recv_counts_secondary_events() } #endif /* #ifdef HAVE_MPI */ + +size_t +MPIManager::get_process_id_of_vp( const size_t vp ) const +{ + return vp % num_processes_; +} + +#ifdef HAVE_MPI + +size_t +MPIManager::get_process_id_of_node_id( const size_t node_id ) const +{ + return node_id % num_processes_; +} + +#else + +size_t +MPIManager::get_process_id_of_node_id( const size_t ) const +{ + return 0; +} + +#endif /* HAVE_MPI */ + +#ifndef HAVE_MPI + +double +MPIManager::time_communicate_alltoallv( int, int ) const +{ + + return 0.0; +} + +double +MPIManager::time_communicate_alltoall( int, int ) const +{ + + return 0.0; +} + +double +MPIManager::time_communicate_offgrid( int, int ) const +{ + + return 0.0; +} + +double +MPIManager::time_communicatev( int, int ) +{ + + return 0.0; +} + +double +MPIManager::time_communicate( int, int ) const +{ + + return 0.0; +} + +bool +MPIManager::any_true( const bool my_bool ) const +{ + + return my_bool; +} + +void +MPIManager::synchronize() const +{ +} + +void +MPIManager::communicate( std::vector< long >& ) +{ +} + +void +MPIManager::communicate( std::vector< int >& ) +{ +} + +void +MPIManager::mpi_abort( int ) const +{ +} + +std::string +MPIManager::get_processor_name() +{ + char name[ 1024 ]; + name[ 1023 ] = '\0'; + gethostname( name, 1023 ); + return name; +} + +#endif /* HAVE_MPI */ + + +bool +MPIManager::adaptive_target_buffers() const +{ + + return adaptive_target_buffers_; +} + +bool +MPIManager::increase_buffer_size_target_data() +{ + + assert( adaptive_target_buffers_ ); + if ( buffer_size_target_data_ >= max_buffer_size_target_data_ ) + { + return false; + } + else + { + if ( buffer_size_target_data_ * growth_factor_buffer_target_data_ < max_buffer_size_target_data_ ) + { + // this also adjusts send_recv_count_target_data_per_rank_ + set_buffer_size_target_data( + static_cast< size_t >( floor( buffer_size_target_data_ * growth_factor_buffer_target_data_ ) ) ); + } + else + { + // this also adjusts send_recv_count_target_data_per_rank_ + set_buffer_size_target_data( max_buffer_size_target_data_ ); + } + return true; + } +} + +void +MPIManager::set_buffer_size_spike_data( const size_t buffer_size ) +{ + + assert( buffer_size >= static_cast< size_t >( 2 * get_num_processes() ) ); + buffer_size_spike_data_ = buffer_size; + + send_recv_count_spike_data_per_rank_ = floor( get_buffer_size_spike_data() / get_num_processes() ); + + assert( send_recv_count_spike_data_per_rank_ * get_num_processes() <= get_buffer_size_spike_data() ); +} + +void +MPIManager::set_buffer_size_target_data( const size_t buffer_size ) +{ + + assert( buffer_size >= static_cast< size_t >( 2 * get_num_processes() ) ); + if ( buffer_size <= max_buffer_size_target_data_ ) + { + buffer_size_target_data_ = buffer_size; + } + else + { + buffer_size_target_data_ = max_buffer_size_target_data_; + } + send_recv_count_target_data_per_rank_ = static_cast< size_t >( + floor( static_cast< double >( get_buffer_size_target_data() ) / static_cast< double >( get_num_processes() ) ) ); + + assert( send_recv_count_target_data_per_rank_ * get_num_processes() <= get_buffer_size_target_data() ); +} + +size_t +MPIManager::get_recv_buffer_size_secondary_events_in_int() const +{ + + return recv_displacements_secondary_events_in_int_per_rank_ + [ recv_displacements_secondary_events_in_int_per_rank_.size() - 1 ] + + recv_counts_secondary_events_in_int_per_rank_[ recv_counts_secondary_events_in_int_per_rank_.size() - 1 ]; +} + +size_t +MPIManager::get_send_buffer_size_secondary_events_in_int() const +{ + + return send_displacements_secondary_events_in_int_per_rank_ + [ send_displacements_secondary_events_in_int_per_rank_.size() - 1 ] + + send_counts_secondary_events_in_int_per_rank_[ send_counts_secondary_events_in_int_per_rank_.size() - 1 ]; +} + +unsigned int +MPIManager::get_send_recv_count_spike_data_per_rank() const +{ + + return send_recv_count_spike_data_per_rank_; +} + +size_t +MPIManager::get_buffer_size_spike_data() const +{ + + return buffer_size_spike_data_; +} + +unsigned int +MPIManager::get_send_recv_count_target_data_per_rank() const +{ + + return send_recv_count_target_data_per_rank_; +} + +size_t +MPIManager::get_buffer_size_target_data() const +{ + + return buffer_size_target_data_; +} + +bool +MPIManager::is_mpi_used() const +{ + + return use_mpi_; +} + +size_t +MPIManager::get_rank() const +{ + + return rank_; +} + +size_t +MPIManager::get_num_processes() const +{ + + return num_processes_; +} + +size_t +MPIManager::get_done_marker_position_in_secondary_events_recv_buffer( const size_t source_rank ) const +{ + + return get_recv_displacement_secondary_events_in_int( source_rank ) + + get_recv_count_secondary_events_in_int( source_rank ) - 1; +} + +size_t +MPIManager::get_done_marker_position_in_secondary_events_send_buffer( const size_t target_rank ) const +{ + + return get_send_displacement_secondary_events_in_int( target_rank ) + + get_send_count_secondary_events_in_int( target_rank ) - 1; +} + +size_t +MPIManager::get_send_displacement_secondary_events_in_int( const size_t target_rank ) const +{ + + return send_displacements_secondary_events_in_int_per_rank_[ target_rank ]; +} + +size_t +MPIManager::get_send_count_secondary_events_in_int( const size_t target_rank ) const +{ + + return send_counts_secondary_events_in_int_per_rank_[ target_rank ]; +} + +size_t +MPIManager::get_recv_displacement_secondary_events_in_int( const size_t source_rank ) const +{ + + return recv_displacements_secondary_events_in_int_per_rank_[ source_rank ]; +} + +size_t +MPIManager::get_recv_count_secondary_events_in_int( const size_t source_rank ) const +{ + + return recv_counts_secondary_events_in_int_per_rank_[ source_rank ]; +} + +void +MPIManager::set_recv_counts_secondary_events_in_int_per_rank( const std::vector< int >& recv_counts_in_int_per_rank ) +{ + + recv_counts_secondary_events_in_int_per_rank_ = recv_counts_in_int_per_rank; + + std::partial_sum( recv_counts_secondary_events_in_int_per_rank_.begin(), + recv_counts_secondary_events_in_int_per_rank_.end() - 1, + recv_displacements_secondary_events_in_int_per_rank_.begin() + 1 ); +} + +#ifndef HAVE_MPI + +void +test_link( int, int ) +{ +} + +void +test_links() +{ +} + +#endif /* HAVE_MPI */ + + +} // namespace nest diff --git a/nestkernel/mpi_manager.h b/nestkernel/mpi_manager.h index a8f4fcea7e..b6f62f9fd4 100644 --- a/nestkernel/mpi_manager.h +++ b/nestkernel/mpi_manager.h @@ -27,24 +27,20 @@ #include "config.h" // C includes: -#include #ifdef HAVE_MPI #include #endif // C++ includes: #include -#include -#include #include -#include #include // Includes from libnestutil: #include "manager_interface.h" -#include "stopwatch.h" // Includes from nestkernel: +#include "kernel_manager.h" #include "nest_types.h" #include "spike_data.h" #include "target_data.h" @@ -118,7 +114,7 @@ class MPIManager : public ManagerInterface /** * If MPI is available, this method calls MPI_Abort with the exitcode. */ - void mpi_abort( int exitcode ); + void mpi_abort( int exitcode ) const; // gather all send_buffer vectors on other mpi process to recv_buffer // vector @@ -149,15 +145,15 @@ class MPIManager : public ManagerInterface void communicate( std::vector< int >& send_buffer, std::vector< int >& recv_buffer, std::vector< int >& displacements ); - void communicate( double, std::vector< double >& ); + void communicate( double, std::vector< double >& ) const; void communicate( std::vector< int >& ); void communicate( std::vector< long >& ); //! Sum across all ranks - void communicate_Allreduce_sum_in_place( double buffer ); - void communicate_Allreduce_sum_in_place( std::vector< double >& buffer ); - void communicate_Allreduce_sum_in_place( std::vector< int >& buffer ); - void communicate_Allreduce_sum( std::vector< double >& send_buffer, std::vector< double >& recv_buffer ); + void communicate_Allreduce_sum_in_place( double buffer ) const; + void communicate_Allreduce_sum_in_place( std::vector< double >& buffer ) const; + void communicate_Allreduce_sum_in_place( std::vector< int >& buffer ) const; + void communicate_Allreduce_sum( std::vector< double >& send_buffer, std::vector< double >& recv_buffer ) const; /** * Equal across all ranks. @@ -166,11 +162,11 @@ class MPIManager : public ManagerInterface * @return true if values across all ranks are equal, false otherwise or if * any rank passes -inf as value */ - bool equal_cross_ranks( const double value ); + bool equal_cross_ranks( const double value ) const; std::string get_processor_name(); - bool is_mpi_used(); + bool is_mpi_used() const; /** * Returns total size of MPI buffer for communication of connections. @@ -204,14 +200,14 @@ class MPIManager : public ManagerInterface #ifdef HAVE_MPI - void communicate_Alltoall_( void* send_buffer, void* recv_buffer, const unsigned int send_recv_count ); + void communicate_Alltoall_( void* send_buffer, void* recv_buffer, const unsigned int send_recv_count ) const; void communicate_Alltoallv_( void* send_buffer, const int* send_counts, const int* send_displacements, void* recv_buffer, const int* recv_counts, - const int* recv_displacements ); + const int* recv_displacements ) const; #endif /* HAVE_MPI */ @@ -232,9 +228,9 @@ class MPIManager : public ManagerInterface * Ensure all processes have reached the same stage by waiting until all * processes have sent a dummy message to process 0. */ - void synchronize(); + void synchronize() const; - bool any_true( const bool ); + bool any_true( const bool ) const; /** * Benchmark communication time of different MPI methods @@ -242,11 +238,11 @@ class MPIManager : public ManagerInterface * The methods `time_communicate*` can be used to benchmark the timing * of different MPI communication methods. */ - double time_communicate( int num_bytes, int samples = 1000 ); + double time_communicate( int num_bytes, int samples = 1000 ) const; double time_communicatev( int num_bytes, int samples = 1000 ); - double time_communicate_offgrid( int num_bytes, int samples = 1000 ); - double time_communicate_alltoall( int num_bytes, int samples = 1000 ); - double time_communicate_alltoallv( int num_bytes, int samples = 1000 ); + double time_communicate_offgrid( int num_bytes, int samples = 1000 ) const; + double time_communicate_alltoall( int num_bytes, int samples = 1000 ) const; + double time_communicate_alltoallv( int num_bytes, int samples = 1000 ) const; void set_buffer_size_target_data( size_t buffer_size ); void set_buffer_size_spike_data( size_t buffer_size ); @@ -362,8 +358,8 @@ class MPIManager : public ManagerInterface std::vector< OffGridSpike >& recv_buffer, std::vector< int >& displacements ); - void communicate_Allgather( std::vector< int >& ); - void communicate_Allgather( std::vector< long >& ); + void communicate_Allgather( std::vector< int >& ) const; + void communicate_Allgather( std::vector< long >& ) const; template < typename T > void communicate_Allgatherv( std::vector< T >& send_buffer, @@ -442,326 +438,6 @@ class MPIManager : public ManagerInterface }; }; -inline void -MPIManager::set_recv_counts_secondary_events_in_int_per_rank( const std::vector< int >& recv_counts_in_int_per_rank ) -{ - recv_counts_secondary_events_in_int_per_rank_ = recv_counts_in_int_per_rank; - - std::partial_sum( recv_counts_secondary_events_in_int_per_rank_.begin(), - recv_counts_secondary_events_in_int_per_rank_.end() - 1, - recv_displacements_secondary_events_in_int_per_rank_.begin() + 1 ); -} - -inline size_t -MPIManager::get_recv_count_secondary_events_in_int( const size_t source_rank ) const -{ - return recv_counts_secondary_events_in_int_per_rank_[ source_rank ]; -} - -inline size_t -MPIManager::get_recv_displacement_secondary_events_in_int( const size_t source_rank ) const -{ - return recv_displacements_secondary_events_in_int_per_rank_[ source_rank ]; -} - -inline size_t -MPIManager::get_send_count_secondary_events_in_int( const size_t target_rank ) const -{ - return send_counts_secondary_events_in_int_per_rank_[ target_rank ]; -} - -inline size_t -MPIManager::get_send_displacement_secondary_events_in_int( const size_t target_rank ) const -{ - return send_displacements_secondary_events_in_int_per_rank_[ target_rank ]; -} - -inline size_t -MPIManager::get_done_marker_position_in_secondary_events_send_buffer( const size_t target_rank ) const -{ - return get_send_displacement_secondary_events_in_int( target_rank ) - + get_send_count_secondary_events_in_int( target_rank ) - 1; -} - -inline size_t -MPIManager::get_done_marker_position_in_secondary_events_recv_buffer( const size_t source_rank ) const -{ - return get_recv_displacement_secondary_events_in_int( source_rank ) - + get_recv_count_secondary_events_in_int( source_rank ) - 1; -} - -inline size_t -MPIManager::get_num_processes() const -{ - return num_processes_; -} - -inline size_t -MPIManager::get_rank() const -{ - return rank_; -} - -inline bool -MPIManager::is_mpi_used() -{ - return use_mpi_; -} - -inline size_t -MPIManager::get_buffer_size_target_data() const -{ - return buffer_size_target_data_; -} - -inline unsigned int -MPIManager::get_send_recv_count_target_data_per_rank() const -{ - return send_recv_count_target_data_per_rank_; -} - -inline size_t -MPIManager::get_buffer_size_spike_data() const -{ - return buffer_size_spike_data_; -} - -inline unsigned int -MPIManager::get_send_recv_count_spike_data_per_rank() const -{ - return send_recv_count_spike_data_per_rank_; -} - -inline size_t -MPIManager::get_send_buffer_size_secondary_events_in_int() const -{ - return send_displacements_secondary_events_in_int_per_rank_ - [ send_displacements_secondary_events_in_int_per_rank_.size() - 1 ] - + send_counts_secondary_events_in_int_per_rank_[ send_counts_secondary_events_in_int_per_rank_.size() - 1 ]; -} - -inline size_t -MPIManager::get_recv_buffer_size_secondary_events_in_int() const -{ - return recv_displacements_secondary_events_in_int_per_rank_ - [ recv_displacements_secondary_events_in_int_per_rank_.size() - 1 ] - + recv_counts_secondary_events_in_int_per_rank_[ recv_counts_secondary_events_in_int_per_rank_.size() - 1 ]; -} - -inline void -MPIManager::set_buffer_size_target_data( const size_t buffer_size ) -{ - assert( buffer_size >= static_cast< size_t >( 2 * get_num_processes() ) ); - if ( buffer_size <= max_buffer_size_target_data_ ) - { - buffer_size_target_data_ = buffer_size; - } - else - { - buffer_size_target_data_ = max_buffer_size_target_data_; - } - send_recv_count_target_data_per_rank_ = static_cast< size_t >( - floor( static_cast< double >( get_buffer_size_target_data() ) / static_cast< double >( get_num_processes() ) ) ); - - assert( send_recv_count_target_data_per_rank_ * get_num_processes() <= get_buffer_size_target_data() ); -} - -inline void -MPIManager::set_buffer_size_spike_data( const size_t buffer_size ) -{ - assert( buffer_size >= static_cast< size_t >( 2 * get_num_processes() ) ); - buffer_size_spike_data_ = buffer_size; - - send_recv_count_spike_data_per_rank_ = floor( get_buffer_size_spike_data() / get_num_processes() ); - - assert( send_recv_count_spike_data_per_rank_ * get_num_processes() <= get_buffer_size_spike_data() ); -} - -inline bool -MPIManager::increase_buffer_size_target_data() -{ - assert( adaptive_target_buffers_ ); - if ( buffer_size_target_data_ >= max_buffer_size_target_data_ ) - { - return false; - } - else - { - if ( buffer_size_target_data_ * growth_factor_buffer_target_data_ < max_buffer_size_target_data_ ) - { - // this also adjusts send_recv_count_target_data_per_rank_ - set_buffer_size_target_data( - static_cast< size_t >( floor( buffer_size_target_data_ * growth_factor_buffer_target_data_ ) ) ); - } - else - { - // this also adjusts send_recv_count_target_data_per_rank_ - set_buffer_size_target_data( max_buffer_size_target_data_ ); - } - return true; - } -} - -inline bool -MPIManager::adaptive_target_buffers() const -{ - return adaptive_target_buffers_; -} - -#ifndef HAVE_MPI -inline std::string -MPIManager::get_processor_name() -{ - char name[ 1024 ]; - name[ 1023 ] = '\0'; - gethostname( name, 1023 ); - return name; -} - -inline void -MPIManager::mpi_abort( int ) -{ -} - -inline void -MPIManager::communicate( std::vector< int >& ) -{ -} - -inline void -MPIManager::communicate( std::vector< long >& ) -{ -} - -inline void -MPIManager::synchronize() -{ -} - -inline void -test_link( int, int ) -{ -} - -inline void -test_links() -{ -} - -inline bool -MPIManager::any_true( const bool my_bool ) -{ - return my_bool; -} - -inline double -MPIManager::time_communicate( int, int ) -{ - return 0.0; -} - -inline double -MPIManager::time_communicatev( int, int ) -{ - return 0.0; -} - -inline double -MPIManager::time_communicate_offgrid( int, int ) -{ - return 0.0; -} - -inline double -MPIManager::time_communicate_alltoall( int, int ) -{ - return 0.0; -} - -inline double -MPIManager::time_communicate_alltoallv( int, int ) -{ - return 0.0; -} - -#endif /* HAVE_MPI */ - -#ifdef HAVE_MPI -template < class D > -void -MPIManager::communicate_Alltoall( std::vector< D >& send_buffer, - std::vector< D >& recv_buffer, - const unsigned int send_recv_count ) -{ - void* send_buffer_int = static_cast< void* >( &send_buffer[ 0 ] ); - void* recv_buffer_int = static_cast< void* >( &recv_buffer[ 0 ] ); - - communicate_Alltoall_( send_buffer_int, recv_buffer_int, send_recv_count ); -} - -template < class D > -void -MPIManager::communicate_secondary_events_Alltoallv( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) -{ - void* send_buffer_int = static_cast< void* >( &send_buffer[ 0 ] ); - void* recv_buffer_int = static_cast< void* >( &recv_buffer[ 0 ] ); - - communicate_Alltoallv_( send_buffer_int, - &send_counts_secondary_events_in_int_per_rank_[ 0 ], - &send_displacements_secondary_events_in_int_per_rank_[ 0 ], - recv_buffer_int, - &recv_counts_secondary_events_in_int_per_rank_[ 0 ], - &recv_displacements_secondary_events_in_int_per_rank_[ 0 ] ); -} - -#else // HAVE_MPI -template < class D > -void -MPIManager::MPIManager::communicate_Alltoall( std::vector< D >& send_buffer, - std::vector< D >& recv_buffer, - const unsigned int ) -{ - recv_buffer.swap( send_buffer ); -} - -template < class D > -void -MPIManager::communicate_secondary_events_Alltoallv( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) -{ - recv_buffer.swap( send_buffer ); -} - -#endif /* HAVE_MPI */ - -template < class D > -void -MPIManager::communicate_target_data_Alltoall( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) -{ - const size_t send_recv_count_target_data_in_int_per_rank = - sizeof( TargetData ) / sizeof( unsigned int ) * send_recv_count_target_data_per_rank_; - - communicate_Alltoall( send_buffer, recv_buffer, send_recv_count_target_data_in_int_per_rank ); -} - -template < class D > -void -MPIManager::communicate_spike_data_Alltoall( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) -{ - const size_t send_recv_count_spike_data_in_int_per_rank = - sizeof( SpikeData ) / sizeof( unsigned int ) * send_recv_count_spike_data_per_rank_; - - communicate_Alltoall( send_buffer, recv_buffer, send_recv_count_spike_data_in_int_per_rank ); -} - -template < class D > -void -MPIManager::communicate_off_grid_spike_data_Alltoall( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) -{ - const size_t send_recv_count_off_grid_spike_data_in_int_per_rank = - sizeof( OffGridSpikeData ) / sizeof( unsigned int ) * send_recv_count_spike_data_per_rank_; - - communicate_Alltoall( send_buffer, recv_buffer, send_recv_count_off_grid_spike_data_in_int_per_rank ); -} } #endif /* MPI_MANAGER_H */ diff --git a/nestkernel/mpi_manager_impl.h b/nestkernel/mpi_manager_impl.h index 1f596adc3c..2aa4b5712b 100644 --- a/nestkernel/mpi_manager_impl.h +++ b/nestkernel/mpi_manager_impl.h @@ -23,26 +23,89 @@ #ifndef MPI_MANAGER_IMPL_H #define MPI_MANAGER_IMPL_H -#include "config.h" +#include "mpi_manager.h" + +namespace nest +{ #ifdef HAVE_MPI -// C includes: -#include -#endif /* #ifdef HAVE_MPI */ +template < class D > +void +MPIManager::communicate_Alltoall( std::vector< D >& send_buffer, + std::vector< D >& recv_buffer, + const unsigned int send_recv_count ) +{ + void* send_buffer_int = static_cast< void* >( &send_buffer[ 0 ] ); + void* recv_buffer_int = static_cast< void* >( &recv_buffer[ 0 ] ); -#include "mpi_manager.h" + communicate_Alltoall_( send_buffer_int, recv_buffer_int, send_recv_count ); +} -// Includes from nestkernel: -#include "kernel_manager.h" +template < class D > +void +MPIManager::communicate_secondary_events_Alltoallv( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) +{ + void* send_buffer_int = static_cast< void* >( &send_buffer[ 0 ] ); + void* recv_buffer_int = static_cast< void* >( &recv_buffer[ 0 ] ); + + communicate_Alltoallv_( send_buffer_int, + &send_counts_secondary_events_in_int_per_rank_[ 0 ], + &send_displacements_secondary_events_in_int_per_rank_[ 0 ], + recv_buffer_int, + &recv_counts_secondary_events_in_int_per_rank_[ 0 ], + &recv_displacements_secondary_events_in_int_per_rank_[ 0 ] ); +} -inline size_t -nest::MPIManager::get_process_id_of_vp( const size_t vp ) const +#else // HAVE_MPI +template < class D > +void +MPIManager::MPIManager::communicate_Alltoall( std::vector< D >& send_buffer, + std::vector< D >& recv_buffer, + const unsigned int ) { - return vp % num_processes_; + recv_buffer.swap( send_buffer ); } -#ifdef HAVE_MPI +template < class D > +void +MPIManager::communicate_secondary_events_Alltoallv( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) +{ + recv_buffer.swap( send_buffer ); +} + +#endif /* HAVE_MPI */ + +template < class D > +void +MPIManager::communicate_target_data_Alltoall( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) +{ + const size_t send_recv_count_target_data_in_int_per_rank = + sizeof( TargetData ) / sizeof( unsigned int ) * send_recv_count_target_data_per_rank_; + communicate_Alltoall( send_buffer, recv_buffer, send_recv_count_target_data_in_int_per_rank ); +} + +template < class D > +void +MPIManager::communicate_spike_data_Alltoall( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) +{ + const size_t send_recv_count_spike_data_in_int_per_rank = + sizeof( SpikeData ) / sizeof( unsigned int ) * send_recv_count_spike_data_per_rank_; + + communicate_Alltoall( send_buffer, recv_buffer, send_recv_count_spike_data_in_int_per_rank ); +} + +template < class D > +void +MPIManager::communicate_off_grid_spike_data_Alltoall( std::vector< D >& send_buffer, std::vector< D >& recv_buffer ) +{ + const size_t send_recv_count_off_grid_spike_data_in_int_per_rank = + sizeof( OffGridSpikeData ) / sizeof( unsigned int ) * send_recv_count_spike_data_per_rank_; + + communicate_Alltoall( send_buffer, recv_buffer, send_recv_count_off_grid_spike_data_in_int_per_rank ); +} + +#ifdef HAVE_MPI // Variable to hold the MPI communicator to use. #ifdef HAVE_MUSIC extern MPI::Intracomm comm; @@ -74,21 +137,9 @@ nest::MPIManager::communicate_Allgatherv( std::vector< T >& send_buffer, comm ); } -inline size_t -nest::MPIManager::get_process_id_of_node_id( const size_t node_id ) const -{ - return node_id % kernel().vp_manager.get_num_virtual_processes() % num_processes_; -} - -#else // HAVE_MPI +#endif /* HAVE_MPI */ -inline size_t -nest::MPIManager::get_process_id_of_node_id( const size_t ) const -{ - return 0; } -#endif /* HAVE_MPI */ - -#endif /* MPI_MANAGER_IMPL_H */ +#endif diff --git a/nestkernel/music_event_handler.cpp b/nestkernel/music_event_handler.cpp index 9f0a7dc616..6f8855e0c5 100644 --- a/nestkernel/music_event_handler.cpp +++ b/nestkernel/music_event_handler.cpp @@ -31,6 +31,8 @@ // Includes from nestkernel: #include "event.h" #include "kernel_manager.h" +#include "logging_manager.h" +#include "music_manager.h" #include "nest_types.h" namespace nest @@ -93,7 +95,7 @@ MusicEventHandler::publish_port() { if ( not published_ ) { - music_port_ = kernel().music_manager.get_music_setup()->publishEventInput( portname_ ); + music_port_ = kernel::manager< MUSICManager >.get_music_setup()->publishEventInput( portname_ ); // MUSIC wants seconds, NEST has miliseconds const double acceptable_latency_s = 0.001 * acceptable_latency_; diff --git a/nestkernel/music_manager.cpp b/nestkernel/music_manager.cpp index ec237eca7d..deedb47277 100644 --- a/nestkernel/music_manager.cpp +++ b/nestkernel/music_manager.cpp @@ -30,7 +30,10 @@ #endif // Includes from nestkernel: +#include "compose.hpp" #include "kernel_manager.h" +#include "logging.h" +#include "logging_manager.h" // Includes from sli: #include "dictutils.h" diff --git a/nestkernel/music_rate_in_handler.cpp b/nestkernel/music_rate_in_handler.cpp index 0ebfe55f41..40d6a189cc 100644 --- a/nestkernel/music_rate_in_handler.cpp +++ b/nestkernel/music_rate_in_handler.cpp @@ -29,8 +29,10 @@ #include "logging.h" // Includes from nestkernel: -#include "event.h" +#include "connection_manager.h" #include "kernel_manager.h" +#include "logging_manager.h" +#include "music_manager.h" #include "nest_types.h" namespace nest @@ -83,7 +85,7 @@ MusicRateInHandler::publish_port() if ( not published_ ) { - MUSIC::Setup* s = kernel().music_manager.get_music_setup(); + MUSIC::Setup* s = kernel::manager< MUSICManager >.get_music_setup(); if ( s == 0 ) { throw MUSICSimulationHasRun( "" ); @@ -124,7 +126,7 @@ MusicRateInHandler::publish_port() void MusicRateInHandler::update( Time const&, const long, const long ) { - const size_t buffer_size = kernel().connection_manager.get_min_delay(); + const size_t buffer_size = kernel::manager< ConnectionManager >.get_min_delay(); std::vector< double > new_rates( buffer_size, 0.0 ); for ( size_t channel = 0; channel < channelmap_.size(); ++channel ) diff --git a/nestkernel/nest.cpp b/nestkernel/nest.cpp index c435834125..308b0e6eda 100644 --- a/nestkernel/nest.cpp +++ b/nestkernel/nest.cpp @@ -26,10 +26,17 @@ #include // Includes from nestkernel: +#include "connection_manager.h" #include "exceptions.h" +#include "io_manager.h" #include "kernel_manager.h" -#include "mpi_manager_impl.h" +#include "logging_manager.h" +#include "model_manager.h" +#include "node_manager.h" #include "parameter.h" +#include "random_manager.h" +#include "simulation_manager.h" +#include "sp_manager.h" // Includes from sli: #include "sliexceptions.h" @@ -41,9 +48,8 @@ namespace nest void init_nest( int* argc, char** argv[] ) { - KernelManager::create_kernel_manager(); - kernel().mpi_manager.init_mpi( argc, argv ); - kernel().initialize(); + kernel::manager< MPIManager >.init_mpi( argc, argv ); + kernel::manager< KernelManager >.initialize(); } void @@ -59,54 +65,54 @@ install_module( const std::string& ) void reset_kernel() { - kernel().reset(); + kernel::manager< KernelManager >.reset(); } void register_logger_client( const deliver_logging_event_ptr client_callback ) { - kernel().logging_manager.register_logging_client( client_callback ); + kernel::manager< LoggingManager >.register_logging_client( client_callback ); } void print_nodes_to_stream( std::ostream& ostr ) { - kernel().node_manager.print( ostr ); + kernel::manager< NodeManager >.print( ostr ); } RngPtr get_rank_synced_rng() { - return kernel().random_manager.get_rank_synced_rng(); + return kernel::manager< RandomManager >.get_rank_synced_rng(); } RngPtr get_vp_synced_rng( size_t tid ) { - return kernel().random_manager.get_vp_synced_rng( tid ); + return kernel::manager< RandomManager >.get_vp_synced_rng( tid ); } RngPtr get_vp_specific_rng( size_t tid ) { - return kernel().random_manager.get_vp_specific_rng( tid ); + return kernel::manager< RandomManager >.get_vp_specific_rng( tid ); } void set_kernel_status( const DictionaryDatum& dict ) { dict->clear_access_flags(); - kernel().set_status( dict ); + kernel::manager< KernelManager >.set_status( dict ); ALL_ENTRIES_ACCESSED( *dict, "SetKernelStatus", "Unread dictionary entries: " ); } DictionaryDatum get_kernel_status() { - assert( kernel().is_initialized() ); + assert( kernel::manager< KernelManager >.is_initialized() ); DictionaryDatum d( new Dictionary ); - kernel().get_status( d ); + kernel::manager< KernelManager >.get_status( d ); return d; } @@ -114,13 +120,13 @@ get_kernel_status() void set_node_status( const size_t node_id, const DictionaryDatum& dict ) { - kernel().node_manager.set_status( node_id, dict ); + kernel::manager< NodeManager >.set_status( node_id, dict ); } DictionaryDatum get_node_status( const size_t node_id ) { - return kernel().node_manager.get_status( node_id ); + return kernel::manager< NodeManager >.get_status( node_id ); } void @@ -135,7 +141,7 @@ set_connection_status( const ConnectionDatum& conn, const DictionaryDatum& dict dict->clear_access_flags(); - kernel().connection_manager.set_synapse_status( source_node_id, target_node_id, tid, syn_id, p, dict ); + kernel::manager< ConnectionManager >.set_synapse_status( source_node_id, target_node_id, tid, syn_id, p, dict ); ALL_ENTRIES_ACCESSED2( *dict, "SetStatus", @@ -147,7 +153,7 @@ set_connection_status( const ConnectionDatum& conn, const DictionaryDatum& dict DictionaryDatum get_connection_status( const ConnectionDatum& conn ) { - return kernel().connection_manager.get_synapse_status( conn.get_source_node_id(), + return kernel::manager< ConnectionManager >.get_synapse_status( conn.get_source_node_id(), conn.get_target_node_id(), conn.get_target_thread(), conn.get_synapse_model_id(), @@ -162,14 +168,14 @@ create( const Name& model_name, const size_t n_nodes ) throw RangeCheck(); } - const size_t model_id = kernel().model_manager.get_node_model_id( model_name ); - return kernel().node_manager.add_node( model_id, n_nodes ); + const size_t model_id = kernel::manager< ModelManager >.get_node_model_id( model_name ); + return kernel::manager< NodeManager >.add_node( model_id, n_nodes ); } NodeCollectionPTR get_nodes( const DictionaryDatum& params, const bool local_only ) { - return kernel().node_manager.get_nodes( params, local_only ); + return kernel::manager< NodeManager >.get_nodes( params, local_only ); } void @@ -178,7 +184,7 @@ connect( NodeCollectionPTR sources, const DictionaryDatum& connectivity, const std::vector< DictionaryDatum >& synapse_params ) { - kernel().connection_manager.connect( sources, targets, connectivity, synapse_params ); + kernel::manager< ConnectionManager >.connect( sources, targets, connectivity, synapse_params ); } void @@ -189,7 +195,7 @@ connect_tripartite( NodeCollectionPTR sources, const DictionaryDatum& third_connectivity, const std::map< Name, std::vector< DictionaryDatum > >& synapse_specs ) { - kernel().connection_manager.connect_tripartite( + kernel::manager< ConnectionManager >.connect_tripartite( sources, targets, third, connectivity, third_connectivity, synapse_specs ); } @@ -203,7 +209,8 @@ connect_arrays( long* sources, size_t n, std::string syn_model ) { - kernel().connection_manager.connect_arrays( sources, targets, weights, delays, p_keys, p_values, n, syn_model ); + kernel::manager< ConnectionManager >.connect_arrays( + sources, targets, weights, delays, p_keys, p_values, n, syn_model ); } ArrayDatum @@ -211,7 +218,7 @@ get_connections( const DictionaryDatum& dict ) { dict->clear_access_flags(); - ArrayDatum array = kernel().connection_manager.get_connections( dict ); + ArrayDatum array = kernel::manager< ConnectionManager >.get_connections( dict ); ALL_ENTRIES_ACCESSED( *dict, "GetConnections", "Unread dictionary entries: " ); @@ -222,13 +229,13 @@ void disconnect( const ArrayDatum& conns ) { // probably not strictly necessary here, but does nothing if all is up to date - kernel().node_manager.update_thread_local_node_data(); + kernel::manager< NodeManager >.update_thread_local_node_data(); for ( size_t conn_index = 0; conn_index < conns.size(); ++conn_index ) { const auto conn_datum = getValue< ConnectionDatum >( conns.get( conn_index ) ); - const auto target_node = kernel().node_manager.get_node_or_proxy( conn_datum.get_target_node_id() ); - kernel().sp_manager.disconnect( + const auto target_node = kernel::manager< NodeManager >.get_node_or_proxy( conn_datum.get_target_node_id() ); + kernel::manager< SPManager >.disconnect( conn_datum.get_source_node_id(), target_node, conn_datum.get_target_thread(), conn_datum.get_synapse_model_id() ); } } @@ -261,38 +268,38 @@ run( const double& time ) "of the simulation resolution." ); } - kernel().simulation_manager.run( t_sim ); + kernel::manager< SimulationManager >.run( t_sim ); } void prepare() { - kernel().prepare(); + kernel::manager< KernelManager >.prepare(); } void cleanup() { - kernel().cleanup(); + kernel::manager< KernelManager >.cleanup(); } void copy_model( const Name& oldmodname, const Name& newmodname, const DictionaryDatum& dict ) { - kernel().model_manager.copy_model( oldmodname, newmodname, dict ); + kernel::manager< ModelManager >.copy_model( oldmodname, newmodname, dict ); } void set_model_defaults( const std::string component, const DictionaryDatum& dict ) { - if ( kernel().model_manager.set_model_defaults( component, dict ) ) + if ( kernel::manager< ModelManager >.set_model_defaults( component, dict ) ) { return; } - if ( kernel().io_manager.is_valid_recording_backend( component ) ) + if ( kernel::manager< IOManager >.is_valid_recording_backend( component ) ) { - kernel().io_manager.set_recording_backend_status( component, dict ); + kernel::manager< IOManager >.set_recording_backend_status( component, dict ); return; } @@ -304,8 +311,8 @@ get_model_defaults( const std::string component ) { try { - const size_t model_id = kernel().model_manager.get_node_model_id( component ); - return kernel().model_manager.get_node_model( model_id )->get_status(); + const size_t model_id = kernel::manager< ModelManager >.get_node_model_id( component ); + return kernel::manager< ModelManager >.get_node_model( model_id )->get_status(); } catch ( UnknownModelName& ) { @@ -314,17 +321,17 @@ get_model_defaults( const std::string component ) try { - const size_t synapse_model_id = kernel().model_manager.get_synapse_model_id( component ); - return kernel().model_manager.get_connector_defaults( synapse_model_id ); + const size_t synapse_model_id = kernel::manager< ModelManager >.get_synapse_model_id( component ); + return kernel::manager< ModelManager >.get_connector_defaults( synapse_model_id ); } catch ( UnknownSynapseType& ) { // ignore errors; throw at the end of the function if that's reached } - if ( kernel().io_manager.is_valid_recording_backend( component ) ) + if ( kernel::manager< IOManager >.is_valid_recording_backend( component ) ) { - return kernel().io_manager.get_recording_backend_status( component ); + return kernel::manager< IOManager >.get_recording_backend_status( component ); } throw UnknownComponent( component ); @@ -364,7 +371,7 @@ apply( const ParameterDatum& param, const NodeCollectionDatum& nc ) RngPtr rng = get_rank_synced_rng(); for ( auto it = nc->begin(); it < nc->end(); ++it ) { - auto node = kernel().node_manager.get_node_or_proxy( ( *it ).node_id ); + auto node = kernel::manager< NodeManager >.get_node_or_proxy( ( *it ).node_id ); result.push_back( param->value( rng, node ) ); } return result; diff --git a/nestkernel/nest.h b/nestkernel/nest.h index e49c7dcb5e..9257d6e7ae 100644 --- a/nestkernel/nest.h +++ b/nestkernel/nest.h @@ -23,17 +23,12 @@ #ifndef NEST_H #define NEST_H -// C++ includes: -#include - // Includes from libnestutil: -#include "enum_bitfield.h" #include "logging.h" // Includes from nestkernel: +#include "kernel_manager.h" #include "nest_datums.h" -#include "nest_time.h" -#include "nest_types.h" // Includes from sli: #include "arraydatum.h" diff --git a/nestkernel/nest_extension_interface.h b/nestkernel/nest_extension_interface.h index ff4d519a21..624317dbe1 100644 --- a/nestkernel/nest_extension_interface.h +++ b/nestkernel/nest_extension_interface.h @@ -26,19 +26,12 @@ // Includes from nestkernel; placed here so module developer does not need to // include them manually #include "config.h" -#include "connection_manager_impl.h" -#include "connector_model_impl.h" #include "exceptions.h" #include "genericmodel.h" -#include "genericmodel_impl.h" -#include "io_manager_impl.h" #include "kernel_manager.h" #include "model.h" -#include "model_manager_impl.h" #include "nest.h" -#include "nest_impl.h" #include "nestmodule.h" -#include "sp_manager_impl.h" #include "target_identifier.h" // C++ includes diff --git a/nestkernel/nest_impl.h b/nestkernel/nest_impl.h index 45da1a8808..da2a2acbb8 100644 --- a/nestkernel/nest_impl.h +++ b/nestkernel/nest_impl.h @@ -20,12 +20,11 @@ * */ +#ifndef NEST_IMPL_H +#define NEST_IMPL_H -// Includes from nestkernel: -#include "connector_model_impl.h" -#include "genericmodel_impl.h" -#include "kernel_manager.h" #include "model_manager_impl.h" +#include "nest.h" namespace nest { @@ -34,13 +33,16 @@ template < template < typename > class ConnectorModelT > void register_connection_model( const std::string& name ) { - kernel().model_manager.register_connection_model< ConnectorModelT >( name ); + kernel::manager< ModelManager >.template register_connection_model< ConnectorModelT >( name ); } template < typename NodeModelT > void register_node_model( const std::string& name, std::string deprecation_info ) { - kernel().model_manager.register_node_model< NodeModelT >( name, deprecation_info ); + kernel::manager< ModelManager >.template register_node_model< NodeModelT >( name, deprecation_info ); } + } + +#endif /* NEST_IMPL_H */ diff --git a/nestkernel/nest_time.cpp b/nestkernel/nest_time.cpp index dfae699e8b..64ca63a986 100644 --- a/nestkernel/nest_time.cpp +++ b/nestkernel/nest_time.cpp @@ -185,6 +185,311 @@ Time::reset_to_defaults() Range::STEPS_PER_MS = 1 / Range::MS_PER_STEP; } +///////////////////////////////////////////////////////////// +// Resolution: set tics per ms, steps per ms +///////////////////////////////////////////////////////////// + +Time +Time::get_resolution() +{ + return Time( Range::TICS_PER_STEP ); +} + +bool +Time::resolution_is_default() +{ + return Range::TICS_PER_STEP == Range::TICS_PER_STEP_DEFAULT; +} + +///////////////////////////////////////////////////////////// +// Common zero-ary or unary operations +///////////////////////////////////////////////////////////// + +void +Time::set_to_zero() +{ + tics = 0; +} + +void +Time::advance() +{ + tics += Range::TICS_PER_STEP; + range(); +} + +Time +Time::succ() const +{ + return tic( tics + Range::TICS_PER_STEP ); +} // check range + +Time +Time::pred() const +{ + return tic( tics - Range::TICS_PER_STEP ); +} // check range + +///////////////////////////////////////////////////////////// +// Subtypes of Time (bool tests) +///////////////////////////////////////////////////////////// + + +bool +Time::is_finite() const +{ + return tics != LIM_POS_INF.tics and tics != LIM_NEG_INF.tics; +} + +bool +Time::is_neg_inf() const +{ + // Currently tics can never become smaller than LIM_NEG_INF.tics. However, if + // LIM_NEG_INF.tics represent negative infinity, any smaller + // value cannot be larger and thus must be infinity as well. to be on the safe side + // we use less-or-equal instead of just equal. + return tics <= LIM_NEG_INF.tics; +} + +bool +Time::is_pos_inf() const +{ + return tics >= LIM_POS_INF.tics; // see comment for is_neg_inf() +} + +bool +Time::is_grid_time() const +{ + return ( tics % Range::TICS_PER_STEP ) == 0; +} + +bool +Time::is_step() const +{ + return tics > 0 and is_grid_time(); +} + +bool +Time::is_multiple_of( const Time& divisor ) const +{ + assert( divisor.tics > 0 ); + return ( tics % divisor.tics ) == 0; +} +///////////////////////////////////////////////////////////// +// Singleton'ish types +///////////////////////////////////////////////////////////// + + +Time +Time::max() +{ + return Time( LIM_MAX.tics ); +} +Time +Time::min() +{ + return Time( LIM_MIN.tics ); +} +double +Time::get_ms_per_tic() +{ + return Range::MS_PER_TIC; +} +Time +Time::neg_inf() +{ + return Time( LIM_NEG_INF.tics ); +} +Time +Time::pos_inf() +{ + return Time( LIM_POS_INF.tics ); +} + +///////////////////////////////////////////////////////////// +// Overflow checks & recalibrate after resolution setting +///////////////////////////////////////////////////////////// + + +void +Time::range() +{ + if ( time_abs( tics ) < LIM_MAX.tics ) + { + return; + } + tics = ( tics < 0 ) ? LIM_NEG_INF.tics : LIM_POS_INF.tics; +} + +void +Time::calibrate() +{ + range(); +} + +///////////////////////////////////////////////////////////// +// Unary operators +///////////////////////////////////////////////////////////// +Time& +Time::operator+=( const Time& t ) +{ + tics += t.tics; + range(); + return *this; +} + +///////////////////////////////////////////////////////////// +// Convert to external units +///////////////////////////////////////////////////////////// + + +tic_t +Time::get_tics() const +{ + return tics; +} +tic_t +Time::get_tics_per_step() +{ + return Range::TICS_PER_STEP; +} +double +Time::get_tics_per_ms() +{ + return Range::TICS_PER_MS; +} + +double +Time::get_ms() const +{ + if ( is_pos_inf() ) + { + return LIM_POS_INF_ms; + } + if ( is_neg_inf() ) + { + return LIM_NEG_INF_ms; + } + return Range::MS_PER_TIC * tics; +} + +long +Time::get_steps() const +{ + if ( is_pos_inf() ) + { + return LIM_POS_INF.steps; + } + if ( is_neg_inf() ) + { + return LIM_NEG_INF.steps; + } + + // round tics up to nearest step + // by adding TICS_PER_STEP-1 before division + return ( tics + Range::TICS_PER_STEP_RND ) * Range::TICS_PER_STEP_INV; +} + +/** + * Convert between delays given in steps and milliseconds. + * + * This is not a reversible operation, since steps have a finite + * rounding resolution. This is not a truncation, but rounding as per + * ld_round, which is different from ms_stamp --> Time mapping, which rounds + * up. See #903. + */ +double +Time::delay_steps_to_ms( long steps ) +{ + return steps * Range::MS_PER_STEP; +} + +long +Time::delay_ms_to_steps( double ms ) +{ + return ld_round( ms * Range::STEPS_PER_MS ); +} + +///////////////////////////////////////////////////////////// +// Binary operators +///////////////////////////////////////////////////////////// + +namespace nest +{ +bool +operator==( const Time& t1, const Time& t2 ) +{ + return t1.tics == t2.tics; +} + +bool +operator!=( const Time& t1, const Time& t2 ) +{ + return t1.tics != t2.tics; +} + +bool +operator<( const Time& t1, const Time& t2 ) +{ + return t1.tics < t2.tics; +} + +bool +operator>( const Time& t1, const Time& t2 ) +{ + return t1.tics > t2.tics; +} + +bool +operator<=( const Time& t1, const Time& t2 ) +{ + return t1.tics <= t2.tics; +} + +bool +operator>=( const Time& t1, const Time& t2 ) +{ + return t1.tics >= t2.tics; +} + +Time +operator+( const Time& t1, const Time& t2 ) +{ + return Time::tic( t1.tics + t2.tics ); // check range +} + +Time +operator-( const Time& t1, const Time& t2 ) +{ + return Time::tic( t1.tics - t2.tics ); // check range +} + +Time +operator*( const long factor, const Time& t ) +{ + const tic_t n = factor * t.tics; + // if no overflow: + if ( t.tics == 0 or n / t.tics == factor ) + { + return Time::tic( n ); // check range + } + if ( ( t.tics > 0 and factor > 0 ) or ( t.tics < 0 and factor < 0 ) ) + { + return Time( Time::LIM_POS_INF.tics ); + } + else + { + return Time( Time::LIM_NEG_INF.tics ); + } +} + +Time +operator*( const Time& t, long factor ) +{ + return factor * t; +} + +} std::ostream& operator<<( std::ostream& strm, const Time& t ) { diff --git a/nestkernel/nest_time.h b/nestkernel/nest_time.h index f579af5659..78bca66505 100644 --- a/nestkernel/nest_time.h +++ b/nestkernel/nest_time.h @@ -331,201 +331,74 @@ class Time static void reset_resolution(); static void reset_to_defaults(); - static Time - get_resolution() - { - return Time( Range::TICS_PER_STEP ); - } + static Time get_resolution(); - static bool - resolution_is_default() - { - return Range::TICS_PER_STEP == Range::TICS_PER_STEP_DEFAULT; - } + static bool resolution_is_default(); ///////////////////////////////////////////////////////////// // Common zero-ary or unary operations ///////////////////////////////////////////////////////////// - void - set_to_zero() - { - tics = 0; - } + void set_to_zero(); - void - advance() - { - tics += Range::TICS_PER_STEP; - range(); - } + void advance(); - Time - succ() const - { - return tic( tics + Range::TICS_PER_STEP ); - } // check range - Time - pred() const - { - return tic( tics - Range::TICS_PER_STEP ); - } // check range + Time succ() const; + + Time pred() const; ///////////////////////////////////////////////////////////// // Subtypes of Time (bool tests) ///////////////////////////////////////////////////////////// - bool - is_finite() const - { - return tics != LIM_POS_INF.tics and tics != LIM_NEG_INF.tics; - } - - bool - is_neg_inf() const - { - // Currently tics can never become smaller than LIM_NEG_INF.tics. However, if - // LIM_NEG_INF.tics represent negative infinity, any smaller - // value cannot be larger and thus must be infinity as well. to be on the safe side - // we use less-or-equal instead of just equal. - return tics <= LIM_NEG_INF.tics; - } - bool - is_pos_inf() const - { - return tics >= LIM_POS_INF.tics; // see comment for is_neg_inf() - } - - bool - is_grid_time() const - { - return ( tics % Range::TICS_PER_STEP ) == 0; - } - bool - is_step() const - { - return tics > 0 and is_grid_time(); - } + bool is_finite() const; + bool is_neg_inf() const; + bool is_pos_inf() const; - bool - is_multiple_of( const Time& divisor ) const - { - assert( divisor.tics > 0 ); - return ( tics % divisor.tics ) == 0; - } + bool is_grid_time() const; + bool is_step() const; + bool is_multiple_of( const Time& divisor ) const; ///////////////////////////////////////////////////////////// // Singleton'ish types ///////////////////////////////////////////////////////////// - static Time - max() - { - return Time( LIM_MAX.tics ); - } - static Time - min() - { - return Time( LIM_MIN.tics ); - } - static double - get_ms_per_tic() - { - return Range::MS_PER_TIC; - } - static Time - neg_inf() - { - return Time( LIM_NEG_INF.tics ); - } - static Time - pos_inf() - { - return Time( LIM_POS_INF.tics ); - } + static Time max(); + + static Time min(); + + static double get_ms_per_tic(); + + static Time neg_inf(); + + static Time pos_inf(); + ///////////////////////////////////////////////////////////// // Overflow checks & recalibrate after resolution setting ///////////////////////////////////////////////////////////// - void - range() - { - if ( time_abs( tics ) < LIM_MAX.tics ) - { - return; - } - tics = ( tics < 0 ) ? LIM_NEG_INF.tics : LIM_POS_INF.tics; - } + void range(); - void - calibrate() - { - range(); - } + void calibrate(); ///////////////////////////////////////////////////////////// // Unary operators ///////////////////////////////////////////////////////////// - Time& - operator+=( const Time& t ) - { - tics += t.tics; - range(); - return *this; - } + Time& operator+=( const Time& t ); ///////////////////////////////////////////////////////////// // Convert to external units ///////////////////////////////////////////////////////////// - tic_t - get_tics() const - { - return tics; - } - static tic_t - get_tics_per_step() - { - return Range::TICS_PER_STEP; - } - static double - get_tics_per_ms() - { - return Range::TICS_PER_MS; - } + tic_t get_tics() const; + static tic_t get_tics_per_step(); + static double get_tics_per_ms(); - double - get_ms() const - { - if ( is_pos_inf() ) - { - return LIM_POS_INF_ms; - } - if ( is_neg_inf() ) - { - return LIM_NEG_INF_ms; - } - return Range::MS_PER_TIC * tics; - } - - long - get_steps() const - { - if ( is_pos_inf() ) - { - return LIM_POS_INF.steps; - } - if ( is_neg_inf() ) - { - return LIM_NEG_INF.steps; - } + double get_ms() const; - // round tics up to nearest step - // by adding TICS_PER_STEP-1 before division - return ( tics + Range::TICS_PER_STEP_RND ) * Range::TICS_PER_STEP_INV; - } + long get_steps() const; /** * Convert between delays given in steps and milliseconds. @@ -535,17 +408,9 @@ class Time * ld_round, which is different from ms_stamp --> Time mapping, which rounds * up. See #903. */ - static double - delay_steps_to_ms( long steps ) - { - return steps * Range::MS_PER_STEP; - } + static double delay_steps_to_ms( long steps ); - static long - delay_ms_to_steps( double ms ) - { - return ld_round( ms * Range::STEPS_PER_MS ); - } + static long delay_ms_to_steps( double ms ); }; ///////////////////////////////////////////////////////////// @@ -556,82 +421,6 @@ class Time // maybe make the zero visible for optimization. const Time TimeZero; -///////////////////////////////////////////////////////////// -// Binary operators -///////////////////////////////////////////////////////////// - -inline bool -operator==( const Time& t1, const Time& t2 ) -{ - return t1.tics == t2.tics; -} - -inline bool -operator!=( const Time& t1, const Time& t2 ) -{ - return t1.tics != t2.tics; -} - -inline bool -operator<( const Time& t1, const Time& t2 ) -{ - return t1.tics < t2.tics; -} - -inline bool -operator>( const Time& t1, const Time& t2 ) -{ - return t1.tics > t2.tics; -} - -inline bool -operator<=( const Time& t1, const Time& t2 ) -{ - return t1.tics <= t2.tics; -} - -inline bool -operator>=( const Time& t1, const Time& t2 ) -{ - return t1.tics >= t2.tics; -} - -inline Time -operator+( const Time& t1, const Time& t2 ) -{ - return Time::tic( t1.tics + t2.tics ); // check range -} - -inline Time -operator-( const Time& t1, const Time& t2 ) -{ - return Time::tic( t1.tics - t2.tics ); // check range -} - -inline Time -operator*( const long factor, const Time& t ) -{ - const tic_t n = factor * t.tics; - // if no overflow: - if ( t.tics == 0 or n / t.tics == factor ) - { - return Time::tic( n ); // check range - } - if ( ( t.tics > 0 and factor > 0 ) or ( t.tics < 0 and factor < 0 ) ) - { - return Time( Time::LIM_POS_INF.tics ); - } - else - { - return Time( Time::LIM_NEG_INF.tics ); - } -} - -inline Time -operator*( const Time& t, long factor ) -{ - return factor * t; -} } // namespace std::ostream& operator<<( std::ostream&, const nest::Time& ); diff --git a/nestkernel/nestmodule.cpp b/nestkernel/nestmodule.cpp index 56fa7ec848..077c3a560b 100644 --- a/nestkernel/nestmodule.cpp +++ b/nestkernel/nestmodule.cpp @@ -29,23 +29,18 @@ #include "logging.h" // Includes from nestkernel: -#include "conn_builder.h" -#include "connection_creator_impl.h" #include "free_layer.h" -#include "genericmodel.h" -#include "grid_layer.h" #include "grid_mask.h" #include "kernel_manager.h" -#include "layer.h" #include "layer_impl.h" -#include "mask.h" -#include "mask_impl.h" -#include "model_manager_impl.h" +#include "logging_manager.h" +#include "model_manager.h" +#include "module_manager.h" +#include "music_manager.h" #include "nest.h" #include "nest_datums.h" -#include "nest_types.h" -#include "node.h" #include "parameter.h" +#include "sp_manager.h" #include "spatial.h" #include "stopwatch_impl.h" @@ -381,7 +376,7 @@ NestModule::SetStatus_aaFunction::execute( SLIInterpreter* i ) const { ConnectionDatum con_id = getValue< ConnectionDatum >( conn_a[ con ] ); dict->clear_access_flags(); - kernel().connection_manager.set_synapse_status( con_id.get_source_node_id(), + kernel::manager< ConnectionManager >.set_synapse_status( con_id.get_source_node_id(), con_id.get_target_node_id(), con_id.get_target_thread(), con_id.get_synapse_model_id(), @@ -399,7 +394,7 @@ NestModule::SetStatus_aaFunction::execute( SLIInterpreter* i ) const DictionaryDatum dict = getValue< DictionaryDatum >( dict_a[ con ] ); ConnectionDatum con_id = getValue< ConnectionDatum >( conn_a[ con ] ); dict->clear_access_flags(); - kernel().connection_manager.set_synapse_status( con_id.get_source_node_id(), + kernel::manager< ConnectionManager >.set_synapse_status( con_id.get_source_node_id(), con_id.get_target_node_id(), con_id.get_target_thread(), con_id.get_synapse_model_id(), @@ -463,7 +458,7 @@ NestModule::GetStatus_CFunction::execute( SLIInterpreter* i ) const ConnectionDatum conn = getValue< ConnectionDatum >( i->OStack.pick( 0 ) ); - DictionaryDatum result_dict = kernel().connection_manager.get_synapse_status( conn.get_source_node_id(), + DictionaryDatum result_dict = kernel::manager< ConnectionManager >.get_synapse_status( conn.get_source_node_id(), conn.get_target_node_id(), conn.get_target_thread(), conn.get_synapse_model_id(), @@ -486,7 +481,7 @@ NestModule::GetStatus_aFunction::execute( SLIInterpreter* i ) const for ( size_t nt = 0; nt < n_results; ++nt ) { ConnectionDatum con_id = getValue< ConnectionDatum >( conns.get( nt ) ); - DictionaryDatum result_dict = kernel().connection_manager.get_synapse_status( con_id.get_source_node_id(), + DictionaryDatum result_dict = kernel::manager< ConnectionManager >.get_synapse_status( con_id.get_source_node_id(), con_id.get_target_node_id(), con_id.get_target_thread(), con_id.get_synapse_model_id(), @@ -563,7 +558,7 @@ NestModule::Install_sFunction::execute( SLIInterpreter* i ) const const std::string modulename = getValue< std::string >( i->OStack.pick( 0 ) ); - kernel().module_manager.install( modulename ); + kernel::manager< ModuleManager >.install( modulename ); i->OStack.pop(); i->EStack.pop(); @@ -635,7 +630,7 @@ NestModule::CopyModel_l_l_DFunction::execute( SLIInterpreter* i ) const const Name new_name = getValue< Name >( i->OStack.pick( 1 ) ); DictionaryDatum params = getValue< DictionaryDatum >( i->OStack.pick( 0 ) ); - kernel().model_manager.copy_model( old_name, new_name, params ); + kernel::manager< ModelManager >.copy_model( old_name, new_name, params ); i->OStack.pop( 3 ); i->EStack.pop(); @@ -699,7 +694,7 @@ NestModule::Disconnect_g_g_D_DFunction::execute( SLIInterpreter* i ) const DictionaryDatum synapse_params = getValue< DictionaryDatum >( i->OStack.pick( 0 ) ); // dictionary access checking is handled by disconnect - kernel().sp_manager.disconnect( sources, targets, connectivity, synapse_params ); + kernel::manager< SPManager >.disconnect( sources, targets, connectivity, synapse_params ); i->OStack.pop( 4 ); i->EStack.pop(); @@ -724,7 +719,7 @@ NestModule::Disconnect_aFunction::execute( SLIInterpreter* i ) const void NestModule::Connect_g_g_D_DFunction::execute( SLIInterpreter* i ) const { - kernel().connection_manager.sw_construction_connect.start(); + kernel::manager< ConnectionManager >.sw_construction_connect.start(); i->assert_stack_load( 4 ); @@ -734,18 +729,18 @@ NestModule::Connect_g_g_D_DFunction::execute( SLIInterpreter* i ) const DictionaryDatum synapse_params = getValue< DictionaryDatum >( i->OStack.pick( 0 ) ); // dictionary access checking is handled by connect - kernel().connection_manager.connect( sources, targets, connectivity, { synapse_params } ); + kernel::manager< ConnectionManager >.connect( sources, targets, connectivity, { synapse_params } ); i->OStack.pop( 4 ); i->EStack.pop(); - kernel().connection_manager.sw_construction_connect.stop(); + kernel::manager< ConnectionManager >.sw_construction_connect.stop(); } void NestModule::Connect_g_g_D_aFunction::execute( SLIInterpreter* i ) const { - kernel().connection_manager.sw_construction_connect.start(); + kernel::manager< ConnectionManager >.sw_construction_connect.start(); i->assert_stack_load( 4 ); @@ -761,19 +756,19 @@ NestModule::Connect_g_g_D_aFunction::execute( SLIInterpreter* i ) const } // dictionary access checking is handled by connect - kernel().connection_manager.connect( sources, targets, connectivity, synapse_params ); + kernel::manager< ConnectionManager >.connect( sources, targets, connectivity, synapse_params ); i->OStack.pop( 4 ); i->EStack.pop(); - kernel().connection_manager.sw_construction_connect.stop(); + kernel::manager< ConnectionManager >.sw_construction_connect.stop(); } void NestModule::ConnectTripartite_g_g_g_D_D_DFunction::execute( SLIInterpreter* i ) const { - kernel().connection_manager.sw_construction_connect.start(); + kernel::manager< ConnectionManager >.sw_construction_connect.start(); i->assert_stack_load( 6 ); @@ -804,26 +799,26 @@ NestModule::ConnectTripartite_g_g_g_D_D_DFunction::execute( SLIInterpreter* i ) i->OStack.pop( 6 ); i->EStack.pop(); - kernel().connection_manager.sw_construction_connect.stop(); + kernel::manager< ConnectionManager >.sw_construction_connect.stop(); } void NestModule::ConnectSonata_D_Function::execute( SLIInterpreter* i ) const { - kernel().connection_manager.sw_construction_connect.start(); + kernel::manager< ConnectionManager >.sw_construction_connect.start(); i->assert_stack_load( 2 ); DictionaryDatum graph_specs = getValue< DictionaryDatum >( i->OStack.pick( 1 ) ); const long hyberslab_size = getValue< long >( i->OStack.pick( 0 ) ); - kernel().connection_manager.connect_sonata( graph_specs, hyberslab_size ); + kernel::manager< ConnectionManager >.connect_sonata( graph_specs, hyberslab_size ); i->OStack.pop( 2 ); i->EStack.pop(); - kernel().connection_manager.sw_construction_connect.stop(); + kernel::manager< ConnectionManager >.sw_construction_connect.stop(); } /** @BeginDocumentation @@ -843,7 +838,7 @@ NestModule::ConnectSonata_D_Function::execute( SLIInterpreter* i ) const void NestModule::MemoryInfoFunction::execute( SLIInterpreter* i ) const { - kernel().model_manager.memory_info(); + kernel::manager< ModelManager >.memory_info(); i->EStack.pop(); } @@ -868,21 +863,21 @@ NestModule::PrintNodesToStreamFunction::execute( SLIInterpreter* i ) const void NestModule::RankFunction::execute( SLIInterpreter* i ) const { - i->OStack.push( kernel().mpi_manager.get_rank() ); + i->OStack.push( kernel::manager< MPIManager >.get_rank() ); i->EStack.pop(); } void NestModule::NumProcessesFunction::execute( SLIInterpreter* i ) const { - i->OStack.push( kernel().mpi_manager.get_num_processes() ); + i->OStack.push( kernel::manager< MPIManager >.get_num_processes() ); i->EStack.pop(); } void NestModule::SyncProcessesFunction::execute( SLIInterpreter* i ) const { - kernel().mpi_manager.synchronize(); + kernel::manager< MPIManager >.synchronize(); i->EStack.pop(); } @@ -897,11 +892,11 @@ NestModule::TimeCommunication_i_i_bFunction::execute( SLIInterpreter* i ) const double time = 0.0; if ( offgrid ) { - time = kernel().mpi_manager.time_communicate_offgrid( num_bytes, samples ); + time = kernel::manager< MPIManager >.time_communicate_offgrid( num_bytes, samples ); } else { - time = kernel().mpi_manager.time_communicate( num_bytes, samples ); + time = kernel::manager< MPIManager >.time_communicate( num_bytes, samples ); } i->OStack.pop( 3 ); @@ -919,7 +914,7 @@ NestModule::TimeCommunicationv_i_iFunction::execute( SLIInterpreter* i ) const double time = 0.0; - time = kernel().mpi_manager.time_communicatev( num_bytes, samples ); + time = kernel::manager< MPIManager >.time_communicatev( num_bytes, samples ); i->OStack.pop( 2 ); i->OStack.push( time ); @@ -936,7 +931,7 @@ NestModule::TimeCommunicationAlltoall_i_iFunction::execute( SLIInterpreter* i ) double time = 0.0; - time = kernel().mpi_manager.time_communicate_alltoall( num_bytes, samples ); + time = kernel::manager< MPIManager >.time_communicate_alltoall( num_bytes, samples ); i->OStack.pop( 2 ); i->OStack.push( time ); @@ -953,7 +948,7 @@ NestModule::TimeCommunicationAlltoallv_i_iFunction::execute( SLIInterpreter* i ) double time = 0.0; - time = kernel().mpi_manager.time_communicate_alltoallv( num_bytes, samples ); + time = kernel::manager< MPIManager >.time_communicate_alltoallv( num_bytes, samples ); i->OStack.pop( 2 ); i->OStack.push( time ); @@ -963,7 +958,7 @@ NestModule::TimeCommunicationAlltoallv_i_iFunction::execute( SLIInterpreter* i ) void NestModule::ProcessorNameFunction::execute( SLIInterpreter* i ) const { - i->OStack.push( kernel().mpi_manager.get_processor_name() ); + i->OStack.push( kernel::manager< MPIManager >.get_processor_name() ); i->EStack.pop(); } @@ -973,7 +968,7 @@ NestModule::MPIAbort_iFunction::execute( SLIInterpreter* i ) const { i->assert_stack_load( 1 ); long exitcode = getValue< long >( i->OStack.pick( 0 ) ); - kernel().mpi_manager.mpi_abort( exitcode ); + kernel::manager< MPIManager >.mpi_abort( exitcode ); i->EStack.pop(); } #endif @@ -1296,7 +1291,7 @@ NestModule::SetAcceptableLatencyFunction::execute( SLIInterpreter* i ) const std::string port_name = getValue< std::string >( i->OStack.pick( 1 ) ); double latency = getValue< double >( i->OStack.pick( 0 ) ); - kernel().music_manager.set_music_in_port_acceptable_latency( port_name, latency ); + kernel::manager< MUSICManager >.set_music_in_port_acceptable_latency( port_name, latency ); i->OStack.pop( 2 ); i->EStack.pop(); @@ -1310,7 +1305,7 @@ NestModule::SetMaxBufferedFunction::execute( SLIInterpreter* i ) const std::string port_name = getValue< std::string >( i->OStack.pick( 1 ) ); int maxBuffered = getValue< long >( i->OStack.pick( 0 ) ); - kernel().music_manager.set_music_in_port_max_buffered( port_name, maxBuffered ); + kernel::manager< MUSICManager >.set_music_in_port_max_buffered( port_name, maxBuffered ); i->OStack.pop( 2 ); i->EStack.pop(); @@ -1321,14 +1316,14 @@ NestModule::SetMaxBufferedFunction::execute( SLIInterpreter* i ) const void NestModule::EnableStructuralPlasticity_Function::execute( SLIInterpreter* i ) const { - kernel().sp_manager.enable_structural_plasticity(); + kernel::manager< SPManager >.enable_structural_plasticity(); i->EStack.pop(); } void NestModule::DisableStructuralPlasticity_Function::execute( SLIInterpreter* i ) const { - kernel().sp_manager.disable_structural_plasticity(); + kernel::manager< SPManager >.disable_structural_plasticity(); i->EStack.pop(); } @@ -1339,7 +1334,7 @@ NestModule::SetStdpEps_dFunction::execute( SLIInterpreter* i ) const i->assert_stack_load( 1 ); const double stdp_eps = getValue< double >( i->OStack.top() ); - kernel().connection_manager.set_stdp_eps( stdp_eps ); + kernel::manager< ConnectionManager >.set_stdp_eps( stdp_eps ); i->OStack.pop(); i->EStack.pop(); @@ -1901,7 +1896,7 @@ NestModule::Sub_M_MFunction::execute( SLIInterpreter* i ) const void NestModule::ConnectLayers_g_g_DFunction::execute( SLIInterpreter* i ) const { - kernel().connection_manager.sw_construction_connect.start(); + kernel::manager< ConnectionManager >.sw_construction_connect.start(); i->assert_stack_load( 3 ); @@ -1914,7 +1909,7 @@ NestModule::ConnectLayers_g_g_DFunction::execute( SLIInterpreter* i ) const i->OStack.pop( 3 ); i->EStack.pop(); - kernel().connection_manager.sw_construction_connect.stop(); + kernel::manager< ConnectionManager >.sw_construction_connect.stop(); } void @@ -2194,7 +2189,7 @@ NestModule::init( SLIInterpreter* i ) Token statusd = i->baselookup( Name( "statusdict" ) ); DictionaryDatum dd = getValue< DictionaryDatum >( statusd ); dd->insert( Name( "kernelname" ), new StringDatum( "NEST" ) ); - dd->insert( Name( "is_mpi" ), new BoolDatum( kernel().mpi_manager.is_mpi_used() ) ); + dd->insert( Name( "is_mpi" ), new BoolDatum( kernel::manager< MPIManager >.is_mpi_used() ) ); register_parameter< ConstantParameter >( "constant" ); register_parameter< UniformParameter >( "uniform" ); @@ -2226,4 +2221,17 @@ NestModule::init( SLIInterpreter* i ) register_mask< GridMask< 2 > >(); } +bool +NestModule::register_mask( const Name& name, MaskCreatorFunction creator ) +{ + return mask_factory_().register_subtype( name, creator ); +} + +AbstractMask* +NestModule::create_mask( const Name& name, const DictionaryDatum& d ) +{ + return mask_factory_().create( name, d ); +} + + } // namespace nest diff --git a/nestkernel/nestmodule.h b/nestkernel/nestmodule.h index d381e699b6..e7c76421d9 100644 --- a/nestkernel/nestmodule.h +++ b/nestkernel/nestmodule.h @@ -25,14 +25,11 @@ // Includes from nestkernel: #include "event.h" -#include "exceptions.h" -#include "generic_factory.h" -#include "ntree.h" +#include "generic_factory_impl.h" +#include "ntree_impl.h" #include "parameter.h" -#include "position.h" // Includes from sli: -#include "dict.h" #include "sharedptrdatum.h" #include "slifunction.h" #include "slimodule.h" @@ -1874,18 +1871,6 @@ NestModule::register_mask() return mask_factory_().register_subtype< T >( T::get_name() ); } -inline bool -NestModule::register_mask( const Name& name, MaskCreatorFunction creator ) -{ - return mask_factory_().register_subtype( name, creator ); -} - -inline AbstractMask* -NestModule::create_mask( const Name& name, const DictionaryDatum& d ) -{ - return mask_factory_().create( name, d ); -} - } // namespace #endif diff --git a/nestkernel/node.cpp b/nestkernel/node.cpp index 6f54cc1075..c960f9e041 100644 --- a/nestkernel/node.cpp +++ b/nestkernel/node.cpp @@ -29,6 +29,8 @@ // Includes from nestkernel: #include "exceptions.h" #include "kernel_manager.h" +#include "model_manager.h" +#include "node_manager.h" // Includes from sli: #include "arraydatum.h" @@ -114,14 +116,14 @@ Node::get_name() const return std::string( "UnknownNode" ); } - return kernel().model_manager.get_node_model( model_id_ )->get_name(); + return kernel::manager< ModelManager >.get_node_model( model_id_ )->get_name(); } Model& Node::get_model_() const { assert( model_id_ >= 0 ); - return *kernel().model_manager.get_node_model( model_id_ ); + return *kernel::manager< ModelManager >.get_node_model( model_id_ ); } DictionaryDatum @@ -149,7 +151,7 @@ Node::get_status_base() DictionaryDatum dict = get_status_dict_(); // add information available for all nodes - ( *dict )[ names::local ] = kernel().node_manager.is_local_node( this ); + ( *dict )[ names::local ] = kernel::manager< NodeManager >.is_local_node( this ); ( *dict )[ names::model ] = LiteralDatum( get_name() ); ( *dict )[ names::model_id ] = get_model_id(); ( *dict )[ names::global_id ] = get_node_id(); @@ -582,4 +584,239 @@ Node::event_hook( DSCurrentEvent& e ) e.get_receiver().handle( e ); } +size_t +Node::get_tmp_nc_index() +{ + + assert( tmp_nc_index_ != invalid_index ); + + const auto index = tmp_nc_index_; + tmp_nc_index_ = invalid_index; + + return index; +} + +void +Node::set_tmp_nc_index( size_t index ) +{ + + tmp_nc_index_ = index; +} + +size_t +Node::get_thread_lid() const +{ + + return thread_lid_; +} + +void +Node::set_thread_lid( const size_t tlid ) +{ + + thread_lid_ = tlid; +} + +size_t +Node::get_vp() const +{ + + return vp_; +} + +void +Node::set_vp( size_t vp ) +{ + + vp_ = vp; +} + +size_t +Node::get_thread() const +{ + + return thread_; +} + +void +Node::set_thread( size_t t ) +{ + + thread_ = t; +} + +bool +Node::is_model_prototype() const +{ + + return vp_ == invalid_thread; +} + +void +Node::set_model_id( int i ) +{ + + model_id_ = i; +} + +int +Node::get_model_id() const +{ + + return model_id_; +} + +void +Node::set_node_id_( size_t i ) +{ + + node_id_ = i; +} + +size_t +Node::get_node_id() const +{ + + return node_id_; +} + +Name +Node::get_element_type() const +{ + + return names::neuron; +} + +bool +Node::is_proxy() const +{ + + return false; +} + +bool +Node::is_off_grid() const +{ + + return false; +} + +bool +Node::one_node_per_process() const +{ + + return false; +} + +bool +Node::local_receiver() const +{ + + return false; +} + +bool +Node::has_proxies() const +{ + + return true; +} + +void +Node::set_node_uses_wfr( const bool uwfr ) +{ + + node_uses_wfr_ = uwfr; +} + +bool +Node::supports_urbanczik_archiving() const +{ + + return false; +} + +bool +Node::node_uses_wfr() const +{ + + return node_uses_wfr_; +} + +bool +Node::is_frozen() const +{ + + return frozen_; +} + +std::map< Name, double > +Node::get_synaptic_elements() const +{ + + return std::map< Name, double >(); +} + +int +Node::get_synaptic_elements_connected( Name ) const +{ + + return 0; +} + +int +Node::get_synaptic_elements_vacant( Name ) const +{ + + return 0; +} + +double +Node::get_synaptic_elements( Name ) const +{ + + return 0.0; +} + +double +Node::get_Ca_minus() const +{ + + return 0.0; +} + +void +Node::finalize() +{ +} + +void +Node::post_run_cleanup() +{ +} + +void +Node::calibrate_time( const TimeConverter& ) +{ +} + +SignalType +Node::sends_signal() const +{ + return SPIKE; +} + +SignalType +Node::receives_signal() const +{ + return SPIKE; +} + +void +Node::set_frozen_( bool frozen ) +{ + frozen_ = frozen; +} + + } // namespace diff --git a/nestkernel/node.h b/nestkernel/node.h index 5c41113f43..9d52e0d9ad 100644 --- a/nestkernel/node.h +++ b/nestkernel/node.h @@ -26,9 +26,7 @@ // C++ includes: #include #include -#include #include -#include #include // Includes from nestkernel: @@ -36,10 +34,9 @@ #include "deprecation_warning.h" #include "event.h" #include "histentry.h" -#include "nest_names.h" #include "nest_time.h" #include "nest_types.h" -#include "secondary_event.h" +#include "secondary_event_impl.h" #include "weight_optimizer.h" // Includes from sli: @@ -253,10 +250,7 @@ class Node * Re-calculate time-based properties of the node. * This function is called after a change in resolution. */ - virtual void - calibrate_time( const TimeConverter& ) - { - } + virtual void calibrate_time( const TimeConverter& ); /** * Cleanup node after Run. @@ -266,10 +260,7 @@ class Node * SimulationManager::run() returns. Typical use-cases are devices * that need to flush buffers. */ - virtual void - post_run_cleanup() - { - } + virtual void post_run_cleanup(); /** * Finalize node. @@ -278,10 +269,7 @@ class Node * full simulation, i.e., a cycle of Prepare, Run, Cleanup. Typical * use-cases are devices that need to close files. */ - virtual void - finalize() - { - } + virtual void finalize(); /** * Bring the node from state $t$ to $t+n*dt$. @@ -697,11 +685,7 @@ class Node * Return 0.0 if not overridden * @ingroup SP_functions */ - virtual double - get_Ca_minus() const - { - return 0.0; - } + virtual double get_Ca_minus() const; /** * Get the number of synaptic element for the current Node at Ca_t which @@ -710,22 +694,14 @@ class Node * Return 0.0 if not overridden * @ingroup SP_functions */ - virtual double - get_synaptic_elements( Name ) const - { - return 0.0; - } + virtual double get_synaptic_elements( Name ) const; /** * Get the number of vacant synaptic element for the current Node * Return 0 if not overridden * @ingroup SP_functions */ - virtual int - get_synaptic_elements_vacant( Name ) const - { - return 0; - } + virtual int get_synaptic_elements_vacant( Name ) const; /** * Get the number of connected synaptic element for the current Node @@ -733,11 +709,7 @@ class Node * Return 0 if not overridden * @ingroup SP_functions */ - virtual int - get_synaptic_elements_connected( Name ) const - { - return 0; - } + virtual int get_synaptic_elements_connected( Name ) const; /** * Get the number of all synaptic elements for the current Node at time t @@ -745,11 +717,7 @@ class Node * Return an empty map if not overridden * @ingroup SP_functions */ - virtual std::map< Name, double > - get_synaptic_elements() const - { - return std::map< Name, double >(); - } + virtual std::map< Name, double > get_synaptic_elements() const; /** * Triggers the update of all SynapticElements @@ -942,23 +910,14 @@ class Node * used in check_connection to only connect neurons which send / receive * compatible information */ - virtual SignalType - sends_signal() const - { - return SPIKE; - } + virtual SignalType sends_signal() const; /** * @returns type of signal this node consumes * used in check_connection to only connect neurons which send / receive * compatible information */ - virtual SignalType - receives_signal() const - { - return SPIKE; - } - + virtual SignalType receives_signal() const; /** * Return a dictionary with the node's properties. @@ -1064,11 +1023,7 @@ class Node Model& get_model_() const; //! Mark node as frozen. - void - set_frozen_( bool frozen ) - { - frozen_ = frozen; - } + void set_frozen_( bool frozen ); /** * Auxiliary function to downcast a Node to a concrete class derived from @@ -1119,161 +1074,16 @@ class Node size_t tmp_nc_index_; }; -inline bool -Node::is_frozen() const -{ - return frozen_; -} - -inline bool -Node::node_uses_wfr() const -{ - return node_uses_wfr_; -} - -inline bool -Node::supports_urbanczik_archiving() const -{ - return false; -} - -inline void -Node::set_node_uses_wfr( const bool uwfr ) -{ - node_uses_wfr_ = uwfr; -} - -inline bool -Node::has_proxies() const -{ - return true; -} - -inline bool -Node::local_receiver() const -{ - return false; -} - -inline bool -Node::one_node_per_process() const -{ - return false; -} - -inline bool -Node::is_off_grid() const -{ - return false; -} - -inline bool -Node::is_proxy() const -{ - return false; -} - -inline Name -Node::get_element_type() const -{ - return names::neuron; -} - -inline size_t -Node::get_node_id() const -{ - return node_id_; -} - - -inline void -Node::set_node_id_( size_t i ) -{ - node_id_ = i; -} - - -inline int -Node::get_model_id() const -{ - return model_id_; -} - -inline void -Node::set_model_id( int i ) -{ - model_id_ = i; -} - -inline bool -Node::is_model_prototype() const -{ - return vp_ == invalid_thread; -} - -inline void -Node::set_thread( size_t t ) -{ - thread_ = t; -} - -inline size_t -Node::get_thread() const -{ - return thread_; -} - -inline void -Node::set_vp( size_t vp ) -{ - vp_ = vp; -} - -inline size_t -Node::get_vp() const -{ - return vp_; -} - template < typename ConcreteNode > const ConcreteNode& Node::downcast( const Node& n ) { + ConcreteNode const* tp = dynamic_cast< ConcreteNode const* >( &n ); assert( tp != 0 ); return *tp; } -inline void -Node::set_thread_lid( const size_t tlid ) -{ - thread_lid_ = tlid; -} - -inline size_t -Node::get_thread_lid() const -{ - return thread_lid_; -} - -inline void -Node::set_tmp_nc_index( size_t index ) -{ - tmp_nc_index_ = index; -} - -inline size_t -Node::get_tmp_nc_index() -{ - assert( tmp_nc_index_ != invalid_index ); - - const auto index = tmp_nc_index_; - tmp_nc_index_ = invalid_index; - - return index; -} - - } // namespace #endif diff --git a/nestkernel/node_collection.cpp b/nestkernel/node_collection.cpp index b4323921f4..bd37ce9115 100644 --- a/nestkernel/node_collection.cpp +++ b/nestkernel/node_collection.cpp @@ -27,14 +27,14 @@ // Includes from nestkernel: #include "kernel_manager.h" -#include "mpi_manager_impl.h" +#include "model_manager.h" +#include "modelrange_manager.h" #include "node.h" -#include "vp_manager_impl.h" // C++ includes: +#include "numeric" // accumulate #include // copy #include // lcm -#include // accumulate namespace nest @@ -63,24 +63,24 @@ nc_const_iterator::nc_const_iterator( NodeCollectionPTR collection_ptr, : coll_ptr_( collection_ptr ) , element_idx_( offset ) , part_idx_( 0 ) - , step_( kind == NCIteratorKind::RANK_LOCAL - ? std::lcm( stride, kernel().mpi_manager.get_num_processes() ) - : ( kind == NCIteratorKind::THREAD_LOCAL ? std::lcm( stride, kernel().vp_manager.get_num_virtual_processes() ) - : stride ) ) + , step_( kind == NCIteratorKind::RANK_LOCAL ? std::lcm( stride, kernel::manager< MPIManager >.get_num_processes() ) + : ( kind == NCIteratorKind::THREAD_LOCAL ? std::lcm( stride, + kernel::manager< VPManager >.get_num_virtual_processes() ) + : stride ) ) , kind_( kind ) , rank_or_vp_( kind == NCIteratorKind::RANK_LOCAL - ? kernel().mpi_manager.get_rank() - : ( kind == NCIteratorKind::THREAD_LOCAL ? kernel().vp_manager.get_vp() : invalid_thread ) ) + ? kernel::manager< MPIManager >.get_rank() + : ( kind == NCIteratorKind::THREAD_LOCAL ? kernel::manager< VPManager >.get_vp() : invalid_thread ) ) , primitive_collection_( &collection ) , composite_collection_( nullptr ) { assert( not collection_ptr.get() or collection_ptr.get() == &collection ); assert( element_idx_ <= collection.size() ); // allow == for end() - FULL_LOGGING_ONLY( - kernel().write_to_dump( String::compose( "NCIT Prim ctor rk %1, thr %2, pix %3, eix %4, step %5, kind %6, rvp %7", - kernel().mpi_manager.get_rank(), - kernel().vp_manager.get_thread_id(), + FULL_LOGGING_ONLY( kernel::manager< KernelManager >.write_to_dump( + String::compose( "NCIT Prim ctor rk %1, thr %2, pix %3, eix %4, step %5, kind %6, rvp %7", + kernel::manager< MPIManager >.get_rank(), + kernel::manager< VPManager >.get_thread_id(), part_idx_, element_idx_, step_, @@ -97,14 +97,14 @@ nc_const_iterator::nc_const_iterator( NodeCollectionPTR collection_ptr, : coll_ptr_( collection_ptr ) , element_idx_( offset ) , part_idx_( part ) - , step_( kind == NCIteratorKind::RANK_LOCAL - ? std::lcm( stride, kernel().mpi_manager.get_num_processes() ) - : ( kind == NCIteratorKind::THREAD_LOCAL ? std::lcm( stride, kernel().vp_manager.get_num_virtual_processes() ) - : stride ) ) + , step_( kind == NCIteratorKind::RANK_LOCAL ? std::lcm( stride, kernel::manager< MPIManager >.get_num_processes() ) + : ( kind == NCIteratorKind::THREAD_LOCAL ? std::lcm( stride, + kernel::manager< VPManager >.get_num_virtual_processes() ) + : stride ) ) , kind_( kind ) , rank_or_vp_( kind == NCIteratorKind::RANK_LOCAL - ? kernel().mpi_manager.get_rank() - : ( kind == NCIteratorKind::THREAD_LOCAL ? kernel().vp_manager.get_vp() : invalid_thread ) ) + ? kernel::manager< MPIManager >.get_rank() + : ( kind == NCIteratorKind::THREAD_LOCAL ? kernel::manager< VPManager >.get_vp() : invalid_thread ) ) , primitive_collection_( nullptr ) , composite_collection_( &collection ) { @@ -113,10 +113,10 @@ nc_const_iterator::nc_const_iterator( NodeCollectionPTR collection_ptr, // Allow <= for end iterator assert( ( part < collection.parts_.size() and offset <= collection.parts_[ part ].size() ) ); - FULL_LOGGING_ONLY( - kernel().write_to_dump( String::compose( "NCIT Comp ctor rk %1, thr %2, pix %3, eix %4, step %5, kind %6, rvp %7", - kernel().mpi_manager.get_rank(), - kernel().vp_manager.get_thread_id(), + FULL_LOGGING_ONLY( kernel::manager< KernelManager >.write_to_dump( + String::compose( "NCIT Comp ctor rk %1, thr %2, pix %3, eix %4, step %5, kind %6, rvp %7", + kernel::manager< MPIManager >.get_rank(), + kernel::manager< VPManager >.get_thread_id(), part_idx_, element_idx_, step_, @@ -225,20 +225,21 @@ nc_const_iterator::advance_local_iter_to_new_part_( size_t n ) { case NCIteratorKind::RANK_LOCAL: { - const size_t num_ranks = kernel().mpi_manager.get_num_processes(); - const size_t current_rank = kernel().mpi_manager.get_rank(); + const size_t num_ranks = kernel::manager< MPIManager >.get_num_processes(); + const size_t current_rank = kernel::manager< MPIManager >.get_rank(); std::tie( part_idx_, element_idx_ ) = composite_collection_->specific_local_begin_( num_ranks, current_rank, part_idx_, element_idx_, NodeCollectionComposite::gid_to_rank_ ); - FULL_LOGGING_ONLY( kernel().write_to_dump( - String::compose( "ACIL rk %1, pix %2, eix %3", kernel().mpi_manager.get_rank(), part_idx_, element_idx_ ) ); ) + FULL_LOGGING_ONLY( kernel::manager< KernelManager >.write_to_dump( String::compose( + "ACIL rk %1, pix %2, eix %3", kernel::manager< MPIManager >.get_rank(), part_idx_, element_idx_ ) ); ) break; } case NCIteratorKind::THREAD_LOCAL: { - const size_t num_vps = kernel().vp_manager.get_num_virtual_processes(); - const size_t current_vp = kernel().vp_manager.thread_to_vp( kernel().vp_manager.get_thread_id() ); + const size_t num_vps = kernel::manager< VPManager >.get_num_virtual_processes(); + const size_t current_vp = + kernel::manager< VPManager >.thread_to_vp( kernel::manager< VPManager >.get_thread_id() ); std::tie( part_idx_, element_idx_ ) = composite_collection_->specific_local_begin_( num_vps, current_vp, part_idx_, element_idx_, NodeCollectionComposite::gid_to_vp_ ); @@ -290,9 +291,9 @@ nc_const_iterator::operator*() const { if ( not composite_collection_->valid_idx_( part_idx_, element_idx_ ) ) { - FULL_LOGGING_ONLY( kernel().write_to_dump( + FULL_LOGGING_ONLY( kernel::manager< KernelManager >.write_to_dump( String::compose( "nci::op* comp err rk %1, lp %2, le %3, pix %4, eix %5, end_pix %6, end_eix %7", - kernel().mpi_manager.get_rank(), + kernel::manager< MPIManager >.get_rank(), composite_collection_->last_part_, composite_collection_->last_elem_, part_idx_, @@ -313,7 +314,7 @@ nc_const_iterator::operator*() const } NodeCollection::NodeCollection() - : fingerprint_( kernel().get_fingerprint() ) + : fingerprint_( kernel::manager< KernelManager >.get_fingerprint() ) { } @@ -402,7 +403,7 @@ NodeCollection::create_( const std::vector< size_t >& node_ids ) { size_t current_first = node_ids[ 0 ]; size_t current_last = current_first; - size_t current_model = kernel().modelrange_manager.get_model_id( node_ids[ 0 ] ); + size_t current_model = kernel::manager< ModelRangeManager >.get_model_id( node_ids[ 0 ] ); std::vector< NodeCollectionPrimitive > parts; @@ -415,7 +416,7 @@ NodeCollection::create_( const std::vector< size_t >& node_ids ) } old_node_id = *node_id; - const size_t next_model = kernel().modelrange_manager.get_model_id( *node_id ); + const size_t next_model = kernel::manager< ModelRangeManager >.get_model_id( *node_id ); if ( next_model == current_model and *node_id == ( current_last + 1 ) ) { @@ -448,7 +449,7 @@ NodeCollection::create_( const std::vector< size_t >& node_ids ) bool NodeCollection::valid() const { - return fingerprint_ == kernel().get_fingerprint(); + return fingerprint_ == kernel::manager< KernelManager >.get_fingerprint(); } void @@ -470,7 +471,7 @@ NodeCollectionPrimitive::NodeCollectionPrimitive( size_t first, , last_( last ) , model_id_( model_id ) , metadata_( meta ) - , nodes_have_no_proxies_( not kernel().model_manager.get_node_model( model_id_ )->has_proxies() ) + , nodes_have_no_proxies_( not kernel::manager< ModelManager >.get_node_model( model_id_ )->has_proxies() ) { assert( first_ <= last_ ); assert_consistent_model_ids_( model_id_ ); @@ -481,7 +482,7 @@ NodeCollectionPrimitive::NodeCollectionPrimitive( size_t first, size_t last, siz , last_( last ) , model_id_( model_id ) , metadata_( nullptr ) - , nodes_have_no_proxies_( not kernel().model_manager.get_node_model( model_id_ )->has_proxies() ) + , nodes_have_no_proxies_( not kernel::manager< ModelManager >.get_node_model( model_id_ )->has_proxies() ) { assert( first_ <= last_ ); } @@ -495,18 +496,18 @@ NodeCollectionPrimitive::NodeCollectionPrimitive( size_t first, size_t last ) assert( first_ <= last_ ); // find the model_id - const auto first_model_id = kernel().modelrange_manager.get_model_id( first ); + const auto first_model_id = kernel::manager< ModelRangeManager >.get_model_id( first ); const auto init_index = first + 1; for ( size_t node_id = init_index; node_id <= last; ++node_id ) { - const auto model_id = kernel().modelrange_manager.get_model_id( node_id ); + const auto model_id = kernel::manager< ModelRangeManager >.get_model_id( node_id ); if ( model_id != first_model_id ) { throw BadProperty( "model ids does not match" ); } } model_id_ = first_model_id; - nodes_have_no_proxies_ = not kernel().model_manager.get_node_model( model_id_ )->has_proxies(); + nodes_have_no_proxies_ = not kernel::manager< ModelManager >.get_node_model( model_id_ )->has_proxies(); } NodeCollectionPrimitive::NodeCollectionPrimitive() @@ -534,7 +535,7 @@ NodeCollection::to_array( const std::string& selection ) const // We need to defined zero explicitly here, otherwise push_back() does strange things const size_t zero = 0; node_ids.push_back( zero ); - node_ids.push_back( kernel().vp_manager.get_thread_id() ); + node_ids.push_back( kernel::manager< VPManager >.get_thread_id() ); node_ids.push_back( zero ); const auto end_it = end(); @@ -647,10 +648,10 @@ NodeCollectionPrimitive::operator+( NodeCollectionPTR rhs ) const NodeCollection::const_iterator NodeCollectionPrimitive::rank_local_begin( NodeCollectionPTR cp ) const { - const size_t num_processes = kernel().mpi_manager.get_num_processes(); - const size_t rank = kernel().mpi_manager.get_rank(); + const size_t num_processes = kernel::manager< MPIManager >.get_num_processes(); + const size_t rank = kernel::manager< MPIManager >.get_rank(); const size_t first_elem_rank = - kernel().mpi_manager.get_process_id_of_vp( kernel().vp_manager.node_id_to_vp( first_ ) ); + kernel::manager< MPIManager >.get_process_id_of_vp( kernel::manager< VPManager >.node_id_to_vp( first_ ) ); const size_t elem_idx = ( rank - first_elem_rank + num_processes ) % num_processes; if ( elem_idx > size() ) // Too few node IDs to be shared among all MPI processes. @@ -666,9 +667,9 @@ NodeCollectionPrimitive::rank_local_begin( NodeCollectionPTR cp ) const NodeCollection::const_iterator NodeCollectionPrimitive::thread_local_begin( NodeCollectionPTR cp ) const { - const size_t num_vps = kernel().vp_manager.get_num_virtual_processes(); - const size_t current_vp = kernel().vp_manager.thread_to_vp( kernel().vp_manager.get_thread_id() ); - const size_t vp_first_node = kernel().vp_manager.node_id_to_vp( first_ ); + const size_t num_vps = kernel::manager< VPManager >.get_num_virtual_processes(); + const size_t current_vp = kernel::manager< VPManager >.thread_to_vp( kernel::manager< VPManager >.get_thread_id() ); + const size_t vp_first_node = kernel::manager< VPManager >.node_id_to_vp( first_ ); const size_t offset = ( current_vp - vp_first_node + num_vps ) % num_vps; if ( offset >= size() ) // Too few node IDs to be shared among all vps. @@ -735,7 +736,7 @@ void NodeCollectionPrimitive::print_primitive( std::ostream& out ) const { const std::string model = - model_id_ != invalid_index ? kernel().model_manager.get_node_model( model_id_ )->get_name() : "none"; + model_id_ != invalid_index ? kernel::manager< ModelManager >.get_node_model( model_id_ )->get_name() : "none"; out << "model=" << model << ", size=" << size(); @@ -766,11 +767,12 @@ NodeCollectionPrimitive::assert_consistent_model_ids_( const size_t expected_mod { for ( size_t node_id = first_; node_id <= last_; ++node_id ) { - const auto model_id = kernel().modelrange_manager.get_model_id( node_id ); + const auto model_id = kernel::manager< ModelRangeManager >.get_model_id( node_id ); if ( model_id != expected_model_id ) { - const auto node_model = kernel().modelrange_manager.get_model_of_node_id( model_id )->get_name(); - const auto expected_model = kernel().modelrange_manager.get_model_of_node_id( expected_model_id )->get_name(); + const auto node_model = kernel::manager< ModelRangeManager >.get_model_of_node_id( model_id )->get_name(); + const auto expected_model = + kernel::manager< ModelRangeManager >.get_model_of_node_id( expected_model_id )->get_name(); const auto message = "All nodes must have the same model (node with ID " + std::to_string( node_id ) + " has model " + node_model + ", expected " + expected_model + ")"; throw BadProperty( message ); @@ -1131,11 +1133,11 @@ NodeCollectionComposite::specific_local_begin_( size_t period, elem_idx += first_elem; } - FULL_LOGGING_ONLY( - kernel().write_to_dump( String::compose( "SPLB rk %1, thr %2, phase_first %3, offs %4, stp %5, sto %6," - " pix %7, lp %8, le %9, primsz %10, nprts: %11, this: %12", - kernel().mpi_manager.get_rank(), - kernel().vp_manager.get_thread_id(), + FULL_LOGGING_ONLY( kernel::manager< KernelManager >.write_to_dump( + String::compose( "SPLB rk %1, thr %2, phase_first %3, offs %4, stp %5, sto %6," + " pix %7, lp %8, le %9, primsz %10, nprts: %11, this: %12", + kernel::manager< MPIManager >.get_rank(), + kernel::manager< VPManager >.get_thread_id(), phase_first_node, offset, first_part, @@ -1179,20 +1181,20 @@ NodeCollectionComposite::specific_local_begin_( size_t period, size_t NodeCollectionComposite::gid_to_vp_( size_t gid ) { - return kernel().vp_manager.node_id_to_vp( gid ); + return kernel::manager< VPManager >.node_id_to_vp( gid ); } size_t NodeCollectionComposite::gid_to_rank_( size_t gid ) { - return kernel().mpi_manager.get_process_id_of_vp( kernel().vp_manager.node_id_to_vp( gid ) ); + return kernel::manager< MPIManager >.get_process_id_of_vp( kernel::manager< VPManager >.node_id_to_vp( gid ) ); } NodeCollection::const_iterator NodeCollectionComposite::rank_local_begin( NodeCollectionPTR cp ) const { - const size_t num_ranks = kernel().mpi_manager.get_num_processes(); - const size_t current_rank = kernel().mpi_manager.get_rank(); + const size_t num_ranks = kernel::manager< MPIManager >.get_num_processes(); + const size_t current_rank = kernel::manager< MPIManager >.get_rank(); const auto [ part_index, part_offset ] = specific_local_begin_( num_ranks, current_rank, first_part_, first_elem_, gid_to_rank_ ); @@ -1214,8 +1216,8 @@ NodeCollectionComposite::rank_local_begin( NodeCollectionPTR cp ) const NodeCollection::const_iterator NodeCollectionComposite::thread_local_begin( NodeCollectionPTR cp ) const { - const size_t num_vps = kernel().vp_manager.get_num_virtual_processes(); - const size_t current_vp = kernel().vp_manager.thread_to_vp( kernel().vp_manager.get_thread_id() ); + const size_t num_vps = kernel::manager< VPManager >.get_num_virtual_processes(); + const size_t current_vp = kernel::manager< VPManager >.thread_to_vp( kernel::manager< VPManager >.get_thread_id() ); const auto [ part_index, part_offset ] = specific_local_begin_( num_vps, current_vp, first_part_, first_elem_, gid_to_vp_ ); @@ -1252,9 +1254,9 @@ NodeCollectionComposite::slice( size_t start, size_t end, size_t stride ) const "InvalidNodeCollection: note that ResetKernel invalidates all previously created NodeCollections." ); } - FULL_LOGGING_ONLY( kernel().write_to_dump( "Calling NCC from slice()" ); ) + FULL_LOGGING_ONLY( kernel::manager< KernelManager >.write_to_dump( "Calling NCC from slice()" ); ) const auto new_composite = NodeCollectionComposite( *this, start, end, stride ); - FULL_LOGGING_ONLY( kernel().write_to_dump( "Calling NCC from slice() --- DONE" ); ) + FULL_LOGGING_ONLY( kernel::manager< KernelManager >.write_to_dump( "Calling NCC from slice() --- DONE" ); ) if ( stride == 1 and new_composite.first_part_ == new_composite.last_part_ ) { @@ -1263,8 +1265,8 @@ NodeCollectionComposite::slice( size_t start, size_t end, size_t stride ) const new_composite.first_elem_, new_composite.last_elem_ + 1 ); } - FULL_LOGGING_ONLY( - kernel().write_to_dump( String::compose( "NewComposite: fp %1, fe %2, lp %3, le %4, sz %5, strd %6", + FULL_LOGGING_ONLY( kernel::manager< KernelManager >.write_to_dump( + String::compose( "NewComposite: fp %1, fe %2, lp %3, le %4, sz %5, strd %6", new_composite.first_part_, new_composite.first_elem_, new_composite.last_part_, @@ -1416,7 +1418,7 @@ NodeCollectionComposite::print_me( std::ostream& out ) const { // Need to count the primitive, so can't start at begin() out << "\n" + space - << "model=" << kernel().model_manager.get_node_model( first_in_primitive.model_id )->get_name() + << "model=" << kernel::manager< ModelManager >.get_node_model( first_in_primitive.model_id )->get_name() << ", size=" << primitive_size << ", "; if ( primitive_size == 1 ) { @@ -1444,7 +1446,8 @@ NodeCollectionComposite::print_me( std::ostream& out ) const } // Need to also print the last primitive - out << "\n" + space << "model=" << kernel().model_manager.get_node_model( first_in_primitive.model_id )->get_name() + out << "\n" + space + << "model=" << kernel::manager< ModelManager >.get_node_model( first_in_primitive.model_id )->get_name() << ", size=" << primitive_size << ", "; if ( primitive_size == 1 ) { @@ -1482,4 +1485,359 @@ NodeCollectionComposite::print_me( std::ostream& out ) const out << ")"; } +bool +NodeCollectionComposite::valid_idx_( const size_t part_idx, const size_t element_idx ) const +{ + + return part_idx < last_part_ or ( part_idx == last_part_ and element_idx <= last_elem_ ); +} + +bool +NodeCollectionComposite::contains( const size_t node_id ) const +{ + + return get_nc_index( node_id ) != -1; +} + +bool +NodeCollectionComposite::empty() const +{ + + // Composite NodeCollections can never be empty. + return false; +} + +bool +NodeCollectionComposite::is_range() const +{ + + return false; +} + +NodeCollectionMetadataPTR +NodeCollectionComposite::get_metadata() const +{ + + return parts_[ 0 ].get_metadata(); +} + +void +NodeCollectionComposite::set_metadata( NodeCollectionMetadataPTR meta ) +{ + + for ( auto& part : parts_ ) + { + part.set_metadata( meta ); + } +} + +size_t +NodeCollectionComposite::stride() const +{ + + return stride_; +} + +size_t +NodeCollectionComposite::size() const +{ + + return size_; +} + +NodeCollection::const_iterator +NodeCollectionComposite::end( NodeCollectionPTR cp ) const +{ + + // The unique end() element of a composite NC is given by one past the last element + // This is the (potentially non-existing) next element irrespective of stride and step + return nc_const_iterator( + cp, *this, last_part_, last_elem_ + 1, /* stride */ 1, nc_const_iterator::NCIteratorKind::END ); +} + +NodeCollection::const_iterator +NodeCollectionComposite::begin( NodeCollectionPTR cp ) const +{ + + return nc_const_iterator( cp, *this, first_part_, first_elem_, stride_ ); +} + +bool +NodeCollectionPrimitive::has_proxies() const +{ + + return not nodes_have_no_proxies_; +} + +long +NodeCollectionPrimitive::get_nc_index( const size_t neuron_id ) const +{ + + if ( neuron_id < first_ or last_ < neuron_id ) + { + return -1; + } + else + { + return neuron_id - first_; + } +} + +bool +NodeCollectionPrimitive::empty() const +{ + + return last_ == 0; +} + +bool +NodeCollectionPrimitive::is_range() const +{ + + return true; +} + +NodeCollectionMetadataPTR +NodeCollectionPrimitive::get_metadata() const +{ + + return metadata_; +} + +void +NodeCollectionPrimitive::set_metadata( NodeCollectionMetadataPTR meta ) +{ + + metadata_ = meta; +} + +bool +NodeCollectionPrimitive::contains( const size_t node_id ) const +{ + + return first_ <= node_id and node_id <= last_; +} + +size_t +NodeCollectionPrimitive::stride() const +{ + + return 1; +} + +size_t +NodeCollectionPrimitive::size() const +{ + + // empty NC has first_ == last_ == 0, need to handle that special + return std::min( last_, last_ - first_ + 1 ); +} + +NodeCollection::const_iterator +NodeCollectionPrimitive::end( NodeCollectionPTR cp ) const +{ + + // The unique end() element of a primitive NC is given by (part 0, element size()) ) + return nc_const_iterator( cp, *this, /* offset */ size(), /* stride */ 1, nc_const_iterator::NCIteratorKind::END ); +} + +NodeCollection::const_iterator +NodeCollectionPrimitive::begin( NodeCollectionPTR cp ) const +{ + + return nc_const_iterator( cp, *this, /* offset */ 0, /* stride */ 1 ); +} + +bool +NodeCollectionPrimitive::operator==( const NodeCollectionPrimitive& rhs ) const +{ + + // Not dereferencing rhs_ptr->metadata_ in the equality comparison because we want to avoid overloading + // operator==() of *metadata_, and to let it handle typechecking. + const bool eq_metadata = + ( not metadata_ and not rhs.metadata_ ) or ( metadata_ and rhs.metadata_ and *metadata_ == rhs.metadata_ ); + + return first_ == rhs.first_ and last_ == rhs.last_ and model_id_ == rhs.model_id_ and eq_metadata; +} + +bool +NodeCollectionPrimitive::operator==( NodeCollectionPTR rhs ) const +{ + + auto const* const rhs_ptr = dynamic_cast< NodeCollectionPrimitive const* >( rhs.get() ); + // Checking that rhs_ptr is valid first, to avoid segfaults. If rhs is a NodeCollectionComposite, + // rhs_ptr will be a null pointer. + if ( not rhs_ptr ) + { + return false; + } + + // We know we have a primitive collection, so forward + return *this == *rhs_ptr; +} + +size_t +NodeCollectionPrimitive::operator[]( const size_t idx ) const +{ + + // throw exception if outside of NodeCollection + if ( first_ + idx > last_ ) + { + throw std::out_of_range( String::compose( "pos %1 points outside of the NodeCollection", idx ) ); + } + return first_ + idx; +} + +size_t +nc_const_iterator::get_step_size() const +{ + + return step_; +} + +std::pair< size_t, size_t > +nc_const_iterator::get_part_offset() const +{ + + return { part_idx_, element_idx_ }; +} + +bool +nc_const_iterator::operator>=( const nc_const_iterator& rhs ) const +{ + + return not( *this < rhs ); +} + +bool +nc_const_iterator::operator>( const nc_const_iterator& rhs ) const +{ + + return not( *this <= rhs ); +} + +bool +nc_const_iterator::operator<=( const nc_const_iterator& rhs ) const +{ + + return ( *this < rhs or *this == rhs ); +} + +bool +nc_const_iterator::operator<( const nc_const_iterator& rhs ) const +{ + + return ( part_idx_ < rhs.part_idx_ or ( part_idx_ == rhs.part_idx_ and element_idx_ < rhs.element_idx_ ) ); +} + +bool +nc_const_iterator::operator!=( const nc_const_iterator& rhs ) const +{ + + return not( *this == rhs ); +} + +bool +nc_const_iterator::operator==( const nc_const_iterator& rhs ) const +{ + + return part_idx_ == rhs.part_idx_ and element_idx_ == rhs.element_idx_; +} + +nc_const_iterator +nc_const_iterator::operator++( int ) +{ + + nc_const_iterator tmp = *this; + ++( *this ); + return tmp; +} + +nc_const_iterator& +nc_const_iterator::operator++() +{ + + ( *this ) += 1; + return *this; +} + +nc_const_iterator +nc_const_iterator::operator+( const size_t n ) const +{ + + nc_const_iterator it = *this; + return it += n; +} + +nc_const_iterator& +nc_const_iterator::operator+=( const size_t n ) +{ + + assert( kind_ != NCIteratorKind::END ); + + if ( n == 0 ) + { + return *this; + } + + const auto new_element_idx = find_next_within_part_( n ); + + // For a primitive collection, we either have a new element or are at the end + // For a composite collection, we may need to search through further parts, + // which is signalled by new_element_idx == element_idx_ + if ( primitive_collection_ or new_element_idx != element_idx_ ) + { + element_idx_ = new_element_idx; + } + else + { + // We did not find a new element in the current part and have not exhausted the collection + if ( kind_ == NCIteratorKind::GLOBAL ) + { + advance_global_iter_to_new_part_( n ); + } + else + { + advance_local_iter_to_new_part_( n ); + } + } + + return *this; +} + +size_t +NodeCollection::get_last() const +{ + + assert( size() > 0 ); + return ( *( begin() + ( size() - 1 ) ) ).node_id; +} + +size_t +NodeCollection::get_first() const +{ + + return ( *begin() ).node_id; +} + +void +NodeCollection::set_metadata( NodeCollectionMetadataPTR ) +{ + + throw KernelException( "Cannot set Metadata on this type of NodeCollection." ); +} + +bool +NodeCollection::operator!=( NodeCollectionPTR rhs ) const +{ + + return not( *this == rhs ); +} + +NodeCollectionPTR +operator+( NodeCollectionPTR lhs, NodeCollectionPTR rhs ) +{ + return lhs->operator+( rhs ); +} + } // namespace nest diff --git a/nestkernel/node_collection.h b/nestkernel/node_collection.h index 0b127e574d..f0b98e6e4d 100644 --- a/nestkernel/node_collection.h +++ b/nestkernel/node_collection.h @@ -1125,321 +1125,6 @@ class NodeCollectionComposite : public NodeCollection bool has_proxies() const override; }; -inline bool -NodeCollection::operator!=( NodeCollectionPTR rhs ) const -{ - return not( *this == rhs ); -} - -inline void -NodeCollection::set_metadata( NodeCollectionMetadataPTR ) -{ - throw KernelException( "Cannot set Metadata on this type of NodeCollection." ); -} - -inline size_t -NodeCollection::get_first() const -{ - return ( *begin() ).node_id; -} - -inline size_t -NodeCollection::get_last() const -{ - assert( size() > 0 ); - return ( *( begin() + ( size() - 1 ) ) ).node_id; -} - -inline nc_const_iterator& -nc_const_iterator::operator+=( const size_t n ) -{ - assert( kind_ != NCIteratorKind::END ); - - if ( n == 0 ) - { - return *this; - } - - const auto new_element_idx = find_next_within_part_( n ); - - // For a primitive collection, we either have a new element or are at the end - // For a composite collection, we may need to search through further parts, - // which is signalled by new_element_idx == element_idx_ - if ( primitive_collection_ or new_element_idx != element_idx_ ) - { - element_idx_ = new_element_idx; - } - else - { - // We did not find a new element in the current part and have not exhausted the collection - if ( kind_ == NCIteratorKind::GLOBAL ) - { - advance_global_iter_to_new_part_( n ); - } - else - { - advance_local_iter_to_new_part_( n ); - } - } - - return *this; -} - -inline nc_const_iterator -nc_const_iterator::operator+( const size_t n ) const -{ - nc_const_iterator it = *this; - return it += n; -} - -inline nc_const_iterator& -nc_const_iterator::operator++() -{ - ( *this ) += 1; - return *this; -} - -inline nc_const_iterator -nc_const_iterator::operator++( int ) -{ - nc_const_iterator tmp = *this; - ++( *this ); - return tmp; -} - -inline bool -nc_const_iterator::operator==( const nc_const_iterator& rhs ) const -{ - return part_idx_ == rhs.part_idx_ and element_idx_ == rhs.element_idx_; -} - -inline bool -nc_const_iterator::operator!=( const nc_const_iterator& rhs ) const -{ - return not( *this == rhs ); -} - -inline bool -nc_const_iterator::operator<( const nc_const_iterator& rhs ) const -{ - return ( part_idx_ < rhs.part_idx_ or ( part_idx_ == rhs.part_idx_ and element_idx_ < rhs.element_idx_ ) ); -} - -inline bool -nc_const_iterator::operator<=( const nc_const_iterator& rhs ) const -{ - return ( *this < rhs or *this == rhs ); -} - -inline bool -nc_const_iterator::operator>( const nc_const_iterator& rhs ) const -{ - return not( *this <= rhs ); -} - -inline bool -nc_const_iterator::operator>=( const nc_const_iterator& rhs ) const -{ - return not( *this < rhs ); -} - -inline std::pair< size_t, size_t > -nc_const_iterator::get_part_offset() const -{ - return { part_idx_, element_idx_ }; -} - -inline size_t -nc_const_iterator::get_step_size() const -{ - return step_; -} - -inline NodeCollectionPTR -operator+( NodeCollectionPTR lhs, NodeCollectionPTR rhs ) -{ - return lhs->operator+( rhs ); -} - -inline size_t -NodeCollectionPrimitive::operator[]( const size_t idx ) const -{ - // throw exception if outside of NodeCollection - if ( first_ + idx > last_ ) - { - throw std::out_of_range( String::compose( "pos %1 points outside of the NodeCollection", idx ) ); - } - return first_ + idx; -} - -inline bool -NodeCollectionPrimitive::operator==( NodeCollectionPTR rhs ) const -{ - auto const* const rhs_ptr = dynamic_cast< NodeCollectionPrimitive const* >( rhs.get() ); - // Checking that rhs_ptr is valid first, to avoid segfaults. If rhs is a NodeCollectionComposite, - // rhs_ptr will be a null pointer. - if ( not rhs_ptr ) - { - return false; - } - - // We know we have a primitive collection, so forward - return *this == *rhs_ptr; -} - -inline bool -NodeCollectionPrimitive::operator==( const NodeCollectionPrimitive& rhs ) const -{ - // Not dereferencing rhs_ptr->metadata_ in the equality comparison because we want to avoid overloading - // operator==() of *metadata_, and to let it handle typechecking. - const bool eq_metadata = - ( not metadata_ and not rhs.metadata_ ) or ( metadata_ and rhs.metadata_ and *metadata_ == rhs.metadata_ ); - - return first_ == rhs.first_ and last_ == rhs.last_ and model_id_ == rhs.model_id_ and eq_metadata; -} - -inline NodeCollection::const_iterator -NodeCollectionPrimitive::begin( NodeCollectionPTR cp ) const -{ - return nc_const_iterator( cp, *this, /* offset */ 0, /* stride */ 1 ); -} - -inline NodeCollection::const_iterator -NodeCollectionPrimitive::end( NodeCollectionPTR cp ) const -{ - // The unique end() element of a primitive NC is given by (part 0, element size()) ) - return nc_const_iterator( cp, *this, /* offset */ size(), /* stride */ 1, nc_const_iterator::NCIteratorKind::END ); -} - -inline size_t -NodeCollectionPrimitive::size() const -{ - // empty NC has first_ == last_ == 0, need to handle that special - return std::min( last_, last_ - first_ + 1 ); -} - -inline size_t -NodeCollectionPrimitive::stride() const -{ - return 1; -} - -inline bool -NodeCollectionPrimitive::contains( const size_t node_id ) const -{ - return first_ <= node_id and node_id <= last_; -} - -inline void -NodeCollectionPrimitive::set_metadata( NodeCollectionMetadataPTR meta ) -{ - metadata_ = meta; -} - -inline NodeCollectionMetadataPTR -NodeCollectionPrimitive::get_metadata() const -{ - return metadata_; -} - -inline bool -NodeCollectionPrimitive::is_range() const -{ - return true; -} - -inline bool -NodeCollectionPrimitive::empty() const -{ - return last_ == 0; -} - -inline long -NodeCollectionPrimitive::get_nc_index( const size_t neuron_id ) const -{ - if ( neuron_id < first_ or last_ < neuron_id ) - { - return -1; - } - else - { - return neuron_id - first_; - } -} - -inline bool -NodeCollectionPrimitive::has_proxies() const -{ - return not nodes_have_no_proxies_; -} - -inline NodeCollection::const_iterator -NodeCollectionComposite::begin( NodeCollectionPTR cp ) const -{ - return nc_const_iterator( cp, *this, first_part_, first_elem_, stride_ ); -} - -inline NodeCollection::const_iterator -NodeCollectionComposite::end( NodeCollectionPTR cp ) const -{ - // The unique end() element of a composite NC is given by one past the last element - // This is the (potentially non-existing) next element irrespective of stride and step - return nc_const_iterator( - cp, *this, last_part_, last_elem_ + 1, /* stride */ 1, nc_const_iterator::NCIteratorKind::END ); -} - -inline size_t -NodeCollectionComposite::size() const -{ - return size_; -} - -inline size_t -NodeCollectionComposite::stride() const -{ - return stride_; -} - -inline void -NodeCollectionComposite::set_metadata( NodeCollectionMetadataPTR meta ) -{ - for ( auto& part : parts_ ) - { - part.set_metadata( meta ); - } -} - -inline NodeCollectionMetadataPTR -NodeCollectionComposite::get_metadata() const -{ - return parts_[ 0 ].get_metadata(); -} - -inline bool -NodeCollectionComposite::is_range() const -{ - return false; -} - -inline bool -NodeCollectionComposite::empty() const -{ - // Composite NodeCollections can never be empty. - return false; -} - -inline bool -NodeCollectionComposite::contains( const size_t node_id ) const -{ - return get_nc_index( node_id ) != -1; -} - -inline bool -NodeCollectionComposite::valid_idx_( const size_t part_idx, const size_t element_idx ) const -{ - return part_idx < last_part_ or ( part_idx == last_part_ and element_idx <= last_elem_ ); -} - } // namespace nest #endif /* #ifndef NODE_COLLECTION_H */ diff --git a/nestkernel/node_manager.cpp b/nestkernel/node_manager.cpp index 03a637494f..bfca02e78f 100644 --- a/nestkernel/node_manager.cpp +++ b/nestkernel/node_manager.cpp @@ -31,18 +31,21 @@ #include "logging.h" // Includes from nestkernel: +#include "connection_manager.h" +#include "event_delivery_manager.h" #include "kernel_manager.h" +#include "logging_manager.h" #include "model.h" -#include "model_manager_impl.h" +#include "model_manager.h" +#include "modelrange_manager.h" #include "node.h" -#include "secondary_event_impl.h" -#include "stopwatch_impl.h" #include "vp_manager.h" -#include "vp_manager_impl.h" // Includes from sli: #include "dictutils.h" +#include "simulation_manager.h" + namespace nest { @@ -71,8 +74,8 @@ NodeManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { // explicitly force construction of thread-local node data to ensure consistent state size_last_local_data_update_ = 0; - local_nodes_.resize( kernel().vp_manager.get_num_threads() ); - num_thread_local_devices_.resize( kernel().vp_manager.get_num_threads(), 0 ); + local_nodes_.resize( kernel::manager< VPManager >.get_num_threads() ); + num_thread_local_devices_.resize( kernel::manager< VPManager >.get_num_threads(), 0 ); update_thread_local_node_data(); if ( not adjust_number_of_threads_or_rng_only ) @@ -112,7 +115,7 @@ NodeManager::add_node( size_t model_id, long n ) throw BadProperty(); } - Model* model = kernel().model_manager.get_node_model( model_id ); + Model* model = kernel::manager< ModelManager >.get_node_model( model_id ); assert( model ); model->deprecation_warning( "Create" ); @@ -127,10 +130,10 @@ NodeManager::add_node( size_t model_id, long n ) throw KernelException( "OutOfMemory" ); } - kernel().modelrange_manager.add_range( model_id, min_node_id, max_node_id ); + kernel::manager< ModelRangeManager >.add_range( model_id, min_node_id, max_node_id ); // clear any exceptions from previous call - std::vector< std::shared_ptr< WrappedThreadException > >( kernel().vp_manager.get_num_threads() ) + std::vector< std::shared_ptr< WrappedThreadException > >( kernel::manager< VPManager >.get_num_threads() ) .swap( exceptions_raised_ ); auto nc_ptr = NodeCollectionPTR( new NodeCollectionPrimitive( min_node_id, max_node_id, model_id ) ); @@ -150,7 +153,7 @@ NodeManager::add_node( size_t model_id, long n ) } // check if any exceptions have been raised - for ( size_t t = 0; t < kernel().vp_manager.get_num_threads(); ++t ) + for ( size_t t = 0; t < kernel::manager< VPManager >.get_num_threads(); ++t ) { if ( exceptions_raised_.at( t ).get() ) { @@ -162,7 +165,7 @@ NodeManager::add_node( size_t model_id, long n ) // successfully if ( model->is_off_grid() ) { - kernel().event_delivery_manager.set_off_grid_communication( true ); + kernel::manager< EventDeliveryManager >.set_off_grid_communication( true ); LOG( M_INFO, "NodeManager::add_node", "Neuron models emitting precisely timed spikes exist: " @@ -173,12 +176,12 @@ NodeManager::add_node( size_t model_id, long n ) // resize the target table for delivery of events to devices to make sure the first dimension // matches the number of local nodes and the second dimension matches number of synapse types - kernel().connection_manager.resize_target_table_devices_to_number_of_neurons(); + kernel::manager< ConnectionManager >.resize_target_table_devices_to_number_of_neurons(); #pragma omp parallel { // must be called in parallel context to properly configure per-thread data structures - kernel().connection_manager.resize_target_table_devices_to_number_of_synapse_types(); + kernel::manager< ConnectionManager >.resize_target_table_devices_to_number_of_synapse_types(); } sw_construction_create_.stop(); @@ -189,7 +192,7 @@ NodeManager::add_node( size_t model_id, long n ) void NodeManager::add_neurons_( Model& model, size_t min_node_id, size_t max_node_id ) { - const size_t num_vps = kernel().vp_manager.get_num_virtual_processes(); + const size_t num_vps = kernel::manager< VPManager >.get_num_virtual_processes(); // Upper limit for number of neurons per thread; in practice, either // max_new_per_thread-1 or max_new_per_thread nodes will be created. const size_t max_new_per_thread = @@ -197,7 +200,7 @@ NodeManager::add_neurons_( Model& model, size_t min_node_id, size_t max_node_id #pragma omp parallel { - const size_t t = kernel().vp_manager.get_thread_id(); + const size_t t = kernel::manager< VPManager >.get_thread_id(); try { @@ -205,8 +208,8 @@ NodeManager::add_neurons_( Model& model, size_t min_node_id, size_t max_node_id // Need to find smallest node ID with: // - node ID local to this vp // - node_id >= min_node_id - const size_t vp = kernel().vp_manager.thread_to_vp( t ); - const size_t min_node_id_vp = kernel().vp_manager.node_id_to_vp( min_node_id ); + const size_t vp = kernel::manager< VPManager >.thread_to_vp( t ); + const size_t min_node_id_vp = kernel::manager< VPManager >.node_id_to_vp( min_node_id ); size_t node_id = min_node_id + ( num_vps + vp - min_node_id_vp ) % num_vps; @@ -240,7 +243,7 @@ NodeManager::add_devices_( Model& model, size_t min_node_id, size_t max_node_id #pragma omp parallel { - const size_t t = kernel().vp_manager.get_thread_id(); + const size_t t = kernel::manager< VPManager >.get_thread_id(); try { model.reserve_additional( t, n_per_thread ); @@ -254,7 +257,7 @@ NodeManager::add_devices_( Model& model, size_t min_node_id, size_t max_node_id node->set_node_id_( node_id ); node->set_model_id( model.get_model_id() ); node->set_thread( t ); - node->set_vp( kernel().vp_manager.thread_to_vp( t ) ); + node->set_vp( kernel::manager< VPManager >.thread_to_vp( t ) ); node->set_local_device_id( num_thread_local_devices_[ t ] - 1 ); node->set_initialized(); @@ -276,7 +279,7 @@ NodeManager::add_music_nodes_( Model& model, size_t min_node_id, size_t max_node { #pragma omp parallel { - const size_t t = kernel().vp_manager.get_thread_id(); + const size_t t = kernel::manager< VPManager >.get_thread_id(); try { if ( t == 0 ) @@ -290,7 +293,7 @@ NodeManager::add_music_nodes_( Model& model, size_t min_node_id, size_t max_node node->set_node_id_( node_id ); node->set_model_id( model.get_model_id() ); node->set_thread( 0 ); - node->set_vp( kernel().vp_manager.thread_to_vp( 0 ) ); + node->set_vp( kernel::manager< VPManager >.thread_to_vp( 0 ) ); node->set_local_device_id( num_thread_local_devices_[ t ] - 1 ); node->set_initialized(); @@ -347,10 +350,10 @@ NodeManager::get_nodes( const DictionaryDatum& params, const bool local_only ) if ( params->empty() ) { std::vector< std::vector< long > > nodes_on_thread; - nodes_on_thread.resize( kernel().vp_manager.get_num_threads() ); + nodes_on_thread.resize( kernel::manager< VPManager >.get_num_threads() ); #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); for ( auto node : get_local_nodes( tid ) ) { @@ -367,7 +370,7 @@ NodeManager::get_nodes( const DictionaryDatum& params, const bool local_only ) } else { - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { // Select those nodes fulfilling the key/value pairs of the dictionary for ( auto node : get_local_nodes( tid ) ) @@ -405,7 +408,7 @@ NodeManager::get_nodes( const DictionaryDatum& params, const bool local_only ) if ( not local_only ) { std::vector< long > globalnodes; - kernel().mpi_manager.communicate( nodes, globalnodes ); + kernel::manager< MPIManager >.communicate( nodes, globalnodes ); for ( size_t i = 0; i < globalnodes.size(); ++i ) { @@ -431,21 +434,21 @@ NodeManager::get_nodes( const DictionaryDatum& params, const bool local_only ) bool NodeManager::is_local_node( Node* n ) const { - return kernel().vp_manager.is_local_vp( n->get_vp() ); + return kernel::manager< VPManager >.is_local_vp( n->get_vp() ); } bool NodeManager::is_local_node_id( size_t node_id ) const { - const size_t vp = kernel().vp_manager.node_id_to_vp( node_id ); - return kernel().vp_manager.is_local_vp( vp ); + const size_t vp = kernel::manager< VPManager >.node_id_to_vp( node_id ); + return kernel::manager< VPManager >.is_local_vp( vp ); } size_t NodeManager::get_max_num_local_nodes() const { return static_cast< size_t >( - ceil( static_cast< double >( size() ) / kernel().vp_manager.get_num_virtual_processes() ) ); + ceil( static_cast< double >( size() ) / kernel::manager< VPManager >.get_num_virtual_processes() ) ); } size_t @@ -457,13 +460,13 @@ NodeManager::get_num_thread_local_devices( size_t t ) const Node* NodeManager::get_node_or_proxy( size_t node_id, size_t t ) { - assert( t < kernel().vp_manager.get_num_threads() ); + assert( t < kernel::manager< VPManager >.get_num_threads() ); assert( node_id <= size() ); Node* node = local_nodes_[ t ].get_node_by_node_id( node_id ); if ( not node ) { - return kernel().model_manager.get_proxy_node( t, node_id ); + return kernel::manager< ModelManager >.get_proxy_node( t, node_id ); } return node; @@ -474,17 +477,17 @@ NodeManager::get_node_or_proxy( size_t node_id ) { assert( 0 < node_id and node_id <= size() ); - size_t vp = kernel().vp_manager.node_id_to_vp( node_id ); - if ( not kernel().vp_manager.is_local_vp( vp ) ) + size_t vp = kernel::manager< VPManager >.node_id_to_vp( node_id ); + if ( not kernel::manager< VPManager >.is_local_vp( vp ) ) { - return kernel().model_manager.get_proxy_node( 0, node_id ); + return kernel::manager< ModelManager >.get_proxy_node( 0, node_id ); } - size_t t = kernel().vp_manager.vp_to_thread( vp ); + size_t t = kernel::manager< VPManager >.vp_to_thread( vp ); Node* node = local_nodes_[ t ].get_node_by_node_id( node_id ); if ( not node ) { - return kernel().model_manager.get_proxy_node( t, node_id ); + return kernel::manager< ModelManager >.get_proxy_node( t, node_id ); } return node; @@ -493,13 +496,13 @@ NodeManager::get_node_or_proxy( size_t node_id ) Node* NodeManager::get_mpi_local_node_or_device_head( size_t node_id ) { - size_t t = kernel().vp_manager.vp_to_thread( kernel().vp_manager.node_id_to_vp( node_id ) ); + size_t t = kernel::manager< VPManager >.vp_to_thread( kernel::manager< VPManager >.node_id_to_vp( node_id ) ); Node* node = local_nodes_[ t ].get_node_by_node_id( node_id ); if ( not node ) { - return kernel().model_manager.get_proxy_node( t, node_id ); + return kernel::manager< ModelManager >.get_proxy_node( t, node_id ); } if ( not node->has_proxies() ) { @@ -512,7 +515,7 @@ NodeManager::get_mpi_local_node_or_device_head( size_t node_id ) std::vector< Node* > NodeManager::get_thread_siblings( size_t node_id ) const { - size_t num_threads = kernel().vp_manager.get_num_threads(); + size_t num_threads = kernel::manager< VPManager >.get_num_threads(); std::vector< Node* > siblings( num_threads ); for ( size_t t = 0; t < num_threads; ++t ) { @@ -531,7 +534,7 @@ NodeManager::get_thread_siblings( size_t node_id ) const void NodeManager::update_thread_local_node_data() { - kernel().vp_manager.assert_single_threaded(); + kernel::manager< VPManager >.assert_single_threaded(); if ( thread_local_data_is_up_to_date() ) { @@ -540,9 +543,9 @@ NodeManager::update_thread_local_node_data() // We clear the existing wfr_nodes_vec_ and then rebuild it. wfr_nodes_vec_.clear(); - wfr_nodes_vec_.resize( kernel().vp_manager.get_num_threads() ); + wfr_nodes_vec_.resize( kernel::manager< VPManager >.get_num_threads() ); - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { wfr_nodes_vec_[ tid ].clear(); @@ -572,7 +575,7 @@ NodeManager::update_thread_local_node_data() // step, because gather_events() has to be done in an // openmp single section wfr_is_used_ = false; - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { if ( wfr_nodes_vec_[ tid ].size() > 0 ) { @@ -586,7 +589,7 @@ NodeManager::destruct_nodes_() { #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); for ( auto node : local_nodes_[ tid ] ) { delete node.get_node(); @@ -625,18 +628,19 @@ NodeManager::prepare_node_( Node* n ) void NodeManager::prepare_nodes() { - assert( kernel().is_initialized() ); + assert( kernel::manager< KernelManager >.is_initialized() ); // We initialize the buffers of each node and calibrate it. size_t num_active_nodes = 0; // counts nodes that will be updated size_t num_active_wfr_nodes = 0; // counts nodes that use waveform relaxation - std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised( kernel().vp_manager.get_num_threads() ); + std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised( + kernel::manager< VPManager >.get_num_threads() ); #pragma omp parallel reduction( + : num_active_nodes, num_active_wfr_nodes ) { - size_t t = kernel().vp_manager.get_thread_id(); + size_t t = kernel::manager< VPManager >.get_thread_id(); // We prepare nodes in a parallel region. Therefore, we need to catch // exceptions here and then handle them after the parallel region. @@ -663,7 +667,7 @@ NodeManager::prepare_nodes() } // omp parallel // check if any exceptions have been raised - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { if ( exceptions_raised.at( tid ).get() ) { @@ -690,7 +694,7 @@ NodeManager::post_run_cleanup() { #pragma omp parallel { - size_t t = kernel().vp_manager.get_thread_id(); + size_t t = kernel::manager< VPManager >.get_thread_id(); SparseNodeArray::const_iterator n; for ( n = local_nodes_[ t ].begin(); n != local_nodes_[ t ].end(); ++n ) { @@ -704,7 +708,7 @@ NodeManager::finalize_nodes() { #pragma omp parallel { - size_t tid = kernel().vp_manager.get_thread_id(); + size_t tid = kernel::manager< VPManager >.get_thread_id(); SparseNodeArray::const_iterator n; for ( n = local_nodes_[ tid ].begin(); n != local_nodes_[ tid ].end(); ++n ) { @@ -716,15 +720,15 @@ NodeManager::finalize_nodes() void NodeManager::check_wfr_use() { - wfr_is_used_ = kernel().mpi_manager.any_true( wfr_is_used_ ); + wfr_is_used_ = kernel::manager< MPIManager >.any_true( wfr_is_used_ ); - GapJunctionEvent::set_coeff_length( - kernel().connection_manager.get_min_delay() * ( kernel().simulation_manager.get_wfr_interpolation_order() + 1 ) ); - InstantaneousRateConnectionEvent::set_coeff_length( kernel().connection_manager.get_min_delay() ); - DelayedRateConnectionEvent::set_coeff_length( kernel().connection_manager.get_min_delay() ); - DiffusionConnectionEvent::set_coeff_length( kernel().connection_manager.get_min_delay() ); - LearningSignalConnectionEvent::set_coeff_length( kernel().connection_manager.get_min_delay() ); - SICEvent::set_coeff_length( kernel().connection_manager.get_min_delay() ); + GapJunctionEvent::set_coeff_length( kernel::manager< ConnectionManager >.get_min_delay() + * ( kernel::manager< SimulationManager >.get_wfr_interpolation_order() + 1 ) ); + InstantaneousRateConnectionEvent::set_coeff_length( kernel::manager< ConnectionManager >.get_min_delay() ); + DelayedRateConnectionEvent::set_coeff_length( kernel::manager< ConnectionManager >.get_min_delay() ); + DiffusionConnectionEvent::set_coeff_length( kernel::manager< ConnectionManager >.get_min_delay() ); + LearningSignalConnectionEvent::set_coeff_length( kernel::manager< ConnectionManager >.get_min_delay() ); + SICEvent::set_coeff_length( kernel::manager< ConnectionManager >.get_min_delay() ); } void @@ -734,13 +738,13 @@ NodeManager::print( std::ostream& out ) const const double max_node_id_width = std::floor( std::log10( max_node_id ) ); const double node_id_range_width = 6 + 2 * max_node_id_width; - for ( std::vector< modelrange >::const_iterator it = kernel().modelrange_manager.begin(); - it != kernel().modelrange_manager.end(); + for ( std::vector< modelrange >::const_iterator it = kernel::manager< ModelRangeManager >.begin(); + it != kernel::manager< ModelRangeManager >.end(); ++it ) { const size_t first_node_id = it->get_first_node_id(); const size_t last_node_id = it->get_last_node_id(); - const Model* mod = kernel().model_manager.get_node_model( it->get_model_id() ); + const Model* mod = kernel::manager< ModelManager >.get_node_model( it->get_model_id() ); std::stringstream node_id_range_strs; node_id_range_strs << std::setw( max_node_id_width + 1 ) << first_node_id; @@ -750,7 +754,7 @@ NodeManager::print( std::ostream& out ) const } out << std::setw( node_id_range_width ) << std::left << node_id_range_strs.str() << " " << mod->get_name(); - if ( it + 1 != kernel().modelrange_manager.end() ) + if ( it + 1 != kernel::manager< ModelRangeManager >.end() ) { out << std::endl; } @@ -760,7 +764,7 @@ NodeManager::print( std::ostream& out ) const void NodeManager::set_status( size_t node_id, const DictionaryDatum& d ) { - for ( size_t t = 0; t < kernel().vp_manager.get_num_threads(); ++t ) + for ( size_t t = 0; t < kernel::manager< VPManager >.get_num_threads(); ++t ) { Node* node = local_nodes_[ t ].get_node_by_node_id( node_id ); if ( node ) @@ -782,4 +786,60 @@ NodeManager::set_status( const DictionaryDatum& ) { } +void +NodeManager::set_have_nodes_changed( const bool changed ) +{ + + have_nodes_changed_ = changed; +} + +bool +NodeManager::have_nodes_changed() const +{ + + return have_nodes_changed_; +} + +const SparseNodeArray& +NodeManager::get_local_nodes( size_t t ) const +{ + + return local_nodes_[ t ]; +} + +bool +NodeManager::wfr_is_used() const +{ + + return wfr_is_used_; +} + +const std::vector< Node* >& +NodeManager::get_wfr_nodes_on_thread( size_t t ) const +{ + + return wfr_nodes_vec_.at( t ); +} + +Node* +NodeManager::thread_lid_to_node( size_t t, targetindex thread_local_id ) const +{ + + return local_nodes_[ t ].get_node_by_index( thread_local_id ); +} + +size_t +NodeManager::size() const +{ + + return local_nodes_[ 0 ].get_max_node_id(); +} + +size_t +NodeManager::get_num_active_nodes() +{ + + return num_active_nodes_; +} + } // namespace nest diff --git a/nestkernel/node_manager.h b/nestkernel/node_manager.h index ce0c4b3b48..939edddca1 100644 --- a/nestkernel/node_manager.h +++ b/nestkernel/node_manager.h @@ -28,7 +28,7 @@ // Includes from libnestutil: #include "manager_interface.h" -#include "stopwatch.h" +#include "stopwatch_impl.h" // Includes from nestkernel: #include "conn_builder.h" @@ -212,11 +212,7 @@ class NodeManager : public ManagerInterface * @see prepare_nodes() * @return number of active nodes */ - size_t - get_num_active_nodes() - { - return num_active_nodes_; - }; + size_t get_num_active_nodes(); /** * Invoke post_run_cleanup() on all nodes. @@ -369,47 +365,6 @@ class NodeManager : public ManagerInterface Stopwatch< StopwatchGranularity::Normal, StopwatchParallelism::MasterOnly > sw_construction_create_; }; -inline size_t -NodeManager::size() const -{ - return local_nodes_[ 0 ].get_max_node_id(); -} - -inline Node* -NodeManager::thread_lid_to_node( size_t t, targetindex thread_local_id ) const -{ - return local_nodes_[ t ].get_node_by_index( thread_local_id ); -} - -inline const std::vector< Node* >& -NodeManager::get_wfr_nodes_on_thread( size_t t ) const -{ - return wfr_nodes_vec_.at( t ); -} - -inline bool -NodeManager::wfr_is_used() const -{ - return wfr_is_used_; -} - -inline const SparseNodeArray& -NodeManager::get_local_nodes( size_t t ) const -{ - return local_nodes_[ t ]; -} - -inline bool -NodeManager::have_nodes_changed() const -{ - return have_nodes_changed_; -} - -inline void -NodeManager::set_have_nodes_changed( const bool changed ) -{ - have_nodes_changed_ = changed; -} inline bool NodeManager::thread_local_data_is_up_to_date() const diff --git a/nestkernel/conn_builder_impl.h b/nestkernel/ntree.cpp similarity index 50% rename from nestkernel/conn_builder_impl.h rename to nestkernel/ntree.cpp index 385bb12ec8..8cf1ba8db8 100644 --- a/nestkernel/conn_builder_impl.h +++ b/nestkernel/ntree.cpp @@ -1,5 +1,5 @@ /* - * conn_builder_impl.h + * ntree.cpp * * This file is part of NEST. * @@ -20,32 +20,21 @@ * */ -#ifndef CONN_BUILDER_IMPL_H -#define CONN_BUILDER_IMPL_H - -#include "conn_builder.h" - -// Includes from nestkernel: -#include "kernel_manager.h" -#include "nest_names.h" +#include "ntree.h" +#include namespace nest { -inline void -BipartiteConnBuilder::single_disconnect_( size_t snode_id, Node& target, size_t target_thread ) +double +mod( double x, double p ) { - // index tnode_id = target.get_node_id(); - // This is the most simple case in which only the synapse_model_ has been - // defined. TODO: Add functionality to delete synapses with a given weight - // or a given delay - if ( synapse_model_id_.size() > 1 ) + x = std::fmod( x, p ); + if ( x < 0 ) { - throw KernelException( "Can only disconnect when single element syn_spec has been used." ); + x += p; } - kernel().sp_manager.disconnect( snode_id, &target, target_thread, synapse_model_id_[ 0 ] ); + return x; } } // namespace nest - -#endif /* CONN_BUILDER_IMPL_H */ diff --git a/nestkernel/ntree.h b/nestkernel/ntree.h index 256f16deec..2eb35ec51e 100644 --- a/nestkernel/ntree.h +++ b/nestkernel/ntree.h @@ -400,91 +400,8 @@ class Ntree friend class masked_iterator; }; -template < int D, class T, int max_capacity, int max_depth > -Ntree< D, T, max_capacity, max_depth >::Ntree( const Position< D >& lower_left, - const Position< D >& extent, - std::bitset< D > periodic, - Ntree< D, T, max_capacity, max_depth >* parent, - int subquad ) - : lower_left_( lower_left ) - , extent_( extent ) - , leaf_( true ) - , parent_( parent ) - , my_subquad_( subquad ) - , my_depth_( parent ? parent->my_depth_ + 1 : 0 ) - , periodic_( periodic ) -{ -} - -template < int D, class T, int max_capacity, int max_depth > -Ntree< D, T, max_capacity, max_depth >::~Ntree() -{ - if ( leaf_ ) - { - // if T is a vector class, we do not delete the pointees - return; - } - - for ( size_t n = 0; n < static_cast< size_t >( N ); ++n ) - { - delete children_[ n ]; // calls destructor in child, thus recursing - } -} - -template < int D, class T, int max_capacity, int max_depth > -Ntree< D, T, max_capacity, max_depth >::iterator::iterator( Ntree& q, size_t n ) - : ntree_( &q ) - , top_( &q ) - , node_( n ) -{ - assert( ntree_->leaf_ ); - - // First ancestor - while ( top_->parent_ ) - { - top_ = top_->parent_; - } -} - -template < int D, class T, int max_capacity, int max_depth > -bool -Ntree< D, T, max_capacity, max_depth >::is_leaf() const -{ - return leaf_; -} - - -template < int D, class T, int max_capacity, int max_depth > -std::vector< std::pair< Position< D >, T > > -Ntree< D, T, max_capacity, max_depth >::get_nodes() -{ - std::vector< std::pair< Position< D >, T > > result; - append_nodes_( result ); - return result; -} - -template < int D, class T, int max_capacity, int max_depth > -std::vector< std::pair< Position< D >, T > > -Ntree< D, T, max_capacity, max_depth >::get_nodes( const Mask< D >& mask, const Position< D >& anchor ) -{ - std::vector< std::pair< Position< D >, T > > result; - append_nodes_( result, mask, anchor ); - return result; -} - -template < int D, class T, int max_capacity, int max_depth > -typename Ntree< D, T, max_capacity, max_depth >::iterator -Ntree< D, T, max_capacity, max_depth >::insert( const std::pair< Position< D >, T >& val ) -{ - return insert( val.first, val.second ); -} - -template < int D, class T, int max_capacity, int max_depth > -typename Ntree< D, T, max_capacity, max_depth >::iterator -Ntree< D, T, max_capacity, max_depth >::insert( iterator, const std::pair< Position< D >, T >& val ) -{ - return insert( val.first, val.second ); -} +// Proper mod which returns non-negative numbers +double mod( double x, double p ); } // namespace nest diff --git a/nestkernel/ntree_impl.h b/nestkernel/ntree_impl.h index a478097df9..67877853de 100644 --- a/nestkernel/ntree_impl.h +++ b/nestkernel/ntree_impl.h @@ -23,16 +23,104 @@ #ifndef NTREE_IMPL_H #define NTREE_IMPL_H -#include - #include "ntree.h" +#include "position.h" -// Includes from spatial: -#include "mask.h" +#include +#include +#include +#include namespace nest { + +template < int D, class T, int max_capacity, int max_depth > +Ntree< D, T, max_capacity, max_depth >::Ntree( const Position< D >& lower_left, + const Position< D >& extent, + std::bitset< D > periodic, + Ntree< D, T, max_capacity, max_depth >* parent, + int subquad ) + : lower_left_( lower_left ) + , extent_( extent ) + , leaf_( true ) + , parent_( parent ) + , my_subquad_( subquad ) + , my_depth_( parent ? parent->my_depth_ + 1 : 0 ) + , periodic_( periodic ) +{ +} + +template < int D, class T, int max_capacity, int max_depth > +Ntree< D, T, max_capacity, max_depth >::~Ntree() +{ + if ( leaf_ ) + { + // if T is a vector class, we do not delete the pointees + return; + } + + for ( size_t n = 0; n < static_cast< size_t >( N ); ++n ) + { + delete children_[ n ]; // calls destructor in child, thus recursing + } +} + +template < int D, class T, int max_capacity, int max_depth > +Ntree< D, T, max_capacity, max_depth >::iterator::iterator( Ntree& q, size_t n ) + : ntree_( &q ) + , top_( &q ) + , node_( n ) +{ + assert( ntree_->leaf_ ); + + // First ancestor + while ( top_->parent_ ) + { + top_ = top_->parent_; + } +} + +template < int D, class T, int max_capacity, int max_depth > +bool +Ntree< D, T, max_capacity, max_depth >::is_leaf() const +{ + return leaf_; +} + + +template < int D, class T, int max_capacity, int max_depth > +std::vector< std::pair< Position< D >, T > > +Ntree< D, T, max_capacity, max_depth >::get_nodes() +{ + std::vector< std::pair< Position< D >, T > > result; + append_nodes_( result ); + return result; +} + +template < int D, class T, int max_capacity, int max_depth > +std::vector< std::pair< Position< D >, T > > +Ntree< D, T, max_capacity, max_depth >::get_nodes( const Mask< D >& mask, const Position< D >& anchor ) +{ + std::vector< std::pair< Position< D >, T > > result; + append_nodes_( result, mask, anchor ); + return result; +} + +template < int D, class T, int max_capacity, int max_depth > +typename Ntree< D, T, max_capacity, max_depth >::iterator +Ntree< D, T, max_capacity, max_depth >::insert( const std::pair< Position< D >, T >& val ) +{ + return insert( val.first, val.second ); +} + +template < int D, class T, int max_capacity, int max_depth > +typename Ntree< D, T, max_capacity, max_depth >::iterator +Ntree< D, T, max_capacity, max_depth >::insert( iterator, const std::pair< Position< D >, T >& val ) +{ + return insert( val.first, val.second ); +} + template < int D, class T, int max_capacity, int max_depth > Ntree< D, T, max_capacity, max_depth >::iterator::iterator( Ntree& q ) : ntree_( &q ) @@ -108,18 +196,6 @@ Ntree< D, T, max_capacity, max_depth >::iterator::next_leaf_() } } -// Proper mod which returns non-negative numbers -static inline double -mod( double x, double p ) -{ - x = std::fmod( x, p ); - if ( x < 0 ) - { - x += p; - } - return x; -} - template < int D, class T, int max_capacity, int max_depth > Ntree< D, T, max_capacity, max_depth >::masked_iterator::masked_iterator( Ntree< D, T, max_capacity, max_depth >& q, const Mask< D >& mask, @@ -529,4 +605,5 @@ Ntree< D, T, max_capacity, max_depth >::split_() } } + #endif diff --git a/nestkernel/parameter.cpp b/nestkernel/parameter.cpp index f5d5301f35..c398c2cf3f 100644 --- a/nestkernel/parameter.cpp +++ b/nestkernel/parameter.cpp @@ -22,12 +22,11 @@ #include +#include "nest.h" #include "node.h" #include "node_collection.h" -#include "spatial.h" -#include "vp_manager_impl.h" - #include "parameter.h" +#include "spatial.h" namespace nest @@ -92,14 +91,15 @@ NormalParameter::NormalParameter( const DictionaryDatum& d ) normal_distribution::param_type param( mean_, std_ ); dist.param( param ); assert( normal_dists_.size() == 0 ); - normal_dists_.resize( kernel().vp_manager.get_num_threads(), dist ); + normal_dists_.resize( kernel::manager< VPManager >.get_num_threads(), dist ); } double NormalParameter::value( RngPtr rng, Node* node ) { - const auto tid = node ? kernel().vp_manager.vp_to_thread( kernel().vp_manager.node_id_to_vp( node->get_node_id() ) ) - : kernel().vp_manager.get_thread_id(); + const auto tid = node + ? kernel::manager< VPManager >.vp_to_thread( kernel::manager< VPManager >.node_id_to_vp( node->get_node_id() ) ) + : kernel::manager< VPManager >.get_thread_id(); return normal_dists_[ tid ]( rng ); } @@ -118,14 +118,15 @@ LognormalParameter::LognormalParameter( const DictionaryDatum& d ) const lognormal_distribution::param_type param( mean_, std_ ); dist.param( param ); assert( lognormal_dists_.size() == 0 ); - lognormal_dists_.resize( kernel().vp_manager.get_num_threads(), dist ); + lognormal_dists_.resize( kernel::manager< VPManager >.get_num_threads(), dist ); } double LognormalParameter::value( RngPtr rng, Node* node ) { - const auto tid = node ? kernel().vp_manager.vp_to_thread( kernel().vp_manager.node_id_to_vp( node->get_node_id() ) ) - : kernel().vp_manager.get_thread_id(); + const auto tid = node + ? kernel::manager< VPManager >.vp_to_thread( kernel::manager< VPManager >.node_id_to_vp( node->get_node_id() ) ) + : kernel::manager< VPManager >.get_thread_id(); return lognormal_dists_[ tid ]( rng ); } @@ -137,7 +138,7 @@ NodePosParameter::get_node_pos_( Node* node ) const { throw KernelException( "NodePosParameter: not node" ); } - NodeCollectionPTR nc = kernel().node_manager.node_id_to_node_collection( node ); + NodeCollectionPTR nc = kernel::manager< NodeManager >.node_id_to_node_collection( node ); if ( not nc.get() ) { throw KernelException( "NodePosParameter: not nc" ); @@ -521,4 +522,391 @@ dimension_parameter( const std::shared_ptr< Parameter > x_parameter, return std::shared_ptr< Parameter >( new DimensionParameter( x_parameter, y_parameter, z_parameter ) ); } +double +ConstantParameter::value( RngPtr, Node* ) +{ + return value_; +} + +double +UniformParameter::value( RngPtr rng, Node* ) +{ + return lower_ + rng->drand() * range_; +} + +double +UniformIntParameter::value( RngPtr rng, Node* ) +{ + return rng->ulrand( max_ ); +} + +double +ExponentialParameter::value( RngPtr rng, Node* ) +{ + return beta_ * ( -std::log( 1 - rng->drand() ) ); +} + +double +NodePosParameter::value( RngPtr, Node* node ) +{ + if ( synaptic_endpoint_ != 0 ) + { + throw BadParameterValue( "Source or target position parameter can only be used when connecting." ); + } + if ( not node ) + { + throw KernelException( "Node position parameter can only be used when connecting spatially distributed nodes." ); + } + return get_node_pos_( node ); +} + +double +NodePosParameter::value( RngPtr, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer&, + Node* ) +{ + switch ( synaptic_endpoint_ ) + { + case 0: + throw BadParameterValue( "Node position parameter cannot be used when connecting." ); + case 1: + { + return source_pos[ dimension_ ]; + } + case 2: + return target_pos[ dimension_ ]; + } + throw KernelException( "Wrong synaptic_endpoint_." ); +} + +double +SpatialDistanceParameter::value( RngPtr, Node* ) +{ + throw BadParameterValue( "Spatial distance parameter can only be used when connecting." ); +} + +double +ProductParameter::value( RngPtr rng, Node* node ) +{ + return parameter1_->value( rng, node ) * parameter2_->value( rng, node ); +} + +double +ProductParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return parameter1_->value( rng, source_pos, target_pos, layer, node ) + * parameter2_->value( rng, source_pos, target_pos, layer, node ); +} + +double +QuotientParameter::value( RngPtr rng, Node* node ) +{ + return parameter1_->value( rng, node ) / parameter2_->value( rng, node ); +} + +double +QuotientParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return parameter1_->value( rng, source_pos, target_pos, layer, node ) + / parameter2_->value( rng, source_pos, target_pos, layer, node ); +} + +double +SumParameter::value( RngPtr rng, Node* node ) +{ + return parameter1_->value( rng, node ) + parameter2_->value( rng, node ); +} + +double +SumParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return parameter1_->value( rng, source_pos, target_pos, layer, node ) + + parameter2_->value( rng, source_pos, target_pos, layer, node ); +} + +double +DifferenceParameter::value( RngPtr rng, Node* node ) +{ + return parameter1_->value( rng, node ) - parameter2_->value( rng, node ); +} + +double +DifferenceParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return parameter1_->value( rng, source_pos, target_pos, layer, node ) + - parameter2_->value( rng, source_pos, target_pos, layer, node ); +} + +double +ComparingParameter::value( RngPtr rng, Node* node ) +{ + return compare_( parameter1_->value( rng, node ), parameter2_->value( rng, node ) ); +} + +double +ComparingParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return compare_( parameter1_->value( rng, source_pos, target_pos, layer, node ), + parameter2_->value( rng, source_pos, target_pos, layer, node ) ); +} + +bool +ComparingParameter::compare_( double value_a, double value_b ) const +{ + switch ( comparator_ ) + { + case 0: + return value_a < value_b; + case 1: + return value_a <= value_b; + case 2: + return value_a == value_b; + case 3: + return value_a != value_b; + case 4: + return value_a >= value_b; + case 5: + return value_a > value_b; + } + throw KernelException( "Wrong comparison operator." ); +} + +double +ConditionalParameter::value( RngPtr rng, Node* node ) +{ + if ( condition_->value( rng, node ) ) + { + return if_true_->value( rng, node ); + } + else + { + return if_false_->value( rng, node ); + } +} + +double +ConditionalParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + if ( condition_->value( rng, source_pos, target_pos, layer, node ) ) + { + return if_true_->value( rng, source_pos, target_pos, layer, node ); + } + else + { + return if_false_->value( rng, source_pos, target_pos, layer, node ); + } +} + +double +MinParameter::value( RngPtr rng, Node* node ) +{ + return std::min( p_->value( rng, node ), other_value_ ); +} + +double +MinParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return std::min( p_->value( rng, source_pos, target_pos, layer, node ), other_value_ ); +} + +double +MaxParameter::value( RngPtr rng, Node* node ) +{ + return std::max( p_->value( rng, node ), other_value_ ); +} + +double +MaxParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return std::max( p_->value( rng, source_pos, target_pos, layer, node ), other_value_ ); +} + +double +ExpParameter::value( RngPtr rng, Node* node ) +{ + return std::exp( p_->value( rng, node ) ); +} + +double +ExpParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return std::exp( p_->value( rng, source_pos, target_pos, layer, node ) ); +} + +double +SinParameter::value( RngPtr rng, Node* node ) +{ + return std::sin( p_->value( rng, node ) ); +} + +double +SinParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return std::sin( p_->value( rng, source_pos, target_pos, layer, node ) ); +} + +double +CosParameter::value( RngPtr rng, Node* node ) +{ + return std::cos( p_->value( rng, node ) ); +} + +double +CosParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return std::cos( p_->value( rng, source_pos, target_pos, layer, node ) ); +} + +double +PowParameter::value( RngPtr rng, Node* node ) +{ + return std::pow( p_->value( rng, node ), exponent_ ); +} + +double +PowParameter::value( RngPtr rng, + const std::vector< double >& source_pos, + const std::vector< double >& target_pos, + const AbstractLayer& layer, + Node* node ) +{ + return std::pow( p_->value( rng, source_pos, target_pos, layer, node ), exponent_ ); +} + +double +DimensionParameter::value( RngPtr, Node* ) +{ + throw KernelException( "Cannot get value of DimensionParameter." ); +} + +/** + * Generates a position with values for each dimension generated from their respective parameters. + * + * @returns The position, given as an array. + */ +std::vector< double > +DimensionParameter::get_values( RngPtr rng ) +{ + switch ( num_dimensions_ ) + { + case 2: + return { px_->value( rng, nullptr ), py_->value( rng, nullptr ) }; + case 3: + return { px_->value( rng, nullptr ), py_->value( rng, nullptr ), pz_->value( rng, nullptr ) }; + } + throw KernelException( "Wrong number of dimensions in get_values!" ); +} + +int +DimensionParameter::get_num_dimensions() const +{ + return num_dimensions_; +} + +double +ExpDistParameter::value( RngPtr, Node* ) +{ + throw BadParameterValue( "Exponential distribution parameter can only be used when connecting." ); +} + +double +GaussianParameter::value( RngPtr, Node* ) +{ + throw BadParameterValue( "Gaussian distribution parameter can only be used when connecting." ); +} + +double +Gaussian2DParameter::value( RngPtr, Node* ) +{ + throw BadParameterValue( "Gaussian 2D parameter can only be used when connecting." ); +} + +double +GaborParameter::value( RngPtr, Node* ) +{ + throw BadParameterValue( "Gabor parameter can only be used when connecting." ); +} + +double +GammaParameter::value( RngPtr, Node* ) +{ + throw BadParameterValue( "Gamma distribution parameter can only be used when connecting." ); +} + +double +Parameter::value( RngPtr rng, + const std::vector< double >&, + const std::vector< double >&, + const AbstractLayer&, + Node* node ) +{ + return value( rng, node ); +} + +bool +Parameter::is_spatial() const +{ + return is_spatial_; +} + +bool +Parameter::returns_int_only() const +{ + return returns_int_only_; +} + +bool +Parameter::value_is_integer_( const double value ) const +{ + // Here fmod calculates the remainder of the division operation x/y. By using y=1.0, the remainder is the + // fractional part of the value. If the fractional part is zero, the value is an integer. + return std::fmod( value, static_cast< double >( 1.0 ) ) == 0.0; +} + } // namespace nest diff --git a/nestkernel/parameter.h b/nestkernel/parameter.h index dfae3cfcb9..527ff12ced 100644 --- a/nestkernel/parameter.h +++ b/nestkernel/parameter.h @@ -159,11 +159,7 @@ class ConstantParameter : public Parameter /** * @returns the constant value of this parameter. */ - double - value( RngPtr, Node* ) override - { - return value_; - } + double value( RngPtr, Node* ) override; private: double value_; @@ -203,11 +199,7 @@ class UniformParameter : public Parameter range_ -= lower_; } - double - value( RngPtr rng, Node* ) override - { - return lower_ + rng->drand() * range_; - } + double value( RngPtr rng, Node* ) override; private: double lower_, range_; @@ -240,11 +232,7 @@ class UniformIntParameter : public Parameter } } - double - value( RngPtr rng, Node* ) override - { - return rng->ulrand( max_ ); - } + double value( RngPtr rng, Node* ) override; private: double max_; @@ -327,11 +315,7 @@ class ExponentialParameter : public Parameter updateValue< double >( d, names::beta, beta_ ); } - double - value( RngPtr rng, Node* ) override - { - return beta_ * ( -std::log( 1 - rng->drand() ) ); - } + double value( RngPtr rng, Node* ) override; private: double beta_; @@ -377,40 +361,13 @@ class NodePosParameter : public Parameter } } - double - value( RngPtr, Node* node ) override - { - if ( synaptic_endpoint_ != 0 ) - { - throw BadParameterValue( "Source or target position parameter can only be used when connecting." ); - } - if ( not node ) - { - throw KernelException( "Node position parameter can only be used when connecting spatially distributed nodes." ); - } - return get_node_pos_( node ); - } + double value( RngPtr, Node* node ) override; - double - value( RngPtr, + double value( RngPtr, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer&, - Node* ) override - { - switch ( synaptic_endpoint_ ) - { - case 0: - throw BadParameterValue( "Node position parameter cannot be used when connecting." ); - case 1: - { - return source_pos[ dimension_ ]; - } - case 2: - return target_pos[ dimension_ ]; - } - throw KernelException( "Wrong synaptic_endpoint_." ); - } + Node* ) override; private: int dimension_; @@ -437,11 +394,7 @@ class SpatialDistanceParameter : public Parameter } } - double - value( RngPtr, Node* ) override - { - throw BadParameterValue( "Spatial distance parameter can only be used when connecting." ); - } + double value( RngPtr, Node* ) override; double value( RngPtr rng, const std::vector< double >& source_pos, @@ -482,22 +435,13 @@ class ProductParameter : public Parameter /** * @returns the value of the product. */ - double - value( RngPtr rng, Node* node ) override - { - return parameter1_->value( rng, node ) * parameter2_->value( rng, node ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return parameter1_->value( rng, source_pos, target_pos, layer, node ) - * parameter2_->value( rng, source_pos, target_pos, layer, node ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const parameter1_; @@ -532,22 +476,13 @@ class QuotientParameter : public Parameter /** * @returns the value of the product. */ - double - value( RngPtr rng, Node* node ) override - { - return parameter1_->value( rng, node ) / parameter2_->value( rng, node ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return parameter1_->value( rng, source_pos, target_pos, layer, node ) - / parameter2_->value( rng, source_pos, target_pos, layer, node ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const parameter1_; @@ -582,22 +517,13 @@ class SumParameter : public Parameter /** * @returns the value of the sum. */ - double - value( RngPtr rng, Node* node ) override - { - return parameter1_->value( rng, node ) + parameter2_->value( rng, node ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return parameter1_->value( rng, source_pos, target_pos, layer, node ) - + parameter2_->value( rng, source_pos, target_pos, layer, node ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const parameter1_; @@ -632,22 +558,13 @@ class DifferenceParameter : public Parameter /** * @returns the value of the difference. */ - double - value( RngPtr rng, Node* node ) override - { - return parameter1_->value( rng, node ) - parameter2_->value( rng, node ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return parameter1_->value( rng, source_pos, target_pos, layer, node ) - - parameter2_->value( rng, source_pos, target_pos, layer, node ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const parameter1_; @@ -700,48 +617,20 @@ class ComparingParameter : public Parameter /** * @returns the result of the comparison, bool given as a double. */ - double - value( RngPtr rng, Node* node ) override - { - return compare_( parameter1_->value( rng, node ), parameter2_->value( rng, node ) ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return compare_( parameter1_->value( rng, source_pos, target_pos, layer, node ), - parameter2_->value( rng, source_pos, target_pos, layer, node ) ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const parameter1_; std::shared_ptr< Parameter > const parameter2_; private: - bool - compare_( double value_a, double value_b ) const - { - switch ( comparator_ ) - { - case 0: - return value_a < value_b; - case 1: - return value_a <= value_b; - case 2: - return value_a == value_b; - case 3: - return value_a != value_b; - case 4: - return value_a >= value_b; - case 5: - return value_a > value_b; - } - throw KernelException( "Wrong comparison operator." ); - } + bool compare_( double value_a, double value_b ) const; int comparator_; }; @@ -779,35 +668,12 @@ class ConditionalParameter : public Parameter /** * @returns the value chosen by the comparison. */ - double - value( RngPtr rng, Node* node ) override - { - if ( condition_->value( rng, node ) ) - { - return if_true_->value( rng, node ); - } - else - { - return if_false_->value( rng, node ); - } - } - - double - value( RngPtr rng, + double value( RngPtr rng, Node* node ) override; + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - if ( condition_->value( rng, source_pos, target_pos, layer, node ) ) - { - return if_true_->value( rng, source_pos, target_pos, layer, node ); - } - else - { - return if_false_->value( rng, source_pos, target_pos, layer, node ); - } - } + Node* node ) override; protected: std::shared_ptr< Parameter > const condition_; @@ -844,21 +710,13 @@ class MinParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr rng, Node* node ) override - { - return std::min( p_->value( rng, node ), other_value_ ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return std::min( p_->value( rng, source_pos, target_pos, layer, node ), other_value_ ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const p_; @@ -893,21 +751,13 @@ class MaxParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr rng, Node* node ) override - { - return std::max( p_->value( rng, node ), other_value_ ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return std::max( p_->value( rng, source_pos, target_pos, layer, node ), other_value_ ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const p_; @@ -979,21 +829,13 @@ class ExpParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr rng, Node* node ) override - { - return std::exp( p_->value( rng, node ) ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return std::exp( p_->value( rng, source_pos, target_pos, layer, node ) ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const p_; @@ -1025,21 +867,13 @@ class SinParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr rng, Node* node ) override - { - return std::sin( p_->value( rng, node ) ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return std::sin( p_->value( rng, source_pos, target_pos, layer, node ) ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const p_; @@ -1070,21 +904,13 @@ class CosParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr rng, Node* node ) override - { - return std::cos( p_->value( rng, node ) ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return std::cos( p_->value( rng, source_pos, target_pos, layer, node ) ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const p_; @@ -1118,21 +944,13 @@ class PowParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr rng, Node* node ) override - { - return std::pow( p_->value( rng, node ), exponent_ ); - } + double value( RngPtr rng, Node* node ) override; - double - value( RngPtr rng, + double value( RngPtr rng, const std::vector< double >& source_pos, const std::vector< double >& target_pos, const AbstractLayer& layer, - Node* node ) override - { - return std::pow( p_->value( rng, source_pos, target_pos, layer, node ), exponent_ ); - } + Node* node ) override; protected: std::shared_ptr< Parameter > const p_; @@ -1187,35 +1005,16 @@ class DimensionParameter : public Parameter /** * The DimensionParameter has no double value, so this method will always throw. */ - double - value( RngPtr, Node* ) override - { - throw KernelException( "Cannot get value of DimensionParameter." ); - } + double value( RngPtr, Node* ) override; /** * Generates a position with values for each dimension generated from their respective parameters. * * @returns The position, given as an array. */ - std::vector< double > - get_values( RngPtr rng ) - { - switch ( num_dimensions_ ) - { - case 2: - return { px_->value( rng, nullptr ), py_->value( rng, nullptr ) }; - case 3: - return { px_->value( rng, nullptr ), py_->value( rng, nullptr ), pz_->value( rng, nullptr ) }; - } - throw KernelException( "Wrong number of dimensions in get_values!" ); - } + std::vector< double > get_values( RngPtr rng ); - int - get_num_dimensions() const - { - return num_dimensions_; - } + int get_num_dimensions() const; protected: int num_dimensions_; @@ -1251,11 +1050,7 @@ class ExpDistParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr, Node* ) override - { - throw BadParameterValue( "Exponential distribution parameter can only be used when connecting." ); - } + double value( RngPtr, Node* ) override; double value( RngPtr rng, const std::vector< double >& source_pos, @@ -1295,11 +1090,7 @@ class GaussianParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr, Node* ) override - { - throw BadParameterValue( "Gaussian distribution parameter can only be used when connecting." ); - } + double value( RngPtr, Node* ) override; double value( RngPtr rng, const std::vector< double >& source_pos, @@ -1344,11 +1135,7 @@ class Gaussian2DParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr, Node* ) override - { - throw BadParameterValue( "Gaussian 2D parameter can only be used when connecting." ); - } + double value( RngPtr, Node* ) override; double value( RngPtr rng, const std::vector< double >& source_pos, @@ -1395,11 +1182,7 @@ class GaborParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr, Node* ) override - { - throw BadParameterValue( "Gabor parameter can only be used when connecting." ); - } + double value( RngPtr, Node* ) override; double value( RngPtr rng, const std::vector< double >& source_pos, @@ -1446,11 +1229,7 @@ class GammaParameter : public Parameter /** * @returns the value of the parameter. */ - double - value( RngPtr, Node* ) override - { - throw BadParameterValue( "Gamma distribution parameter can only be used when connecting." ); - } + double value( RngPtr, Node* ) override; double value( RngPtr rng, const std::vector< double >& source_pos, @@ -1465,37 +1244,6 @@ class GammaParameter : public Parameter const double delta_; }; -inline double -Parameter::value( RngPtr rng, - const std::vector< double >&, - const std::vector< double >&, - const AbstractLayer&, - Node* node ) -{ - return value( rng, node ); -} - -inline bool -Parameter::is_spatial() const -{ - return is_spatial_; -} - -inline bool -Parameter::returns_int_only() const -{ - return returns_int_only_; -} - -inline bool -Parameter::value_is_integer_( const double value ) const -{ - // Here fmod calculates the remainder of the division operation x/y. By using y=1.0, the remainder is the - // fractional part of the value. If the fractional part is zero, the value is an integer. - return std::fmod( value, static_cast< double >( 1.0 ) ) == 0.0; -} - - /** * Create the product of one parameter with another. * diff --git a/nestkernel/per_thread_bool_indicator.cpp b/nestkernel/per_thread_bool_indicator.cpp index 4032a7320f..97d5de3e45 100644 --- a/nestkernel/per_thread_bool_indicator.cpp +++ b/nestkernel/per_thread_bool_indicator.cpp @@ -24,7 +24,8 @@ // Includes from nestkernel #include "kernel_manager.h" -#include "stopwatch_impl.h" + +#include "simulation_manager.h" namespace nest { @@ -48,7 +49,7 @@ PerThreadBoolIndicator::operator[]( const size_t tid ) void PerThreadBoolIndicator::initialize( const size_t num_threads, const bool status ) { - kernel().vp_manager.assert_single_threaded(); + kernel::manager< VPManager >.assert_single_threaded(); per_thread_status_.clear(); per_thread_status_.resize( num_threads, BoolIndicatorUInt64( status ) ); size_ = num_threads; @@ -65,7 +66,7 @@ PerThreadBoolIndicator::initialize( const size_t num_threads, const bool status bool PerThreadBoolIndicator::all_false() const { - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); // We need two barriers here to ensure that no thread can continue and change the result // before all threads have determined the result. #pragma omp barrier @@ -74,43 +75,102 @@ PerThreadBoolIndicator::all_false() const bool ret = ( are_true_ == 0 ); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); return ret; } bool PerThreadBoolIndicator::all_true() const { - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier bool ret = ( are_true_ == size_ ); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); return ret; } bool PerThreadBoolIndicator::any_false() const { - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier bool ret = ( are_true_ < size_ ); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); return ret; } bool PerThreadBoolIndicator::any_true() const { - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier bool ret = ( are_true_ > 0 ); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); return ret; } +bool +BoolIndicatorUInt64::is_true() const +{ + return ( status_ == true_uint64 ); +} + +bool +BoolIndicatorUInt64::is_false() const +{ + return ( status_ == false_uint64 ); +} + +void +BoolIndicatorUInt64::set_true() +{ + status_ = true_uint64; +} + +void +BoolIndicatorUInt64::set_false() +{ + status_ = false_uint64; +} + +void +BoolIndicatorUInt64::logical_and( const bool status ) +{ + status_ = ( static_cast< bool >( status_ ) and status ); +} + +void +PerThreadBoolIndicator::set_true( const size_t tid ) +{ + if ( per_thread_status_[ tid ].is_false() ) + { + are_true_++; + per_thread_status_[ tid ].set_true(); + } +} + +void +PerThreadBoolIndicator::set_false( const size_t tid ) +{ + if ( per_thread_status_[ tid ].is_true() ) + { + are_true_--; + per_thread_status_[ tid ].set_false(); + } +} + +void +PerThreadBoolIndicator::logical_and( const size_t tid, const bool status ) +{ + if ( per_thread_status_[ tid ].is_true() and not status ) + { + are_true_--; + per_thread_status_[ tid ].set_false(); + } +} } // namespace nest diff --git a/nestkernel/per_thread_bool_indicator.h b/nestkernel/per_thread_bool_indicator.h index bafd79a307..edc67ec689 100644 --- a/nestkernel/per_thread_bool_indicator.h +++ b/nestkernel/per_thread_bool_indicator.h @@ -66,35 +66,6 @@ class BoolIndicatorUInt64 friend class PerThreadBoolIndicator; }; -inline bool -BoolIndicatorUInt64::is_true() const -{ - return ( status_ == true_uint64 ); -} - -inline bool -BoolIndicatorUInt64::is_false() const -{ - return ( status_ == false_uint64 ); -} - -inline void -BoolIndicatorUInt64::set_true() -{ - status_ = true_uint64; -} - -inline void -BoolIndicatorUInt64::set_false() -{ - status_ = false_uint64; -} - -inline void -BoolIndicatorUInt64::logical_and( const bool status ) -{ - status_ = ( static_cast< bool >( status_ ) and status ); -} /** * A thread-safe vector to keep track of the status across threads, @@ -109,35 +80,11 @@ class PerThreadBoolIndicator BoolIndicatorUInt64& operator[]( const size_t tid ); - void - set_true( const size_t tid ) - { - if ( per_thread_status_[ tid ].is_false() ) - { - are_true_++; - per_thread_status_[ tid ].set_true(); - } - } - - void - set_false( const size_t tid ) - { - if ( per_thread_status_[ tid ].is_true() ) - { - are_true_--; - per_thread_status_[ tid ].set_false(); - } - } - - void - logical_and( const size_t tid, const bool status ) - { - if ( per_thread_status_[ tid ].is_true() and not status ) - { - are_true_--; - per_thread_status_[ tid ].set_false(); - } - } + void set_true( const size_t tid ); + + void set_false( const size_t tid ); + + void logical_and( const size_t tid, const bool status ); /** * Resize to the given number of threads and set all elements to false. diff --git a/nestkernel/position.h b/nestkernel/position.h index 812239be92..88ebd690ca 100644 --- a/nestkernel/position.h +++ b/nestkernel/position.h @@ -417,429 +417,6 @@ class MultiIndex : public Position< D, int > Position< D, int > upper_right_; }; - -template < int D, class T > -inline Position< D, T >::Position() -{ - x_.fill( 0 ); -} - -template < int D, class T > -inline Position< D, T >::Position( const T& x, const T& y ) -{ - assert( D == 2 ); - x_[ 0 ] = x; - x_[ 1 ] = y; -} - -template < int D, class T > -inline Position< D, T >::Position( const T& x, const T& y, const T& z ) -{ - assert( D == 3 ); - x_[ 0 ] = x; - x_[ 1 ] = y; - x_[ 2 ] = z; -} - -template < int D, class T > -inline Position< D, T >::Position( const T* const y ) -{ - for ( int i = 0; i < D; ++i ) - { - x_[ i ] = y[ i ]; - } -} - -template < int D, class T > -inline Position< D, T >::Position( const std::vector< T >& y ) -{ - if ( y.size() != D ) - { - throw BadProperty( String::compose( "Expected a %1-dimensional position.", D ) ); - } - std::copy( y.begin(), y.end(), x_.begin() ); -} - -template < int D, class T > -inline Position< D, T >::Position( const Position< D, T >& other ) - : x_( other.x_ ) -{ -} - -template < int D, class T > -template < class U > -inline Position< D, T >::Position( const Position< D, U >& other ) - : x_( other.x_ ) -{ -} - -template < int D, class T > -inline Position< D, T >::Position( Position&& other ) -{ - x_ = std::move( other.x_ ); -} - -template < int D, class T > -inline Position< D, T >& -Position< D, T >::operator=( const std::vector< T >& y ) -{ - if ( y.size() != D ) - { - throw BadProperty( String::compose( "Expected a %1-dimensional position.", D ) ); - } - std::copy( y.begin(), y.end(), x_.begin() ); - - return *this; -} - -template < int D, class T > -inline T& -Position< D, T >::operator[]( int i ) -{ - return x_[ i ]; -} - -template < int D, class T > -inline const T& -Position< D, T >::operator[]( int i ) const -{ - return x_[ i ]; -} - -template < int D, class T > -Token -Position< D, T >::getToken() const -{ - std::vector< T > result = get_vector(); - return Token( result ); -} - - -template < int D, class T > -const std::vector< T > -Position< D, T >::get_vector() const -{ - return std::vector< T >( x_.begin(), x_.end() ); -} - -template < int D, class T > -void -Position< D, T >::get_vector( std::vector< T >& vector ) const -{ - assert( vector.size() == D ); - std::copy( x_.begin(), x_.end(), vector.begin() ); -} - - -template < int D, class T > -template < class OT > -inline Position< D, T > -Position< D, T >::operator+( const Position< D, OT >& other ) const -{ - Position p = *this; - p += other; - return p; -} - -template < int D, class T > -template < class OT > -inline Position< D, T > -Position< D, T >::operator-( const Position< D, OT >& other ) const -{ - Position p = *this; - p -= other; - return p; -} - -template < int D, class T > -inline Position< D, T > -Position< D, T >::operator-() const -{ - Position p; - p -= *this; - return p; -} - -template < int D, class T > -template < class OT > -inline Position< D, T > -Position< D, T >::operator*( const Position< D, OT >& other ) const -{ - Position p = *this; - p *= other; - return p; -} - -template < int D, class T > -template < class OT > -inline Position< D, T > -Position< D, T >::operator/( const Position< D, OT >& other ) const -{ - Position p = *this; - p /= other; - return p; -} - -template < int D, class T > -inline Position< D, T > -Position< D, T >::operator+( const T& a ) const -{ - Position p = *this; - p += a; - return p; -} - -template < int D, class T > -inline Position< D, T > -Position< D, T >::operator-( const T& a ) const -{ - Position p = *this; - p -= a; - return p; -} - -template < int D, class T > -inline Position< D, T > -Position< D, T >::operator*( const T& a ) const -{ - Position p = *this; - p *= a; - return p; -} - -template < int D, class T > -inline Position< D, T > -Position< D, T >::operator/( const T& a ) const -{ - Position p = *this; - p /= a; - return p; -} - -template < int D, class T > -template < class OT > -inline Position< D, T >& -Position< D, T >::operator+=( const Position< D, OT >& other ) -{ - for ( int i = 0; i < D; ++i ) - { - x_[ i ] += other.x_[ i ]; - } - return *this; -} - -template < int D, class T > -template < class OT > -inline Position< D, T >& -Position< D, T >::operator-=( const Position< D, OT >& other ) -{ - for ( int i = 0; i < D; ++i ) - { - x_[ i ] -= other.x_[ i ]; - } - return *this; -} - -template < int D, class T > -template < class OT > -inline Position< D, T >& -Position< D, T >::operator*=( const Position< D, OT >& other ) -{ - for ( int i = 0; i < D; ++i ) - { - x_[ i ] *= other.x_[ i ]; - } - return *this; -} - -template < int D, class T > -template < class OT > -inline Position< D, T >& -Position< D, T >::operator/=( const Position< D, OT >& other ) -{ - for ( int i = 0; i < D; ++i ) - { - x_[ i ] /= other.x_[ i ]; - } - return *this; -} - -template < int D, class T > -inline Position< D, T >& -Position< D, T >::operator+=( const T& a ) -{ - for ( int i = 0; i < D; ++i ) - { - x_[ i ] += a; - } - return *this; -} - -template < int D, class T > -inline Position< D, T >& -Position< D, T >::operator-=( const T& a ) -{ - for ( int i = 0; i < D; ++i ) - { - x_[ i ] -= a; - } - return *this; -} - -template < int D, class T > -inline Position< D, T >& -Position< D, T >::operator*=( const T& a ) -{ - for ( int i = 0; i < D; ++i ) - { - x_[ i ] *= a; - } - return *this; -} - -template < int D, class T > -inline Position< D, T >& -Position< D, T >::operator/=( const T& a ) -{ - for ( int i = 0; i < D; ++i ) - { - x_[ i ] /= a; - } - return *this; -} - -template < int D, class T > -inline bool -Position< D, T >::operator==( const Position< D, T >& y ) const -{ - for ( int i = 0; i < D; ++i ) - { - if ( x_[ i ] != y.x_[ i ] ) - { - return false; - } - } - return true; -} - -template < int D, class T > -inline bool -Position< D, T >::operator!=( const Position< D, T >& y ) const -{ - for ( int i = 0; i < D; ++i ) - { - if ( x_[ i ] != y.x_[ i ] ) - { - return true; - } - } - return false; -} - -template < int D, class T > -inline bool -Position< D, T >::operator<( const Position< D, T >& y ) const -{ - for ( int i = 0; i < D; ++i ) - { - if ( x_[ i ] >= y.x_[ i ] ) - { - return false; - } - } - return true; -} - -template < int D, class T > -inline bool -Position< D, T >::operator>( const Position< D, T >& y ) const -{ - for ( int i = 0; i < D; ++i ) - { - if ( x_[ i ] <= y.x_[ i ] ) - { - return false; - } - } - return true; -} - -template < int D, class T > -inline bool -Position< D, T >::operator<=( const Position< D, T >& y ) const -{ - for ( int i = 0; i < D; ++i ) - { - if ( x_[ i ] > y.x_[ i ] ) - { - return false; - } - } - return true; -} - -template < int D, class T > -inline bool -Position< D, T >::operator>=( const Position< D, T >& y ) const -{ - for ( int i = 0; i < D; ++i ) - { - if ( x_[ i ] < y.x_[ i ] ) - { - return false; - } - } - return true; -} - -template < int D, class T > -T -Position< D, T >::length() const -{ - T lensq = 0; - for ( int i = 0; i < D; ++i ) - { - lensq += x_[ i ] * x_[ i ]; - } - return std::sqrt( lensq ); -} - -template < int D, class T > -Position< D, T >::operator std::string() const -{ - std::stringstream ss; - ss << *this; - return ss.str(); -} - -template < int D, class T > -void -Position< D, T >::print( std::ostream& out, char sep ) const -{ - out << x_[ 0 ]; - for ( int i = 1; i < D; ++i ) - { - out << sep << x_[ i ]; - } -} - -template < int D, class T > -std::ostream& -operator<<( std::ostream& os, const Position< D, T >& pos ) -{ - os << "("; - if ( D > 0 ) - { - os << pos.x_[ 0 ]; - } - for ( int i = 1; i < D; ++i ) - { - os << ", " << pos.x_[ i ]; - } - os << ")"; - return os; -} - } // namespace nest #endif diff --git a/nestkernel/position_impl.h b/nestkernel/position_impl.h new file mode 100644 index 0000000000..13b83031b2 --- /dev/null +++ b/nestkernel/position_impl.h @@ -0,0 +1,455 @@ +/* + * position_impl.h + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#ifndef POSITION_IMPL_H +#define POSITION_IMPL_H + +#include "position.h" + +namespace nest +{ + +template < int D, class T > +inline Position< D, T >::Position() +{ + x_.fill( 0 ); +} + +template < int D, class T > +inline Position< D, T >::Position( const T& x, const T& y ) +{ + assert( D == 2 ); + x_[ 0 ] = x; + x_[ 1 ] = y; +} + +template < int D, class T > +inline Position< D, T >::Position( const T& x, const T& y, const T& z ) +{ + assert( D == 3 ); + x_[ 0 ] = x; + x_[ 1 ] = y; + x_[ 2 ] = z; +} + +template < int D, class T > +inline Position< D, T >::Position( const T* const y ) +{ + for ( int i = 0; i < D; ++i ) + { + x_[ i ] = y[ i ]; + } +} + +template < int D, class T > +inline Position< D, T >::Position( const std::vector< T >& y ) +{ + if ( y.size() != D ) + { + throw BadProperty( String::compose( "Expected a %1-dimensional position.", D ) ); + } + std::copy( y.begin(), y.end(), x_.begin() ); +} + +template < int D, class T > +inline Position< D, T >::Position( const Position< D, T >& other ) + : x_( other.x_ ) +{ +} + +template < int D, class T > +template < class U > +inline Position< D, T >::Position( const Position< D, U >& other ) + : x_( other.x_ ) +{ +} + +template < int D, class T > +inline Position< D, T >::Position( Position&& other ) +{ + x_ = std::move( other.x_ ); +} + +template < int D, class T > +inline Position< D, T >& +Position< D, T >::operator=( const std::vector< T >& y ) +{ + if ( y.size() != D ) + { + throw BadProperty( String::compose( "Expected a %1-dimensional position.", D ) ); + } + std::copy( y.begin(), y.end(), x_.begin() ); + + return *this; +} + +template < int D, class T > +inline T& +Position< D, T >::operator[]( int i ) +{ + return x_[ i ]; +} + +template < int D, class T > +inline const T& +Position< D, T >::operator[]( int i ) const +{ + return x_[ i ]; +} + +template < int D, class T > +Token +Position< D, T >::getToken() const +{ + std::vector< T > result = get_vector(); + return Token( result ); +} + + +template < int D, class T > +const std::vector< T > +Position< D, T >::get_vector() const +{ + return std::vector< T >( x_.begin(), x_.end() ); +} + +template < int D, class T > +void +Position< D, T >::get_vector( std::vector< T >& vector ) const +{ + assert( vector.size() == D ); + std::copy( x_.begin(), x_.end(), vector.begin() ); +} + + +template < int D, class T > +template < class OT > +inline Position< D, T > +Position< D, T >::operator+( const Position< D, OT >& other ) const +{ + Position p = *this; + p += other; + return p; +} + +template < int D, class T > +template < class OT > +inline Position< D, T > +Position< D, T >::operator-( const Position< D, OT >& other ) const +{ + Position p = *this; + p -= other; + return p; +} + +template < int D, class T > +inline Position< D, T > +Position< D, T >::operator-() const +{ + Position p; + p -= *this; + return p; +} + +template < int D, class T > +template < class OT > +inline Position< D, T > +Position< D, T >::operator*( const Position< D, OT >& other ) const +{ + Position p = *this; + p *= other; + return p; +} + +template < int D, class T > +template < class OT > +inline Position< D, T > +Position< D, T >::operator/( const Position< D, OT >& other ) const +{ + Position p = *this; + p /= other; + return p; +} + +template < int D, class T > +inline Position< D, T > +Position< D, T >::operator+( const T& a ) const +{ + Position p = *this; + p += a; + return p; +} + +template < int D, class T > +inline Position< D, T > +Position< D, T >::operator-( const T& a ) const +{ + Position p = *this; + p -= a; + return p; +} + +template < int D, class T > +inline Position< D, T > +Position< D, T >::operator*( const T& a ) const +{ + Position p = *this; + p *= a; + return p; +} + +template < int D, class T > +inline Position< D, T > +Position< D, T >::operator/( const T& a ) const +{ + Position p = *this; + p /= a; + return p; +} + +template < int D, class T > +template < class OT > +inline Position< D, T >& +Position< D, T >::operator+=( const Position< D, OT >& other ) +{ + for ( int i = 0; i < D; ++i ) + { + x_[ i ] += other.x_[ i ]; + } + return *this; +} + +template < int D, class T > +template < class OT > +inline Position< D, T >& +Position< D, T >::operator-=( const Position< D, OT >& other ) +{ + for ( int i = 0; i < D; ++i ) + { + x_[ i ] -= other.x_[ i ]; + } + return *this; +} + +template < int D, class T > +template < class OT > +inline Position< D, T >& +Position< D, T >::operator*=( const Position< D, OT >& other ) +{ + for ( int i = 0; i < D; ++i ) + { + x_[ i ] *= other.x_[ i ]; + } + return *this; +} + +template < int D, class T > +template < class OT > +inline Position< D, T >& +Position< D, T >::operator/=( const Position< D, OT >& other ) +{ + for ( int i = 0; i < D; ++i ) + { + x_[ i ] /= other.x_[ i ]; + } + return *this; +} + +template < int D, class T > +inline Position< D, T >& +Position< D, T >::operator+=( const T& a ) +{ + for ( int i = 0; i < D; ++i ) + { + x_[ i ] += a; + } + return *this; +} + +template < int D, class T > +inline Position< D, T >& +Position< D, T >::operator-=( const T& a ) +{ + for ( int i = 0; i < D; ++i ) + { + x_[ i ] -= a; + } + return *this; +} + +template < int D, class T > +inline Position< D, T >& +Position< D, T >::operator*=( const T& a ) +{ + for ( int i = 0; i < D; ++i ) + { + x_[ i ] *= a; + } + return *this; +} + +template < int D, class T > +inline Position< D, T >& +Position< D, T >::operator/=( const T& a ) +{ + for ( int i = 0; i < D; ++i ) + { + x_[ i ] /= a; + } + return *this; +} + +template < int D, class T > +inline bool +Position< D, T >::operator==( const Position< D, T >& y ) const +{ + for ( int i = 0; i < D; ++i ) + { + if ( x_[ i ] != y.x_[ i ] ) + { + return false; + } + } + return true; +} + +template < int D, class T > +inline bool +Position< D, T >::operator!=( const Position< D, T >& y ) const +{ + for ( int i = 0; i < D; ++i ) + { + if ( x_[ i ] != y.x_[ i ] ) + { + return true; + } + } + return false; +} + +template < int D, class T > +inline bool +Position< D, T >::operator<( const Position< D, T >& y ) const +{ + for ( int i = 0; i < D; ++i ) + { + if ( x_[ i ] >= y.x_[ i ] ) + { + return false; + } + } + return true; +} + +template < int D, class T > +inline bool +Position< D, T >::operator>( const Position< D, T >& y ) const +{ + for ( int i = 0; i < D; ++i ) + { + if ( x_[ i ] <= y.x_[ i ] ) + { + return false; + } + } + return true; +} + +template < int D, class T > +inline bool +Position< D, T >::operator<=( const Position< D, T >& y ) const +{ + for ( int i = 0; i < D; ++i ) + { + if ( x_[ i ] > y.x_[ i ] ) + { + return false; + } + } + return true; +} + +template < int D, class T > +inline bool +Position< D, T >::operator>=( const Position< D, T >& y ) const +{ + for ( int i = 0; i < D; ++i ) + { + if ( x_[ i ] < y.x_[ i ] ) + { + return false; + } + } + return true; +} + +template < int D, class T > +T +Position< D, T >::length() const +{ + T lensq = 0; + for ( int i = 0; i < D; ++i ) + { + lensq += x_[ i ] * x_[ i ]; + } + return std::sqrt( lensq ); +} + +template < int D, class T > +Position< D, T >::operator std::string() const +{ + std::stringstream ss; + ss << *this; + return ss.str(); +} + +template < int D, class T > +void +Position< D, T >::print( std::ostream& out, char sep ) const +{ + out << x_[ 0 ]; + for ( int i = 1; i < D; ++i ) + { + out << sep << x_[ i ]; + } +} + +template < int D, class T > +std::ostream& +operator<<( std::ostream& os, const Position< D, T >& pos ) +{ + os << "("; + if ( D > 0 ) + { + os << pos.x_[ 0 ]; + } + for ( int i = 1; i < D; ++i ) + { + os << ", " << pos.x_[ i ]; + } + os << ")"; + return os; +} + +} + +#endif diff --git a/nestkernel/proxynode.cpp b/nestkernel/proxynode.cpp index af4b624a57..88b08a448b 100644 --- a/nestkernel/proxynode.cpp +++ b/nestkernel/proxynode.cpp @@ -25,6 +25,7 @@ // Includes from nestkernel: #include "connection.h" #include "kernel_manager.h" +#include "model_manager.h" // Includes from sli: #include "dictutils.h" @@ -45,59 +46,63 @@ proxynode::proxynode( size_t node_id, size_t model_id, size_t vp ) size_t proxynode::send_test_event( Node& target, size_t receptor_type, synindex syn_id, bool dummy_target ) { - Model* model = kernel().model_manager.get_node_model( get_model_id() ); + Model* model = kernel::manager< ModelManager >.get_node_model( get_model_id() ); return model->send_test_event( target, receptor_type, syn_id, dummy_target ); } void proxynode::sends_secondary_event( GapJunctionEvent& ge ) { - kernel().model_manager.get_node_model( get_model_id() )->sends_secondary_event( ge ); + kernel::manager< ModelManager >.get_node_model( get_model_id() )->sends_secondary_event( ge ); } void proxynode::sends_secondary_event( InstantaneousRateConnectionEvent& re ) { - kernel().model_manager.get_node_model( get_model_id() )->sends_secondary_event( re ); + kernel::manager< ModelManager >.get_node_model( get_model_id() )->sends_secondary_event( re ); } void proxynode::sends_secondary_event( DiffusionConnectionEvent& de ) { - kernel().model_manager.get_node_model( get_model_id() )->sends_secondary_event( de ); + kernel::manager< ModelManager >.get_node_model( get_model_id() )->sends_secondary_event( de ); } void proxynode::sends_secondary_event( DelayedRateConnectionEvent& re ) { - kernel().model_manager.get_node_model( get_model_id() )->sends_secondary_event( re ); + kernel::manager< ModelManager >.get_node_model( get_model_id() )->sends_secondary_event( re ); } void proxynode::sends_secondary_event( LearningSignalConnectionEvent& re ) { - kernel().model_manager.get_node_model( get_model_id() )->sends_secondary_event( re ); + kernel::manager< ModelManager >.get_node_model( get_model_id() )->sends_secondary_event( re ); } void proxynode::sends_secondary_event( SICEvent& sic ) { - kernel().model_manager.get_node_model( get_model_id() )->sends_secondary_event( sic ); + kernel::manager< ModelManager >.get_node_model( get_model_id() )->sends_secondary_event( sic ); } nest::SignalType proxynode::sends_signal() const { - return kernel().model_manager.get_node_model( get_model_id() )->sends_signal(); + return kernel::manager< ModelManager >.get_node_model( get_model_id() )->sends_signal(); } void proxynode::get_status( DictionaryDatum& d ) const { - const Model* model = kernel().model_manager.get_node_model( model_id_ ); + const Model* model = kernel::manager< ModelManager >.get_node_model( model_id_ ); const Name element_type = model->get_prototype().get_element_type(); ( *d )[ names::element_type ] = LiteralDatum( element_type ); } - +bool +proxynode::is_proxy() const +{ + return true; +} } // namespace diff --git a/nestkernel/proxynode.h b/nestkernel/proxynode.h index 4207e8763e..b6f1703f1f 100644 --- a/nestkernel/proxynode.h +++ b/nestkernel/proxynode.h @@ -143,12 +143,6 @@ class proxynode : public Node } }; -inline bool -proxynode::is_proxy() const -{ - return true; -} - } // namespace #endif /* #ifndef PROXYNODE_H */ diff --git a/nestkernel/pseudo_recording_device.cpp b/nestkernel/pseudo_recording_device.cpp new file mode 100644 index 0000000000..b9ae056771 --- /dev/null +++ b/nestkernel/pseudo_recording_device.cpp @@ -0,0 +1,45 @@ +/* + * pseudo_recording_device.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "pseudo_recording_device.h" + +namespace nest +{ + +PseudoRecordingDevice::PseudoRecordingDevice() + : Device() +{ +} + +PseudoRecordingDevice::PseudoRecordingDevice( const PseudoRecordingDevice& prd ) + : Device( prd ) +{ +} + +bool +PseudoRecordingDevice::is_active( Time const& T ) const +{ + const long stamp = T.get_steps(); + return get_t_min_() < stamp and stamp <= get_t_max_(); +} + +} // namespace nest diff --git a/nestkernel/pseudo_recording_device.h b/nestkernel/pseudo_recording_device.h index caee7e5aab..5081f7380a 100644 --- a/nestkernel/pseudo_recording_device.h +++ b/nestkernel/pseudo_recording_device.h @@ -92,24 +92,6 @@ class PseudoRecordingDevice : public Device bool is_active( Time const& T ) const override; }; -inline PseudoRecordingDevice::PseudoRecordingDevice() - : Device() -{ -} - -inline PseudoRecordingDevice::PseudoRecordingDevice( const PseudoRecordingDevice& prd ) - : Device( prd ) -{ -} - -inline bool -PseudoRecordingDevice::is_active( Time const& T ) const -{ - const long stamp = T.get_steps(); - - return get_t_min_() < stamp and stamp <= get_t_max_(); -} - } // namespace #endif /* #ifndef PSEUDO_RECORDING_DEVICE_H */ diff --git a/nestkernel/random_manager.cpp b/nestkernel/random_manager.cpp index db0a58fd65..e1c0281783 100644 --- a/nestkernel/random_manager.cpp +++ b/nestkernel/random_manager.cpp @@ -27,9 +27,12 @@ #include // Includes from nestkernel: +#include "dictutils.h" #include "kernel_manager.h" +#include "mpi_manager.h" +#include "nest_names.h" #include "random_generators.h" -#include "vp_manager_impl.h" +#include "vp_manager.h" // Includes from libnestutil: #ifdef HAVE_RANDOM123 @@ -84,13 +87,13 @@ nest::RandomManager::initialize( const bool adjust_number_of_threads_or_rng_only // Create new RNGs of the currently used RNG type. rank_synced_rng_ = rng_types_[ current_rng_type_ ]->create( { base_seed_, RANK_SYNCED_SEEDER_ } ); - vp_synced_rngs_.resize( kernel().vp_manager.get_num_threads() ); - vp_specific_rngs_.resize( kernel().vp_manager.get_num_threads() ); + vp_synced_rngs_.resize( kernel::manager< VPManager >.get_num_threads() ); + vp_specific_rngs_.resize( kernel::manager< VPManager >.get_num_threads() ); #pragma omp parallel { - const auto tid = kernel().vp_manager.get_thread_id(); - const std::uint32_t vp = kernel().vp_manager.get_vp(); // type required for rng initializer + const auto tid = kernel::manager< VPManager >.get_thread_id(); + const std::uint32_t vp = kernel::manager< VPManager >.get_vp(); // type required for rng initializer vp_synced_rngs_[ tid ] = rng_types_[ current_rng_type_ ]->create( { base_seed_, THREAD_SYNCED_SEEDER_ } ); vp_specific_rngs_[ tid ] = rng_types_[ current_rng_type_ ]->create( { base_seed_, THREAD_SPECIFIC_SEEDER_, vp } ); } @@ -186,7 +189,7 @@ nest::RandomManager::check_rng_synchrony() const for ( auto n = 0; n < NUM_ROUNDS; ++n ) { const auto r = rank_synced_rng_->drand(); - if ( not kernel().mpi_manager.equal_cross_ranks( r ) ) + if ( not kernel::manager< MPIManager >.equal_cross_ranks( r ) ) { throw KernelException( "Rank-synchronized random number generators are out of sync." ); } @@ -195,7 +198,7 @@ nest::RandomManager::check_rng_synchrony() const // We check thread-synchrony under all circumstances to keep the code simple. for ( auto n = 0; n < NUM_ROUNDS; ++n ) { - const size_t num_threads = kernel().vp_manager.get_num_threads(); + const size_t num_threads = kernel::manager< VPManager >.get_num_threads(); double local_min = std::numeric_limits< double >::max(); double local_max = std::numeric_limits< double >::min(); for ( size_t t = 0; t < num_threads; ++t ) @@ -211,7 +214,7 @@ nest::RandomManager::check_rng_synchrony() const local_min = -std::numeric_limits< double >::infinity(); } - if ( not kernel().mpi_manager.equal_cross_ranks( local_min ) ) + if ( not kernel::manager< MPIManager >.equal_cross_ranks( local_min ) ) { throw KernelException( "Thread-synchronized random number generators are out of sync." ); } @@ -224,3 +227,24 @@ nest::RandomManager::register_rng_type( const std::string& name ) { rng_types_.insert( std::make_pair( name, new RandomGeneratorFactory< RNG_TYPE >() ) ); } + + +nest::RngPtr +nest::RandomManager::get_rank_synced_rng() const +{ + return rank_synced_rng_; +} + +nest::RngPtr +nest::RandomManager::get_vp_synced_rng( size_t tid ) const +{ + assert( tid < static_cast< size_t >( vp_specific_rngs_.size() ) ); + return vp_synced_rngs_[ tid ]; +} + +nest::RngPtr +nest::RandomManager::get_vp_specific_rng( size_t tid ) const +{ + assert( tid < static_cast< size_t >( vp_specific_rngs_.size() ) ); + return vp_specific_rngs_[ tid ]; +} diff --git a/nestkernel/random_manager.h b/nestkernel/random_manager.h index 5956f54b0d..c7efc53407 100644 --- a/nestkernel/random_manager.h +++ b/nestkernel/random_manager.h @@ -145,26 +145,6 @@ class RandomManager : public ManagerInterface static const std::uint32_t THREAD_SPECIFIC_SEEDER_; }; -inline RngPtr -nest::RandomManager::get_rank_synced_rng() const -{ - return rank_synced_rng_; -} - -inline RngPtr -nest::RandomManager::get_vp_synced_rng( size_t tid ) const -{ - assert( tid < static_cast< size_t >( vp_specific_rngs_.size() ) ); - return vp_synced_rngs_[ tid ]; -} - -inline RngPtr -nest::RandomManager::get_vp_specific_rng( size_t tid ) const -{ - assert( tid < static_cast< size_t >( vp_specific_rngs_.size() ) ); - return vp_specific_rngs_[ tid ]; -} - } // namespace nest #endif /* RANDOM_MANAGER_H */ diff --git a/nestkernel/recording_backend_ascii.cpp b/nestkernel/recording_backend_ascii.cpp index 773aa36a82..b0474b0177 100644 --- a/nestkernel/recording_backend_ascii.cpp +++ b/nestkernel/recording_backend_ascii.cpp @@ -24,13 +24,17 @@ #include "compose.hpp" // Includes from nestkernel: +#include "io_manager.h" +#include "logging.h" +#include "logging_manager.h" +#include "node_manager.h" +#include "recording_backend_ascii.h" #include "recording_device.h" -#include "vp_manager_impl.h" +#include "simulation_manager.h" // includes from sli: #include "dictutils.h" -#include "recording_backend_ascii.h" const unsigned int nest::RecordingBackendASCII::ASCII_REC_BACKEND_VERSION = 2; @@ -45,7 +49,7 @@ nest::RecordingBackendASCII::~RecordingBackendASCII() throw() void nest::RecordingBackendASCII::initialize() { - data_map tmp( kernel().vp_manager.get_num_threads() ); + data_map tmp( kernel::manager< VPManager >.get_num_threads() ); device_data_.swap( tmp ); } @@ -156,8 +160,8 @@ nest::RecordingBackendASCII::write( const RecordingDevice& device, const std::string nest::RecordingBackendASCII::compute_vp_node_id_string_( const RecordingDevice& device ) const { - const double num_vps = kernel().vp_manager.get_num_virtual_processes(); - const double num_nodes = kernel().node_manager.size(); + const double num_vps = kernel::manager< VPManager >.get_num_virtual_processes(); + const double num_nodes = kernel::manager< NodeManager >.size(); const int vp_digits = static_cast< int >( std::floor( std::log10( num_vps ) ) + 1 ); const int node_id_digits = static_cast< int >( std::floor( std::log10( num_nodes ) ) + 1 ); @@ -251,7 +255,7 @@ nest::RecordingBackendASCII::DeviceData::open_file() std::string filename = compute_filename_(); std::ifstream test( filename.c_str() ); - if ( test.good() and not kernel().io_manager.overwrite_files() ) + if ( test.good() and not kernel::manager< IOManager >.overwrite_files() ) { std::string msg = String::compose( "The file '%1' already exists and overwriting files is disabled. To overwrite files, set " @@ -344,7 +348,7 @@ nest::RecordingBackendASCII::DeviceData::set_status( const DictionaryDatum& d ) bool time_in_steps = false; if ( updateValue< bool >( d, names::time_in_steps, time_in_steps ) ) { - if ( kernel().simulation_manager.has_been_simulated() ) + if ( kernel::manager< SimulationManager >.has_been_simulated() ) { throw BadProperty( "Property time_in_steps cannot be set after Simulate has been called." ); } @@ -356,7 +360,7 @@ nest::RecordingBackendASCII::DeviceData::set_status( const DictionaryDatum& d ) std::string nest::RecordingBackendASCII::DeviceData::compute_filename_() const { - std::string data_path = kernel().io_manager.get_data_path(); + std::string data_path = kernel::manager< IOManager >.get_data_path(); if ( not data_path.empty() and not( data_path[ data_path.size() - 1 ] == '/' ) ) { data_path += '/'; @@ -368,7 +372,7 @@ nest::RecordingBackendASCII::DeviceData::compute_filename_() const label = modelname_; } - std::string data_prefix = kernel().io_manager.get_data_prefix(); + std::string data_prefix = kernel::manager< IOManager >.get_data_prefix(); return data_path + data_prefix + label + vp_node_id_string_ + "." + file_extension_; } diff --git a/nestkernel/recording_backend_memory.cpp b/nestkernel/recording_backend_memory.cpp index 3ff816c685..ef5111b396 100644 --- a/nestkernel/recording_backend_memory.cpp +++ b/nestkernel/recording_backend_memory.cpp @@ -21,10 +21,11 @@ */ // Includes from nestkernel: +#include "recording_backend_memory.h" #include "recording_device.h" -#include "vp_manager_impl.h" +#include "simulation_manager.h" -#include "recording_backend_memory.h" +#include nest::RecordingBackendMemory::RecordingBackendMemory() { @@ -37,7 +38,7 @@ nest::RecordingBackendMemory::~RecordingBackendMemory() throw() void nest::RecordingBackendMemory::initialize() { - device_data_map tmp( kernel().vp_manager.get_num_threads() ); + device_data_map tmp( kernel::manager< VPManager >.get_num_threads() ); device_data_.swap( tmp ); } @@ -266,7 +267,7 @@ nest::RecordingBackendMemory::DeviceData::set_status( const DictionaryDatum& d ) bool time_in_steps = false; if ( updateValue< bool >( d, names::time_in_steps, time_in_steps ) ) { - if ( kernel().simulation_manager.has_been_simulated() ) + if ( kernel::manager< SimulationManager >.has_been_simulated() ) { throw BadProperty( "Property time_in_steps cannot be set after Simulate has been called." ); } diff --git a/nestkernel/recording_backend_mpi.cpp b/nestkernel/recording_backend_mpi.cpp index 3c048211a0..d2c9fb9cfd 100644 --- a/nestkernel/recording_backend_mpi.cpp +++ b/nestkernel/recording_backend_mpi.cpp @@ -22,10 +22,13 @@ // C++ includes: #include - +#include // Includes from nestkernel: #include "exceptions.h" +#include "io_manager.h" +#include "logging.h" +#include "logging_manager.h" #include "recording_backend_mpi.h" #include "recording_device.h" @@ -43,7 +46,7 @@ nest::RecordingBackendMPI::~RecordingBackendMPI() throw() void nest::RecordingBackendMPI::initialize() { - auto nthreads = kernel().vp_manager.get_num_threads(); + auto nthreads = kernel::manager< VPManager >.get_num_threads(); std::vector< std::vector< std::vector< std::array< double, 3 > > > > empty_vector( nthreads ); buffer_.swap( empty_vector ); device_map devices( nthreads ); @@ -129,14 +132,14 @@ nest::RecordingBackendMPI::prepare() } prepared_ = true; size_t thread_id_master = 0; -#pragma omp parallel default( none ) shared( thread_id_master ) +#pragma omp parallel shared( thread_id_master ) { #pragma omp master { // Create the connection with MPI // 1) take all the ports of the connections // get port and update the list of devices - thread_id_master = kernel().vp_manager.get_thread_id(); + thread_id_master = kernel::manager< VPManager >.get_thread_id(); } } int count_max = 0; @@ -187,10 +190,10 @@ nest::RecordingBackendMPI::prepare() msg << "Connect to " << it_comm.first.data() << "\n"; LOG( M_INFO, "MPI Record connect", msg.str() ); } -#pragma omp parallel default( none ) shared( thread_id_master ) +#pragma omp parallel shared( thread_id_master ) { // Update all the threads - size_t thread_id = kernel().vp_manager.get_thread_id(); + size_t thread_id = kernel::manager< VPManager >.get_thread_id(); if ( thread_id != thread_id_master ) { for ( auto& it_device : devices_[ thread_id ] ) @@ -290,7 +293,7 @@ nest::RecordingBackendMPI::cleanup() } // clear map of device commMap_.clear(); - size_t thread_id_master = kernel().vp_manager.get_thread_id(); + size_t thread_id_master = kernel::manager< VPManager >.get_thread_id(); for ( auto& it_device : devices_[ thread_id_master ] ) { std::get< 0 >( it_device.second ) = -1; @@ -326,7 +329,7 @@ nest::RecordingBackendMPI::write( const RecordingDevice& device, const std::vector< long >& ) { // For each event send a message through the right MPI communicator - const size_t thread_id = kernel().get_kernel_manager().vp_manager.get_thread_id(); + const size_t thread_id = kernel::manager< VPManager >.get_thread_id(); const size_t sender = event.get_sender_node_id(); const size_t recorder = device.get_node_id(); const Time stamp = event.get_stamp(); @@ -385,12 +388,12 @@ nest::RecordingBackendMPI::get_port( const size_t index_node, const std::string& // path of the file : path+label+id+.txt // (file contains only one line with name of the port ) std::ostringstream basename; - const std::string& path = kernel().io_manager.get_data_path(); + const std::string& path = kernel::manager< IOManager >.get_data_path(); if ( not path.empty() ) { basename << path << '/'; } - basename << kernel().io_manager.get_data_prefix(); + basename << kernel::manager< IOManager >.get_data_prefix(); if ( not label.empty() ) { diff --git a/nestkernel/recording_backend_screen.cpp b/nestkernel/recording_backend_screen.cpp index 9b31ea6f57..06351d1460 100644 --- a/nestkernel/recording_backend_screen.cpp +++ b/nestkernel/recording_backend_screen.cpp @@ -28,10 +28,12 @@ #include "recording_backend_screen.h" +#include + void nest::RecordingBackendScreen::initialize() { - device_data_map tmp( kernel().vp_manager.get_num_threads() ); + device_data_map tmp( kernel::manager< VPManager >.get_num_threads() ); device_data_.swap( tmp ); } diff --git a/nestkernel/recording_backend_sionlib.cpp b/nestkernel/recording_backend_sionlib.cpp index 5aabb26ebc..7a7d7eeb0a 100644 --- a/nestkernel/recording_backend_sionlib.cpp +++ b/nestkernel/recording_backend_sionlib.cpp @@ -32,14 +32,13 @@ // Includes from libnestutil: #include "compose.hpp" -// Includes from nest: -#include "../nest/neststartup.h" - // Includes from nestkernel: -#include "recording_device.h" -#include "vp_manager_impl.h" - +#include "io_manager.h" +#include "logging.h" +#include "logging_manager.h" #include "recording_backend_sionlib.h" +#include "recording_device.h" +#include "simulation_manager.h" const unsigned int nest::RecordingBackendSIONlib::SIONLIB_REC_BACKEND_VERSION = 2; const unsigned int nest::RecordingBackendSIONlib::DEV_NAME_BUFFERSIZE = 32; @@ -61,7 +60,7 @@ nest::RecordingBackendSIONlib::~RecordingBackendSIONlib() throw() void nest::RecordingBackendSIONlib::initialize() { - device_map devices( kernel().vp_manager.get_num_threads() ); + device_map devices( kernel::manager< VPManager >.get_num_threads() ); devices_.swap( devices ); } @@ -170,11 +169,11 @@ nest::RecordingBackendSIONlib::open_files_() WrappedThreadException* we = nullptr; // This code is executed in a parallel region (opened above)! - const size_t t = kernel().vp_manager.get_thread_id(); - const size_t task = kernel().vp_manager.thread_to_vp( t ); + const size_t t = kernel::manager< VPManager >.get_thread_id(); + const size_t task = kernel::manager< VPManager >.thread_to_vp( t ); if ( not task ) { - t_start_ = kernel().simulation_manager.get_time().get_ms(); + t_start_ = kernel::manager< SimulationManager >.get_time().get_ms(); } // set n_rec counters to zero in every device on every thread @@ -199,7 +198,7 @@ nest::RecordingBackendSIONlib::open_files_() std::string filename = build_filename_(); std::ifstream test( filename.c_str() ); - if ( test.good() & not kernel().io_manager.overwrite_files() ) + if ( test.good() & not kernel::manager< IOManager >.overwrite_files() ) { std::string msg = String::compose( "The device file '%1' exists already and will not be overwritten. " @@ -218,12 +217,12 @@ nest::RecordingBackendSIONlib::open_files_() #endif /* BG_MULTIFILE */ sion_int32 fs_block_size = -1; sion_int64 sion_chunksize = P_.sion_chunksize_; - int rank = kernel().mpi_manager.get_rank(); + int rank = kernel::manager< MPIManager >.get_rank(); file.sid = sion_paropen_ompi( filename.c_str(), P_.sion_collective_ ? "bw,cmerge,collsize=-1" : "bw", &n_files, - kernel().mpi_manager.get_communicator(), + kernel::manager< MPIManager >.get_communicator(), &local_comm, &sion_chunksize, &fs_block_size, @@ -273,8 +272,8 @@ nest::RecordingBackendSIONlib::close_files_() #pragma omp parallel { - const size_t t = kernel().vp_manager.get_thread_id(); - const size_t task = kernel().vp_manager.thread_to_vp( t ); + const size_t t = kernel::manager< VPManager >.get_thread_id(); + const size_t task = kernel::manager< VPManager >.thread_to_vp( t ); assert( ( files_.find( task ) != files_.end() ) and "initialize() was not called before calling cleanup()" ); @@ -307,7 +306,8 @@ nest::RecordingBackendSIONlib::close_files_() // accumulate number of recorded data points over all ranks unsigned long n_rec_total = 0; - MPI_Reduce( &n_rec, &n_rec_total, 1, MPI_UNSIGNED_LONG, MPI_SUM, 0, kernel().mpi_manager.get_communicator() ); + MPI_Reduce( + &n_rec, &n_rec_total, 1, MPI_UNSIGNED_LONG, MPI_SUM, 0, kernel::manager< MPIManager >.get_communicator() ); assert( sizeof( unsigned long ) <= sizeof( sion_uint64 ) ); it->second.info.n_rec = static_cast< sion_uint64 >( n_rec_total ); } @@ -328,7 +328,7 @@ nest::RecordingBackendSIONlib::close_files_() sion_int64 info_pos; } data_end = { info_blk, info_pos }; - double t_end = kernel().simulation_manager.get_time().get_ms(); + double t_end = kernel::manager< SimulationManager >.get_time().get_ms(); double resolution = Time::get_resolution().get_ms(); sion_fwrite( &t_start_, sizeof( double ), 1, file.sid ); @@ -521,12 +521,12 @@ const std::string nest::RecordingBackendSIONlib::build_filename_() const { std::ostringstream basename; - const std::string& path = kernel().io_manager.get_data_path(); + const std::string& path = kernel::manager< IOManager >.get_data_path(); if ( not path.empty() ) { basename << path << '/'; } - basename << kernel().io_manager.get_data_prefix(); + basename << kernel::manager< IOManager >.get_data_prefix(); return basename.str() + P_.filename_; } @@ -676,8 +676,8 @@ nest::RecordingBackendSIONlib::post_step_hook() return; } - const size_t t = kernel().vp_manager.get_thread_id(); - const size_t task = kernel().vp_manager.thread_to_vp( t ); + const size_t t = kernel::manager< VPManager >.get_thread_id(); + const size_t task = kernel::manager< VPManager >.thread_to_vp( t ); FileEntry& file = files_[ task ]; SIONBuffer& buffer = file.buffer; @@ -703,3 +703,15 @@ nest::RecordingBackendSIONlib::get_device_status( const nest::RecordingDevice&, { // nothing to do } + +size_t +nest::RecordingBackendSIONlib::SIONBuffer::get_size() +{ + return ptr_; +} + +size_t +nest::RecordingBackendSIONlib::SIONBuffer::get_capacity() +{ + return max_size_; +} diff --git a/nestkernel/recording_backend_sionlib.h b/nestkernel/recording_backend_sionlib.h index ea7ea77753..9333da6e58 100644 --- a/nestkernel/recording_backend_sionlib.h +++ b/nestkernel/recording_backend_sionlib.h @@ -261,17 +261,9 @@ class RecordingBackendSIONlib : public RecordingBackend void ensure_space( size_t size ); void write( const char* v, size_t n ); - size_t - get_capacity() - { - return max_size_; - }; + size_t get_capacity(); - size_t - get_size() - { - return ptr_; - }; + size_t get_size(); size_t get_free() diff --git a/nestkernel/recording_device.cpp b/nestkernel/recording_device.cpp index 205fde2e6b..f3946692ac 100644 --- a/nestkernel/recording_device.cpp +++ b/nestkernel/recording_device.cpp @@ -21,10 +21,13 @@ */ // Includes from libnestutil: +#include "recording_device.h" #include "compose.hpp" +#include "io_manager.h" #include "kernel_manager.h" +#include "simulation_manager.h" -#include "recording_device.h" +#include nest::RecordingDevice::RecordingDevice() : DeviceNode() @@ -45,7 +48,7 @@ nest::RecordingDevice::RecordingDevice( const RecordingDevice& rd ) void nest::RecordingDevice::set_initialized_() { - kernel().io_manager.enroll_recorder( P_.record_to_, *this, backend_params_ ); + kernel::manager< IOManager >.enroll_recorder( P_.record_to_, *this, backend_params_ ); } void @@ -53,7 +56,7 @@ nest::RecordingDevice::pre_run_hook( const std::vector< Name >& double_value_nam const std::vector< Name >& long_value_names ) { Device::pre_run_hook(); - kernel().io_manager.set_recording_value_names( P_.record_to_, *this, double_value_names, long_value_names ); + kernel::manager< IOManager >.set_recording_value_names( P_.record_to_, *this, double_value_names, long_value_names ); } const std::string& @@ -83,7 +86,7 @@ nest::RecordingDevice::Parameters_::set( const DictionaryDatum& d ) std::string record_to; if ( updateValue< std::string >( d, names::record_to, record_to ) ) { - if ( not kernel().io_manager.is_valid_recording_backend( record_to ) ) + if ( not kernel::manager< IOManager >.is_valid_recording_backend( record_to ) ) { std::string msg = String::compose( "Unknown recording backend '%1'", record_to ); throw BadProperty( msg ); @@ -124,7 +127,7 @@ nest::RecordingDevice::State_::set( const DictionaryDatum& d ) void nest::RecordingDevice::set_status( const DictionaryDatum& d ) { - if ( kernel().simulation_manager.has_been_prepared() ) + if ( kernel::manager< SimulationManager >.has_been_prepared() ) { throw BadProperty( "Recorder parameters cannot be changed while inside a Prepare/Run/Cleanup context." ); } @@ -150,7 +153,7 @@ nest::RecordingDevice::set_status( const DictionaryDatum& d ) } } - kernel().io_manager.check_recording_backend_device_status( ptmp.record_to_, backend_params ); + kernel::manager< IOManager >.check_recording_backend_device_status( ptmp.record_to_, backend_params ); // cache all properties accessed by the backend in private member backend_params_->clear(); @@ -165,7 +168,7 @@ nest::RecordingDevice::set_status( const DictionaryDatum& d ) } else { - kernel().io_manager.enroll_recorder( ptmp.record_to_, *this, d ); + kernel::manager< IOManager >.enroll_recorder( ptmp.record_to_, *this, d ); } // if we get here, temporaries contain consistent set of properties @@ -186,7 +189,7 @@ nest::RecordingDevice::get_status( DictionaryDatum& d ) const if ( get_node_id() == 0 ) // this is a model prototype, not an actual instance { // first get the defaults from the backend - kernel().io_manager.get_recording_backend_device_defaults( P_.record_to_, d ); + kernel::manager< IOManager >.get_recording_backend_device_defaults( P_.record_to_, d ); // then overwrite with cached parameters for ( auto kv_pair = backend_params_->begin(); kv_pair != backend_params_->end(); ++kv_pair ) @@ -196,7 +199,7 @@ nest::RecordingDevice::get_status( DictionaryDatum& d ) const } else { - kernel().io_manager.get_recording_backend_device_status( P_.record_to_, *this, d ); + kernel::manager< IOManager >.get_recording_backend_device_status( P_.record_to_, *this, d ); } } @@ -213,6 +216,6 @@ nest::RecordingDevice::write( const Event& event, const std::vector< double >& double_values, const std::vector< long >& long_values ) { - kernel().io_manager.write( P_.record_to_, *this, event, double_values, long_values ); + kernel::manager< IOManager >.write( P_.record_to_, *this, event, double_values, long_values ); S_.n_events_++; } diff --git a/nestkernel/ring_buffer.cpp b/nestkernel/ring_buffer.cpp index 48ee802b1c..cd409f66ed 100644 --- a/nestkernel/ring_buffer.cpp +++ b/nestkernel/ring_buffer.cpp @@ -20,17 +20,21 @@ * */ -#include "ring_buffer.h" +#include "connection_manager.h" +#include "ring_buffer_impl.h" nest::RingBuffer::RingBuffer() - : buffer_( kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay(), 0.0 ) + : buffer_( + kernel::manager< ConnectionManager >.get_min_delay() + kernel::manager< ConnectionManager >.get_max_delay(), + 0.0 ) { } void nest::RingBuffer::resize() { - size_t size = kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay(); + size_t size = + kernel::manager< ConnectionManager >.get_min_delay() + kernel::manager< ConnectionManager >.get_max_delay(); if ( buffer_.size() != size ) { buffer_.resize( size ); @@ -47,14 +51,17 @@ nest::RingBuffer::clear() nest::MultRBuffer::MultRBuffer() - : buffer_( kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay(), 0.0 ) + : buffer_( + kernel::manager< ConnectionManager >.get_min_delay() + kernel::manager< ConnectionManager >.get_max_delay(), + 0.0 ) { } void nest::MultRBuffer::resize() { - size_t size = kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay(); + size_t size = + kernel::manager< ConnectionManager >.get_min_delay() + kernel::manager< ConnectionManager >.get_max_delay(); if ( buffer_.size() != size ) { buffer_.resize( size ); @@ -70,14 +77,16 @@ nest::MultRBuffer::clear() nest::ListRingBuffer::ListRingBuffer() - : buffer_( kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay() ) + : buffer_( + kernel::manager< ConnectionManager >.get_min_delay() + kernel::manager< ConnectionManager >.get_max_delay() ) { } void nest::ListRingBuffer::resize() { - size_t size = kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay(); + size_t size = + kernel::manager< ConnectionManager >.get_min_delay() + kernel::manager< ConnectionManager >.get_max_delay(); if ( buffer_.size() != size ) { buffer_.resize( size ); @@ -94,3 +103,109 @@ nest::ListRingBuffer::clear() buffer_[ i ].clear(); } } + + +void +nest::RingBuffer::add_value( const long offs, const double v ) +{ + buffer_[ get_index_( offs ) ] += v; +} + +void +nest::RingBuffer::set_value( const long offs, const double v ) +{ + buffer_[ get_index_( offs ) ] = v; +} + +double +nest::RingBuffer::get_value( const long offs ) +{ + assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); + assert( offs < kernel::manager< ConnectionManager >.get_min_delay() ); + + // offs == 0 is beginning of slice, but we have to + // take modulo into account when indexing + long idx = get_index_( offs ); + double val = buffer_[ idx ]; + buffer_[ idx ] = 0.0; // clear buffer after reading + return val; +} + +double +nest::RingBuffer::get_value_wfr_update( const long offs ) +{ + assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); + assert( offs < kernel::manager< ConnectionManager >.get_min_delay() ); + + // offs == 0 is beginning of slice, but we have to + // take modulo into account when indexing + long idx = get_index_( offs ); + double val = buffer_[ idx ]; + return val; +} + +size_t +nest::RingBuffer::get_index_( const long d ) const +{ + const long idx = kernel::manager< EventDeliveryManager >.get_modulo( d ); + assert( 0 <= idx ); + assert( static_cast< size_t >( idx ) < buffer_.size() ); + return idx; +} + + +void +nest::MultRBuffer::add_value( const long offs, const double v ) +{ + assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); + buffer_[ get_index_( offs ) ] *= v; +} + +double +nest::MultRBuffer::get_value( const long offs ) +{ + assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); + assert( offs < kernel::manager< ConnectionManager >.get_min_delay() ); + + // offs == 0 is beginning of slice, but we have to + // take modulo into account when indexing + long idx = get_index_( offs ); + double val = buffer_[ idx ]; + buffer_[ idx ] = 0.0; // clear buffer after reading + return val; +} + +size_t +nest::MultRBuffer::get_index_( const long d ) const +{ + const long idx = kernel::manager< EventDeliveryManager >.get_modulo( d ); + assert( 0 <= idx and static_cast< size_t >( idx ) < buffer_.size() ); + return idx; +} + +void +nest::ListRingBuffer::append_value( const long offs, const double v ) +{ + buffer_[ get_index_( offs ) ].push_back( v ); +} + +std::list< double >& +nest::ListRingBuffer::get_list( const long offs ) +{ + assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); + assert( offs < kernel::manager< ConnectionManager >.get_min_delay() ); + + // offs == 0 is beginning of slice, but we have to + // take modulo into account when indexing + long idx = get_index_( offs ); + return buffer_[ idx ]; +} + +size_t +nest::ListRingBuffer::get_index_( const long d ) const +{ + const long idx = kernel::manager< EventDeliveryManager >.get_modulo( d ); + assert( 0 <= idx ); + assert( static_cast< size_t >( idx ) < buffer_.size() ); + return idx; +} diff --git a/nestkernel/ring_buffer.h b/nestkernel/ring_buffer.h index 9e7328f766..ab04a8c424 100644 --- a/nestkernel/ring_buffer.h +++ b/nestkernel/ring_buffer.h @@ -29,9 +29,7 @@ #include // Includes from nestkernel: -#include "kernel_manager.h" -#include "nest_time.h" -#include "nest_types.h" +#include "event_delivery_manager.h" namespace nest { @@ -154,54 +152,6 @@ class RingBuffer size_t get_index_( const long d ) const; }; -inline void -RingBuffer::add_value( const long offs, const double v ) -{ - buffer_[ get_index_( offs ) ] += v; -} - -inline void -RingBuffer::set_value( const long offs, const double v ) -{ - buffer_[ get_index_( offs ) ] = v; -} - -inline double -RingBuffer::get_value( const long offs ) -{ - assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); - assert( offs < kernel().connection_manager.get_min_delay() ); - - // offs == 0 is beginning of slice, but we have to - // take modulo into account when indexing - long idx = get_index_( offs ); - double val = buffer_[ idx ]; - buffer_[ idx ] = 0.0; // clear buffer after reading - return val; -} - -inline double -RingBuffer::get_value_wfr_update( const long offs ) -{ - assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); - assert( offs < kernel().connection_manager.get_min_delay() ); - - // offs == 0 is beginning of slice, but we have to - // take modulo into account when indexing - long idx = get_index_( offs ); - double val = buffer_[ idx ]; - return val; -} - -inline size_t -RingBuffer::get_index_( const long d ) const -{ - const long idx = kernel().event_delivery_manager.get_modulo( d ); - assert( 0 <= idx ); - assert( static_cast< size_t >( idx ) < buffer_.size() ); - return idx; -} - class MultRBuffer { @@ -255,35 +205,6 @@ class MultRBuffer size_t get_index_( const long d ) const; }; -inline void -MultRBuffer::add_value( const long offs, const double v ) -{ - assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); - buffer_[ get_index_( offs ) ] *= v; -} - -inline double -MultRBuffer::get_value( const long offs ) -{ - assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); - assert( offs < kernel().connection_manager.get_min_delay() ); - - // offs == 0 is beginning of slice, but we have to - // take modulo into account when indexing - long idx = get_index_( offs ); - double val = buffer_[ idx ]; - buffer_[ idx ] = 0.0; // clear buffer after reading - return val; -} - -inline size_t -MultRBuffer::get_index_( const long d ) const -{ - const long idx = kernel().event_delivery_manager.get_modulo( d ); - assert( 0 <= idx and static_cast< size_t >( idx ) < buffer_.size() ); - return idx; -} - class ListRingBuffer { @@ -337,33 +258,6 @@ class ListRingBuffer size_t get_index_( const long d ) const; }; -inline void -ListRingBuffer::append_value( const long offs, const double v ) -{ - buffer_[ get_index_( offs ) ].push_back( v ); -} - -inline std::list< double >& -ListRingBuffer::get_list( const long offs ) -{ - assert( 0 <= offs and static_cast< size_t >( offs ) < buffer_.size() ); - assert( offs < kernel().connection_manager.get_min_delay() ); - - // offs == 0 is beginning of slice, but we have to - // take modulo into account when indexing - long idx = get_index_( offs ); - return buffer_[ idx ]; -} - -inline size_t -ListRingBuffer::get_index_( const long d ) const -{ - const long idx = kernel().event_delivery_manager.get_modulo( d ); - assert( 0 <= idx ); - assert( static_cast< size_t >( idx ) < buffer_.size() ); - return idx; -} - template < unsigned int num_channels > class MultiChannelInputBuffer @@ -392,37 +286,6 @@ class MultiChannelInputBuffer std::vector< std::array< double, num_channels > > buffer_; }; -template < unsigned int num_channels > -inline void -MultiChannelInputBuffer< num_channels >::reset_values_all_channels( const size_t slot ) -{ - assert( slot < buffer_.size() ); - buffer_[ slot ].fill( 0.0 ); -} - -template < unsigned int num_channels > -inline void -MultiChannelInputBuffer< num_channels >::add_value( const size_t slot, const size_t channel, const double value ) -{ - buffer_[ slot ][ channel ] += value; -} - -template < unsigned int num_channels > -inline const std::array< double, num_channels >& -MultiChannelInputBuffer< num_channels >::get_values_all_channels( const size_t slot ) const -{ - assert( slot < buffer_.size() ); - return buffer_[ slot ]; -} - -template < unsigned int num_channels > -inline size_t -MultiChannelInputBuffer< num_channels >::size() const -{ - return buffer_.size(); -} - } // namespace nest - #endif /* #ifndef RING_BUFFER_H */ diff --git a/nestkernel/ring_buffer_impl.h b/nestkernel/ring_buffer_impl.h index 76db8a6fb6..73e5332b7b 100644 --- a/nestkernel/ring_buffer_impl.h +++ b/nestkernel/ring_buffer_impl.h @@ -25,18 +25,53 @@ #include "ring_buffer.h" +namespace nest +{ + +template < unsigned int num_channels > +inline void +MultiChannelInputBuffer< num_channels >::reset_values_all_channels( const size_t slot ) +{ + assert( slot < buffer_.size() ); + buffer_[ slot ].fill( 0.0 ); +} + +template < unsigned int num_channels > +inline void +MultiChannelInputBuffer< num_channels >::add_value( const size_t slot, const size_t channel, const double value ) +{ + buffer_[ slot ][ channel ] += value; +} + template < unsigned int num_channels > -nest::MultiChannelInputBuffer< num_channels >::MultiChannelInputBuffer() - : buffer_( kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay(), +inline const std::array< double, num_channels >& +MultiChannelInputBuffer< num_channels >::get_values_all_channels( const size_t slot ) const +{ + assert( slot < buffer_.size() ); + return buffer_[ slot ]; +} + +template < unsigned int num_channels > +inline size_t +MultiChannelInputBuffer< num_channels >::size() const +{ + return buffer_.size(); +} + +template < unsigned int num_channels > +MultiChannelInputBuffer< num_channels >::MultiChannelInputBuffer() + : buffer_( + kernel::manager< ConnectionManager >.get_min_delay() + kernel::manager< ConnectionManager >.get_max_delay(), std::array< double, num_channels >() ) { } template < unsigned int num_channels > void -nest::MultiChannelInputBuffer< num_channels >::resize() +MultiChannelInputBuffer< num_channels >::resize() { - const size_t size = kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay(); + const size_t size = + kernel::manager< ConnectionManager >.get_min_delay() + kernel::manager< ConnectionManager >.get_max_delay(); if ( buffer_.size() != size ) { buffer_.resize( size, std::array< double, num_channels >() ); @@ -45,7 +80,7 @@ nest::MultiChannelInputBuffer< num_channels >::resize() template < unsigned int num_channels > void -nest::MultiChannelInputBuffer< num_channels >::clear() +MultiChannelInputBuffer< num_channels >::clear() { resize(); // does nothing if size is fine // set all elements to 0.0 @@ -55,4 +90,6 @@ nest::MultiChannelInputBuffer< num_channels >::clear() } } +} + #endif diff --git a/nestkernel/secondary_event.cpp b/nestkernel/secondary_event.cpp new file mode 100644 index 0000000000..bb9f2ed7a6 --- /dev/null +++ b/nestkernel/secondary_event.cpp @@ -0,0 +1,89 @@ +/* + * secondary_event.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + + +#include "secondary_event_impl.h" + +namespace nest +{ + +// ----- GapJunctionEvent ------------------------------------------------------ + +GapJunctionEvent* +GapJunctionEvent::clone() const +{ + return new GapJunctionEvent( *this ); +} + +// ----- InstantaneousRateConnectionEvent -------------------------------------- + +InstantaneousRateConnectionEvent* +InstantaneousRateConnectionEvent::clone() const +{ + return new InstantaneousRateConnectionEvent( *this ); +} + +// ----- DelayedRateConnectionEvent -------------------------------------------- + +DelayedRateConnectionEvent* +DelayedRateConnectionEvent::clone() const +{ + return new DelayedRateConnectionEvent( *this ); +} + +// ----- DiffusionConnectionEvent ---------------------------------------------- + +DiffusionConnectionEvent* +DiffusionConnectionEvent::clone() const +{ + return new DiffusionConnectionEvent( *this ); +} + +double +DiffusionConnectionEvent::get_drift_factor() const +{ + return drift_factor_; +} + +double +DiffusionConnectionEvent::get_diffusion_factor() const +{ + return diffusion_factor_; +} + +// ----- LearningSignalConnectionEvent ----------------------------------------- + +LearningSignalConnectionEvent* +LearningSignalConnectionEvent::clone() const +{ + return new LearningSignalConnectionEvent( *this ); +} + +// ----- SICEvent --------------------------------------------------------------- + +SICEvent* +SICEvent::clone() const +{ + return new SICEvent( *this ); +} + +} // namespace nest diff --git a/nestkernel/secondary_event.h b/nestkernel/secondary_event.h index 00676e68f1..ad40bf70b3 100644 --- a/nestkernel/secondary_event.h +++ b/nestkernel/secondary_event.h @@ -32,6 +32,8 @@ namespace nest { +class SICEvent; + /** * Base class of secondary events. Provides interface for * serialization and deserialization. This event type may be @@ -112,33 +114,6 @@ write_to_comm_buffer( T d, std::vector< unsigned int >::iterator& pos ) pos += num_uints; } -/** - * This template function reads data of type T from a given position of a - * std::vector< unsigned int >. The function is used to read SecondaryEvents - * data from the NEST communication buffer. The pos iterator is advanced - * during execution. For a discussion on the functionality of this function see - * github issue #181 and pull request #184. - */ -template < typename T > -void -read_from_comm_buffer( T& d, std::vector< unsigned int >::iterator& pos ) -{ - // there is no aliasing problem here, since cast to char* invalidate strict - // aliasing assumptions - char* const c = reinterpret_cast< char* >( &d ); - - const size_t num_uints = number_of_uints_covered< T >(); - size_t left_to_copy = sizeof( T ); - - for ( size_t i = 0; i < num_uints; i++ ) - { - memcpy( c + i * sizeof( unsigned int ), &( *( pos + i ) ), std::min( left_to_copy, sizeof( unsigned int ) ) ); - left_to_copy -= sizeof( unsigned int ); - } - - pos += num_uints; -} - /** * Template class for the storage and communication of a std::vector of type * DataType. The class provides the functionality to communicate homogeneous @@ -248,6 +223,7 @@ class DataSecondaryEvent : public SecondaryEvent return pos; } + /** * The following operator is used to write the information of the * DataSecondaryEvent into the secondary_events_buffer_. @@ -392,86 +368,6 @@ class LearningSignalConnectionEvent : public DataSecondaryEvent< double, Learnin LearningSignalConnectionEvent* clone() const override; }; -template < typename DataType, typename Subclass > -inline DataType -DataSecondaryEvent< DataType, Subclass >::get_coeffvalue( std::vector< unsigned int >::iterator& pos ) -{ - DataType elem; - read_from_comm_buffer( elem, pos ); - return elem; -} - -template < typename DataType, typename Subclass > -std::set< synindex > DataSecondaryEvent< DataType, Subclass >::supported_syn_ids_; - -template < typename DataType, typename Subclass > -size_t DataSecondaryEvent< DataType, Subclass >::coeff_length_ = 0; - -inline GapJunctionEvent* -GapJunctionEvent::clone() const -{ - return new GapJunctionEvent( *this ); -} - -inline InstantaneousRateConnectionEvent* -InstantaneousRateConnectionEvent::clone() const -{ - return new InstantaneousRateConnectionEvent( *this ); -} - -inline DelayedRateConnectionEvent* -DelayedRateConnectionEvent::clone() const -{ - return new DelayedRateConnectionEvent( *this ); -} - -inline DiffusionConnectionEvent* -DiffusionConnectionEvent::clone() const -{ - return new DiffusionConnectionEvent( *this ); -} - -inline double -DiffusionConnectionEvent::get_drift_factor() const -{ - return drift_factor_; -} - -inline double -DiffusionConnectionEvent::get_diffusion_factor() const -{ - return diffusion_factor_; -} - -inline LearningSignalConnectionEvent* -LearningSignalConnectionEvent::clone() const -{ - return new LearningSignalConnectionEvent( *this ); -} - -/** - * Event for slow inward current (SIC) connections between astrocytes and neurons. - * - * The event transmits the slow inward current to the connected neurons. - */ -class SICEvent : public DataSecondaryEvent< double, SICEvent > -{ - -public: - SICEvent() - { - } - - void operator()(); - SICEvent* clone() const; -}; - -inline SICEvent* -SICEvent::clone() const -{ - return new SICEvent( *this ); -} - } // namespace nest #endif /* #ifndef SECONDARY_EVENT_H */ diff --git a/nestkernel/secondary_event_impl.h b/nestkernel/secondary_event_impl.h index 1ad6fe92ee..2641c26f65 100644 --- a/nestkernel/secondary_event_impl.h +++ b/nestkernel/secondary_event_impl.h @@ -20,16 +20,80 @@ * */ +#ifndef SECONDARY_EVENT_IMPL_H +#define SECONDARY_EVENT_IMPL_H + +#include "event.h" #include "secondary_event.h" +#include + +namespace nest +{ + +/** + * This template function reads data of type T from a given position of a + * std::vector< unsigned int >. The function is used to read SecondaryEvents + * data from the NEST communication buffer. The pos iterator is advanced + * during execution. For a discussion on the functionality of this function see + * github issue #181 and pull request #184. + */ +template < typename T > +void +read_from_comm_buffer( T& d, std::vector< unsigned int >::iterator& pos ) +{ + // there is no aliasing problem here, since cast to char* invalidate strict + // aliasing assumptions + char* const c = reinterpret_cast< char* >( &d ); + + const size_t num_uints = number_of_uints_covered< T >(); + size_t left_to_copy = sizeof( T ); + + for ( size_t i = 0; i < num_uints; i++ ) + { + memcpy( c + i * sizeof( unsigned int ), &( *( pos + i ) ), std::min( left_to_copy, sizeof( unsigned int ) ) ); + left_to_copy -= sizeof( unsigned int ); + } + + pos += num_uints; +} + +template < typename DataType, typename Subclass > +inline DataType +DataSecondaryEvent< DataType, Subclass >::get_coeffvalue( std::vector< unsigned int >::iterator& pos ) +{ + DataType elem; + read_from_comm_buffer( elem, pos ); + return elem; +} -// Includes from nestkernel -#include "kernel_manager.h" +template < typename DataType, typename Subclass > +std::set< synindex > DataSecondaryEvent< DataType, Subclass >::supported_syn_ids_; + +template < typename DataType, typename Subclass > +size_t DataSecondaryEvent< DataType, Subclass >::coeff_length_ = 0; + +/** + * Event for slow inward current (SIC) connections between astrocytes and neurons. + * + * The event transmits the slow inward current to the connected neurons. + */ +class SICEvent : public DataSecondaryEvent< double, SICEvent > +{ + +public: + SICEvent() + { + } + + void operator()(); + SICEvent* clone() const; +}; template < typename DataType, typename Subclass > void -nest::DataSecondaryEvent< DataType, Subclass >::add_syn_id( const nest::synindex synid ) +DataSecondaryEvent< DataType, Subclass >::add_syn_id( const synindex synid ) { - kernel().vp_manager.assert_thread_parallel(); + kernel::manager< VPManager >.assert_thread_parallel(); // This is done during connection model cloning, which happens thread-parallel. // To not risk trashing the set data structure, we let only master register the @@ -44,8 +108,11 @@ nest::DataSecondaryEvent< DataType, Subclass >::add_syn_id( const nest::synindex template < typename DataType, typename Subclass > void -nest::DataSecondaryEvent< DataType, Subclass >::set_coeff_length( const size_t coeff_length ) +DataSecondaryEvent< DataType, Subclass >::set_coeff_length( const size_t coeff_length ) { - kernel().vp_manager.assert_single_threaded(); + kernel::manager< VPManager >.assert_single_threaded(); coeff_length_ = coeff_length; } +} + +#endif diff --git a/nestkernel/send_buffer_position.cpp b/nestkernel/send_buffer_position.cpp index 3e652aa618..a1e6ed85a5 100644 --- a/nestkernel/send_buffer_position.cpp +++ b/nestkernel/send_buffer_position.cpp @@ -26,12 +26,12 @@ #include "send_buffer_position.h" nest::SendBufferPosition::SendBufferPosition() - : begin_( kernel().mpi_manager.get_num_processes(), 0 ) - , end_( kernel().mpi_manager.get_num_processes(), 0 ) - , idx_( kernel().mpi_manager.get_num_processes(), 0 ) + : begin_( kernel::manager< MPIManager >.get_num_processes(), 0 ) + , end_( kernel::manager< MPIManager >.get_num_processes(), 0 ) + , idx_( kernel::manager< MPIManager >.get_num_processes(), 0 ) { - const size_t num_procs = kernel().mpi_manager.get_num_processes(); - const size_t send_recv_count_per_rank = kernel().mpi_manager.get_send_recv_count_spike_data_per_rank(); + const size_t num_procs = kernel::manager< MPIManager >.get_num_processes(); + const size_t send_recv_count_per_rank = kernel::manager< MPIManager >.get_send_recv_count_spike_data_per_rank(); for ( size_t rank = 0; rank < num_procs; ++rank ) { @@ -40,3 +40,113 @@ nest::SendBufferPosition::SendBufferPosition() idx_[ rank ] = begin_[ rank ]; } } + +void +nest::TargetSendBufferPosition::increase( const size_t rank ) +{ + + ++idx_[ rank_to_index_( rank ) ]; + ++num_target_data_written_; +} + +bool +nest::TargetSendBufferPosition::are_all_chunks_filled() const +{ + + return num_target_data_written_ == send_recv_count_per_rank_ * idx_.size(); +} + +bool +nest::TargetSendBufferPosition::is_chunk_filled( const size_t rank ) const +{ + + return idx( rank ) == end( rank ); +} + +unsigned int +nest::TargetSendBufferPosition::end( const size_t rank ) const +{ + + return end_[ rank_to_index_( rank ) ]; +} + +unsigned int +nest::TargetSendBufferPosition::begin( const size_t rank ) const +{ + + return begin_[ rank_to_index_( rank ) ]; +} + +unsigned int +nest::TargetSendBufferPosition::idx( const size_t rank ) const +{ + + return idx_[ rank_to_index_( rank ) ]; +} + +size_t +nest::TargetSendBufferPosition::rank_to_index_( const size_t rank ) const +{ + + assert( begin_rank_ <= rank ); + assert( rank < end_rank_ ); + return rank % max_size_; +} + +nest::TargetSendBufferPosition::TargetSendBufferPosition( const AssignedRanks& assigned_ranks, + const unsigned int send_recv_count_per_rank ) + : begin_rank_( assigned_ranks.begin ) + , end_rank_( assigned_ranks.end ) + , max_size_( assigned_ranks.max_size ) + , num_target_data_written_( 0 ) + , send_recv_count_per_rank_( send_recv_count_per_rank ) +{ + + idx_.resize( assigned_ranks.size ); + begin_.resize( assigned_ranks.size ); + end_.resize( assigned_ranks.size ); + for ( size_t rank = assigned_ranks.begin; rank < assigned_ranks.end; ++rank ) + { + // thread-local index of (global) rank + const size_t lr_idx = rank % assigned_ranks.max_size; + assert( lr_idx < assigned_ranks.size ); + idx_[ lr_idx ] = rank * send_recv_count_per_rank; + begin_[ lr_idx ] = rank * send_recv_count_per_rank; + end_[ lr_idx ] = ( rank + 1 ) * send_recv_count_per_rank; + } +} + +void +nest::SendBufferPosition::increase( const size_t rank ) +{ + + ++idx_[ rank ]; +} + +bool +nest::SendBufferPosition::is_chunk_filled( const size_t rank ) const +{ + + return idx_[ rank ] == end_[ rank ]; +} + +size_t +nest::SendBufferPosition::end( const size_t rank ) const +{ + + return end_[ rank ]; +} + +size_t +nest::SendBufferPosition::begin( const size_t rank ) const +{ + + return begin_[ rank ]; +} + +size_t +nest::SendBufferPosition::idx( const size_t rank ) const +{ + + return idx_[ rank ]; +} diff --git a/nestkernel/send_buffer_position.h b/nestkernel/send_buffer_position.h index 0578b2c529..4496b3a7cf 100644 --- a/nestkernel/send_buffer_position.h +++ b/nestkernel/send_buffer_position.h @@ -73,36 +73,6 @@ class SendBufferPosition void increase( const size_t rank ); }; -inline size_t -SendBufferPosition::idx( const size_t rank ) const -{ - return idx_[ rank ]; -} - -inline size_t -SendBufferPosition::begin( const size_t rank ) const -{ - return begin_[ rank ]; -} - -inline size_t -SendBufferPosition::end( const size_t rank ) const -{ - return end_[ rank ]; -} - -inline bool -SendBufferPosition::is_chunk_filled( const size_t rank ) const -{ - return idx_[ rank ] == end_[ rank ]; -} - -inline void -SendBufferPosition::increase( const size_t rank ) -{ - ++idx_[ rank ]; -} - /** * This class simplifies keeping track of write position in MPI buffer @@ -157,73 +127,6 @@ class TargetSendBufferPosition void increase( const size_t rank ); }; -inline TargetSendBufferPosition::TargetSendBufferPosition( const AssignedRanks& assigned_ranks, - const unsigned int send_recv_count_per_rank ) - : begin_rank_( assigned_ranks.begin ) - , end_rank_( assigned_ranks.end ) - , max_size_( assigned_ranks.max_size ) - , num_target_data_written_( 0 ) - , send_recv_count_per_rank_( send_recv_count_per_rank ) -{ - idx_.resize( assigned_ranks.size ); - begin_.resize( assigned_ranks.size ); - end_.resize( assigned_ranks.size ); - for ( size_t rank = assigned_ranks.begin; rank < assigned_ranks.end; ++rank ) - { - // thread-local index of (global) rank - const size_t lr_idx = rank % assigned_ranks.max_size; - assert( lr_idx < assigned_ranks.size ); - idx_[ lr_idx ] = rank * send_recv_count_per_rank; - begin_[ lr_idx ] = rank * send_recv_count_per_rank; - end_[ lr_idx ] = ( rank + 1 ) * send_recv_count_per_rank; - } -} - -inline size_t -TargetSendBufferPosition::rank_to_index_( const size_t rank ) const -{ - assert( begin_rank_ <= rank ); - assert( rank < end_rank_ ); - return rank % max_size_; -} - -inline unsigned int -TargetSendBufferPosition::idx( const size_t rank ) const -{ - return idx_[ rank_to_index_( rank ) ]; -} - -inline unsigned int -TargetSendBufferPosition::begin( const size_t rank ) const -{ - return begin_[ rank_to_index_( rank ) ]; -} - -inline unsigned int -TargetSendBufferPosition::end( const size_t rank ) const -{ - return end_[ rank_to_index_( rank ) ]; -} - -inline bool -TargetSendBufferPosition::is_chunk_filled( const size_t rank ) const -{ - return idx( rank ) == end( rank ); -} - -inline bool -TargetSendBufferPosition::are_all_chunks_filled() const -{ - return num_target_data_written_ == send_recv_count_per_rank_ * idx_.size(); -} - -inline void -TargetSendBufferPosition::increase( const size_t rank ) -{ - ++idx_[ rank_to_index_( rank ) ]; - ++num_target_data_written_; -} - } // namespace nest #endif /* SEND_BUFFER_POSITION_H */ diff --git a/nestkernel/simulation_manager.cpp b/nestkernel/simulation_manager.cpp index 44aeec3efd..fd2c73fc58 100644 --- a/nestkernel/simulation_manager.cpp +++ b/nestkernel/simulation_manager.cpp @@ -34,10 +34,16 @@ #include "numerics.h" // Includes from nestkernel: -#include "connection_manager_impl.h" #include "event_delivery_manager.h" +#include "io_manager.h" #include "kernel_manager.h" -#include "stopwatch_impl.h" +#include "logging_manager.h" +#include "model_manager.h" +#include "music_manager.h" +#include "nest_timeconverter.h" +#include "node_manager.h" +#include "random_manager.h" +#include "sp_manager.h" // Includes from sli: #include "dictutils.h" @@ -72,6 +78,10 @@ nest::SimulationManager::SimulationManager() void nest::SimulationManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { + sw_omp_synchronization_construction_.reset(); + sw_omp_synchronization_simulation_.reset(); + sw_mpi_synchronization_.reset(); + if ( adjust_number_of_threads_or_rng_only ) { return; @@ -167,7 +177,7 @@ nest::SimulationManager::set_status( const DictionaryDatum& d ) from_step_ = 0; slice_ = 0; // clear all old spikes - kernel().event_delivery_manager.configure_spike_data_buffers(); + kernel::manager< EventDeliveryManager >.configure_spike_data_buffers(); } } @@ -184,7 +194,7 @@ nest::SimulationManager::set_status( const DictionaryDatum& d ) if ( tics_per_ms_updated or res_updated ) { std::vector< std::string > errors; - if ( kernel().node_manager.size() > 0 ) + if ( kernel::manager< NodeManager >.size() > 0 ) { errors.push_back( "Nodes have already been created" ); } @@ -192,7 +202,7 @@ nest::SimulationManager::set_status( const DictionaryDatum& d ) { errors.push_back( "Network has been simulated" ); } - if ( kernel().model_manager.are_model_defaults_modified() ) + if ( kernel::manager< ModelManager >.are_model_defaults_modified() ) { errors.push_back( "Model defaults were modified" ); } @@ -231,8 +241,8 @@ nest::SimulationManager::set_status( const DictionaryDatum& d ) // adjust to new resolution clock_.calibrate(); // adjust delays in the connection system to new resolution - kernel().connection_manager.calibrate( time_converter ); - kernel().model_manager.calibrate( time_converter ); + kernel::manager< ConnectionManager >.calibrate( time_converter ); + kernel::manager< ModelManager >.calibrate( time_converter ); std::string msg = String::compose( "Tics per ms and resolution changed from %1 tics and %2 ms to %3 tics and %4 ms.", @@ -268,8 +278,8 @@ nest::SimulationManager::set_status( const DictionaryDatum& d ) Time::set_resolution( resd ); clock_.calibrate(); // adjust to new resolution // adjust delays in the connection system to new resolution - kernel().connection_manager.calibrate( time_converter ); - kernel().model_manager.calibrate( time_converter ); + kernel::manager< ConnectionManager >.calibrate( time_converter ); + kernel::manager< ModelManager >.calibrate( time_converter ); std::string msg = String::compose( "Temporal resolution changed from %1 to %2 ms.", old_res, resd ); LOG( M_INFO, "SimulationManager::set_status", msg ); @@ -295,7 +305,7 @@ nest::SimulationManager::set_status( const DictionaryDatum& d ) bool wfr; if ( updateValue< bool >( d, names::use_wfr, wfr ) ) { - if ( kernel().node_manager.size() > 0 ) + if ( kernel::manager< NodeManager >.size() > 0 ) { LOG( M_ERROR, "SimulationManager::set_status", @@ -329,7 +339,7 @@ nest::SimulationManager::set_status( const DictionaryDatum& d ) "relaxation is disabled. Set use_wfr to true first." ); throw KernelException(); } - else if ( kernel().connection_manager.get_num_connections() != 0 ) + else if ( kernel::manager< ConnectionManager >.get_num_connections() != 0 ) { LOG( M_ERROR, "SimulationManager::set_status", @@ -483,6 +493,12 @@ nest::SimulationManager::get_status( DictionaryDatum& d ) sw_deliver_spike_data_.get_status( d, names::time_deliver_spike_data, names::time_deliver_spike_data_cpu ); sw_deliver_secondary_data_.get_status( d, names::time_deliver_secondary_data, names::time_deliver_secondary_data_cpu ); + sw_omp_synchronization_construction_.get_status( + d, names::time_omp_synchronization_construction, names::time_omp_synchronization_construction_cpu ); + sw_omp_synchronization_simulation_.get_status( + d, names::time_omp_synchronization_simulation, names::time_omp_synchronization_simulation_cpu ); + sw_mpi_synchronization_.get_status( d, names::time_mpi_synchronization, names::time_mpi_synchronization_cpu ); + def< double >( d, names::eprop_update_interval, eprop_update_interval_ ); def< double >( d, names::eprop_learning_window, eprop_learning_window_ ); def< bool >( d, names::eprop_reset_neurons_on_update, eprop_reset_neurons_on_update_ ); @@ -491,7 +507,7 @@ nest::SimulationManager::get_status( DictionaryDatum& d ) void nest::SimulationManager::prepare() { - assert( kernel().is_initialized() ); + assert( kernel::manager< KernelManager >.is_initialized() ); if ( prepared_ ) { @@ -507,9 +523,12 @@ nest::SimulationManager::prepare() "earlier error. Please run ResetKernel first." ); } + sw_omp_synchronization_simulation_.reset(); + sw_mpi_synchronization_.reset(); + // reset profiling timers reset_timers_for_dynamics(); - kernel().event_delivery_manager.reset_timers_for_dynamics(); + kernel::manager< EventDeliveryManager >.reset_timers_for_dynamics(); t_real_ = 0; t_slice_begin_ = timeval(); // set to timeval{0, 0} as unset flag @@ -517,38 +536,39 @@ nest::SimulationManager::prepare() // find shortest and longest delay across all MPI processes // this call sets the member variables - kernel().connection_manager.update_delay_extrema_(); - kernel().event_delivery_manager.init_moduli(); + kernel::manager< ConnectionManager >.update_delay_extrema_(); + kernel::manager< EventDeliveryManager >.init_moduli(); // if at the beginning of a simulation, set up spike buffers if ( not simulated_ ) { - kernel().event_delivery_manager.configure_spike_data_buffers(); + kernel::manager< EventDeliveryManager >.configure_spike_data_buffers(); } - kernel().node_manager.update_thread_local_node_data(); - kernel().node_manager.prepare_nodes(); + kernel::manager< NodeManager >.update_thread_local_node_data(); + kernel::manager< NodeManager >.prepare_nodes(); // we have to do enter_runtime after prepare_nodes, since we use // calibrate to map the ports of MUSIC devices, which has to be done // before enter_runtime if ( not simulated_ ) // only enter the runtime mode once { - double tick = Time::get_resolution().get_ms() * kernel().connection_manager.get_min_delay(); - kernel().music_manager.enter_runtime( tick ); + double tick = Time::get_resolution().get_ms() * kernel::manager< ConnectionManager >.get_min_delay(); + kernel::manager< MUSICManager >.enter_runtime( tick ); } prepared_ = true; // check whether waveform relaxation is used on any MPI process; // needs to be called before update_connection_intrastructure_since // it resizes coefficient arrays for secondary events - kernel().node_manager.check_wfr_use(); + kernel::manager< NodeManager >.check_wfr_use(); - if ( kernel().node_manager.have_nodes_changed() or kernel().connection_manager.connections_have_changed() ) + if ( kernel::manager< NodeManager >.have_nodes_changed() + or kernel::manager< ConnectionManager >.connections_have_changed() ) { #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); update_connection_infrastructure( tid ); } // of omp parallel } @@ -600,7 +620,7 @@ nest::SimulationManager::run( Time const& t ) { assert_valid_simtime( t ); - kernel().random_manager.check_rng_synchrony(); + kernel::manager< RandomManager >.check_rng_synchrony(); if ( not prepared_ ) { @@ -617,10 +637,10 @@ nest::SimulationManager::run( Time const& t ) return; } - kernel().io_manager.pre_run_hook(); + kernel::manager< IOManager >.pre_run_hook(); // Reset local spike counters within event_delivery_manager - kernel().event_delivery_manager.reset_counters(); + kernel::manager< EventDeliveryManager >.reset_counters(); sw_simulate_.start(); @@ -628,14 +648,14 @@ nest::SimulationManager::run( Time const& t ) // of a simulation, it has been reset properly elsewhere. If // a simulation was ended and is now continued, from_step_ will // have the proper value. to_step_ is set as in advance_time(). - to_step_ = std::min( from_step_ + to_do_, kernel().connection_manager.get_min_delay() ); + to_step_ = std::min( from_step_ + to_do_, kernel::manager< ConnectionManager >.get_min_delay() ); // Warn about possible inconsistencies, see #504. // This test cannot come any earlier, because we first need to compute // min_delay_ // above. - if ( t.get_steps() % kernel().connection_manager.get_min_delay() != 0 ) + if ( t.get_steps() % kernel::manager< ConnectionManager >.get_min_delay() != 0 ) { LOG( M_WARNING, "SimulationManager::run", @@ -649,8 +669,8 @@ nest::SimulationManager::run( Time const& t ) call_update_(); - kernel().io_manager.post_run_hook(); - kernel().random_manager.check_rng_synchrony(); + kernel::manager< IOManager >.post_run_hook(); + kernel::manager< RandomManager >.check_rng_synchrony(); sw_simulate_.stop(); } @@ -671,30 +691,30 @@ nest::SimulationManager::cleanup() return; } - kernel().node_manager.finalize_nodes(); + kernel::manager< NodeManager >.finalize_nodes(); prepared_ = false; } void nest::SimulationManager::call_update_() { - assert( kernel().is_initialized() and not inconsistent_state_ ); + assert( kernel::manager< KernelManager >.is_initialized() and not inconsistent_state_ ); std::ostringstream os; double t_sim = to_do_ * Time::get_resolution().get_ms(); - size_t num_active_nodes = kernel().node_manager.get_num_active_nodes(); + size_t num_active_nodes = kernel::manager< NodeManager >.get_num_active_nodes(); os << "Number of local nodes: " << num_active_nodes << std::endl; os << "Simulation time (ms): " << t_sim; #ifdef _OPENMP - os << std::endl << "Number of OpenMP threads: " << kernel().vp_manager.get_num_threads(); + os << std::endl << "Number of OpenMP threads: " << kernel::manager< VPManager >.get_num_threads(); #else os << std::endl << "Not using OpenMP"; #endif #ifdef HAVE_MPI - os << std::endl << "Number of MPI processes: " << kernel().mpi_manager.get_num_processes(); + os << std::endl << "Number of MPI processes: " << kernel::manager< MPIManager >.get_num_processes(); #else os << std::endl << "Not using MPI"; #endif @@ -726,7 +746,7 @@ nest::SimulationManager::call_update_() std::cout << std::endl; } - kernel().mpi_manager.synchronize(); + kernel::manager< MPIManager >.synchronize(); LOG( M_INFO, "SimulationManager::run", "Simulation finished." ); } @@ -734,49 +754,49 @@ nest::SimulationManager::call_update_() void nest::SimulationManager::update_connection_infrastructure( const size_t tid ) { - kernel().get_omp_synchronization_construction_stopwatch().start(); + get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + get_omp_synchronization_construction_stopwatch().stop(); sw_communicate_prepare_.start(); - kernel().connection_manager.sort_connections( tid ); + kernel::manager< ConnectionManager >.sort_connections( tid ); sw_gather_target_data_.start(); - kernel().connection_manager.restructure_connection_tables( tid ); - kernel().connection_manager.collect_compressed_spike_data( tid ); + kernel::manager< ConnectionManager >.restructure_connection_tables( tid ); + kernel::manager< ConnectionManager >.collect_compressed_spike_data( tid ); sw_gather_target_data_.stop(); - kernel().get_omp_synchronization_construction_stopwatch().start(); + get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier // wait for all threads to finish sorting - kernel().get_omp_synchronization_construction_stopwatch().stop(); + get_omp_synchronization_construction_stopwatch().stop(); #pragma omp single { - kernel().connection_manager.compute_target_data_buffer_size(); - kernel().event_delivery_manager.resize_send_recv_buffers_target_data(); + kernel::manager< ConnectionManager >.compute_target_data_buffer_size(); + kernel::manager< EventDeliveryManager >.resize_send_recv_buffers_target_data(); // check whether primary and secondary connections exists on any // compute node - kernel().connection_manager.sync_has_primary_connections(); - kernel().connection_manager.check_secondary_connections_exist(); + kernel::manager< ConnectionManager >.sync_has_primary_connections(); + kernel::manager< ConnectionManager >.check_secondary_connections_exist(); } - if ( kernel().connection_manager.secondary_connections_exist() ) + if ( kernel::manager< ConnectionManager >.secondary_connections_exist() ) { - kernel().get_omp_synchronization_construction_stopwatch().start(); + get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + get_omp_synchronization_construction_stopwatch().stop(); - kernel().connection_manager.compute_compressed_secondary_recv_buffer_positions( tid ); + kernel::manager< ConnectionManager >.compute_compressed_secondary_recv_buffer_positions( tid ); - kernel().get_omp_synchronization_construction_stopwatch().start(); + get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + get_omp_synchronization_construction_stopwatch().stop(); #pragma omp single { - kernel().mpi_manager.communicate_recv_counts_secondary_events(); - kernel().event_delivery_manager.configure_secondary_buffers(); + kernel::manager< MPIManager >.communicate_recv_counts_secondary_events(); + kernel::manager< EventDeliveryManager >.configure_secondary_buffers(); } } @@ -784,35 +804,35 @@ nest::SimulationManager::update_connection_infrastructure( const size_t tid ) // communicate connection information from postsynaptic to // presynaptic side - if ( kernel().connection_manager.use_compressed_spikes() ) + if ( kernel::manager< ConnectionManager >.use_compressed_spikes() ) { #pragma omp barrier #pragma omp single { - kernel().connection_manager.initialize_iteration_state(); // could possibly be combined with s'th above + kernel::manager< ConnectionManager >.initialize_iteration_state(); // could possibly be combined with s'th above } - kernel().event_delivery_manager.gather_target_data_compressed( tid ); + kernel::manager< EventDeliveryManager >.gather_target_data_compressed( tid ); } else { - kernel().event_delivery_manager.gather_target_data( tid ); + kernel::manager< EventDeliveryManager >.gather_target_data( tid ); } sw_gather_target_data_.stop(); - if ( kernel().connection_manager.secondary_connections_exist() ) + if ( kernel::manager< ConnectionManager >.secondary_connections_exist() ) { - kernel().connection_manager.compress_secondary_send_buffer_pos( tid ); + kernel::manager< ConnectionManager >.compress_secondary_send_buffer_pos( tid ); } - kernel().get_omp_synchronization_construction_stopwatch().start(); + get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + get_omp_synchronization_construction_stopwatch().stop(); #pragma omp single { - kernel().connection_manager.clear_compressed_spike_data_map(); - kernel().node_manager.set_have_nodes_changed( false ); - kernel().connection_manager.unset_connections_have_changed(); + kernel::manager< ConnectionManager >.clear_compressed_spike_data_map(); + kernel::manager< NodeManager >.set_have_nodes_changed( false ); + kernel::manager< ConnectionManager >.unset_connections_have_changed(); } sw_communicate_prepare_.stop(); } @@ -836,12 +856,13 @@ nest::SimulationManager::update_() bool update_time_limit_exceeded = false; // End of variables updated by master thread - std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised( kernel().vp_manager.get_num_threads() ); + std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised( + kernel::manager< VPManager >.get_num_threads() ); // parallel section begins #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); // We update in a parallel region. Therefore, we need to catch // exceptions here and then handle them after the parallel region. @@ -864,18 +885,18 @@ nest::SimulationManager::update_() // reach target neurons before spikes are propagated through eprop synapses. // This sequence safeguards the gradient computation from missing critical information // from the time step preceding the arrival of the spike triggering the weight update. - if ( kernel().connection_manager.secondary_connections_exist() ) + if ( kernel::manager< ConnectionManager >.secondary_connections_exist() ) { sw_deliver_secondary_data_.start(); - kernel().event_delivery_manager.deliver_secondary_events( tid, false ); + kernel::manager< EventDeliveryManager >.deliver_secondary_events( tid, false ); sw_deliver_secondary_data_.stop(); } - if ( kernel().connection_manager.has_primary_connections() ) + if ( kernel::manager< ConnectionManager >.has_primary_connections() ) { sw_deliver_spike_data_.start(); // Deliver spikes from receive buffer to ring buffers. - kernel().event_delivery_manager.deliver_events( tid ); + kernel::manager< EventDeliveryManager >.deliver_events( tid ); sw_deliver_spike_data_.stop(); } @@ -887,9 +908,9 @@ nest::SimulationManager::update_() // MUSIC *before* MUSIC time is advanced // wait until all threads are done -> synchronize - kernel().get_omp_synchronization_simulation_stopwatch().start(); + get_omp_synchronization_simulation_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_simulation_stopwatch().stop(); + get_omp_synchronization_simulation_stopwatch().stop(); // the following block is executed by the master thread only // the other threads are enforced to wait at the end of the block #pragma omp master @@ -900,11 +921,11 @@ nest::SimulationManager::update_() // MUSIC *before* MUSIC time is advanced if ( slice_ > 0 ) { - kernel().music_manager.advance_music_time(); + kernel::manager< MUSICManager >.advance_music_time(); } // the following could be made thread-safe - kernel().music_manager.update_music_event_handlers( clock_, from_step_, to_step_ ); + kernel::manager< MUSICManager >.update_music_event_handlers( clock_, from_step_, to_step_ ); } // end of master section, all threads have to synchronize at this point #pragma omp barrier @@ -914,7 +935,8 @@ nest::SimulationManager::update_() // preliminary update of nodes that use waveform relaxtion, only // necessary if secondary connections exist and any node uses // wfr - if ( kernel().connection_manager.secondary_connections_exist() and kernel().node_manager.wfr_is_used() ) + if ( kernel::manager< ConnectionManager >.secondary_connections_exist() + and kernel::manager< NodeManager >.wfr_is_used() ) { #pragma omp single { @@ -925,14 +947,15 @@ nest::SimulationManager::update_() // needs to be done in omp single since to_step_ is a scheduler // variable old_to_step = to_step_; - if ( to_step_ < kernel().connection_manager.get_min_delay() ) + if ( to_step_ < kernel::manager< ConnectionManager >.get_min_delay() ) { - to_step_ = kernel().connection_manager.get_min_delay(); + to_step_ = kernel::manager< ConnectionManager >.get_min_delay(); } } bool max_iterations_reached = true; - const std::vector< Node* >& thread_local_wfr_nodes = kernel().node_manager.get_wfr_nodes_on_thread( tid ); + const std::vector< Node* >& thread_local_wfr_nodes = + kernel::manager< NodeManager >.get_wfr_nodes_on_thread( tid ); for ( long n = 0; n < wfr_max_iterations_; ++n ) { bool done_p = true; @@ -952,9 +975,9 @@ nest::SimulationManager::update_() done.push_back( done_p ); } // parallel section ends, wait until all threads are done -> synchronize - kernel().get_omp_synchronization_simulation_stopwatch().start(); + get_omp_synchronization_simulation_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_simulation_stopwatch().stop(); + get_omp_synchronization_simulation_stopwatch().stop(); // the following block is executed by a single thread // the other threads wait at the end of the block @@ -967,7 +990,7 @@ nest::SimulationManager::update_() } // gather SecondaryEvents (e.g. GapJunctionEvents) - kernel().event_delivery_manager.gather_secondary_events( done_all ); + kernel::manager< EventDeliveryManager >.gather_secondary_events( done_all ); // reset done and done_all //(needs to be in the single threaded part) @@ -977,7 +1000,7 @@ nest::SimulationManager::update_() // deliver SecondaryEvents generated during wfr_update // returns the done value over all threads - done_p = kernel().event_delivery_manager.deliver_secondary_events( tid, true ); + done_p = kernel::manager< EventDeliveryManager >.deliver_secondary_events( tid, true ); if ( done_p ) { @@ -1001,29 +1024,29 @@ nest::SimulationManager::update_() } // of if(wfr_is_used) // end of preliminary update - if ( kernel().sp_manager.is_structural_plasticity_enabled() + if ( kernel::manager< SPManager >.is_structural_plasticity_enabled() and ( std::fmod( Time( Time::step( clock_.get_steps() + from_step_ ) ).get_ms(), - kernel().sp_manager.get_structural_plasticity_update_interval() ) + kernel::manager< SPManager >.get_structural_plasticity_update_interval() ) == 0 ) ) { #pragma omp barrier - for ( SparseNodeArray::const_iterator i = kernel().node_manager.get_local_nodes( tid ).begin(); - i != kernel().node_manager.get_local_nodes( tid ).end(); + for ( SparseNodeArray::const_iterator i = kernel::manager< NodeManager >.get_local_nodes( tid ).begin(); + i != kernel::manager< NodeManager >.get_local_nodes( tid ).end(); ++i ) { Node* node = i->get_node(); node->update_synaptic_elements( Time( Time::step( clock_.get_steps() + from_step_ ) ).get_ms() ); } - kernel().get_omp_synchronization_simulation_stopwatch().start(); + get_omp_synchronization_simulation_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_simulation_stopwatch().stop(); + get_omp_synchronization_simulation_stopwatch().stop(); #pragma omp single { - kernel().sp_manager.update_structural_plasticity(); + kernel::manager< SPManager >.update_structural_plasticity(); } // Remove 10% of the vacant elements - for ( SparseNodeArray::const_iterator i = kernel().node_manager.get_local_nodes( tid ).begin(); - i != kernel().node_manager.get_local_nodes( tid ).end(); + for ( SparseNodeArray::const_iterator i = kernel::manager< NodeManager >.get_local_nodes( tid ).begin(); + i != kernel::manager< NodeManager >.get_local_nodes( tid ).end(); ++i ) { Node* node = i->get_node(); @@ -1039,7 +1062,7 @@ nest::SimulationManager::update_() } // of structural plasticity sw_update_.start(); - const SparseNodeArray& thread_local_nodes = kernel().node_manager.get_local_nodes( tid ); + const SparseNodeArray& thread_local_nodes = kernel::manager< NodeManager >.get_local_nodes( tid ); for ( SparseNodeArray::const_iterator n = thread_local_nodes.begin(); n != thread_local_nodes.end(); ++n ) { @@ -1053,27 +1076,27 @@ nest::SimulationManager::update_() sw_update_.stop(); // parallel section ends, wait until all threads are done -> synchronize - kernel().get_omp_synchronization_simulation_stopwatch().start(); + get_omp_synchronization_simulation_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_simulation_stopwatch().stop(); + get_omp_synchronization_simulation_stopwatch().stop(); // the following block is executed by the master thread only // the other threads are enforced to wait at the end of the block #pragma omp master { // gather and deliver only at end of slice, i.e., end of min_delay step - if ( to_step_ == kernel().connection_manager.get_min_delay() ) + if ( to_step_ == kernel::manager< ConnectionManager >.get_min_delay() ) { - if ( kernel().connection_manager.has_primary_connections() ) + if ( kernel::manager< ConnectionManager >.has_primary_connections() ) { sw_gather_spike_data_.start(); - kernel().event_delivery_manager.gather_spike_data(); + kernel::manager< EventDeliveryManager >.gather_spike_data(); sw_gather_spike_data_.stop(); } - if ( kernel().connection_manager.secondary_connections_exist() ) + if ( kernel::manager< ConnectionManager >.secondary_connections_exist() ) { sw_gather_secondary_data_.start(); - kernel().event_delivery_manager.gather_secondary_events( true ); + kernel::manager< EventDeliveryManager >.gather_secondary_events( true ); sw_gather_secondary_data_.stop(); } } @@ -1111,18 +1134,18 @@ nest::SimulationManager::update_() // if block to avoid omp barrier if SIONLIB is not used #ifdef HAVE_SIONLIB - kernel().io_manager.post_step_hook(); + kernel::manager< IOManager >.post_step_hook(); // enforce synchronization after post-step activities of the recording backends - kernel().get_omp_synchronization_simulation_stopwatch().start(); + get_omp_synchronization_simulation_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_simulation_stopwatch().stop(); + get_omp_synchronization_simulation_stopwatch().stop(); #endif } while ( to_do_ > 0 ); // End of the slice, we update the number of synaptic elements - for ( SparseNodeArray::const_iterator i = kernel().node_manager.get_local_nodes( tid ).begin(); - i != kernel().node_manager.get_local_nodes( tid ).end(); + for ( SparseNodeArray::const_iterator i = kernel::manager< NodeManager >.get_local_nodes( tid ).begin(); + i != kernel::manager< NodeManager >.get_local_nodes( tid ).end(); ++i ) { Node* node = i->get_node(); @@ -1143,7 +1166,7 @@ nest::SimulationManager::update_() } // check if any exceptions have been raised - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { if ( exceptions_raised.at( tid ).get() ) { @@ -1161,11 +1184,11 @@ nest::SimulationManager::advance_time_() to_do_ -= to_step_ - from_step_; // advance clock, update modulos, slice counter only if slice completed - if ( to_step_ == kernel().connection_manager.get_min_delay() ) + if ( to_step_ == kernel::manager< ConnectionManager >.get_min_delay() ) { - clock_ += Time::step( kernel().connection_manager.get_min_delay() ); + clock_ += Time::step( kernel::manager< ConnectionManager >.get_min_delay() ); ++slice_; - kernel().event_delivery_manager.update_moduli(); + kernel::manager< EventDeliveryManager >.update_moduli(); from_step_ = 0; } else @@ -1175,17 +1198,17 @@ nest::SimulationManager::advance_time_() long end_sim = from_step_ + to_do_; - if ( kernel().connection_manager.get_min_delay() < end_sim ) + if ( kernel::manager< ConnectionManager >.get_min_delay() < end_sim ) { // update to end of time slice - to_step_ = kernel().connection_manager.get_min_delay(); + to_step_ = kernel::manager< ConnectionManager >.get_min_delay(); } else { to_step_ = end_sim; // update to end of simulation time } - assert( to_step_ - from_step_ <= kernel().connection_manager.get_min_delay() ); + assert( to_step_ - from_step_ <= kernel::manager< ConnectionManager >.get_min_delay() ); } void @@ -1218,5 +1241,151 @@ nest::SimulationManager::print_progress_() nest::Time const nest::SimulationManager::get_previous_slice_origin() const { - return clock_ - Time::step( kernel().connection_manager.get_min_delay() ); + return clock_ - Time::step( kernel::manager< ConnectionManager >.get_min_delay() ); +} +bool +nest::SimulationManager::get_eprop_reset_neurons_on_update() const +{ + + return eprop_reset_neurons_on_update_; +} + +nest::Time +nest::SimulationManager::get_eprop_learning_window() const +{ + + return Time::ms( eprop_learning_window_ ); +} + +nest::Time +nest::SimulationManager::get_eprop_update_interval() const +{ + + return Time::ms( eprop_update_interval_ ); +} + +size_t +nest::SimulationManager::get_wfr_interpolation_order() const +{ + + return wfr_interpolation_order_; +} + +double +nest::SimulationManager::get_wfr_tol() const +{ + + return wfr_tol_; +} + +double +nest::SimulationManager::get_wfr_comm_interval() const +{ + + return wfr_comm_interval_; +} + +bool +nest::SimulationManager::use_wfr() const +{ + + return use_wfr_; +} + +long +nest::SimulationManager::get_to_step() const +{ + + return to_step_; +} + +long +nest::SimulationManager::get_from_step() const +{ + + return from_step_; +} + +nest::Time +nest::SimulationManager::run_end_time() const +{ + + assert( not simulating_ ); // implicit due to using get_time() + return ( get_time().get_steps() + to_do_ ) * Time::get_resolution(); +} + +nest::Time +nest::SimulationManager::run_start_time() const +{ + + assert( not simulating_ ); // implicit due to using get_time() + return get_time() - ( to_do_total_ - to_do_ ) * Time::get_resolution(); +} + +nest::Time +nest::SimulationManager::run_duration() const +{ + + return to_do_total_ * Time::get_resolution(); +} + +nest::Time const& +nest::SimulationManager::get_clock() const +{ + + return clock_; +} + +size_t +nest::SimulationManager::get_slice() const +{ + + return slice_; +} + +bool +nest::SimulationManager::has_been_prepared() const +{ + + return prepared_; +} + +bool +nest::SimulationManager::has_been_simulated() const +{ + + return simulated_; +} + +nest::Time const +nest::SimulationManager::get_time() const +{ + + assert( not simulating_ ); + return clock_ + Time::step( from_step_ ); +} + +nest::Time const& +nest::SimulationManager::get_slice_origin() const +{ + + return clock_; +} + +nest::Stopwatch< nest::StopwatchGranularity::Detailed, nest::StopwatchParallelism::MasterOnly >& +nest::SimulationManager::get_mpi_synchronization_stopwatch() +{ + return sw_mpi_synchronization_; +} + +nest::Stopwatch< nest::StopwatchGranularity::Detailed, nest::StopwatchParallelism::Threaded >& +nest::SimulationManager::get_omp_synchronization_simulation_stopwatch() +{ + return sw_omp_synchronization_simulation_; +} + +nest::Stopwatch< nest::StopwatchGranularity::Detailed, nest::StopwatchParallelism::Threaded >& +nest::SimulationManager::get_omp_synchronization_construction_stopwatch() +{ + return sw_omp_synchronization_construction_; } diff --git a/nestkernel/simulation_manager.h b/nestkernel/simulation_manager.h index 1c83bea508..7b083286b4 100644 --- a/nestkernel/simulation_manager.h +++ b/nestkernel/simulation_manager.h @@ -31,7 +31,7 @@ // Includes from libnestutil: #include "manager_interface.h" -#include "stopwatch.h" +#include "stopwatch_impl.h" // Includes from nestkernel: #include "nest_time.h" @@ -189,6 +189,16 @@ class SimulationManager : public ManagerInterface Time get_eprop_learning_window() const; bool get_eprop_reset_neurons_on_update() const; + //! Get the stopwatch to measure the time each thread is idle during network construction. + Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded >& + get_omp_synchronization_construction_stopwatch(); + + //! Get the stopwatch to measure the time each thread is idle during simulation. + Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded >& + get_omp_synchronization_simulation_stopwatch(); + + Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::MasterOnly >& get_mpi_synchronization_stopwatch(); + private: void call_update_(); //!< actually run simulation, aka wrap update_ void update_(); //! actually perform simulation @@ -238,121 +248,15 @@ class SimulationManager : public ManagerInterface Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded > sw_deliver_spike_data_; Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded > sw_deliver_secondary_data_; + Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded > sw_omp_synchronization_construction_; + Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::Threaded > sw_omp_synchronization_simulation_; + Stopwatch< StopwatchGranularity::Detailed, StopwatchParallelism::MasterOnly > sw_mpi_synchronization_; + double eprop_update_interval_; double eprop_learning_window_; bool eprop_reset_neurons_on_update_; }; -inline Time const& -SimulationManager::get_slice_origin() const -{ - return clock_; -} - -inline Time const -SimulationManager::get_time() const -{ - assert( not simulating_ ); - return clock_ + Time::step( from_step_ ); -} - -inline bool -SimulationManager::has_been_simulated() const -{ - return simulated_; -} - -inline bool -SimulationManager::has_been_prepared() const -{ - return prepared_; -} - -inline size_t -SimulationManager::get_slice() const -{ - return slice_; -} - -inline Time const& -SimulationManager::get_clock() const -{ - return clock_; -} - -inline Time -SimulationManager::run_duration() const -{ - return to_do_total_ * Time::get_resolution(); -} - -inline Time -SimulationManager::run_start_time() const -{ - assert( not simulating_ ); // implicit due to using get_time() - return get_time() - ( to_do_total_ - to_do_ ) * Time::get_resolution(); -} - -inline Time -SimulationManager::run_end_time() const -{ - assert( not simulating_ ); // implicit due to using get_time() - return ( get_time().get_steps() + to_do_ ) * Time::get_resolution(); -} - -inline long -SimulationManager::get_from_step() const -{ - return from_step_; -} - -inline long -SimulationManager::get_to_step() const -{ - return to_step_; -} - -inline bool -SimulationManager::use_wfr() const -{ - return use_wfr_; -} - -inline double -SimulationManager::get_wfr_comm_interval() const -{ - return wfr_comm_interval_; -} - -inline double -SimulationManager::get_wfr_tol() const -{ - return wfr_tol_; -} - -inline size_t -SimulationManager::get_wfr_interpolation_order() const -{ - return wfr_interpolation_order_; -} - -inline Time -SimulationManager::get_eprop_update_interval() const -{ - return Time::ms( eprop_update_interval_ ); -} - -inline Time -SimulationManager::get_eprop_learning_window() const -{ - return Time::ms( eprop_learning_window_ ); -} - -inline bool -SimulationManager::get_eprop_reset_neurons_on_update() const -{ - return eprop_reset_neurons_on_update_; -} } diff --git a/nestkernel/slice_ring_buffer.cpp b/nestkernel/slice_ring_buffer.cpp index ab12ca3aa4..2d5f93a0dc 100644 --- a/nestkernel/slice_ring_buffer.cpp +++ b/nestkernel/slice_ring_buffer.cpp @@ -26,6 +26,9 @@ #include #include +#include "connection_manager.h" +#include "event_delivery_manager.h" + nest::SliceRingBuffer::SliceRingBuffer() : refract_( std::numeric_limits< long >::max(), 0, 0 ) { @@ -35,9 +38,10 @@ nest::SliceRingBuffer::SliceRingBuffer() void nest::SliceRingBuffer::resize() { - long newsize = static_cast< long >( std::ceil( - static_cast< double >( kernel().connection_manager.get_min_delay() + kernel().connection_manager.get_max_delay() ) - / kernel().connection_manager.get_min_delay() ) ); + long newsize = + static_cast< long >( std::ceil( static_cast< double >( kernel::manager< ConnectionManager >.get_min_delay() + + kernel::manager< ConnectionManager >.get_max_delay() ) + / kernel::manager< ConnectionManager >.get_min_delay() ) ); if ( queue_.size() != static_cast< unsigned long >( newsize ) ) { queue_.resize( newsize ); @@ -66,7 +70,7 @@ void nest::SliceRingBuffer::prepare_delivery() { // vector to deliver from in this slice - deliver_ = &( queue_[ kernel().event_delivery_manager.get_slice_modulo( 0 ) ] ); + deliver_ = &( queue_[ kernel::manager< EventDeliveryManager >.get_slice_modulo( 0 ) ] ); // sort events, first event last std::sort( deliver_->begin(), deliver_->end(), std::greater< SpikeInfo >() ); @@ -76,7 +80,119 @@ void nest::SliceRingBuffer::discard_events() { // vector to deliver from in this slice - deliver_ = &( queue_[ kernel().event_delivery_manager.get_slice_modulo( 0 ) ] ); + deliver_ = &( queue_[ kernel::manager< EventDeliveryManager >.get_slice_modulo( 0 ) ] ); deliver_->clear(); } +bool +nest::SliceRingBuffer::SpikeInfo::operator>( const SpikeInfo& b ) const +{ + + return stamp_ == b.stamp_ ? ps_offset_ < b.ps_offset_ : stamp_ > b.stamp_; +} + +bool +nest::SliceRingBuffer::SpikeInfo::operator<=( const SpikeInfo& b ) const +{ + + return not( *this > b ); +} + +bool +nest::SliceRingBuffer::SpikeInfo::operator<( const SpikeInfo& b ) const +{ + + return stamp_ == b.stamp_ ? ps_offset_ > b.ps_offset_ : stamp_ < b.stamp_; +} + +nest::SliceRingBuffer::SpikeInfo::SpikeInfo( long stamp, double ps_offset, double weight ) + : stamp_( stamp ) + , ps_offset_( ps_offset ) + , weight_( weight ) +{ +} + +bool +nest::SliceRingBuffer::get_next_spike( const long req_stamp, + bool accumulate_simultaneous, + double& ps_offset, + double& weight, + bool& end_of_refract ) +{ + + end_of_refract = false; + if ( deliver_->empty() or refract_ <= deliver_->back() ) + { + if ( refract_.stamp_ == req_stamp ) + { // if relies on stamp_==long::max() if not refractory + // return from refractoriness + ps_offset = refract_.ps_offset_; + weight = 0; + end_of_refract = true; + + // mark as non-refractory + refract_.stamp_ = std::numeric_limits< long >::max(); + return true; + } + else + { + return false; + } + } + else if ( deliver_->back().stamp_ == req_stamp ) + { + // we have an event to deliver + ps_offset = deliver_->back().ps_offset_; + weight = deliver_->back().weight_; + deliver_->pop_back(); + + if ( accumulate_simultaneous ) + { + // add weights of all spikes with same stamp and offset + while ( + not deliver_->empty() and deliver_->back().ps_offset_ == ps_offset and deliver_->back().stamp_ == req_stamp ) + { + weight += deliver_->back().weight_; + deliver_->pop_back(); + } + } + + return true; + } + else + { + // ensure that we are not blocked by spike from the past, cf #404 + assert( deliver_->back().stamp_ > req_stamp ); + return false; + } +} + +void +nest::SliceRingBuffer::add_refractory( const long stamp, const double ps_offset ) +{ + + // We require that only one refractory-return pseudo-event is stored per + // time step. + // + // We guard against violation using assert(): refract_.stamp_ must + // be equal to the marker value for non-refractoriness. All else would mean + // that a refractory neuron fired. + assert( refract_.stamp_ == std::numeric_limits< long >::max() ); + + refract_.stamp_ = stamp; + refract_.ps_offset_ = ps_offset; +} + +void +nest::SliceRingBuffer::add_spike( const long rel_delivery, + const long stamp, + const double ps_offset, + const double weight ) +{ + + const long idx = kernel::manager< EventDeliveryManager >.get_slice_modulo( rel_delivery ); + assert( static_cast< size_t >( idx ) < queue_.size() ); + assert( ps_offset >= 0 ); + + queue_[ idx ].push_back( SpikeInfo( stamp, ps_offset, weight ) ); +} diff --git a/nestkernel/slice_ring_buffer.h b/nestkernel/slice_ring_buffer.h index 62999fbc90..1f21cf82a1 100644 --- a/nestkernel/slice_ring_buffer.h +++ b/nestkernel/slice_ring_buffer.h @@ -24,18 +24,8 @@ #define SLICE_RING_BUFFER_H // C++ includes: -#include -#include -#include #include -// Generated includes: -#include "config.h" - -// Includes from nestkernel: -#include "kernel_manager.h" -#include "nest_types.h" - namespace nest { @@ -155,109 +145,6 @@ class SliceRingBuffer SpikeInfo refract_; //!< pseudo-event for return from refractoriness }; -inline void -SliceRingBuffer::add_spike( const long rel_delivery, const long stamp, const double ps_offset, const double weight ) -{ - const long idx = kernel().event_delivery_manager.get_slice_modulo( rel_delivery ); - assert( static_cast< size_t >( idx ) < queue_.size() ); - assert( ps_offset >= 0 ); - - queue_[ idx ].push_back( SpikeInfo( stamp, ps_offset, weight ) ); -} - -inline void -SliceRingBuffer::add_refractory( const long stamp, const double ps_offset ) -{ - // We require that only one refractory-return pseudo-event is stored per - // time step. - // - // We guard against violation using assert(): refract_.stamp_ must - // be equal to the marker value for non-refractoriness. All else would mean - // that a refractory neuron fired. - assert( refract_.stamp_ == std::numeric_limits< long >::max() ); - - refract_.stamp_ = stamp; - refract_.ps_offset_ = ps_offset; -} - -inline bool -SliceRingBuffer::get_next_spike( const long req_stamp, - bool accumulate_simultaneous, - double& ps_offset, - double& weight, - bool& end_of_refract ) -{ - end_of_refract = false; - if ( deliver_->empty() or refract_ <= deliver_->back() ) - { - if ( refract_.stamp_ == req_stamp ) - { // if relies on stamp_==long::max() if not refractory - // return from refractoriness - ps_offset = refract_.ps_offset_; - weight = 0; - end_of_refract = true; - - // mark as non-refractory - refract_.stamp_ = std::numeric_limits< long >::max(); - return true; - } - else - { - return false; - } - } - else if ( deliver_->back().stamp_ == req_stamp ) - { - // we have an event to deliver - ps_offset = deliver_->back().ps_offset_; - weight = deliver_->back().weight_; - deliver_->pop_back(); - - if ( accumulate_simultaneous ) - { - // add weights of all spikes with same stamp and offset - while ( - not deliver_->empty() and deliver_->back().ps_offset_ == ps_offset and deliver_->back().stamp_ == req_stamp ) - { - weight += deliver_->back().weight_; - deliver_->pop_back(); - } - } - - return true; - } - else - { - // ensure that we are not blocked by spike from the past, cf #404 - assert( deliver_->back().stamp_ > req_stamp ); - return false; - } -} - -inline SliceRingBuffer::SpikeInfo::SpikeInfo( long stamp, double ps_offset, double weight ) - : stamp_( stamp ) - , ps_offset_( ps_offset ) - , weight_( weight ) -{ -} - -inline bool -SliceRingBuffer::SpikeInfo::operator<( const SpikeInfo& b ) const -{ - return stamp_ == b.stamp_ ? ps_offset_ > b.ps_offset_ : stamp_ < b.stamp_; -} - -inline bool -SliceRingBuffer::SpikeInfo::operator<=( const SpikeInfo& b ) const -{ - return not( *this > b ); -} - -inline bool -SliceRingBuffer::SpikeInfo::operator>( const SpikeInfo& b ) const -{ - return stamp_ == b.stamp_ ? ps_offset_ < b.ps_offset_ : stamp_ > b.stamp_; -} } // namespace nest diff --git a/nestkernel/sonata_connector.cpp b/nestkernel/sonata_connector.cpp index b44ae89640..66397a1353 100644 --- a/nestkernel/sonata_connector.cpp +++ b/nestkernel/sonata_connector.cpp @@ -21,7 +21,8 @@ */ #include "sonata_connector.h" -#include "config.h" +#include "connection_manager.h" +#include "model_manager.h" #ifdef HAVE_HDF5 @@ -30,7 +31,8 @@ // Includes from nestkernel: #include "kernel_manager.h" -#include "vp_manager_impl.h" +#include "nest.h" +#include "node_manager.h" // Includes from sli: #include "dictutils.h" @@ -402,7 +404,8 @@ SonataConnector::connect_chunk_( const hsize_t hyperslab_size, const hsize_t off read_subset_( delay_dset_, delay_data_subset, H5::PredType::NATIVE_DOUBLE, hyperslab_size, offset ); } - std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( kernel().vp_manager.get_num_threads() ); + std::vector< std::shared_ptr< WrappedThreadException > > exceptions_raised_( + kernel::manager< VPManager >.get_num_threads() ); // Retrieve the correct NodeCollections const auto nest_nodes = getValue< DictionaryDatum >( graph_specs_->lookup( "nodes" ) ); @@ -439,7 +442,7 @@ SonataConnector::connect_chunk_( const hsize_t hyperslab_size, const hsize_t off #pragma omp parallel { - const auto tid = kernel().vp_manager.get_thread_id(); + const auto tid = kernel::manager< VPManager >.get_thread_id(); RngPtr rng = get_vp_specific_rng( tid ); try @@ -451,7 +454,7 @@ SonataConnector::connect_chunk_( const hsize_t hyperslab_size, const hsize_t off const auto sonata_tgt_id = tgt_node_id_data_subset[ i ]; const size_t tnode_id = ( *( tnode_begin + sonata_tgt_id ) ).node_id; - if ( not kernel().vp_manager.is_node_id_vp_local( tnode_id ) ) + if ( not kernel::manager< VPManager >.is_node_id_vp_local( tnode_id ) ) { continue; } @@ -459,7 +462,7 @@ SonataConnector::connect_chunk_( const hsize_t hyperslab_size, const hsize_t off const auto sonata_src_id = src_node_id_data_subset[ i ]; const size_t snode_id = ( *( snode_begin + sonata_src_id ) ).node_id; - Node* target = kernel().node_manager.get_node_or_proxy( tnode_id, tid ); + Node* target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id, tid ); const size_t target_thread = target->get_thread(); const auto edge_type_id = edge_type_id_data_subset[ i ]; @@ -470,7 +473,7 @@ SonataConnector::connect_chunk_( const hsize_t hyperslab_size, const hsize_t off get_synapse_params_( snode_id, *target, target_thread, rng, edge_type_id ); - kernel().connection_manager.connect( snode_id, + kernel::manager< ConnectionManager >.connect( snode_id, target, target_thread, edge_type_id_2_syn_model_.at( edge_type_id ), @@ -490,7 +493,7 @@ SonataConnector::connect_chunk_( const hsize_t hyperslab_size, const hsize_t off } // end parallel region // Check if any exceptions have been raised - for ( size_t thr = 0; thr < kernel().vp_manager.get_num_threads(); ++thr ) + for ( size_t thr = 0; thr < kernel::manager< VPManager >.get_num_threads(); ++thr ) { if ( exceptions_raised_.at( thr ).get() ) { @@ -572,7 +575,7 @@ SonataConnector::create_edge_type_id_2_syn_spec_( DictionaryDatum edge_params ) const auto syn_name = getValue< std::string >( ( *d )[ "synapse_model" ] ); // The following call will throw "UnknownSynapseType" if syn_name is not naming a known model - const size_t synapse_model_id = kernel().model_manager.get_synapse_model_id( syn_name ); + const size_t synapse_model_id = kernel::manager< ModelManager >.get_synapse_model_id( syn_name ); set_synapse_params_( d, synapse_model_id, type_id ); edge_type_id_2_syn_model_[ type_id ] = synapse_model_id; @@ -582,7 +585,7 @@ SonataConnector::create_edge_type_id_2_syn_spec_( DictionaryDatum edge_params ) void SonataConnector::set_synapse_params_( DictionaryDatum syn_dict, size_t synapse_model_id, int type_id ) { - DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( synapse_model_id ); + DictionaryDatum syn_defaults = kernel::manager< ModelManager >.get_connector_defaults( synapse_model_id ); ConnParameterMap synapse_params; for ( Dictionary::const_iterator default_it = syn_defaults->begin(); default_it != syn_defaults->end(); ++default_it ) @@ -597,13 +600,13 @@ SonataConnector::set_synapse_params_( DictionaryDatum syn_dict, size_t synapse_m { synapse_params[ param_name ] = std::shared_ptr< ConnParameter >( - ConnParameter::create( ( *syn_dict )[ param_name ], kernel().vp_manager.get_num_threads() ) ); + ConnParameter::create( ( *syn_dict )[ param_name ], kernel::manager< VPManager >.get_num_threads() ) ); } } // Now create dictionary with dummy values that we will use to pass settings to the synapses created. We // create it here once to avoid re-creating the object over and over again. - edge_type_id_2_param_dicts_[ type_id ].resize( kernel().vp_manager.get_num_threads(), nullptr ); + edge_type_id_2_param_dicts_[ type_id ].resize( kernel::manager< VPManager >.get_num_threads(), nullptr ); edge_type_id_2_syn_spec_[ type_id ] = synapse_params; // TODO: Once NEST is SLIless, the below loop over threads should be parallelizable. In order to parallelize, the @@ -611,7 +614,7 @@ SonataConnector::set_synapse_params_( DictionaryDatum syn_dict, size_t synapse_m // region. Currently, creation of NumericDatum objects is not thread-safe because sli::pool memory is a static // member variable; thus is also the new operator a static member function. // Note that this also applies to the equivalent loop in conn_builder.cpp - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { edge_type_id_2_param_dicts_[ type_id ][ tid ] = new Dictionary; diff --git a/nestkernel/sonata_connector.h b/nestkernel/sonata_connector.h index 4420346b0e..2f2e0395b0 100644 --- a/nestkernel/sonata_connector.h +++ b/nestkernel/sonata_connector.h @@ -29,11 +29,11 @@ // C++ includes: #include +#include #include // Includes from nestkernel: #include "conn_parameter.h" -#include "kernel_manager.h" #include "nest_datums.h" #include "H5Cpp.h" diff --git a/nestkernel/source.cpp b/nestkernel/source.cpp new file mode 100644 index 0000000000..1d814ba4ec --- /dev/null +++ b/nestkernel/source.cpp @@ -0,0 +1,107 @@ +/* + * source.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "source.h" +#include + +namespace nest +{ + + +Source::Source() + : node_id_( 0 ) + , processed_( false ) + , primary_( true ) + , disabled_( false ) +{ +} + +Source::Source( const std::uint64_t node_id, const bool primary ) + : node_id_( node_id ) + , processed_( false ) + , primary_( primary ) + , disabled_( false ) +{ + assert( node_id <= MAX_NODE_ID ); +} + +std::uint64_t +Source::get_node_id() const +{ + return node_id_; +} + +void +Source::set_processed( const bool processed ) +{ + processed_ = processed; +} + +bool +Source::is_processed() const +{ + return processed_; +} + +void +Source::set_primary( const bool primary ) +{ + primary_ = primary; +} + +bool +Source::is_primary() const +{ + return primary_; +} + +void +Source::disable() +{ + disabled_ = true; +} + +bool +Source::is_disabled() const +{ + return disabled_; +} + +bool +operator<( const Source& lhs, const Source& rhs ) +{ + return lhs.node_id_ < rhs.node_id_; +} + +bool +operator>( const Source& lhs, const Source& rhs ) +{ + return rhs < lhs; +} + +bool +operator==( const Source& lhs, const Source& rhs ) +{ + return lhs.node_id_ == rhs.node_id_; +} + +} // namespace nest diff --git a/nestkernel/source.h b/nestkernel/source.h index 2ef1cecad8..ba22c0747e 100644 --- a/nestkernel/source.h +++ b/nestkernel/source.h @@ -83,83 +83,6 @@ class Source friend bool operator==( const Source& lhs, const Source& rhs ); }; -inline Source::Source() - : node_id_( 0 ) - , processed_( false ) - , primary_( true ) - , disabled_( false ) -{ -} - -inline Source::Source( const uint64_t node_id, const bool is_primary ) - : node_id_( node_id ) - , processed_( false ) - , primary_( is_primary ) - , disabled_( false ) -{ - assert( node_id <= MAX_NODE_ID ); -} - -inline uint64_t -Source::get_node_id() const -{ - return node_id_; -} - -inline void -Source::set_processed( const bool processed ) -{ - processed_ = processed; -} - -inline bool -Source::is_processed() const -{ - return processed_; -} - -inline void -Source::set_primary( const bool primary ) -{ - primary_ = primary; -} - -inline bool -Source::is_primary() const -{ - return primary_; -} - -inline void -Source::disable() -{ - disabled_ = true; -} - -inline bool -Source::is_disabled() const -{ - return disabled_; -} - -inline bool -operator<( const Source& lhs, const Source& rhs ) -{ - return ( lhs.node_id_ < rhs.node_id_ ); -} - -inline bool -operator>( const Source& lhs, const Source& rhs ) -{ - return operator<( rhs, lhs ); -} - -inline bool -operator==( const Source& lhs, const Source& rhs ) -{ - return ( lhs.node_id_ == rhs.node_id_ ); -} - } // namespace nest #endif /* #ifndef SOURCE_H */ diff --git a/nestkernel/source_table.cpp b/nestkernel/source_table.cpp index 5be1b6fa4e..851eb8ee49 100644 --- a/nestkernel/source_table.cpp +++ b/nestkernel/source_table.cpp @@ -25,12 +25,11 @@ // Includes from nestkernel: #include "connection_manager.h" -#include "connection_manager_impl.h" #include "kernel_manager.h" -#include "mpi_manager_impl.h" +#include "model_manager.h" #include "source_table.h" -#include "stopwatch_impl.h" -#include "vp_manager_impl.h" + +#include "connector_model.h" nest::SourceTable::SourceTable() { @@ -44,7 +43,7 @@ void nest::SourceTable::initialize() { assert( sizeof( Source ) == 8 ); - const size_t num_threads = kernel().vp_manager.get_num_threads(); + const size_t num_threads = kernel::manager< VPManager >.get_num_threads(); sources_.resize( num_threads ); is_cleared_.initialize( num_threads, false ); saved_entry_point_.initialize( num_threads, false ); @@ -54,7 +53,7 @@ nest::SourceTable::initialize() #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); sources_.at( tid ).resize( 0 ); resize_sources(); compressible_sources_.at( tid ).resize( 0 ); @@ -96,7 +95,7 @@ nest::SourceTablePosition nest::SourceTable::find_maximal_position() const { SourceTablePosition max_position( -1, -1, -1 ); - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { if ( max_position < saved_positions_[ tid ] ) { @@ -155,7 +154,7 @@ nest::SourceTable::clean( const size_t tid ) size_t nest::SourceTable::get_node_id( const size_t tid, const synindex syn_id, const size_t lcid ) const { - if ( not kernel().connection_manager.get_keep_source_table() ) + if ( not kernel::manager< ConnectionManager >.get_keep_source_table() ) { throw KernelException( "Cannot use SourceTable::get_node_id when get_keep_source_table is false" ); } @@ -169,7 +168,7 @@ nest::SourceTable::find_first_source( const size_t tid, const synindex syn_id, c const auto source_end = sources_[ tid ][ syn_id ].end(); auto first_source_match = source_begin; - if ( kernel().connection_manager.use_compressed_spikes() ) + if ( kernel::manager< ConnectionManager >.use_compressed_spikes() ) { // Binary search for first entry matching snode_id; is_primary is ignored const Source requested_source { snode_id, /* is_primary */ true }; @@ -195,7 +194,7 @@ nest::SourceTable::find_first_source( const size_t tid, const synindex syn_id, c size_t nest::SourceTable::remove_disabled_sources( const size_t tid, const synindex syn_id ) { - assert( kernel().connection_manager.use_compressed_spikes() ); + assert( kernel::manager< ConnectionManager >.use_compressed_spikes() ); if ( sources_[ tid ].size() <= syn_id ) { @@ -246,7 +245,7 @@ nest::SourceTable::compute_buffer_pos_for_unique_secondary_sources( const size_t // targets on the same process, but different threads for ( size_t syn_id = 0; syn_id < sources_[ tid ].size(); ++syn_id ) { - const ConnectorModel& conn_model = kernel().model_manager.get_connection_model( syn_id, tid ); + const ConnectorModel& conn_model = kernel::manager< ModelManager >.get_connection_model( syn_id, tid ); const bool is_primary = conn_model.has_property( ConnectionModelProperties::IS_PRIMARY ); if ( not is_primary ) @@ -262,23 +261,25 @@ nest::SourceTable::compute_buffer_pos_for_unique_secondary_sources( const size_t } } } - kernel().get_omp_synchronization_construction_stopwatch().start(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().start(); #pragma omp barrier - kernel().get_omp_synchronization_construction_stopwatch().stop(); + kernel::manager< SimulationManager >.get_omp_synchronization_construction_stopwatch().stop(); #pragma omp single { // compute receive buffer positions for all unique pairs of source // node ID and synapse-type id on this MPI rank - std::vector< int > recv_counts_secondary_events_in_int_per_rank( kernel().mpi_manager.get_num_processes(), 0 ); + std::vector< int > recv_counts_secondary_events_in_int_per_rank( + kernel::manager< MPIManager >.get_num_processes(), 0 ); for ( std::set< std::pair< size_t, size_t > >::const_iterator cit = ( *unique_secondary_source_node_id_syn_id ).begin(); cit != ( *unique_secondary_source_node_id_syn_id ).end(); ++cit ) { - const size_t source_rank = kernel().mpi_manager.get_process_id_of_node_id( cit->first ); - const size_t event_size = kernel().model_manager.get_secondary_event_prototype( cit->second, tid )->size(); + const size_t source_rank = kernel::manager< MPIManager >.get_process_id_of_node_id( cit->first ); + const size_t event_size = + kernel::manager< ModelManager >.get_secondary_event_prototype( cit->second, tid )->size(); buffer_pos_of_source_node_id_syn_id.insert( std::make_pair( pack_source_node_id_and_syn_id( cit->first, cit->second ), @@ -294,7 +295,7 @@ nest::SourceTable::compute_buffer_pos_for_unique_secondary_sources( const size_t ++recv_count; } - kernel().mpi_manager.set_recv_counts_secondary_events_in_int_per_rank( + kernel::manager< MPIManager >.set_recv_counts_secondary_events_in_int_per_rank( recv_counts_secondary_events_in_int_per_rank ); delete unique_secondary_source_node_id_syn_id; } // of omp single @@ -303,8 +304,9 @@ nest::SourceTable::compute_buffer_pos_for_unique_secondary_sources( const size_t void nest::SourceTable::resize_sources() { - kernel().vp_manager.assert_thread_parallel(); - sources_.at( kernel().vp_manager.get_thread_id() ).resize( kernel().model_manager.get_num_connection_models() ); + kernel::manager< VPManager >.assert_thread_parallel(); + sources_.at( kernel::manager< VPManager >.get_thread_id() ) + .resize( kernel::manager< ModelManager >.get_num_connection_models() ); } bool @@ -312,7 +314,7 @@ nest::SourceTable::source_should_be_processed_( const size_t rank_start, const size_t rank_end, const Source& source ) const { - const size_t source_rank = kernel().mpi_manager.get_process_id_of_node_id( source.get_node_id() ); + const size_t source_rank = kernel::manager< MPIManager >.get_process_id_of_node_id( source.get_node_id() ); return not( source.is_processed() or source.is_disabled() @@ -353,13 +355,14 @@ nest::SourceTable::populate_target_data_fields_( const SourceTablePosition& curr const size_t source_rank, TargetData& next_target_data ) const { - assert( not kernel().connection_manager.use_compressed_spikes() ); // handled elsewhere + assert( not kernel::manager< ConnectionManager >.use_compressed_spikes() ); // handled elsewhere const auto node_id = current_source.get_node_id(); // set values of next_target_data - next_target_data.set_source_lid( kernel().vp_manager.node_id_to_lid( node_id ) ); - next_target_data.set_source_tid( kernel().vp_manager.vp_to_thread( kernel().vp_manager.node_id_to_vp( node_id ) ) ); + next_target_data.set_source_lid( kernel::manager< VPManager >.node_id_to_lid( node_id ) ); + next_target_data.set_source_tid( + kernel::manager< VPManager >.vp_to_thread( kernel::manager< VPManager >.node_id_to_vp( node_id ) ) ); next_target_data.reset_marker(); if ( current_source.is_primary() ) // primary connection, i.e., chemical synapses @@ -380,9 +383,9 @@ nest::SourceTable::populate_target_data_fields_( const SourceTablePosition& curr // the source rank will write to the buffer position relative to // the first position from the absolute position in the receive // buffer - const size_t relative_recv_buffer_pos = kernel().connection_manager.get_secondary_recv_buffer_position( + const size_t relative_recv_buffer_pos = kernel::manager< ConnectionManager >.get_secondary_recv_buffer_position( current_position.tid, current_position.syn_id, current_position.lcid ) - - kernel().mpi_manager.get_recv_displacement_secondary_events_in_int( source_rank ); + - kernel::manager< MPIManager >.get_recv_displacement_secondary_events_in_int( source_rank ); SecondaryTargetDataFields& secondary_fields = next_target_data.secondary_data; secondary_fields.set_recv_buffer_pos( relative_recv_buffer_pos ); @@ -427,7 +430,7 @@ nest::SourceTable::get_next_target_data( const size_t tid, // we need to set a marker stating whether the entry following this // entry, if existent, has the same source - kernel().connection_manager.set_source_has_more_targets( current_position.tid, + kernel::manager< ConnectionManager >.set_source_has_more_targets( current_position.tid, current_position.syn_id, current_position.lcid, next_entry_has_same_source_( current_position, current_source ) ); @@ -444,7 +447,7 @@ nest::SourceTable::get_next_target_data( const size_t tid, // communicated via MPI, so we prepare to return the relevant data // set the source rank - source_rank = kernel().mpi_manager.get_process_id_of_node_id( current_source.get_node_id() ); + source_rank = kernel::manager< MPIManager >.get_process_id_of_node_id( current_source.get_node_id() ); if ( not populate_target_data_fields_( current_position, current_source, source_rank, next_target_data ) ) { @@ -467,7 +470,7 @@ nest::SourceTable::resize_compressible_sources() { compressible_sources_[ tid ].clear(); compressible_sources_[ tid ].resize( - kernel().model_manager.get_num_connection_models(), std::map< size_t, SpikeData >() ); + kernel::manager< ModelManager >.get_num_connection_models(), std::map< size_t, SpikeData >() ); } } @@ -490,13 +493,13 @@ nest::SourceTable::collect_compressible_sources( const size_t tid ) ++lcid; while ( ( lcid < syn_sources.size() ) and ( syn_sources[ lcid ].get_node_id() == old_source_node_id ) ) { - kernel().connection_manager.set_source_has_more_targets( tid, syn_id, lcid - 1, true ); + kernel::manager< ConnectionManager >.set_source_has_more_targets( tid, syn_id, lcid - 1, true ); ++lcid; } // Mark last connection in sequence as not having successor. This is essential if connections are // delete, e.g., by structural plasticity, because we do not globally reset the more_targets flag. assert( lcid - 1 < syn_sources.size() ); - kernel().connection_manager.set_source_has_more_targets( tid, syn_id, lcid - 1, false ); + kernel::manager< ConnectionManager >.set_source_has_more_targets( tid, syn_id, lcid - 1, false ); } } } @@ -509,11 +512,11 @@ nest::SourceTable::dump_sources() const { for ( size_t lcid = 0; lcid < sources_[ tid ][ syn_id ].size(); ++lcid ) { - kernel().write_to_dump( String::compose( "src : r%1 t%2 s%3 tg%4 l%5 tt%6", - kernel().mpi_manager.get_rank(), - kernel().vp_manager.get_thread_id(), + kernel::manager< KernelManager >.write_to_dump( String::compose( "src : r%1 t%2 s%3 tg%4 l%5 tt%6", + kernel::manager< MPIManager >.get_rank(), + kernel::manager< VPManager >.get_thread_id(), sources_[ tid ][ syn_id ][ lcid ].get_node_id(), - kernel().connection_manager.get_target_node_id( tid, syn_id, lcid ), + kernel::manager< ConnectionManager >.get_target_node_id( tid, syn_id, lcid ), lcid, tid ) ); } @@ -530,9 +533,9 @@ nest::SourceTable::dump_compressible_sources() const { for ( const auto& entry : compressible_sources_[ tid ][ syn_id ] ) { - kernel().write_to_dump( String::compose( "csrc : r%1 t%2 s%3 l%4 tt%5", - kernel().mpi_manager.get_rank(), - kernel().vp_manager.get_thread_id(), + kernel::manager< KernelManager >.write_to_dump( String::compose( "csrc : r%1 t%2 s%3 l%4 tt%5", + kernel::manager< MPIManager >.get_rank(), + kernel::manager< VPManager >.get_thread_id(), entry.first, entry.second.get_lcid(), entry.second.get_tid() ) ); @@ -545,7 +548,7 @@ void nest::SourceTable::fill_compressed_spike_data( std::vector< std::vector< std::vector< SpikeData > > >& compressed_spike_data ) { - const size_t num_synapse_models = kernel().model_manager.get_num_connection_models(); + const size_t num_synapse_models = kernel::manager< ModelManager >.get_num_connection_models(); compressed_spike_data.clear(); compressed_spike_data.resize( num_synapse_models ); compressed_spike_data_map_.clear(); @@ -558,7 +561,7 @@ nest::SourceTable::fill_compressed_spike_data( // TODO: I believe that at this point compressible_sources_ is ordered by source gid. // Maybe one can exploit that to avoid searching with find() below. - for ( synindex syn_id = 0; syn_id < kernel().model_manager.get_num_connection_models(); ++syn_id ) + for ( synindex syn_id = 0; syn_id < kernel::manager< ModelManager >.get_num_connection_models(); ++syn_id ) { for ( size_t target_thread = 0; target_thread < static_cast< size_t >( compressible_sources_.size() ); ++target_thread ) @@ -572,7 +575,7 @@ nest::SourceTable::fill_compressed_spike_data( // Set up entry for new source const auto new_source_index = compressed_spike_data[ syn_id ].size(); - compressed_spike_data[ syn_id ].emplace_back( kernel().vp_manager.get_num_threads(), + compressed_spike_data[ syn_id ].emplace_back( kernel::manager< VPManager >.get_num_threads(), SpikeData( invalid_targetindex, invalid_synindex, invalid_lcid, 0 ) ); compressed_spike_data_map_[ syn_id ].insert( @@ -602,9 +605,9 @@ nest::SourceTable::dump_compressed_spike_data( : compressed_spike_data_map_ ) { for ( const auto& entry : tab ) { - kernel().write_to_dump( String::compose( "csdm : r%1 t%2 s%3 sx%4 tt%5", - kernel().mpi_manager.get_rank(), - kernel().vp_manager.get_thread_id(), + kernel::manager< KernelManager >.write_to_dump( String::compose( "csdm : r%1 t%2 s%3 sx%4 tt%5", + kernel::manager< MPIManager >.get_rank(), + kernel::manager< VPManager >.get_thread_id(), entry.first, entry.second.get_source_index(), entry.second.get_target_thread() ) ); @@ -617,9 +620,9 @@ nest::SourceTable::dump_compressed_spike_data( { for ( size_t tx = 0; tx < tab[ six ].size(); ++tx ) { - kernel().write_to_dump( String::compose( "csd : r%1 t%2 six%3 tx%4 l%5 tt%6", - kernel().mpi_manager.get_rank(), - kernel().vp_manager.get_thread_id(), + kernel::manager< KernelManager >.write_to_dump( String::compose( "csd : r%1 t%2 six%3 tx%4 l%5 tt%6", + kernel::manager< MPIManager >.get_rank(), + kernel::manager< VPManager >.get_thread_id(), six, tx, tab[ six ][ tx ].get_lcid(), @@ -628,3 +631,200 @@ nest::SourceTable::dump_compressed_spike_data( } } ) } +void +nest::SourceTable::clear_compressed_spike_data_map() +{ + + for ( auto& source_index_map : compressed_spike_data_map_ ) + { + source_index_map.clear(); + } +} + +size_t +nest::SourceTable::pack_source_node_id_and_syn_id( const size_t source_node_id, const synindex syn_id ) const +{ + + assert( source_node_id < 72057594037927936 ); + assert( syn_id < invalid_synindex ); + // syn_id is maximally 256, so shifting node ID by 8 bits and storing + // syn_id in the lowest 8 leads to a unique number + return ( source_node_id << 8 ) + syn_id; +} + +size_t +nest::SourceTable::num_unique_sources( const size_t tid, const synindex syn_id ) const +{ + + size_t n = 0; + size_t last_source = 0; + for ( BlockVector< Source >::const_iterator cit = sources_[ tid ][ syn_id ].begin(); + cit != sources_[ tid ][ syn_id ].end(); + ++cit ) + { + if ( last_source != ( *cit ).get_node_id() ) + { + last_source = ( *cit ).get_node_id(); + ++n; + } + } + return n; +} + +void +nest::SourceTable::get_source_node_ids( const size_t tid, + const synindex syn_id, + const std::vector< size_t >& source_lcids, + std::vector< size_t >& sources ) +{ + + for ( std::vector< size_t >::const_iterator cit = source_lcids.begin(); cit != source_lcids.end(); ++cit ) + { + sources.push_back( sources_[ tid ][ syn_id ][ *cit ].get_node_id() ); + } +} + +void +nest::SourceTable::disable_connection( const size_t tid, const synindex syn_id, const size_t lcid ) +{ + + // disabling a source changes its node ID to 2^62 -1 + // source here + assert( not sources_[ tid ][ syn_id ][ lcid ].is_disabled() ); + sources_[ tid ][ syn_id ][ lcid ].disable(); +} + +void +nest::SourceTable::no_targets_to_process( const size_t tid ) +{ + + current_positions_[ tid ].tid = -1; + current_positions_[ tid ].syn_id = -1; + current_positions_[ tid ].lcid = -1; +} + +void +nest::SourceTable::reset_processed_flags( const size_t tid ) +{ + + for ( std::vector< BlockVector< Source > >::iterator it = sources_[ tid ].begin(); it != sources_[ tid ].end(); ++it ) + { + for ( BlockVector< Source >::iterator iit = it->begin(); iit != it->end(); ++iit ) + { + iit->set_processed( false ); + } + } +} + +void +nest::SourceTable::reset_entry_point( const size_t tid ) +{ + + // Since we read the source table backwards, we need to set saved + // values to the biggest possible value. These will be used to + // initialize current_positions_ correctly upon calling + // restore_entry_point. However, this can only be done if other + // values have valid values. + saved_positions_[ tid ].tid = sources_.size() - 1; + if ( saved_positions_[ tid ].tid > -1 ) + { + saved_positions_[ tid ].syn_id = sources_[ saved_positions_[ tid ].tid ].size() - 1; + } + else + { + saved_positions_[ tid ].syn_id = -1; + } + if ( saved_positions_[ tid ].syn_id > -1 ) + { + saved_positions_[ tid ].lcid = sources_[ saved_positions_[ tid ].tid ][ saved_positions_[ tid ].syn_id ].size() - 1; + } + else + { + saved_positions_[ tid ].lcid = -1; + } +} + +void +nest::SourceTable::restore_entry_point( const size_t tid ) +{ + + current_positions_[ tid ] = saved_positions_[ tid ]; + saved_entry_point_.set_false( tid ); +} + +void +nest::SourceTable::save_entry_point( const size_t tid ) +{ + + if ( saved_entry_point_[ tid ].is_false() ) + { + saved_positions_[ tid ].tid = current_positions_[ tid ].tid; + saved_positions_[ tid ].syn_id = current_positions_[ tid ].syn_id; + + // if tid and syn_id are valid entries, also store valid entry for lcid + if ( current_positions_[ tid ].tid > -1 and current_positions_[ tid ].syn_id > -1 ) + { + // either store current_position.lcid + 1, since this can + // contain non-processed entry (see reject_last_target_data()) or + // store maximal value for lcid. + saved_positions_[ tid ].lcid = std::min( current_positions_[ tid ].lcid + 1, + static_cast< long >( + sources_[ current_positions_[ tid ].tid ][ current_positions_[ tid ].syn_id ].size() - 1 ) ); + } + else + { + assert( current_positions_[ tid ].lcid == -1 ); + saved_positions_[ tid ].lcid = -1; + } + saved_entry_point_.set_true( tid ); + } +} + +void +nest::SourceTable::reject_last_target_data( const size_t tid ) +{ + + // The last target data returned by get_next_target_data() could not + // be inserted into MPI buffer due to overflow. We hence need to + // correct the processed flag of the last entry (see + // source_table.cpp) + assert( current_positions_[ tid ].lcid + 1 + < static_cast< long >( sources_[ current_positions_[ tid ].tid ][ current_positions_[ tid ].syn_id ].size() ) ); + + sources_[ current_positions_[ tid ].tid ][ current_positions_[ tid ].syn_id ][ current_positions_[ tid ].lcid + 1 ] + .set_processed( false ); +} + +void +nest::SourceTable::clear( const size_t tid ) +{ + + for ( std::vector< BlockVector< Source > >::iterator it = sources_[ tid ].begin(); it != sources_[ tid ].end(); ++it ) + { + it->clear(); + } + sources_[ tid ].clear(); + is_cleared_.set_true( tid ); +} + +void +nest::SourceTable::add_source( const size_t tid, const synindex syn_id, const size_t node_id, const bool is_primary ) +{ + + const Source src( node_id, is_primary ); + sources_[ tid ][ syn_id ].push_back( src ); +} + +size_t +nest::CSDMapEntry::get_target_thread() const +{ + + return target_thread_; +} + +size_t +nest::CSDMapEntry::get_source_index() const +{ + + return source_index_; +} diff --git a/nestkernel/source_table.h b/nestkernel/source_table.h index 55f48756ba..561e65e662 100644 --- a/nestkernel/source_table.h +++ b/nestkernel/source_table.h @@ -67,16 +67,8 @@ class CSDMapEntry assert( target_thread <= MAX_TID ); } - size_t - get_source_index() const - { - return source_index_; - } - size_t - get_target_thread() const - { - return target_thread_; - } + size_t get_source_index() const; + size_t get_target_thread() const; private: size_t source_index_ : NUM_BITS_LCID; @@ -360,176 +352,6 @@ class SourceTable const std::vector< std::vector< std::vector< SpikeData > > >& compressed_spike_data ) const; }; -inline void -SourceTable::add_source( const size_t tid, const synindex syn_id, const size_t node_id, const bool is_primary ) -{ - const Source src( node_id, is_primary ); - sources_[ tid ][ syn_id ].push_back( src ); -} - -inline void -SourceTable::clear( const size_t tid ) -{ - for ( std::vector< BlockVector< Source > >::iterator it = sources_[ tid ].begin(); it != sources_[ tid ].end(); ++it ) - { - it->clear(); - } - sources_[ tid ].clear(); - is_cleared_.set_true( tid ); -} - -inline void -SourceTable::reject_last_target_data( const size_t tid ) -{ - // The last target data returned by get_next_target_data() could not - // be inserted into MPI buffer due to overflow. We hence need to - // correct the processed flag of the last entry (see - // source_table.cpp) - assert( current_positions_[ tid ].lcid + 1 - < static_cast< long >( sources_[ current_positions_[ tid ].tid ][ current_positions_[ tid ].syn_id ].size() ) ); - - sources_[ current_positions_[ tid ].tid ][ current_positions_[ tid ].syn_id ][ current_positions_[ tid ].lcid + 1 ] - .set_processed( false ); -} - -inline void -SourceTable::save_entry_point( const size_t tid ) -{ - if ( saved_entry_point_[ tid ].is_false() ) - { - saved_positions_[ tid ].tid = current_positions_[ tid ].tid; - saved_positions_[ tid ].syn_id = current_positions_[ tid ].syn_id; - - // if tid and syn_id are valid entries, also store valid entry for lcid - if ( current_positions_[ tid ].tid > -1 and current_positions_[ tid ].syn_id > -1 ) - { - // either store current_position.lcid + 1, since this can - // contain non-processed entry (see reject_last_target_data()) or - // store maximal value for lcid. - saved_positions_[ tid ].lcid = std::min( current_positions_[ tid ].lcid + 1, - static_cast< long >( - sources_[ current_positions_[ tid ].tid ][ current_positions_[ tid ].syn_id ].size() - 1 ) ); - } - else - { - assert( current_positions_[ tid ].lcid == -1 ); - saved_positions_[ tid ].lcid = -1; - } - saved_entry_point_.set_true( tid ); - } -} - -inline void -SourceTable::restore_entry_point( const size_t tid ) -{ - current_positions_[ tid ] = saved_positions_[ tid ]; - saved_entry_point_.set_false( tid ); -} - -inline void -SourceTable::reset_entry_point( const size_t tid ) -{ - // Since we read the source table backwards, we need to set saved - // values to the biggest possible value. These will be used to - // initialize current_positions_ correctly upon calling - // restore_entry_point. However, this can only be done if other - // values have valid values. - saved_positions_[ tid ].tid = sources_.size() - 1; - if ( saved_positions_[ tid ].tid > -1 ) - { - saved_positions_[ tid ].syn_id = sources_[ saved_positions_[ tid ].tid ].size() - 1; - } - else - { - saved_positions_[ tid ].syn_id = -1; - } - if ( saved_positions_[ tid ].syn_id > -1 ) - { - saved_positions_[ tid ].lcid = sources_[ saved_positions_[ tid ].tid ][ saved_positions_[ tid ].syn_id ].size() - 1; - } - else - { - saved_positions_[ tid ].lcid = -1; - } -} - -inline void -SourceTable::reset_processed_flags( const size_t tid ) -{ - for ( std::vector< BlockVector< Source > >::iterator it = sources_[ tid ].begin(); it != sources_[ tid ].end(); ++it ) - { - for ( BlockVector< Source >::iterator iit = it->begin(); iit != it->end(); ++iit ) - { - iit->set_processed( false ); - } - } -} - -inline void -SourceTable::no_targets_to_process( const size_t tid ) -{ - current_positions_[ tid ].tid = -1; - current_positions_[ tid ].syn_id = -1; - current_positions_[ tid ].lcid = -1; -} - -inline void -SourceTable::disable_connection( const size_t tid, const synindex syn_id, const size_t lcid ) -{ - // disabling a source changes its node ID to 2^62 -1 - // source here - assert( not sources_[ tid ][ syn_id ][ lcid ].is_disabled() ); - sources_[ tid ][ syn_id ][ lcid ].disable(); -} - -inline void -SourceTable::get_source_node_ids( const size_t tid, - const synindex syn_id, - const std::vector< size_t >& source_lcids, - std::vector< size_t >& sources ) -{ - for ( std::vector< size_t >::const_iterator cit = source_lcids.begin(); cit != source_lcids.end(); ++cit ) - { - sources.push_back( sources_[ tid ][ syn_id ][ *cit ].get_node_id() ); - } -} - -inline size_t -SourceTable::num_unique_sources( const size_t tid, const synindex syn_id ) const -{ - size_t n = 0; - size_t last_source = 0; - for ( BlockVector< Source >::const_iterator cit = sources_[ tid ][ syn_id ].begin(); - cit != sources_[ tid ][ syn_id ].end(); - ++cit ) - { - if ( last_source != ( *cit ).get_node_id() ) - { - last_source = ( *cit ).get_node_id(); - ++n; - } - } - return n; -} - -inline size_t -SourceTable::pack_source_node_id_and_syn_id( const size_t source_node_id, const synindex syn_id ) const -{ - assert( source_node_id < 72057594037927936 ); - assert( syn_id < invalid_synindex ); - // syn_id is maximally 256, so shifting node ID by 8 bits and storing - // syn_id in the lowest 8 leads to a unique number - return ( source_node_id << 8 ) + syn_id; -} - -inline void -SourceTable::clear_compressed_spike_data_map() -{ - for ( auto& source_index_map : compressed_spike_data_map_ ) - { - source_index_map.clear(); - } -} } // namespace nest diff --git a/nestkernel/source_table_position.cpp b/nestkernel/source_table_position.cpp new file mode 100644 index 0000000000..5c67a0c695 --- /dev/null +++ b/nestkernel/source_table_position.cpp @@ -0,0 +1,154 @@ +/* + * source_table_position.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ +#include "source_table_position.h" +#include "block_vector.h" +#include "source.h" +#include +#include +#include + +namespace nest +{ + +SourceTablePosition::SourceTablePosition() + : tid( -1 ) + , syn_id( -1 ) + , lcid( -1 ) +{ +} + +SourceTablePosition::SourceTablePosition( const long tid, const long syn_id, const long lcid ) + : tid( tid ) + , syn_id( syn_id ) + , lcid( lcid ) +{ +} + +void +SourceTablePosition::seek_to_next_valid_index( const std::vector< std::vector< BlockVector< Source > > >& sources ) +{ + if ( lcid >= 0 ) + { + return; // nothing to do if we are at a valid index + } + + // we stay in this loop either until we can return a valid position, + // i.e., lcid >= 0, or we have reached the end of the + // multidimensional vector + while ( lcid < 0 ) + { + // first try finding a valid lcid by only decreasing synapse index + --syn_id; + if ( syn_id >= 0 ) + { + lcid = sources[ tid ][ syn_id ].size() - 1; + continue; + } + + // if we can not find a valid lcid by decreasing synapse indices, + // try decreasing thread index + --tid; + if ( tid >= 0 ) + { + syn_id = sources[ tid ].size() - 1; + if ( syn_id >= 0 ) + { + lcid = sources[ tid ][ syn_id ].size() - 1; + } + continue; + } + + // if we can not find a valid lcid by decreasing synapse or thread + // indices, we have read all entries + assert( tid == -1 ); + assert( syn_id == -1 ); + assert( lcid == -1 ); + return; // reached the end without finding a valid entry + } + + return; // found a valid entry +} + +bool +SourceTablePosition::is_invalid() const +{ + return ( tid == -1 and syn_id == -1 and lcid == -1 ); +} + +void +SourceTablePosition::decrease() +{ + --lcid; + assert( lcid >= -1 ); +} + +bool +operator==( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) +{ + return ( lhs.tid == rhs.tid and lhs.syn_id == rhs.syn_id and lhs.lcid == rhs.lcid ); +} + +bool +operator!=( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) +{ + return not operator==( lhs, rhs ); +} + +bool +operator<( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) +{ + if ( lhs.tid == rhs.tid ) + { + if ( lhs.syn_id == rhs.syn_id ) + { + return lhs.lcid < rhs.lcid; + } + else + { + return lhs.syn_id < rhs.syn_id; + } + } + else + { + return lhs.tid < rhs.tid; + } +} + +bool +operator>( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) +{ + return operator<( rhs, lhs ); +} + +bool +operator<=( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) +{ + return not operator>( lhs, rhs ); +} + +bool +operator>=( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) +{ + return not operator<( lhs, rhs ); +} + +} // namespace nest diff --git a/nestkernel/source_table_position.h b/nestkernel/source_table_position.h index 6b37e14d54..6e051b0c95 100644 --- a/nestkernel/source_table_position.h +++ b/nestkernel/source_table_position.h @@ -24,6 +24,7 @@ #define SOURCE_TABLE_POSITION_H // C++ includes: +#include "source.h" #include #include #include @@ -64,127 +65,13 @@ struct SourceTablePosition bool is_invalid() const; }; -inline SourceTablePosition::SourceTablePosition() - : tid( -1 ) - , syn_id( -1 ) - , lcid( -1 ) -{ -} - -inline SourceTablePosition::SourceTablePosition( const long tid, const long syn_id, const long lcid ) - : tid( tid ) - , syn_id( syn_id ) - , lcid( lcid ) -{ -} - -inline void -SourceTablePosition::seek_to_next_valid_index( const std::vector< std::vector< BlockVector< Source > > >& sources ) -{ - if ( lcid >= 0 ) - { - return; // nothing to do if we are at a valid index - } - - // we stay in this loop either until we can return a valid position, - // i.e., lcid >= 0, or we have reached the end of the - // multidimensional vector - while ( lcid < 0 ) - { - // first try finding a valid lcid by only decreasing synapse index - --syn_id; - if ( syn_id >= 0 ) - { - lcid = sources[ tid ][ syn_id ].size() - 1; - continue; - } - - // if we can not find a valid lcid by decreasing synapse indices, - // try decreasing thread index - --tid; - if ( tid >= 0 ) - { - syn_id = sources[ tid ].size() - 1; - if ( syn_id >= 0 ) - { - lcid = sources[ tid ][ syn_id ].size() - 1; - } - continue; - } - - // if we can not find a valid lcid by decreasing synapse or thread - // indices, we have read all entries - assert( tid == -1 ); - assert( syn_id == -1 ); - assert( lcid == -1 ); - return; // reached the end without finding a valid entry - } - - return; // found a valid entry -} - -inline bool -SourceTablePosition::is_invalid() const -{ - return ( tid == -1 and syn_id == -1 and lcid == -1 ); -} - -inline void -SourceTablePosition::decrease() -{ - --lcid; - assert( lcid >= -1 ); -} - -inline bool -operator==( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) -{ - return ( lhs.tid == rhs.tid and lhs.syn_id == rhs.syn_id and lhs.lcid == rhs.lcid ); -} - -inline bool -operator!=( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) -{ - return not operator==( lhs, rhs ); -} - -inline bool -operator<( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) -{ - if ( lhs.tid == rhs.tid ) - { - if ( lhs.syn_id == rhs.syn_id ) - { - return lhs.lcid < rhs.lcid; - } - else - { - return lhs.syn_id < rhs.syn_id; - } - } - else - { - return lhs.tid < rhs.tid; - } -} - -inline bool -operator>( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) -{ - return operator<( rhs, lhs ); -} +bool operator==( const SourceTablePosition& lhs, const SourceTablePosition& rhs ); +bool operator!=( const SourceTablePosition& lhs, const SourceTablePosition& rhs ); +bool operator<( const SourceTablePosition& lhs, const SourceTablePosition& rhs ); +bool operator>( const SourceTablePosition& lhs, const SourceTablePosition& rhs ); +bool operator<=( const SourceTablePosition& lhs, const SourceTablePosition& rhs ); +bool operator>=( const SourceTablePosition& lhs, const SourceTablePosition& rhs ); -inline bool -operator<=( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) -{ - return not operator>( lhs, rhs ); -} - -inline bool -operator>=( const SourceTablePosition& lhs, const SourceTablePosition& rhs ) -{ - return not operator<( lhs, rhs ); -} } // namespace nest diff --git a/nestkernel/sp_manager.cpp b/nestkernel/sp_manager.cpp index 899531e123..1e2ba0abff 100644 --- a/nestkernel/sp_manager.cpp +++ b/nestkernel/sp_manager.cpp @@ -28,11 +28,17 @@ // Includes from nestkernel: #include "conn_builder.h" #include "conn_parameter.h" +#include "connection_manager.h" #include "connector_base.h" #include "connector_model.h" #include "kernel_manager.h" +#include "logging.h" +#include "logging_manager.h" +#include "model_manager.h" +#include "nest.h" #include "nest_names.h" -#include "sp_manager_impl.h" + +#include "node_manager.h" namespace nest { @@ -97,7 +103,8 @@ SPManager::get_status( DictionaryDatum& d ) sp_synapse = DictionaryDatum( new Dictionary() ); def< std::string >( sp_synapse, names::pre_synaptic_element, ( *i )->get_pre_synaptic_element_name() ); def< std::string >( sp_synapse, names::post_synaptic_element, ( *i )->get_post_synaptic_element_name() ); - const std::string model = kernel().model_manager.get_connection_model( ( *i )->get_synapse_model(), 0 ).get_name(); + const std::string model = + kernel::manager< ModelManager >.get_connection_model( ( *i )->get_synapse_model(), 0 ).get_name(); def< std::string >( sp_synapse, names::synapse_model, model ); def< bool >( sp_synapse, names::allow_autapses, ( *i )->allows_autapses() ); def< bool >( sp_synapse, names::allow_multapses, ( *i )->allows_multapses() ); @@ -158,7 +165,8 @@ SPManager::set_status( const DictionaryDatum& d ) // check that the user defined the min and max delay properly, if the // default delay is not used. - if ( not conn_builder->get_default_delay() and not kernel().connection_manager.get_user_set_delay_extrema() ) + if ( not conn_builder->get_default_delay() + and not kernel::manager< ConnectionManager >.get_user_set_delay_extrema() ) { throw BadProperty( "Structural Plasticity: to use different delays for synapses you must " @@ -199,11 +207,11 @@ SPManager::builder_max_delay() const void SPManager::disconnect( const size_t snode_id, Node* target, size_t target_thread, const size_t syn_id ) { - Node* const source = kernel().node_manager.get_node_or_proxy( snode_id ); + Node* const source = kernel::manager< NodeManager >.get_node_or_proxy( snode_id ); // normal nodes and devices with proxies if ( target->has_proxies() ) { - kernel().connection_manager.disconnect( target_thread, syn_id, snode_id, target->get_node_id() ); + kernel::manager< ConnectionManager >.disconnect( target_thread, syn_id, snode_id, target->get_node_id() ); } else if ( target->local_receiver() ) // normal devices { @@ -214,10 +222,10 @@ SPManager::disconnect( const size_t snode_id, Node* target, size_t target_thread if ( ( source->get_thread() != target_thread ) and ( source->has_proxies() ) ) { target_thread = source->get_thread(); - target = kernel().node_manager.get_node_or_proxy( target->get_node_id(), target_thread ); + target = kernel::manager< NodeManager >.get_node_or_proxy( target->get_node_id(), target_thread ); } - kernel().connection_manager.disconnect( target_thread, syn_id, snode_id, target->get_node_id() ); + kernel::manager< ConnectionManager >.disconnect( target_thread, syn_id, snode_id, target->get_node_id() ); } else // globally receiving devices iterate over all target threads { @@ -226,12 +234,12 @@ SPManager::disconnect( const size_t snode_id, Node* target, size_t target_thread { return; } - const size_t n_threads = kernel().vp_manager.get_num_threads(); + const size_t n_threads = kernel::manager< VPManager >.get_num_threads(); for ( size_t t = 0; t < n_threads; t++ ) { - target = kernel().node_manager.get_node_or_proxy( target->get_node_id(), t ); + target = kernel::manager< NodeManager >.get_node_or_proxy( target->get_node_id(), t ); target_thread = target->get_thread(); - kernel().connection_manager.disconnect( target_thread, syn_id, snode_id, target->get_node_id() ); + kernel::manager< ConnectionManager >.disconnect( target_thread, syn_id, snode_id, target->get_node_id() ); } } } @@ -243,14 +251,14 @@ SPManager::disconnect( NodeCollectionPTR sources, DictionaryDatum& syn_spec ) { // probably not strictly necessarye here, but does nothing if all is up to date - kernel().node_manager.update_thread_local_node_data(); + kernel::manager< NodeManager >.update_thread_local_node_data(); - if ( kernel().connection_manager.connections_have_changed() ) + if ( kernel::manager< ConnectionManager >.connections_have_changed() ) { #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); - kernel().simulation_manager.update_connection_infrastructure( tid ); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); + kernel::manager< SimulationManager >.update_connection_infrastructure( tid ); } } @@ -264,7 +272,7 @@ SPManager::disconnect( NodeCollectionPTR sources, } const std::string rule_name = ( *conn_spec )[ names::rule ]; - if ( not kernel().connection_manager.valid_connection_rule( rule_name ) ) + if ( not kernel::manager< ConnectionManager >.valid_connection_rule( rule_name ) ) { throw BadProperty( "Unknown connectivity rule: " + rule_name ); } @@ -275,9 +283,9 @@ SPManager::disconnect( NodeCollectionPTR sources, for ( std::vector< SPBuilder* >::const_iterator i = sp_conn_builders_.begin(); i != sp_conn_builders_.end(); i++ ) { std::string synModel = getValue< std::string >( syn_spec, names::synapse_model ); - if ( ( *i )->get_synapse_model() == kernel().model_manager.get_synapse_model_id( synModel ) ) + if ( ( *i )->get_synapse_model() == kernel::manager< ModelManager >.get_synapse_model_id( synModel ) ) { - cb = kernel().connection_manager.get_conn_builder( rule_name, + cb = kernel::manager< ConnectionManager >.get_conn_builder( rule_name, sources, targets, /* third_out */ nullptr, @@ -290,7 +298,7 @@ SPManager::disconnect( NodeCollectionPTR sources, } else { - cb = kernel().connection_manager.get_conn_builder( rule_name, + cb = kernel::manager< ConnectionManager >.get_conn_builder( rule_name, sources, targets, /* third_out */ nullptr, @@ -304,7 +312,7 @@ SPManager::disconnect( NodeCollectionPTR sources, ALL_ENTRIES_ACCESSED( *syn_spec, "Connect", "Unread dictionary entries: " ); // Set flag before calling cb->disconnect() in case exception is thrown after some connections have been removed. - kernel().connection_manager.set_connections_have_changed(); + kernel::manager< ConnectionManager >.set_connections_have_changed(); cb->disconnect(); delete cb; @@ -346,8 +354,8 @@ SPManager::update_structural_plasticity( SPBuilder* sp_builder ) sp_builder->get_pre_synaptic_element_name(), pre_vacant_id, pre_vacant_n, pre_deleted_id, pre_deleted_n ); // Communicate the number of deleted pre-synaptic elements - kernel().mpi_manager.communicate( pre_deleted_id, pre_deleted_id_global, displacements ); - kernel().mpi_manager.communicate( pre_deleted_n, pre_deleted_n_global, displacements ); + kernel::manager< MPIManager >.communicate( pre_deleted_id, pre_deleted_id_global, displacements ); + kernel::manager< MPIManager >.communicate( pre_deleted_n, pre_deleted_n_global, displacements ); if ( pre_deleted_id_global.size() > 0 ) { @@ -364,8 +372,8 @@ SPManager::update_structural_plasticity( SPBuilder* sp_builder ) get_synaptic_elements( sp_builder->get_post_synaptic_element_name(), post_vacant_id, post_vacant_n, post_deleted_id, post_deleted_n ); // Communicate the number of deleted postsynaptic elements - kernel().mpi_manager.communicate( post_deleted_id, post_deleted_id_global, displacements ); - kernel().mpi_manager.communicate( post_deleted_n, post_deleted_n_global, displacements ); + kernel::manager< MPIManager >.communicate( post_deleted_id, post_deleted_id_global, displacements ); + kernel::manager< MPIManager >.communicate( post_deleted_n, post_deleted_n_global, displacements ); if ( post_deleted_id_global.size() > 0 ) { @@ -381,10 +389,10 @@ SPManager::update_structural_plasticity( SPBuilder* sp_builder ) } // Communicate vacant elements - kernel().mpi_manager.communicate( pre_vacant_id, pre_vacant_id_global, displacements ); - kernel().mpi_manager.communicate( pre_vacant_n, pre_vacant_n_global, displacements ); - kernel().mpi_manager.communicate( post_vacant_id, post_vacant_id_global, displacements ); - kernel().mpi_manager.communicate( post_vacant_n, post_vacant_n_global, displacements ); + kernel::manager< MPIManager >.communicate( pre_vacant_id, pre_vacant_id_global, displacements ); + kernel::manager< MPIManager >.communicate( pre_vacant_n, pre_vacant_n_global, displacements ); + kernel::manager< MPIManager >.communicate( post_vacant_id, post_vacant_id_global, displacements ); + kernel::manager< MPIManager >.communicate( post_vacant_n, post_vacant_n_global, displacements ); bool synapses_created = false; if ( pre_vacant_id_global.size() > 0 and post_vacant_id_global.size() > 0 ) @@ -394,7 +402,7 @@ SPManager::update_structural_plasticity( SPBuilder* sp_builder ) } if ( synapses_created or post_deleted_id.size() > 0 or pre_deleted_id.size() > 0 ) { - kernel().connection_manager.set_connections_have_changed(); + kernel::manager< ConnectionManager >.set_connections_have_changed(); } } @@ -454,7 +462,7 @@ SPManager::delete_synapses_from_pre( const std::vector< size_t >& pre_deleted_id std::vector< size_t >::const_iterator id_it; std::vector< int >::iterator n_it; - kernel().connection_manager.get_targets( pre_deleted_id, synapse_model, se_post_name, connectivity ); + kernel::manager< ConnectionManager >.get_targets( pre_deleted_id, synapse_model, se_post_name, connectivity ); id_it = pre_deleted_id.begin(); n_it = pre_deleted_n.begin(); @@ -462,7 +470,7 @@ SPManager::delete_synapses_from_pre( const std::vector< size_t >& pre_deleted_id for ( ; id_it != pre_deleted_id.end() and n_it != pre_deleted_n.end(); id_it++, n_it++, connectivity_it++ ) { // Communicate the list of targets - kernel().mpi_manager.communicate( *connectivity_it, global_targets, displacements ); + kernel::manager< MPIManager >.communicate( *connectivity_it, global_targets, displacements ); // shuffle only the first n items, n is the number of deleted synaptic // elements if ( -( *n_it ) > static_cast< int >( global_targets.size() ) ) @@ -486,10 +494,10 @@ SPManager::delete_synapse( const size_t snode_id, const std::string se_post_name ) { // get thread id - const size_t tid = kernel().vp_manager.get_thread_id(); - if ( kernel().node_manager.is_local_node_id( snode_id ) ) + const size_t tid = kernel::manager< VPManager >.get_thread_id(); + if ( kernel::manager< NodeManager >.is_local_node_id( snode_id ) ) { - Node* const source = kernel().node_manager.get_node_or_proxy( snode_id ); + Node* const source = kernel::manager< NodeManager >.get_node_or_proxy( snode_id ); const size_t source_thread = source->get_thread(); if ( tid == source_thread ) { @@ -497,13 +505,13 @@ SPManager::delete_synapse( const size_t snode_id, } } - if ( kernel().node_manager.is_local_node_id( tnode_id ) ) + if ( kernel::manager< NodeManager >.is_local_node_id( tnode_id ) ) { - Node* const target = kernel().node_manager.get_node_or_proxy( tnode_id ); + Node* const target = kernel::manager< NodeManager >.get_node_or_proxy( tnode_id ); const size_t target_thread = target->get_thread(); if ( tid == target_thread ) { - kernel().connection_manager.disconnect( tid, syn_id, snode_id, tnode_id ); + kernel::manager< ConnectionManager >.disconnect( tid, syn_id, snode_id, tnode_id ); target->connect_synaptic_element( se_post_name, -1 ); } @@ -532,7 +540,7 @@ SPManager::delete_synapses_from_post( std::vector< size_t >& post_deleted_id, std::vector< int >::iterator n_it; // Retrieve the connected sources - kernel().connection_manager.get_sources( post_deleted_id, synapse_model, connectivity ); + kernel::manager< ConnectionManager >.get_sources( post_deleted_id, synapse_model, connectivity ); id_it = post_deleted_id.begin(); n_it = post_deleted_n.begin(); @@ -541,7 +549,7 @@ SPManager::delete_synapses_from_post( std::vector< size_t >& post_deleted_id, for ( ; id_it != post_deleted_id.end() and n_it != post_deleted_n.end(); id_it++, n_it++, connectivity_it++ ) { // Communicate the list of sources - kernel().mpi_manager.communicate( *connectivity_it, global_sources, displacements ); + kernel::manager< MPIManager >.communicate( *connectivity_it, global_sources, displacements ); // shuffle only the first n items, n is the number of deleted synaptic // elements if ( -( *n_it ) > static_cast< int >( global_sources.size() ) ) @@ -569,7 +577,7 @@ nest::SPManager::get_synaptic_elements( std::string se_name, size_t n_deleted_id = 0; size_t node_id; int n; - size_t n_nodes = kernel().node_manager.size(); + size_t n_nodes = kernel::manager< NodeManager >.size(); se_vacant_id.clear(); se_vacant_n.clear(); se_deleted_id.clear(); @@ -586,9 +594,9 @@ nest::SPManager::get_synaptic_elements( std::string se_name, std::vector< int >::iterator deleted_n_it = se_deleted_n.begin(); SparseNodeArray::const_iterator node_it; - for ( size_t tid = 0; tid < kernel().vp_manager.get_num_threads(); ++tid ) + for ( size_t tid = 0; tid < kernel::manager< VPManager >.get_num_threads(); ++tid ) { - const SparseNodeArray& local_nodes = kernel().node_manager.get_local_nodes( tid ); + const SparseNodeArray& local_nodes = kernel::manager< NodeManager >.get_local_nodes( tid ); SparseNodeArray::const_iterator node_it; for ( node_it = local_nodes.begin(); node_it < local_nodes.end(); node_it++ ) { @@ -671,17 +679,17 @@ nest::SPManager::global_shuffle( std::vector< size_t >& v, size_t n ) void nest::SPManager::enable_structural_plasticity() { - if ( kernel().vp_manager.get_num_threads() > 1 ) + if ( kernel::manager< VPManager >.get_num_threads() > 1 ) { throw KernelException( "Structural plasticity can not be used with multiple threads" ); } - if ( not kernel().connection_manager.get_keep_source_table() ) + if ( not kernel::manager< ConnectionManager >.get_keep_source_table() ) { throw KernelException( "Structural plasticity can not be enabled if keep_source_table has been " "set to false." ); } - if ( not kernel().connection_manager.use_compressed_spikes() ) + if ( not kernel::manager< ConnectionManager >.use_compressed_spikes() ) { throw KernelException( "Structural plasticity can not be enabled if use_compressed_spikes " @@ -696,4 +704,26 @@ nest::SPManager::disable_structural_plasticity() structural_plasticity_enabled_ = false; } + +double +SPManager::get_structural_plasticity_update_interval() const +{ + + return structural_plasticity_update_interval_; +} + +bool +SPManager::is_structural_plasticity_enabled() const +{ + + return structural_plasticity_enabled_; +} + +GrowthCurve* +SPManager::new_growth_curve( Name name ) +{ + + const long nc_id = ( *growthcurvedict_ )[ name ]; + return growthcurve_factories_.at( nc_id )->create(); +} } // namespace nest diff --git a/nestkernel/sp_manager.h b/nestkernel/sp_manager.h index 79cc92a72a..644bb6e9e8 100644 --- a/nestkernel/sp_manager.h +++ b/nestkernel/sp_manager.h @@ -210,23 +210,17 @@ class SPManager : public ManagerInterface DictionaryDatum growthcurvedict_; //!< Dictionary for growth rules. }; -inline GrowthCurve* -SPManager::new_growth_curve( Name name ) -{ - const long nc_id = ( *growthcurvedict_ )[ name ]; - return growthcurve_factories_.at( nc_id )->create(); -} - -inline bool -SPManager::is_structural_plasticity_enabled() const -{ - return structural_plasticity_enabled_; -} -inline double -SPManager::get_structural_plasticity_update_interval() const +template < typename GrowthCurve > +void +SPManager::register_growth_curve( const std::string& name ) { - return structural_plasticity_update_interval_; + assert( not growthcurvedict_->known( name ) ); + GenericGrowthCurveFactory* nc = new GrowthCurveFactory< GrowthCurve >(); + assert( nc ); + const int id = growthcurve_factories_.size(); + growthcurve_factories_.push_back( nc ); + growthcurvedict_->insert( name, id ); } } // namespace nest diff --git a/nestkernel/sparse_node_array.cpp b/nestkernel/sparse_node_array.cpp index 6154eace5d..13da0c1603 100644 --- a/nestkernel/sparse_node_array.cpp +++ b/nestkernel/sparse_node_array.cpp @@ -26,7 +26,6 @@ #include "exceptions.h" #include "kernel_manager.h" #include "node.h" -#include "vp_manager_impl.h" nest::SparseNodeArray::NodeEntry::NodeEntry( Node& node, size_t node_id ) @@ -87,7 +86,7 @@ nest::SparseNodeArray::add_local_node( Node& node ) left_side_has_proxies_ = node.has_proxies(); // we now know which scale applies on which side of the split - const double proxy_scale = 1.0 / static_cast< double >( kernel().vp_manager.get_num_virtual_processes() ); + const double proxy_scale = 1.0 / static_cast< double >( kernel::manager< VPManager >.get_num_virtual_processes() ); if ( left_side_has_proxies_ ) { left_scale_ = proxy_scale; @@ -173,3 +172,61 @@ nest::SparseNodeArray::get_node_by_node_id( size_t node_id ) const return nullptr; } } +size_t +nest::SparseNodeArray::NodeEntry::get_node_id() const +{ + + assert( node_id_ > 0 ); + return node_id_; +} + +nest::Node* +nest::SparseNodeArray::NodeEntry::get_node() const +{ + + assert( node_ ); + return node_; +} + +bool +nest::SparseNodeArray::is_consistent_() const +{ + + return nodes_.size() == 0 or global_max_node_id_ > 0; +} + +size_t +nest::SparseNodeArray::get_max_node_id() const +{ + + return global_max_node_id_; +} + +nest::Node* +nest::SparseNodeArray::get_node_by_index( size_t idx ) const +{ + + assert( idx < nodes_.size() ); + return nodes_[ idx ].node_; +} + +size_t +nest::SparseNodeArray::size() const +{ + + return nodes_.size(); +} + +nest::SparseNodeArray::const_iterator +nest::SparseNodeArray::end() const +{ + + return nodes_.end(); +} + +nest::SparseNodeArray::const_iterator +nest::SparseNodeArray::begin() const +{ + + return nodes_.begin(); +} diff --git a/nestkernel/sparse_node_array.h b/nestkernel/sparse_node_array.h index 9518b227ff..63bb04533d 100644 --- a/nestkernel/sparse_node_array.h +++ b/nestkernel/sparse_node_array.h @@ -223,55 +223,4 @@ class SparseNodeArray } // namespace nest -inline nest::SparseNodeArray::const_iterator -nest::SparseNodeArray::begin() const -{ - return nodes_.begin(); -} - -inline nest::SparseNodeArray::const_iterator -nest::SparseNodeArray::end() const -{ - return nodes_.end(); -} - -inline size_t -nest::SparseNodeArray::size() const -{ - return nodes_.size(); -} - -inline nest::Node* -nest::SparseNodeArray::get_node_by_index( size_t idx ) const -{ - assert( idx < nodes_.size() ); - return nodes_[ idx ].node_; -} - -inline size_t -nest::SparseNodeArray::get_max_node_id() const -{ - return global_max_node_id_; -} - -inline bool -nest::SparseNodeArray::is_consistent_() const -{ - return nodes_.size() == 0 or global_max_node_id_ > 0; -} - -inline nest::Node* -nest::SparseNodeArray::NodeEntry::get_node() const -{ - assert( node_ ); - return node_; -} - -inline size_t -nest::SparseNodeArray::NodeEntry::get_node_id() const -{ - assert( node_id_ > 0 ); - return node_id_; -} - #endif /* SPARSE_NODE_ARRAY_H */ diff --git a/nestkernel/spatial.cpp b/nestkernel/spatial.cpp index 8063eab1c3..a6d5bce6ef 100644 --- a/nestkernel/spatial.cpp +++ b/nestkernel/spatial.cpp @@ -32,17 +32,11 @@ // Includes from nestkernel: #include "exceptions.h" #include "kernel_manager.h" +#include "logging_manager.h" #include "nest.h" #include "nestmodule.h" #include "node.h" -// Includes from sli: -#include "sliexceptions.h" - -// Includes from spatial: -#include "grid_layer.h" -#include "layer_impl.h" - namespace nest { @@ -93,7 +87,7 @@ get_position( NodeCollectionPTR layer_nc ) { size_t node_id = ( *it ).node_id; - if ( not kernel().node_manager.is_local_node_id( node_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( node_id ) ) { throw KernelException( "GetPosition is currently implemented for local nodes only." ); } @@ -110,12 +104,12 @@ get_position( NodeCollectionPTR layer_nc ) std::vector< double > get_position( const size_t node_id ) { - if ( not kernel().node_manager.is_local_node_id( node_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( node_id ) ) { throw KernelException( "GetPosition is currently implemented for local nodes only." ); } - NodeCollectionPTR nc = kernel().node_manager.node_id_to_node_collection( node_id ); + NodeCollectionPTR nc = kernel::manager< NodeManager >.node_id_to_node_collection( node_id ); NodeCollectionMetadataPTR meta = nc->get_metadata(); if ( not meta ) @@ -150,7 +144,7 @@ displacement( NodeCollectionPTR layer_to_nc, NodeCollectionPTR layer_from_nc ) if ( layer_from_nc->size() == 1 ) { size_t node_id = layer_from_nc->operator[]( 0 ); - if ( not kernel().node_manager.is_local_node_id( node_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( node_id ) ) { throw KernelException( "Displacement is currently implemented for local nodes only." ); } @@ -169,7 +163,7 @@ displacement( NodeCollectionPTR layer_to_nc, NodeCollectionPTR layer_from_nc ) for ( NodeCollection::const_iterator it = layer_from_nc->begin(); it < layer_from_nc->end(); ++it ) { size_t node_id = ( *it ).node_id; - if ( not kernel().node_manager.is_local_node_id( node_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( node_id ) ) { throw KernelException( "Displacement is currently implemented for local nodes only." ); } @@ -204,7 +198,7 @@ displacement( NodeCollectionPTR layer_nc, const ArrayDatum point ) for ( NodeCollection::const_iterator it = layer_nc->begin(); it != layer_nc->end(); ++it ) { size_t node_id = ( *it ).node_id; - if ( not kernel().node_manager.is_local_node_id( node_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( node_id ) ) { throw KernelException( "Displacement is currently implemented for local nodes only." ); } @@ -242,7 +236,7 @@ distance( NodeCollectionPTR layer_to_nc, NodeCollectionPTR layer_from_nc ) if ( layer_from_nc->size() == 1 ) { size_t node_id = layer_from_nc->operator[]( 0 ); - if ( not kernel().node_manager.is_local_node_id( node_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( node_id ) ) { throw KernelException( "Distance is currently implemented for local nodes only." ); } @@ -261,7 +255,7 @@ distance( NodeCollectionPTR layer_to_nc, NodeCollectionPTR layer_from_nc ) for ( NodeCollection::const_iterator it = layer_from_nc->begin(); it < layer_from_nc->end(); ++it ) { size_t node_id = ( *it ).node_id; - if ( not kernel().node_manager.is_local_node_id( node_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( node_id ) ) { throw KernelException( "Distance is currently implemented for local nodes only." ); } @@ -296,7 +290,7 @@ distance( NodeCollectionPTR layer_nc, const ArrayDatum point ) for ( NodeCollection::const_iterator it = layer_nc->begin(); it < layer_nc->end(); ++it ) { size_t node_id = ( *it ).node_id; - if ( not kernel().node_manager.is_local_node_id( node_id ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( node_id ) ) { throw KernelException( "Distance is currently implemented for local nodes only." ); } @@ -334,13 +328,13 @@ distance( const ArrayDatum conns ) size_t trgt = conn_id.get_target_node_id(); - if ( not kernel().node_manager.is_local_node_id( trgt ) ) + if ( not kernel::manager< NodeManager >.is_local_node_id( trgt ) ) { throw KernelException( "Distance is currently implemented for local nodes only." ); } - NodeCollectionPTR trgt_nc = kernel().node_manager.node_id_to_node_collection( trgt ); + NodeCollectionPTR trgt_nc = kernel::manager< NodeManager >.node_id_to_node_collection( trgt ); NodeCollectionMetadataPTR meta = trgt_nc->get_metadata(); // distance is NaN if source, target is not spatially distributed @@ -406,10 +400,10 @@ connect_layers( NodeCollectionPTR source_nc, NodeCollectionPTR target_nc, const ConnectionCreator connector( connection_dict ); ALL_ENTRIES_ACCESSED( *connection_dict, "nest::CreateLayers", "Unread dictionary entries: " ); - kernel().node_manager.update_thread_local_node_data(); + kernel::manager< NodeManager >.update_thread_local_node_data(); // Set flag before calling source->connect() in case exception is thrown after some connections have been created. - kernel().connection_manager.set_connections_have_changed(); + kernel::manager< ConnectionManager >.set_connections_have_changed(); source->connect( source_nc, target, target_nc, connector ); } @@ -448,4 +442,52 @@ get_layer_status( NodeCollectionPTR ) return DictionaryDatum(); } +void +LayerMetadata::get_status( DictionaryDatum& d, NodeCollection const* nc ) const +{ + layer_->get_status( d, nc ); +} + +const AbstractLayerPTR +LayerMetadata::get_layer() const +{ + return layer_; +} + +std::string +LayerMetadata::get_type() const +{ + return "spatial"; +} + +void +LayerMetadata::set_first_node_id( size_t node_id ) +{ + first_node_id_ = node_id; +} + +size_t +LayerMetadata::get_first_node_id() const +{ + return first_node_id_; +} + +bool +LayerMetadata::operator==( const NodeCollectionMetadataPTR rhs ) const +{ + const auto rhs_layer_metadata = dynamic_cast< LayerMetadata* >( rhs.get() ); + if ( not rhs_layer_metadata ) + { + return false; + } + // Compare status dictionaries of this layer and rhs layer + DictionaryDatum dict( new Dictionary() ); + DictionaryDatum rhs_dict( new Dictionary() ); + + // Since we do not have access to the node collection here, we + // compare based on all metadata, irrespective of any slicing + get_status( dict, /* nc */ nullptr ); + rhs_layer_metadata->get_status( rhs_dict, /* nc */ nullptr ); + return *dict == *rhs_dict; +} } // namespace nest diff --git a/nestkernel/spatial.h b/nestkernel/spatial.h index 27534cb1b5..822d5e0954 100644 --- a/nestkernel/spatial.h +++ b/nestkernel/spatial.h @@ -59,56 +59,18 @@ class LayerMetadata : public NodeCollectionMetadata void set_status( const DictionaryDatum&, bool ) override {}; - void - get_status( DictionaryDatum& d, NodeCollection const* nc ) const override - { - layer_->get_status( d, nc ); - } + void get_status( DictionaryDatum& d, NodeCollection const* nc ) const override; //! Returns pointer to object with layer representation - const AbstractLayerPTR - get_layer() const - { - return layer_; - } + const AbstractLayerPTR get_layer() const; // Using string as enum would make stuff more complicated - std::string - get_type() const override - { - return "spatial"; - } + std::string get_type() const override; - void - set_first_node_id( size_t node_id ) override - { - first_node_id_ = node_id; - } - - size_t - get_first_node_id() const override - { - return first_node_id_; - } + void set_first_node_id( size_t node_id ) override; - bool - operator==( const NodeCollectionMetadataPTR rhs ) const override - { - const auto rhs_layer_metadata = dynamic_cast< LayerMetadata* >( rhs.get() ); - if ( not rhs_layer_metadata ) - { - return false; - } - // Compare status dictionaries of this layer and rhs layer - DictionaryDatum dict( new Dictionary() ); - DictionaryDatum rhs_dict( new Dictionary() ); - - // Since we do not have access to the node collection here, we - // compare based on all metadata, irrespective of any slicing - get_status( dict, /* nc */ nullptr ); - rhs_layer_metadata->get_status( rhs_dict, /* nc */ nullptr ); - return *dict == *rhs_dict; - } + size_t get_first_node_id() const override; + bool operator==( const NodeCollectionMetadataPTR rhs ) const override; private: const AbstractLayerPTR layer_; //!< layer object diff --git a/nestkernel/spike_data.cpp b/nestkernel/spike_data.cpp new file mode 100644 index 0000000000..fd562e853a --- /dev/null +++ b/nestkernel/spike_data.cpp @@ -0,0 +1,273 @@ +/* + * spike_data.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "spike_data.h" +#include "target.h" + +#include + +namespace nest +{ + +// --- SpikeData --- + +SpikeData::SpikeData() + : lcid_( 0 ) + , marker_( SPIKE_DATA_ID_DEFAULT ) + , lag_( 0 ) + , tid_( 0 ) + , syn_id_( 0 ) +{ +} + +SpikeData::SpikeData( const SpikeData& rhs ) + : lcid_( rhs.lcid_ ) + , marker_( rhs.marker_ ) + , lag_( rhs.lag_ ) + , tid_( rhs.tid_ ) + , syn_id_( rhs.syn_id_ ) +{ +} + +SpikeData::SpikeData( const Target& target, const size_t lag ) + : lcid_( target.get_lcid() ) + , marker_( SPIKE_DATA_ID_DEFAULT ) + , lag_( lag ) + , tid_( target.get_tid() ) + , syn_id_( target.get_syn_id() ) +{ +} + +SpikeData::SpikeData( const size_t tid, const synindex syn_id, const size_t lcid, const unsigned int lag ) + : lcid_( lcid ) + , marker_( SPIKE_DATA_ID_DEFAULT ) + , lag_( lag ) + , tid_( tid ) + , syn_id_( syn_id ) +{ +} + +SpikeData& +SpikeData::operator=( const SpikeData& rhs ) +{ + lcid_ = rhs.lcid_; + marker_ = rhs.marker_; + lag_ = rhs.lag_; + tid_ = rhs.tid_; + syn_id_ = rhs.syn_id_; + return *this; +} + +void +SpikeData::set( const size_t tid, const synindex syn_id, const size_t lcid, const unsigned int lag, const double ) +{ + assert( tid <= MAX_TID ); // MAX_TID is allowed since it is not used as invalid value + assert( syn_id < MAX_SYN_ID ); + assert( lcid < MAX_LCID ); + assert( lag < MAX_LAG ); + + lcid_ = lcid; + marker_ = SPIKE_DATA_ID_DEFAULT; + lag_ = lag; + tid_ = tid; + syn_id_ = syn_id; +} + +size_t +SpikeData::get_lcid() const +{ + return lcid_; +} + +void +SpikeData::set_lcid( size_t value ) +{ + assert( value < MAX_LCID ); + lcid_ = value; +} + + +double +SpikeData::get_offset() const +{ + return 0.0; +} + +unsigned int +SpikeData::get_lag() const +{ + return lag_; +} + +size_t +SpikeData::get_tid() const +{ + return tid_; +} + +synindex +SpikeData::get_syn_id() const +{ + return syn_id_; +} + +unsigned int +SpikeData::get_marker() const +{ + return marker_; +} + +void +SpikeData::reset_marker() +{ + marker_ = SPIKE_DATA_ID_DEFAULT; +} + +void +SpikeData::set_complete_marker() +{ + marker_ = SPIKE_DATA_ID_COMPLETE; +} + +void +SpikeData::set_end_marker() +{ + marker_ = SPIKE_DATA_ID_END; +} + +void +SpikeData::set_invalid_marker() +{ + marker_ = SPIKE_DATA_ID_INVALID; +} + +bool +SpikeData::is_complete_marker() const +{ + return marker_ == SPIKE_DATA_ID_COMPLETE; +} + +bool +SpikeData::is_end_marker() const +{ + return marker_ == SPIKE_DATA_ID_END; +} + +bool +SpikeData::is_invalid_marker() const +{ + return marker_ == SPIKE_DATA_ID_INVALID; +} + + +// --- OffGridSpikeData --- + +OffGridSpikeData::OffGridSpikeData() + : SpikeData() + , offset_( 0.0 ) +{ +} + +OffGridSpikeData::OffGridSpikeData( const Target& target, const size_t lag, const double offset ) + : SpikeData( target, lag ) + , offset_( offset ) +{ +} + +OffGridSpikeData::OffGridSpikeData( const size_t tid, + const synindex syn_id, + const size_t lcid, + const unsigned int lag, + const double offset ) + : SpikeData( tid, syn_id, lcid, lag ) + , offset_( offset ) +{ +} + +OffGridSpikeData::OffGridSpikeData( const OffGridSpikeData& rhs ) + : SpikeData( rhs ) + , offset_( rhs.offset_ ) +{ +} + +OffGridSpikeData& +OffGridSpikeData::operator=( const OffGridSpikeData& rhs ) +{ + lcid_ = rhs.lcid_; + marker_ = rhs.marker_; + lag_ = rhs.lag_; + tid_ = rhs.tid_; + syn_id_ = rhs.syn_id_; + offset_ = rhs.offset_; + return *this; +} + +OffGridSpikeData& +OffGridSpikeData::operator=( const SpikeData& rhs ) +{ + // Need to use get_*() here, direct access to protected members of base-class instance is prohibited, + // see example in https://en.cppreference.com/w/cpp/language/access. + lcid_ = rhs.get_lcid(); + marker_ = rhs.get_marker(); + lag_ = rhs.get_lag(); + tid_ = rhs.get_tid(); + syn_id_ = rhs.get_syn_id(); + offset_ = 0; + return *this; +} + +void +OffGridSpikeData::set( const size_t tid, + const synindex syn_id, + const size_t lcid, + const unsigned int lag, + const double offset ) +{ + assert( tid <= MAX_TID ); // MAX_TID is allowed since it is not used as invalid value + assert( syn_id < MAX_SYN_ID ); + assert( lcid < MAX_LCID ); + assert( lag < MAX_LAG ); + + lcid_ = lcid; + marker_ = SPIKE_DATA_ID_DEFAULT; + lag_ = lag; + tid_ = tid; + syn_id_ = syn_id; + offset_ = offset; +} +// --- SpikeDataWithRank --- + +SpikeDataWithRank::SpikeDataWithRank( const Target& target, const size_t lag ) + : rank( target.get_rank() ) + , spike_data( target, lag ) +{ +} + +// --- OffGridSpikeDataWithRank --- + +OffGridSpikeDataWithRank::OffGridSpikeDataWithRank( const Target& target, const size_t lag, const double offset ) + : rank( target.get_rank() ) + , spike_data( target, lag, offset ) +{ +} + +} // namespace nest diff --git a/nestkernel/spike_data.h b/nestkernel/spike_data.h index 87b1205ba0..ac89dedc63 100644 --- a/nestkernel/spike_data.h +++ b/nestkernel/spike_data.h @@ -192,68 +192,6 @@ class SpikeData //! check legal size using success_spike_data_size = StaticAssert< sizeof( SpikeData ) == 8 >::success; -inline SpikeData::SpikeData() - : lcid_( 0 ) - , marker_( SPIKE_DATA_ID_DEFAULT ) - , lag_( 0 ) - , tid_( 0 ) - , syn_id_( 0 ) -{ -} - -inline SpikeData::SpikeData( const SpikeData& rhs ) - : lcid_( rhs.lcid_ ) - , marker_( rhs.marker_ ) - , lag_( rhs.lag_ ) - , tid_( rhs.tid_ ) - , syn_id_( rhs.syn_id_ ) -{ -} - -inline SpikeData::SpikeData( const Target& target, const size_t lag ) - : lcid_( target.get_lcid() ) - , marker_( SPIKE_DATA_ID_DEFAULT ) - , lag_( lag ) - , tid_( target.get_tid() ) - , syn_id_( target.get_syn_id() ) -{ -} - -inline SpikeData::SpikeData( const size_t tid, const synindex syn_id, const size_t lcid, const unsigned int lag ) - : lcid_( lcid ) - , marker_( SPIKE_DATA_ID_DEFAULT ) - , lag_( lag ) - , tid_( tid ) - , syn_id_( syn_id ) -{ -} - -inline SpikeData& -SpikeData::operator=( const SpikeData& rhs ) -{ - lcid_ = rhs.lcid_; - marker_ = rhs.marker_; - lag_ = rhs.lag_; - tid_ = rhs.tid_; - syn_id_ = rhs.syn_id_; - return *this; -} - -inline void -SpikeData::set( const size_t tid, const synindex syn_id, const size_t lcid, const unsigned int lag, const double ) -{ - assert( tid <= MAX_TID ); // MAX_TID is allowed since it is not used as invalid value - assert( syn_id < MAX_SYN_ID ); - assert( lcid < MAX_LCID ); - assert( lag < MAX_LAG ); - - lcid_ = lcid; - marker_ = SPIKE_DATA_ID_DEFAULT; - lag_ = lag; - tid_ = tid; - syn_id_ = syn_id; -} - template < class TargetT > inline void @@ -268,90 +206,6 @@ SpikeData::set( const TargetT& target, const unsigned int lag ) syn_id_ = target.get_syn_id(); } -inline size_t -SpikeData::get_lcid() const -{ - return lcid_; -} - -inline void -SpikeData::set_lcid( size_t value ) -{ - assert( value < MAX_LCID ); - lcid_ = value; -} - -inline unsigned int -SpikeData::get_lag() const -{ - return lag_; -} - -inline size_t -SpikeData::get_tid() const -{ - return tid_; -} - -inline synindex -SpikeData::get_syn_id() const -{ - return syn_id_; -} - -inline unsigned int -SpikeData::get_marker() const -{ - return marker_; -} - -inline void -SpikeData::reset_marker() -{ - marker_ = SPIKE_DATA_ID_DEFAULT; -} - -inline void -SpikeData::set_complete_marker() -{ - marker_ = SPIKE_DATA_ID_COMPLETE; -} - -inline void -SpikeData::set_end_marker() -{ - marker_ = SPIKE_DATA_ID_END; -} - -inline void -SpikeData::set_invalid_marker() -{ - marker_ = SPIKE_DATA_ID_INVALID; -} - -inline bool -SpikeData::is_complete_marker() const -{ - return marker_ == SPIKE_DATA_ID_COMPLETE; -} - -inline bool -SpikeData::is_end_marker() const -{ - return marker_ == SPIKE_DATA_ID_END; -} - -inline bool -SpikeData::is_invalid_marker() const -{ - return marker_ == SPIKE_DATA_ID_INVALID; -} - -inline double -SpikeData::get_offset() const -{ - return 0; -} class OffGridSpikeData : public SpikeData { @@ -379,80 +233,6 @@ class OffGridSpikeData : public SpikeData //! check legal size using success_offgrid_spike_data_size = StaticAssert< sizeof( OffGridSpikeData ) == 16 >::success; -inline OffGridSpikeData::OffGridSpikeData() - : SpikeData() - , offset_( 0.0 ) -{ -} - -inline OffGridSpikeData::OffGridSpikeData( const Target& target, const size_t lag, const double offset ) - : SpikeData( target, lag ) - , offset_( offset ) -{ -} - -inline OffGridSpikeData::OffGridSpikeData( const size_t tid, - const synindex syn_id, - const size_t lcid, - const unsigned int lag, - const double offset ) - : SpikeData( tid, syn_id, lcid, lag ) - , offset_( offset ) -{ -} - -inline OffGridSpikeData::OffGridSpikeData( const OffGridSpikeData& rhs ) - : SpikeData( rhs ) - , offset_( rhs.offset_ ) -{ -} - -inline OffGridSpikeData& -OffGridSpikeData::operator=( const OffGridSpikeData& rhs ) -{ - lcid_ = rhs.lcid_; - marker_ = rhs.marker_; - lag_ = rhs.lag_; - tid_ = rhs.tid_; - syn_id_ = rhs.syn_id_; - offset_ = rhs.offset_; - return *this; -} - -inline OffGridSpikeData& -OffGridSpikeData::operator=( const SpikeData& rhs ) -{ - // Need to use get_*() here, direct access to protected members of base-class instance is prohibited, - // see example in https://en.cppreference.com/w/cpp/language/access. - lcid_ = rhs.get_lcid(); - marker_ = rhs.get_marker(); - lag_ = rhs.get_lag(); - tid_ = rhs.get_tid(); - syn_id_ = rhs.get_syn_id(); - offset_ = 0; - return *this; -} - -inline void -OffGridSpikeData::set( const size_t tid, - const synindex syn_id, - const size_t lcid, - const unsigned int lag, - const double offset ) -{ - assert( tid <= MAX_TID ); // MAX_TID is allowed since it is not used as invalid value - assert( syn_id < MAX_SYN_ID ); - assert( lcid < MAX_LCID ); - assert( lag < MAX_LAG ); - - lcid_ = lcid; - marker_ = SPIKE_DATA_ID_DEFAULT; - lag_ = lag; - tid_ = tid; - syn_id_ = syn_id; - offset_ = offset; -} - template < class TargetT > inline void @@ -482,12 +262,6 @@ struct SpikeDataWithRank const SpikeData spike_data; //! data on spike transmitted }; -inline SpikeDataWithRank::SpikeDataWithRank( const Target& target, const size_t lag ) - : rank( target.get_rank() ) - , spike_data( target, lag ) -{ -} - /** * Combine target rank and spike data information for storage in emitted_off_grid_spikes_register. * @@ -501,12 +275,6 @@ struct OffGridSpikeDataWithRank const OffGridSpikeData spike_data; //! data on spike transmitted }; -inline OffGridSpikeDataWithRank::OffGridSpikeDataWithRank( const Target& target, const size_t lag, const double offset ) - : rank( target.get_rank() ) - , spike_data( target, lag, offset ) -{ -} - } // namespace nest diff --git a/nestkernel/stimulation_backend_mpi.cpp b/nestkernel/stimulation_backend_mpi.cpp index 8f908d24ce..1d1ff10242 100644 --- a/nestkernel/stimulation_backend_mpi.cpp +++ b/nestkernel/stimulation_backend_mpi.cpp @@ -26,7 +26,11 @@ #include // Includes from nestkernel: +#include "connection_manager.h" +#include "io_manager.h" #include "kernel_manager.h" +#include "logging.h" +#include "logging_manager.h" #include "stimulation_backend.h" #include "stimulation_backend_mpi.h" #include "stimulation_device.h" @@ -45,7 +49,7 @@ nest::StimulationBackendMPI::~StimulationBackendMPI() noexcept void nest::StimulationBackendMPI::initialize() { - auto nthreads = kernel().vp_manager.get_num_threads(); + auto nthreads = kernel::manager< VPManager >.get_num_threads(); device_map devices( nthreads ); devices_.swap( devices ); } @@ -113,7 +117,7 @@ nest::StimulationBackendMPI::prepare() } // need to be run only by the master thread : it is the case because this part is not running in parallel - size_t thread_id_master = kernel().vp_manager.get_thread_id(); + size_t thread_id_master = kernel::manager< VPManager >.get_thread_id(); // Create the connection with MPI // 1) take all the ports of the connections. Get port and update the list of device only for master for ( auto& it_device : devices_[ thread_id_master ] ) @@ -128,7 +132,7 @@ nest::StimulationBackendMPI::prepare() // it's not a new communicator comm = std::get< 0 >( comm_it->second ); // add the id of the device if there are a connection with the device. - if ( kernel().connection_manager.get_device_connected( + if ( kernel::manager< ConnectionManager >.get_device_connected( thread_id_master, it_device.second.second->get_local_device_id() ) ) { std::get< 1 >( comm_it->second )->push_back( it_device.second.second->get_node_id() ); @@ -142,10 +146,12 @@ nest::StimulationBackendMPI::prepare() // This is because the management of threads here is using MPI_THREAD_FUNNELED (see mpi_manager.cpp:119). comm = new MPI_Comm; auto vector_id_device = new std::vector< int >; // vector of ID device for the rank - int* vector_nb_device_th { new int[ kernel().vp_manager.get_num_threads() ] {} }; // number of device by thread - std::fill_n( vector_nb_device_th, kernel().vp_manager.get_num_threads(), 0 ); + int* vector_nb_device_th { + new int[ kernel::manager< VPManager >.get_num_threads() ] {} + }; // number of device by thread + std::fill_n( vector_nb_device_th, kernel::manager< VPManager >.get_num_threads(), 0 ); // add the id of the device if there is a connection with the device. - if ( kernel().connection_manager.get_device_connected( + if ( kernel::manager< ConnectionManager >.get_device_connected( thread_id_master, it_device.second.second->get_local_device_id() ) ) { vector_id_device->push_back( it_device.second.second->get_node_id() ); @@ -159,7 +165,7 @@ nest::StimulationBackendMPI::prepare() } // Add the id of device of the other thread in the vector_id_device and update the count of all device - for ( size_t id_thread = 0; id_thread < kernel().vp_manager.get_num_threads(); id_thread++ ) + for ( size_t id_thread = 0; id_thread < kernel::manager< VPManager >.get_num_threads(); id_thread++ ) { // don't do it again for the master thread if ( id_thread != thread_id_master ) @@ -167,7 +173,7 @@ nest::StimulationBackendMPI::prepare() for ( auto& it_device : devices_[ id_thread ] ) { // add the id of the device if there is a connection with the device. - if ( kernel().connection_manager.get_device_connected( + if ( kernel::manager< ConnectionManager >.get_device_connected( id_thread, it_device.second.second->get_local_device_id() ) ) { std::string port_name; @@ -276,7 +282,7 @@ nest::StimulationBackendMPI::cleanup() } // clear map of devices commMap_.clear(); - size_t thread_id_master = kernel().vp_manager.get_thread_id(); + size_t thread_id_master = kernel::manager< VPManager >.get_thread_id(); for ( auto& it_device : devices_[ thread_id_master ] ) { it_device.second.first = nullptr; @@ -312,12 +318,12 @@ nest::StimulationBackendMPI::get_port( const size_t index_node, const std::strin // (file contains only one line with name of the port) std::ostringstream basename; // get the path from the kernel - const std::string& path = kernel().io_manager.get_data_path(); + const std::string& path = kernel::manager< IOManager >.get_data_path(); if ( not path.empty() ) { basename << path << '/'; } - basename << kernel().io_manager.get_data_prefix(); + basename << kernel::manager< IOManager >.get_data_prefix(); // add the path from the label of the device if ( not label.empty() ) @@ -380,7 +386,7 @@ nest::StimulationBackendMPI::update_device( int* array_index, if ( data.first[ 0 ] != 0 ) { // if there are some data - size_t thread_id = kernel().vp_manager.get_thread_id(); + size_t thread_id = kernel::manager< VPManager >.get_thread_id(); int index_id_device = 0; // the index for the array of device in the data // get the first id of the device for the current thread // if the thread_id == 0, the index_id_device equals 0 diff --git a/nestkernel/stimulation_device.cpp b/nestkernel/stimulation_device.cpp index ab3c800c9b..fbe4ef5bad 100644 --- a/nestkernel/stimulation_device.cpp +++ b/nestkernel/stimulation_device.cpp @@ -23,8 +23,11 @@ // Includes from nestkernel: #include "stimulation_device.h" +#include "io_manager.h" #include "kernel_manager.h" +#include + nest::StimulationDevice::StimulationDevice() : DeviceNode() @@ -78,7 +81,7 @@ nest::StimulationDevice::pre_run_hook() void nest::StimulationDevice::set_initialized_() { - kernel().io_manager.enroll_stimulator( P_.stimulus_source_, *this, backend_params_ ); + kernel::manager< IOManager >.enroll_stimulator( P_.stimulus_source_, *this, backend_params_ ); } const std::string& @@ -110,7 +113,7 @@ nest::StimulationDevice::Parameters_::set( const DictionaryDatum& d ) if ( updateValue< std::string >( d, names::stimulus_source, stimulus_source ) ) { - if ( not kernel().io_manager.is_valid_stimulation_backend( stimulus_source ) ) + if ( not kernel::manager< IOManager >.is_valid_stimulation_backend( stimulus_source ) ) { std::string msg = String::compose( "Unknown input backend '%1'", stimulus_source ); throw BadProperty( msg ); @@ -154,7 +157,7 @@ nest::StimulationDevice::set_status( const DictionaryDatum& d ) } else { - kernel().io_manager.enroll_stimulator( ptmp.stimulus_source_, *this, d ); + kernel::manager< IOManager >.enroll_stimulator( ptmp.stimulus_source_, *this, d ); } // if we get here, temporaries contain consistent set of properties @@ -180,3 +183,15 @@ nest::StimulationDevice::get_status( DictionaryDatum& d ) const } } } + +Name +nest::StimulationDevice::get_element_type() const +{ + return names::stimulator; +} + +bool +nest::StimulationDevice::has_proxies() const +{ + return false; +} diff --git a/nestkernel/stimulation_device.h b/nestkernel/stimulation_device.h index f8b29531b6..05c7521c9f 100644 --- a/nestkernel/stimulation_device.h +++ b/nestkernel/stimulation_device.h @@ -223,18 +223,6 @@ class StimulationDevice : public DeviceNode, public Device DictionaryDatum backend_params_; }; -inline Name -StimulationDevice::get_element_type() const -{ - return names::stimulator; -} - -inline bool -StimulationDevice::has_proxies() const -{ - return false; -} - } // namespace nest #endif /* #ifndef STIMULATION_DEVICE_H */ diff --git a/nestkernel/stopwatch_impl.h b/nestkernel/stopwatch_impl.h index 2fac293267..7b1d63c258 100644 --- a/nestkernel/stopwatch_impl.h +++ b/nestkernel/stopwatch_impl.h @@ -25,12 +25,12 @@ #include "kernel_manager.h" #include "stopwatch.h" +#include "vp_manager.h" namespace nest { -// In each of the following methods compile-time-evaluated ifs decide which code -// is actually included. +// In each of the following methods compile-time-evaluated ifs decide which code is actually included. template < StopwatchGranularity detailed_timer, StopwatchParallelism threaded_timer > void @@ -40,9 +40,9 @@ Stopwatch< detailed_timer, threaded_timer >::start() { if constexpr ( use_timer_array ) { - kernel().vp_manager.assert_thread_parallel(); - walltime_timer_[ kernel().vp_manager.get_thread_id() ].start(); - cputime_timer_[ kernel().vp_manager.get_thread_id() ].start(); + kernel::manager< VPManager >.assert_thread_parallel(); + walltime_timer_[ kernel::manager< VPManager >.get_thread_id() ].start(); + cputime_timer_[ kernel::manager< VPManager >.get_thread_id() ].start(); } else { @@ -67,9 +67,9 @@ Stopwatch< detailed_timer, threaded_timer >::stop() { if constexpr ( use_timer_array ) { - kernel().vp_manager.assert_thread_parallel(); - walltime_timer_[ kernel().vp_manager.get_thread_id() ].stop(); - cputime_timer_[ kernel().vp_manager.get_thread_id() ].stop(); + kernel::manager< VPManager >.assert_thread_parallel(); + walltime_timer_[ kernel::manager< VPManager >.get_thread_id() ].stop(); + cputime_timer_[ kernel::manager< VPManager >.get_thread_id() ].stop(); } else { @@ -90,8 +90,8 @@ Stopwatch< detailed_timer, threaded_timer >::is_running_() const { if constexpr ( use_timer_array ) { - kernel().vp_manager.assert_thread_parallel(); - return walltime_timer_[ kernel().vp_manager.get_thread_id() ].is_running_(); + kernel::manager< VPManager >.assert_thread_parallel(); + return walltime_timer_[ kernel::manager< VPManager >.get_thread_id() ].is_running_(); } else { @@ -117,8 +117,8 @@ Stopwatch< detailed_timer, threaded_timer >::elapsed( timers::timeunit_t timeuni { if constexpr ( use_timer_array ) { - kernel().vp_manager.assert_thread_parallel(); - return walltime_timer_[ kernel().vp_manager.get_thread_id() ].elapsed( timeunit ); + kernel::manager< VPManager >.assert_thread_parallel(); + return walltime_timer_[ kernel::manager< VPManager >.get_thread_id() ].elapsed( timeunit ); } else { @@ -146,8 +146,8 @@ Stopwatch< detailed_timer, threaded_timer >::print( const std::string& msg, { if constexpr ( use_timer_array ) { - kernel().vp_manager.assert_thread_parallel(); - walltime_timer_[ kernel().vp_manager.get_thread_id() ].print( msg, timeunit, os ); + kernel::manager< VPManager >.assert_thread_parallel(); + walltime_timer_[ kernel::manager< VPManager >.get_thread_id() ].print( msg, timeunit, os ); } else { @@ -167,7 +167,7 @@ Stopwatch< detailed_timer, threaded_timer >::get_status( DictionaryDatum& d, { if constexpr ( enable_timer ) { - kernel().vp_manager.assert_single_threaded(); + kernel::manager< VPManager >.assert_single_threaded(); if constexpr ( use_timer_array ) { std::vector< double > wall_times( walltime_timer_.size() ); @@ -198,10 +198,10 @@ Stopwatch< detailed_timer, threaded_timer >::reset() { if constexpr ( enable_timer ) { - kernel().vp_manager.assert_single_threaded(); + kernel::manager< VPManager >.assert_single_threaded(); if constexpr ( use_timer_array ) { - const size_t num_threads = kernel().vp_manager.get_num_threads(); + const size_t num_threads = kernel::manager< VPManager >.get_num_threads(); walltime_timer_.resize( num_threads ); cputime_timer_.resize( num_threads ); for ( size_t i = 0; i < num_threads; ++i ) diff --git a/nestkernel/structural_plasticity_node.cpp b/nestkernel/structural_plasticity_node.cpp index 07a3af88e4..85ebf78de0 100644 --- a/nestkernel/structural_plasticity_node.cpp +++ b/nestkernel/structural_plasticity_node.cpp @@ -28,6 +28,8 @@ // Includes from sli: #include "dictutils.h" +#include + namespace nest { @@ -269,4 +271,16 @@ nest::StructuralPlasticityNode::set_spiketime( Time const& t_sp, double offset ) Ca_minus_ += beta_Ca_; } +double +StructuralPlasticityNode::get_tau_Ca() const +{ + return tau_Ca_; +} + +double +StructuralPlasticityNode::get_Ca_minus() const +{ + return Ca_minus_; +} + } // of namespace nest diff --git a/nestkernel/structural_plasticity_node.h b/nestkernel/structural_plasticity_node.h index ffaf0c9f67..055a1a85c5 100644 --- a/nestkernel/structural_plasticity_node.h +++ b/nestkernel/structural_plasticity_node.h @@ -151,18 +151,6 @@ class StructuralPlasticityNode : public Node std::map< Name, SynapticElement > synaptic_elements_map_; }; -inline double -StructuralPlasticityNode::get_tau_Ca() const -{ - return tau_Ca_; -} - -inline double -StructuralPlasticityNode::get_Ca_minus() const -{ - return Ca_minus_; -} - } // of namespace #endif /* #ifndef STRUCTURAL_PLASTICITY_NODE_H */ diff --git a/nestkernel/syn_id_delay.cpp b/nestkernel/syn_id_delay.cpp new file mode 100644 index 0000000000..f11a53f6e4 --- /dev/null +++ b/nestkernel/syn_id_delay.cpp @@ -0,0 +1,76 @@ +/* + * syn_id_delay.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "syn_id_delay.h" + +namespace nest +{ + +SynIdDelay::SynIdDelay( double d ) + : delay( 0 ) + , syn_id( invalid_synindex ) + , more_targets( false ) + , disabled( false ) +{ + set_delay_ms( d ); +} + +SynIdDelay::SynIdDelay( const SynIdDelay& s ) = default; +SynIdDelay& SynIdDelay::operator=( const SynIdDelay& s ) = default; + +double +SynIdDelay::get_delay_ms() const +{ + return Time::delay_steps_to_ms( delay ); +} + +void +SynIdDelay::set_delay_ms( const double d ) +{ + delay = Time::delay_ms_to_steps( d ); +} + +void +SynIdDelay::set_source_has_more_targets( const bool more ) +{ + more_targets = more; +} + +bool +SynIdDelay::source_has_more_targets() const +{ + return more_targets; +} + +void +SynIdDelay::disable() +{ + disabled = true; +} + +bool +SynIdDelay::is_disabled() const +{ + return disabled; +} + +} // namespace nest diff --git a/nestkernel/syn_id_delay.h b/nestkernel/syn_id_delay.h index c3693137ce..0a05e2230b 100644 --- a/nestkernel/syn_id_delay.h +++ b/nestkernel/syn_id_delay.h @@ -26,6 +26,7 @@ // Includes from nestkernel: #include "nest_time.h" #include "nest_types.h" +#include "static_assert.h" namespace nest { @@ -37,68 +38,36 @@ struct SynIdDelay bool more_targets : 1; bool disabled : 1; - explicit SynIdDelay( double d ) - : syn_id( invalid_synindex ) - , more_targets( false ) - , disabled( false ) - { - set_delay_ms( d ); - } - - SynIdDelay( const SynIdDelay& s ) = default; - SynIdDelay& operator=( const SynIdDelay& s ) = default; + explicit SynIdDelay( double d ); + SynIdDelay( const SynIdDelay& s ); + SynIdDelay& operator=( const SynIdDelay& s ); /** * Return the delay of the connection in ms */ - double - get_delay_ms() const - { - return Time::delay_steps_to_ms( delay ); - } + double get_delay_ms() const; /** * Set the delay of the connection specified in ms */ - void - set_delay_ms( const double d ) - { - delay = Time::delay_ms_to_steps( d ); - } + void set_delay_ms( const double d ); - void - set_source_has_more_targets( const bool more_targets ) - { - this->more_targets = more_targets; - } + void set_source_has_more_targets( const bool more_targets ); - bool - source_has_more_targets() const - { - return more_targets; - } + bool source_has_more_targets() const; /** * Disables the synapse. * * @see is_disabled */ - void - disable() - { - disabled = true; - } - + void disable(); /** * Returns a flag denoting if the synapse is disabled. * * @see disable */ - bool - is_disabled() const - { - return disabled; - } + bool is_disabled() const; }; //! check legal size diff --git a/nestkernel/synaptic_element.cpp b/nestkernel/synaptic_element.cpp index cd51c16861..b67119c51f 100644 --- a/nestkernel/synaptic_element.cpp +++ b/nestkernel/synaptic_element.cpp @@ -25,6 +25,8 @@ // Includes from nestkernel: #include "exceptions.h" #include "kernel_manager.h" +#include "nest_names.h" +#include "sp_manager.h" // Includes from sli: #include "dictutils.h" @@ -53,7 +55,7 @@ nest::SynapticElement::SynapticElement( const SynapticElement& se ) , growth_rate_( se.growth_rate_ ) , tau_vacant_( se.tau_vacant_ ) { - growth_curve_ = kernel().sp_manager.new_growth_curve( se.growth_curve_->get_name() ); + growth_curve_ = kernel::manager< SPManager >.new_growth_curve( se.growth_curve_->get_name() ); assert( growth_curve_ ); DictionaryDatum nc_parameters = DictionaryDatum( new Dictionary ); se.get( nc_parameters ); @@ -66,7 +68,7 @@ nest::SynapticElement::operator=( const SynapticElement& other ) if ( this != &other ) { // 1: allocate new memory and copy the elements - GrowthCurve* new_nc = kernel().sp_manager.new_growth_curve( other.growth_curve_->get_name() ); + GrowthCurve* new_nc = kernel::manager< SPManager >.new_growth_curve( other.growth_curve_->get_name() ); DictionaryDatum nc_parameters = DictionaryDatum( new Dictionary ); other.get( nc_parameters ); @@ -121,7 +123,7 @@ nest::SynapticElement::set( const DictionaryDatum& d ) Name growth_curve_name( getValue< std::string >( d, names::growth_curve ) ); if ( not growth_curve_->is( growth_curve_name ) ) { - growth_curve_ = kernel().sp_manager.new_growth_curve( growth_curve_name ); + growth_curve_ = kernel::manager< SPManager >.new_growth_curve( growth_curve_name ); } } growth_curve_->set( d ); @@ -149,3 +151,73 @@ nest::SynapticElement::update( double t, double t_minus, double Ca_minus, double z_ = growth_curve_->update( t, t_minus, Ca_minus, z_, tau_Ca, growth_rate_ ); z_t_ = t; } + +int +nest::SynapticElement::get_z_vacant() const +{ + return std::floor( z_ ) - z_connected_; +} + +int +nest::SynapticElement::get_z_connected() const +{ + return z_connected_; +} + +double +nest::SynapticElement::get_tau_vacant() const +{ + return tau_vacant_; +} + +void +nest::SynapticElement::connect( int n ) +{ + z_connected_ += n; + if ( z_connected_ > floor( z_ ) ) + { + z_ = z_connected_ + ( z_ - floor( z_ ) ); + } +} + +void +nest::SynapticElement::set_growth_curve( GrowthCurve& g ) +{ + if ( growth_curve_ != &g ) + { + delete growth_curve_; + growth_curve_ = &g; + } +} + +double +nest::SynapticElement::get_growth_rate() const +{ + return growth_rate_; +} + +void +nest::SynapticElement::set_z( const double z_new ) +{ + z_ = z_new; +} +double +nest::SynapticElement::get_z() const +{ + return z_; +} + +void +nest::SynapticElement::decay_z_vacant() +{ + if ( get_z_vacant() > 0 ) + { + z_ -= get_z_vacant() * tau_vacant_; + } +} + +bool +nest::SynapticElement::continuous() const +{ + return continuous_; +} diff --git a/nestkernel/synaptic_element.h b/nestkernel/synaptic_element.h index 8c2dfac349..0c7bf79f1d 100644 --- a/nestkernel/synaptic_element.h +++ b/nestkernel/synaptic_element.h @@ -151,92 +151,43 @@ class SynapticElement * @param a node of this synaptic_element * @param t Current time (in ms) */ - int - get_z_vacant() const - { - return std::floor( z_ ) - z_connected_; - } + int get_z_vacant() const; /** * Retrieves the current number of synaptic elements bound to a synapse */ - int - get_z_connected() const - { - return z_connected_; - } + int get_z_connected() const; /** * Retrieves the value of tau_vacant */ - double - get_tau_vacant() const - { - return tau_vacant_; - } + double get_tau_vacant() const; /** * Changes the number of bound synaptic elements by n. * * @param n number of new connections. Can be negative. */ - void - connect( int n ) - { - z_connected_ += n; - if ( z_connected_ > floor( z_ ) ) - { - z_ = z_connected_ + ( z_ - floor( z_ ) ); - } - } + void connect( int n ); /** * Used to define the dynamics of the synaptic elements using a Growth Curve */ - void - set_growth_curve( GrowthCurve& g ) - { - if ( growth_curve_ != &g ) - { - delete growth_curve_; - growth_curve_ = &g; - } - } + void set_growth_curve( GrowthCurve& g ); /** * Retrieves the current value of the growth rate */ - double - get_growth_rate() const - { - return growth_rate_; - } + double get_growth_rate() const; - void - set_z( const double z_new ) - { - z_ = z_new; - } - double - get_z() const - { - return z_; - } + void set_z( const double z_new ); + + double get_z() const; /** * Reduce the amount of vacant synaptic elements by a factor * of tau_vacant_ */ - void - decay_z_vacant() - { - if ( get_z_vacant() > 0 ) - { - z_ -= get_z_vacant() * tau_vacant_; - } - } + void decay_z_vacant(); - bool - continuous() const - { - return continuous_; - } + + bool continuous() const; private: // The current number of synaptic elements at t = z_t_ diff --git a/nestkernel/target.cpp b/nestkernel/target.cpp new file mode 100644 index 0000000000..eb8624d141 --- /dev/null +++ b/nestkernel/target.cpp @@ -0,0 +1,180 @@ +/* + * target.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "target.h" + +#include + +namespace nest +{ + +// ------------ Target ------------ + +Target::Target() + : remote_target_id_( 0 ) +{ +} + +Target::Target( const Target& target ) + : remote_target_id_( target.remote_target_id_ ) +{ + set_status( TARGET_ID_UNPROCESSED ); // initialize +} + +Target& +Target::operator=( const Target& other ) +{ + remote_target_id_ = other.remote_target_id_; + set_status( TARGET_ID_UNPROCESSED ); + return *this; +} + +Target::Target( const size_t tid, const size_t rank, const synindex syn_id, const size_t lcid ) + : remote_target_id_( 0 ) +{ + // We need to call set_*() methods to properly encode values in bitfield. + // Validity of arguments is asserted in set_*() methods. + set_lcid( lcid ); + set_rank( rank ); + set_tid( tid ); + set_syn_id( syn_id ); + set_status( TARGET_ID_UNPROCESSED ); // initialize +} + +void +Target::set_lcid( const size_t lcid ) +{ + assert( lcid < MAX_LCID ); + remote_target_id_ = ( remote_target_id_ & ( ~MASK_LCID ) ) | ( static_cast< uint64_t >( lcid ) << BITPOS_LCID ); +} + +size_t +Target::get_lcid() const +{ + return ( ( remote_target_id_ & MASK_LCID ) >> BITPOS_LCID ); +} + +void +Target::set_rank( const size_t rank ) +{ + assert( rank <= MAX_RANK ); // MAX_RANK is allowed since it is not used as invalid value + remote_target_id_ = ( remote_target_id_ & ( ~MASK_RANK ) ) | ( static_cast< uint64_t >( rank ) << BITPOS_RANK ); +} + +size_t +Target::get_rank() const +{ + return ( ( remote_target_id_ & MASK_RANK ) >> BITPOS_RANK ); +} + +void +Target::set_tid( const size_t tid ) +{ + assert( tid <= MAX_TID ); // MAX_TID is allowed since it is not used as invalid value + remote_target_id_ = ( remote_target_id_ & ( ~MASK_TID ) ) | ( static_cast< uint64_t >( tid ) << BITPOS_TID ); +} + +size_t +Target::get_tid() const +{ + return ( ( remote_target_id_ & MASK_TID ) >> BITPOS_TID ); +} + +void +Target::set_syn_id( const synindex syn_id ) +{ + assert( syn_id < MAX_SYN_ID ); + remote_target_id_ = ( remote_target_id_ & ( ~MASK_SYN_ID ) ) | ( static_cast< uint64_t >( syn_id ) << BITPOS_SYN_ID ); +} + +synindex +Target::get_syn_id() const +{ + return ( ( remote_target_id_ & MASK_SYN_ID ) >> BITPOS_SYN_ID ); +} + +void +Target::set_status( enum_status_target_id set_status_to ) +{ + switch ( set_status_to ) + { + case TARGET_ID_PROCESSED: + remote_target_id_ = remote_target_id_ | MASK_PROCESSED_FLAG; // set single bit + break; + case TARGET_ID_UNPROCESSED: + remote_target_id_ = remote_target_id_ & ~MASK_PROCESSED_FLAG; // clear single bit + break; + default: + throw InternalError( "Invalid remote target id status." ); + } +} + +enum_status_target_id +Target::get_status() const +{ + if ( ( remote_target_id_ & MASK_PROCESSED_FLAG ) >> BITPOS_PROCESSED_FLAG ) // test single bit + { + return TARGET_ID_PROCESSED; + } + return TARGET_ID_UNPROCESSED; +} + +bool +Target::is_processed() const +{ + return get_status() == TARGET_ID_PROCESSED; +} + +double +Target::get_offset() const +{ + return 0.0; +} + +void +Target::mark_for_removal() +{ + set_status( TARGET_ID_PROCESSED ); +} + + +// --------- OffGridTarget --------- + +OffGridTarget::OffGridTarget() + : Target() + , offset_( 0.0 ) +{ +} + +OffGridTarget::OffGridTarget( const Target& target, const double offset ) + : Target( target ) + , offset_( offset ) +{ +} + +double +OffGridTarget::get_offset() const +{ + return offset_; +} + +} // namespace nest diff --git a/nestkernel/target.h b/nestkernel/target.h index 3d6fee45c1..5d4c22f514 100644 --- a/nestkernel/target.h +++ b/nestkernel/target.h @@ -171,134 +171,6 @@ class Target //!< check legal size using success_target_size = StaticAssert< sizeof( Target ) == 8 >::success; -inline Target::Target() - : remote_target_id_( 0 ) -{ -} - -inline Target::Target( const Target& target ) - : remote_target_id_( target.remote_target_id_ ) -{ - set_status( TARGET_ID_UNPROCESSED ); // initialize -} - -inline Target& -Target::operator=( const Target& other ) -{ - remote_target_id_ = other.remote_target_id_; - set_status( TARGET_ID_UNPROCESSED ); - return *this; -} - -inline Target::Target( const size_t tid, const size_t rank, const synindex syn_id, const size_t lcid ) - : remote_target_id_( 0 ) -{ - // We need to call set_*() methods to properly encode values in bitfield. - // Validity of arguments is asserted in set_*() methods. - set_lcid( lcid ); - set_rank( rank ); - set_tid( tid ); - set_syn_id( syn_id ); - set_status( TARGET_ID_UNPROCESSED ); // initialize -} - -inline void -Target::set_lcid( const size_t lcid ) -{ - assert( lcid < MAX_LCID ); - remote_target_id_ = ( remote_target_id_ & ( ~MASK_LCID ) ) | ( static_cast< uint64_t >( lcid ) << BITPOS_LCID ); -} - -inline size_t -Target::get_lcid() const -{ - return ( ( remote_target_id_ & MASK_LCID ) >> BITPOS_LCID ); -} - -inline void -Target::set_rank( const size_t rank ) -{ - assert( rank <= MAX_RANK ); // MAX_RANK is allowed since it is not used as invalid value - remote_target_id_ = ( remote_target_id_ & ( ~MASK_RANK ) ) | ( static_cast< uint64_t >( rank ) << BITPOS_RANK ); -} - -inline size_t -Target::get_rank() const -{ - return ( ( remote_target_id_ & MASK_RANK ) >> BITPOS_RANK ); -} - -inline void -Target::set_tid( const size_t tid ) -{ - assert( tid <= MAX_TID ); // MAX_TID is allowed since it is not used as invalid value - remote_target_id_ = ( remote_target_id_ & ( ~MASK_TID ) ) | ( static_cast< uint64_t >( tid ) << BITPOS_TID ); -} - -inline size_t -Target::get_tid() const -{ - return ( ( remote_target_id_ & MASK_TID ) >> BITPOS_TID ); -} - -inline void -Target::set_syn_id( const synindex syn_id ) -{ - assert( syn_id < MAX_SYN_ID ); - remote_target_id_ = ( remote_target_id_ & ( ~MASK_SYN_ID ) ) | ( static_cast< uint64_t >( syn_id ) << BITPOS_SYN_ID ); -} - -inline synindex -Target::get_syn_id() const -{ - return ( ( remote_target_id_ & MASK_SYN_ID ) >> BITPOS_SYN_ID ); -} - -inline void -Target::set_status( enum_status_target_id set_status_to ) -{ - switch ( set_status_to ) - { - case TARGET_ID_PROCESSED: - remote_target_id_ = remote_target_id_ | MASK_PROCESSED_FLAG; // set single bit - break; - case TARGET_ID_UNPROCESSED: - remote_target_id_ = remote_target_id_ & ~MASK_PROCESSED_FLAG; // clear single bit - break; - default: - throw InternalError( "Invalid remote target id status." ); - } -} - -inline enum_status_target_id -Target::get_status() const -{ - if ( ( remote_target_id_ & MASK_PROCESSED_FLAG ) >> BITPOS_PROCESSED_FLAG ) // test single bit - { - return ( TARGET_ID_PROCESSED ); - } - return ( TARGET_ID_UNPROCESSED ); -} - -inline bool -Target::is_processed() const -{ - return ( get_status() == TARGET_ID_PROCESSED ); -} - -inline double -Target::get_offset() const -{ - return 0; -} - -inline void -Target::mark_for_removal() -{ - set_status( TARGET_ID_PROCESSED ); -} - - class OffGridTarget : public Target { private: @@ -310,24 +182,6 @@ class OffGridTarget : public Target double get_offset() const; }; -inline OffGridTarget::OffGridTarget() - : Target() - , offset_( 0 ) -{ -} - -inline OffGridTarget::OffGridTarget( const Target& target, const double offset ) - : Target( target ) - , offset_( offset ) -{ -} - -inline double -OffGridTarget::get_offset() const -{ - return offset_; -} - } // namespace nest #endif /* #ifndef TARGET_H */ diff --git a/nestkernel/target_data.cpp b/nestkernel/target_data.cpp new file mode 100644 index 0000000000..f4a534ea05 --- /dev/null +++ b/nestkernel/target_data.cpp @@ -0,0 +1,179 @@ +/* + * target_data.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "target_data.h" + +#include +#include + +namespace nest +{ + +// --- TargetDataFields --- + +void +TargetDataFields::set_lcid( const size_t lcid ) +{ + lcid_ = lcid; +} + +size_t +TargetDataFields::get_lcid() const +{ + return lcid_; +} + +void +TargetDataFields::set_tid( const size_t tid ) +{ + tid_ = tid; +} + +size_t +TargetDataFields::get_tid() const +{ + return tid_; +} + +void +TargetDataFields::set_syn_id( const synindex syn_id ) +{ + syn_id_ = syn_id; +} + +synindex +TargetDataFields::get_syn_id() const +{ + return syn_id_; +} + +// --- SecondaryTargetDataFields --- + +void +SecondaryTargetDataFields::set_recv_buffer_pos( const size_t pos ) +{ + assert( pos < std::numeric_limits< unsigned int >::max() ); + recv_buffer_pos_ = pos; +} + +size_t +SecondaryTargetDataFields::get_recv_buffer_pos() const +{ + return recv_buffer_pos_; +} + +void +SecondaryTargetDataFields::set_syn_id( const synindex syn_id ) +{ + assert( syn_id < std::numeric_limits< unsigned char >::max() ); + syn_id_ = syn_id; +} + +synindex +SecondaryTargetDataFields::get_syn_id() const +{ + return syn_id_; +} + +// --- TargetData --- + +void +TargetData::reset_marker() +{ + marker_ = TARGET_DATA_ID_DEFAULT; +} + +void +TargetData::set_complete_marker() +{ + marker_ = TARGET_DATA_ID_COMPLETE; +} + +void +TargetData::set_end_marker() +{ + marker_ = TARGET_DATA_ID_END; +} + +void +TargetData::set_invalid_marker() +{ + marker_ = TARGET_DATA_ID_INVALID; +} + +bool +TargetData::is_complete_marker() const +{ + return marker_ == TARGET_DATA_ID_COMPLETE; +} + +bool +TargetData::is_end_marker() const +{ + return marker_ == TARGET_DATA_ID_END; +} + +bool +TargetData::is_invalid_marker() const +{ + return marker_ == TARGET_DATA_ID_INVALID; +} + +void +TargetData::set_source_lid( const size_t source_lid ) +{ + assert( source_lid < MAX_LID ); + source_lid_ = source_lid; +} + +void +TargetData::set_source_tid( const size_t source_tid ) +{ + assert( source_tid < MAX_TID ); + source_tid_ = source_tid; +} + +size_t +TargetData::get_source_lid() const +{ + return source_lid_; +} + +size_t +TargetData::get_source_tid() const +{ + return source_tid_; +} + +void +TargetData::set_is_primary( const bool is_primary ) +{ + is_primary_ = is_primary; +} + +bool +TargetData::is_primary() const +{ + return is_primary_; +} + +} // namespace nest diff --git a/nestkernel/target_data.h b/nestkernel/target_data.h index 1fbf09b084..d0924f9418 100644 --- a/nestkernel/target_data.h +++ b/nestkernel/target_data.h @@ -77,42 +77,6 @@ class TargetDataFields //! check legal size using success_target_data_fields_size = StaticAssert< sizeof( TargetDataFields ) == 8 >::success; -inline void -TargetDataFields::set_lcid( const size_t lcid ) -{ - lcid_ = lcid; -} - -inline size_t -TargetDataFields::get_lcid() const -{ - return lcid_; -} - -inline void -TargetDataFields::set_tid( const size_t tid ) -{ - tid_ = tid; -} - -inline size_t -TargetDataFields::get_tid() const -{ - return tid_; -} - -inline void -TargetDataFields::set_syn_id( const synindex syn_id ) -{ - syn_id_ = syn_id; -} - -inline synindex -TargetDataFields::get_syn_id() const -{ - return syn_id_; -} - class SecondaryTargetDataFields { private: @@ -130,32 +94,6 @@ class SecondaryTargetDataFields //! check legal size using success_secondary_target_data_fields_size = StaticAssert< sizeof( SecondaryTargetDataFields ) == 8 >::success; -inline void -SecondaryTargetDataFields::set_recv_buffer_pos( const size_t pos ) -{ - assert( pos < std::numeric_limits< unsigned int >::max() ); - recv_buffer_pos_ = pos; -} - -inline size_t -SecondaryTargetDataFields::get_recv_buffer_pos() const -{ - return recv_buffer_pos_; -} - -inline void -SecondaryTargetDataFields::set_syn_id( const synindex syn_id ) -{ - assert( syn_id < std::numeric_limits< unsigned char >::max() ); - syn_id_ = syn_id; -} - -inline synindex -SecondaryTargetDataFields::get_syn_id() const -{ - return syn_id_; -} - enum enum_status_target_data_id { TARGET_DATA_ID_DEFAULT, @@ -216,85 +154,6 @@ class TargetData //! check legal size using success_target_data_size = StaticAssert< sizeof( TargetData ) == 12 >::success; -inline void -TargetData::reset_marker() -{ - marker_ = TARGET_DATA_ID_DEFAULT; -} - -inline void -TargetData::set_complete_marker() -{ - marker_ = TARGET_DATA_ID_COMPLETE; -} - -inline void -TargetData::set_end_marker() -{ - marker_ = TARGET_DATA_ID_END; -} - -inline void -TargetData::set_invalid_marker() -{ - marker_ = TARGET_DATA_ID_INVALID; -} - -inline bool -TargetData::is_complete_marker() const -{ - return marker_ == TARGET_DATA_ID_COMPLETE; -} - -inline bool -TargetData::is_end_marker() const -{ - return marker_ == TARGET_DATA_ID_END; -} - -inline bool -TargetData::is_invalid_marker() const -{ - return marker_ == TARGET_DATA_ID_INVALID; -} - -inline void -TargetData::set_source_lid( const size_t source_lid ) -{ - assert( source_lid < MAX_LID ); - source_lid_ = source_lid; -} - -inline void -TargetData::set_source_tid( const size_t source_tid ) -{ - assert( source_tid < MAX_TID ); - source_tid_ = source_tid; -} - -inline size_t -TargetData::get_source_lid() const -{ - return source_lid_; -} - -inline size_t -TargetData::get_source_tid() const -{ - return source_tid_; -} - -inline void -TargetData::set_is_primary( const bool is_primary ) -{ - is_primary_ = is_primary; -} - -inline bool -TargetData::is_primary() const -{ - return is_primary_; -} } // namespace nest #endif /* #ifndef TARGET_DATA_H */ diff --git a/nestkernel/target_identifier.cpp b/nestkernel/target_identifier.cpp new file mode 100644 index 0000000000..18eb254029 --- /dev/null +++ b/nestkernel/target_identifier.cpp @@ -0,0 +1,141 @@ +/* + * target_identifier.cpp + * + * This file is part of NEST. + * + * Copyright (C) 2004 The NEST Initiative + * + * NEST is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * NEST is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NEST. If not, see . + * + */ + +#include "target_identifier.h" + +#include "compose.hpp" +#include "kernel_manager.h" +#include "node.h" +#include "node_manager.h" + +#include + +namespace nest +{ + +// -------------------------- +// TargetIdentifierPtrRport +// -------------------------- + +TargetIdentifierPtrRport::TargetIdentifierPtrRport() + : target_( nullptr ) + , rport_( 0 ) +{ +} + +void +TargetIdentifierPtrRport::get_status( DictionaryDatum& d ) const +{ + // Do nothing if called on synapse prototype + if ( target_ ) + { + def< long >( d, names::rport, rport_ ); + def< long >( d, names::target, target_->get_node_id() ); + } +} + +Node* +TargetIdentifierPtrRport::get_target_ptr( const size_t ) const +{ + return target_; +} + +size_t +TargetIdentifierPtrRport::get_rport() const +{ + return rport_; +} + +void +TargetIdentifierPtrRport::set_target( Node* target ) +{ + target_ = target; +} + +void +TargetIdentifierPtrRport::set_rport( size_t rprt ) +{ + rport_ = rprt; +} + + +// ----------------------- +// TargetIdentifierIndex +// ----------------------- + +TargetIdentifierIndex::TargetIdentifierIndex() + : target_( invalid_targetindex ) +{ +} + +void +TargetIdentifierIndex::get_status( DictionaryDatum& d ) const +{ + // Do nothing if called on synapse prototype + if ( target_ != invalid_targetindex ) + { + def< long >( d, names::rport, 0 ); + def< long >( d, names::target, target_ ); + } +} + +Node* +TargetIdentifierIndex::get_target_ptr( const size_t tid ) const +{ + assert( target_ != invalid_targetindex ); + return kernel::manager< NodeManager >.thread_lid_to_node( tid, target_ ); +} + +size_t +TargetIdentifierIndex::get_rport() const +{ + return 0; +} + +void +TargetIdentifierIndex::set_target( Node* target ) +{ + assert( kernel::manager< NodeManager >.thread_local_data_is_up_to_date() ); + + const size_t target_lid = target->get_thread_lid(); + if ( target_lid > max_targetindex ) + { + throw IllegalConnection( + String::compose( "HPC synapses support at most %1 nodes per thread. " + "See Kunkel et al, Front Neuroinform 8:78 (2014), Sec 3.3.2.", + max_targetindex ) ); + } + target_ = target_lid; +} + +void +TargetIdentifierIndex::set_rport( size_t rprt ) +{ + if ( rprt != 0 ) + { + throw IllegalConnection( + "Only rport==0 allowed for HPC synapses. Use normal synapse models " + "instead. See Kunkel et al, Front Neuroinform 8:78 (2014), Sec 3.3.2." ); + } +} + +} // namespace nest diff --git a/nestkernel/target_identifier.h b/nestkernel/target_identifier.h index 5308d707f4..3148896b03 100644 --- a/nestkernel/target_identifier.h +++ b/nestkernel/target_identifier.h @@ -28,8 +28,7 @@ * @file Provide classes to be used as template arguments to Connection. */ -#include "compose.hpp" -#include "kernel_manager.h" +#include "node.h" namespace nest { @@ -48,51 +47,19 @@ class TargetIdentifierPtrRport { public: - TargetIdentifierPtrRport() - : target_( nullptr ) - , rport_( 0 ) - { - } - + TargetIdentifierPtrRport(); TargetIdentifierPtrRport( const TargetIdentifierPtrRport& t ) = default; TargetIdentifierPtrRport& operator=( const TargetIdentifierPtrRport& t ) = default; + void get_status( DictionaryDatum& d ) const; + Node* get_target_ptr( const size_t ) const; + + size_t get_rport() const; + + void set_target( Node* target ); - void - get_status( DictionaryDatum& d ) const - { - // Do nothing if called on synapse prototype - if ( target_ ) - { - def< long >( d, names::rport, rport_ ); - def< long >( d, names::target, target_->get_node_id() ); - } - } - - Node* - get_target_ptr( const size_t ) const - { - return target_; - } - - size_t - get_rport() const - { - return rport_; - } - - void - set_target( Node* target ) - { - target_ = target; - } - - void - set_rport( size_t rprt ) - { - rport_ = rprt; - } + void set_rport( size_t rprt ); private: Node* target_; //!< Target node @@ -113,72 +80,24 @@ class TargetIdentifierIndex { public: - TargetIdentifierIndex() - : target_( invalid_targetindex ) - { - } + TargetIdentifierIndex(); TargetIdentifierIndex( const TargetIdentifierIndex& t ) = default; TargetIdentifierIndex& operator=( const TargetIdentifierIndex& t ) = default; - void - get_status( DictionaryDatum& d ) const - { - // Do nothing if called on synapse prototype - if ( target_ != invalid_targetindex ) - { - def< long >( d, names::rport, 0 ); - def< long >( d, names::target, target_ ); - } - } - - Node* - get_target_ptr( const size_t tid ) const - { - assert( target_ != invalid_targetindex ); - return kernel().node_manager.thread_lid_to_node( tid, target_ ); - } - - size_t - get_rport() const - { - return 0; - } + void get_status( DictionaryDatum& d ) const; + + Node* get_target_ptr( const size_t tid ) const; + size_t get_rport() const; void set_target( Node* target ); - void - set_rport( size_t rprt ) - { - if ( rprt != 0 ) - { - throw IllegalConnection( - "Only rport==0 allowed for HPC synapses. Use normal synapse models " - "instead. See Kunkel et al, Front Neuroinform 8:78 (2014), Sec " - "3.3.2." ); - } - } + void set_rport( size_t rprt ); private: targetindex target_; //!< Target node }; -inline void -TargetIdentifierIndex::set_target( Node* target ) -{ - assert( kernel().node_manager.thread_local_data_is_up_to_date() ); - - size_t target_lid = target->get_thread_lid(); - if ( target_lid > max_targetindex ) - { - throw IllegalConnection( - String::compose( "HPC synapses support at most %1 nodes per thread. " - "See Kunkel et al, Front Neuroinform 8:78 (2014), Sec 3.3.2.", - max_targetindex ) ); - } - target_ = target_lid; -} - } // namespace nest diff --git a/nestkernel/target_table.cpp b/nestkernel/target_table.cpp index d9d06a8c4e..70ab52f382 100644 --- a/nestkernel/target_table.cpp +++ b/nestkernel/target_table.cpp @@ -23,20 +23,25 @@ // Includes from nestkernel: #include "target_table.h" #include "kernel_manager.h" +#include "model_manager.h" +#include "mpi_manager.h" +#include "vp_manager.h" // Includes from libnestutil #include "vector_util.h" +#include + void nest::TargetTable::initialize() { - const size_t num_threads = kernel().vp_manager.get_num_threads(); + const size_t num_threads = kernel::manager< VPManager >.get_num_threads(); targets_.resize( num_threads ); secondary_send_buffer_pos_.resize( num_threads ); #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); targets_[ tid ] = std::vector< std::vector< Target > >(); secondary_send_buffer_pos_[ tid ] = std::vector< std::vector< std::vector< size_t > > >(); } // of omp parallel @@ -54,7 +59,7 @@ nest::TargetTable::prepare( const size_t tid ) { // add one to max_num_local_nodes to avoid possible overflow in case // of rounding errors - const size_t num_local_nodes = kernel().node_manager.get_max_num_local_nodes() + 1; + const size_t num_local_nodes = kernel::manager< NodeManager >.get_max_num_local_nodes() + 1; targets_[ tid ].resize( num_local_nodes ); @@ -63,7 +68,7 @@ nest::TargetTable::prepare( const size_t tid ) for ( size_t lid = 0; lid < num_local_nodes; ++lid ) { // resize to maximal possible synapse-type index - secondary_send_buffer_pos_[ tid ][ lid ].resize( kernel().model_manager.get_num_connection_models() ); + secondary_send_buffer_pos_[ tid ][ lid ].resize( kernel::manager< ModelManager >.get_num_connection_models() ); } } @@ -101,10 +106,32 @@ nest::TargetTable::add_target( const size_t tid, const size_t target_rank, const { const SecondaryTargetDataFields& secondary_fields = target_data.secondary_data; const size_t send_buffer_pos = secondary_fields.get_recv_buffer_pos() - + kernel().mpi_manager.get_send_displacement_secondary_events_in_int( target_rank ); + + kernel::manager< MPIManager >.get_send_displacement_secondary_events_in_int( target_rank ); const synindex syn_id = secondary_fields.get_syn_id(); assert( syn_id < secondary_send_buffer_pos_[ tid ][ lid ].size() ); secondary_send_buffer_pos_[ tid ][ lid ][ syn_id ].push_back( send_buffer_pos ); } } + +const std::vector< nest::Target >& +nest::TargetTable::get_targets( const size_t tid, const size_t lid ) const +{ + return targets_[ tid ][ lid ]; +} + +const std::vector< size_t >& +nest::TargetTable::get_secondary_send_buffer_positions( const size_t tid, + const size_t lid, + const synindex syn_id ) const +{ + assert( syn_id < secondary_send_buffer_pos_[ tid ][ lid ].size() ); + return secondary_send_buffer_pos_[ tid ][ lid ][ syn_id ]; +} + +void +nest::TargetTable::clear( const size_t tid ) +{ + targets_[ tid ].clear(); + secondary_send_buffer_pos_[ tid ].clear(); +} diff --git a/nestkernel/target_table.h b/nestkernel/target_table.h index 4a8699e1cf..feef6c9a96 100644 --- a/nestkernel/target_table.h +++ b/nestkernel/target_table.h @@ -115,26 +115,6 @@ class TargetTable void compress_secondary_send_buffer_pos( const size_t tid ); }; -inline const std::vector< Target >& -TargetTable::get_targets( const size_t tid, const size_t lid ) const -{ - return targets_[ tid ][ lid ]; -} - -inline const std::vector< size_t >& -TargetTable::get_secondary_send_buffer_positions( const size_t tid, const size_t lid, const synindex syn_id ) const -{ - assert( syn_id < secondary_send_buffer_pos_[ tid ][ lid ].size() ); - return secondary_send_buffer_pos_[ tid ][ lid ][ syn_id ]; -} - -inline void -TargetTable::clear( const size_t tid ) -{ - targets_[ tid ].clear(); - secondary_send_buffer_pos_[ tid ].clear(); -} - } // namespace nest #endif /* #ifndef TARGET_TABLE_H */ diff --git a/nestkernel/target_table_devices.cpp b/nestkernel/target_table_devices.cpp index da106e9b43..7bcbfd10b6 100644 --- a/nestkernel/target_table_devices.cpp +++ b/nestkernel/target_table_devices.cpp @@ -21,30 +21,36 @@ */ // Includes from nestkernel: +#include "target_table_devices.h" #include "connector_base.h" +#include "connector_model_impl.h" #include "kernel_manager.h" -#include "target_table_devices_impl.h" -#include "vp_manager_impl.h" +#include "model_manager.h" -nest::TargetTableDevices::TargetTableDevices() +#include "node_manager.h" + +namespace nest +{ + +TargetTableDevices::TargetTableDevices() { } -nest::TargetTableDevices::~TargetTableDevices() +TargetTableDevices::~TargetTableDevices() { } void -nest::TargetTableDevices::initialize() +TargetTableDevices::initialize() { - const size_t num_threads = kernel().vp_manager.get_num_threads(); + const size_t num_threads = kernel::manager< VPManager >.get_num_threads(); target_to_devices_.resize( num_threads ); target_from_devices_.resize( num_threads ); sending_devices_node_ids_.resize( num_threads ); } void -nest::TargetTableDevices::finalize() +TargetTableDevices::finalize() { for ( size_t tid = 0; tid < target_to_devices_.size(); ++tid ) { @@ -74,37 +80,39 @@ nest::TargetTableDevices::finalize() } void -nest::TargetTableDevices::resize_to_number_of_neurons() +TargetTableDevices::resize_to_number_of_neurons() { #pragma omp parallel { - const size_t tid = kernel().vp_manager.get_thread_id(); - target_to_devices_[ tid ].resize( kernel().node_manager.get_max_num_local_nodes() + 1 ); - target_from_devices_[ tid ].resize( kernel().node_manager.get_num_thread_local_devices( tid ) + 1 ); - sending_devices_node_ids_[ tid ].resize( kernel().node_manager.get_num_thread_local_devices( tid ) + 1 ); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); + target_to_devices_[ tid ].resize( kernel::manager< NodeManager >.get_max_num_local_nodes() + 1 ); + target_from_devices_[ tid ].resize( kernel::manager< NodeManager >.get_num_thread_local_devices( tid ) + 1 ); + sending_devices_node_ids_[ tid ].resize( kernel::manager< NodeManager >.get_num_thread_local_devices( tid ) + 1 ); } // end omp parallel } void -nest::TargetTableDevices::resize_to_number_of_synapse_types() +TargetTableDevices::resize_to_number_of_synapse_types() { - kernel().vp_manager.assert_thread_parallel(); + kernel::manager< VPManager >.assert_thread_parallel(); - const size_t tid = kernel().vp_manager.get_thread_id(); + const size_t tid = kernel::manager< VPManager >.get_thread_id(); for ( size_t lid = 0; lid < target_to_devices_.at( tid ).size(); ++lid ) { // make sure this device has support for all synapse types - target_to_devices_.at( tid ).at( lid ).resize( kernel().model_manager.get_num_connection_models(), nullptr ); + target_to_devices_.at( tid ).at( lid ).resize( + kernel::manager< ModelManager >.get_num_connection_models(), nullptr ); } for ( size_t ldid = 0; ldid < target_from_devices_.at( tid ).size(); ++ldid ) { // make sure this device has support for all synapse types - target_from_devices_.at( tid ).at( ldid ).resize( kernel().model_manager.get_num_connection_models(), nullptr ); + target_from_devices_.at( tid ).at( ldid ).resize( + kernel::manager< ModelManager >.get_num_connection_models(), nullptr ); } } void -nest::TargetTableDevices::get_connections_to_devices_( const size_t requested_source_node_id, +TargetTableDevices::get_connections_to_devices_( const size_t requested_source_node_id, const size_t requested_target_node_id, const size_t tid, const synindex syn_id, @@ -113,8 +121,8 @@ nest::TargetTableDevices::get_connections_to_devices_( const size_t requested_so { if ( requested_source_node_id != 0 ) { - const size_t lid = kernel().vp_manager.node_id_to_lid( requested_source_node_id ); - if ( kernel().vp_manager.lid_to_node_id( lid ) != requested_source_node_id ) + const size_t lid = kernel::manager< VPManager >.node_id_to_lid( requested_source_node_id ); + if ( kernel::manager< VPManager >.lid_to_node_id( lid ) != requested_source_node_id ) { return; } @@ -130,7 +138,7 @@ nest::TargetTableDevices::get_connections_to_devices_( const size_t requested_so } void -nest::TargetTableDevices::get_connections_to_device_for_lid_( const size_t lid, +TargetTableDevices::get_connections_to_device_for_lid_( const size_t lid, const size_t requested_target_node_id, const size_t tid, const synindex syn_id, @@ -139,7 +147,7 @@ nest::TargetTableDevices::get_connections_to_device_for_lid_( const size_t lid, { if ( target_to_devices_[ tid ][ lid ].size() > 0 ) { - const size_t source_node_id = kernel().vp_manager.lid_to_node_id( lid ); + const size_t source_node_id = kernel::manager< VPManager >.lid_to_node_id( lid ); // not the valid connector if ( source_node_id > 0 and target_to_devices_[ tid ][ lid ][ syn_id ] ) { @@ -150,7 +158,7 @@ nest::TargetTableDevices::get_connections_to_device_for_lid_( const size_t lid, } void -nest::TargetTableDevices::get_connections_from_devices_( const size_t requested_source_node_id, +TargetTableDevices::get_connections_from_devices_( const size_t requested_source_node_id, const size_t requested_target_node_id, const size_t tid, const synindex syn_id, @@ -164,7 +172,7 @@ nest::TargetTableDevices::get_connections_from_devices_( const size_t requested_ const size_t source_node_id = *it; if ( source_node_id > 0 and ( requested_source_node_id == source_node_id or requested_source_node_id == 0 ) ) { - const Node* source = kernel().node_manager.get_node_or_proxy( source_node_id, tid ); + const Node* source = kernel::manager< NodeManager >.get_node_or_proxy( source_node_id, tid ); const size_t ldid = source->get_local_device_id(); if ( target_from_devices_[ tid ][ ldid ].size() > 0 ) @@ -181,7 +189,7 @@ nest::TargetTableDevices::get_connections_from_devices_( const size_t requested_ } void -nest::TargetTableDevices::get_connections( const size_t requested_source_node_id, +TargetTableDevices::get_connections( const size_t requested_source_node_id, const size_t requested_target_node_id, const size_t tid, const synindex syn_id, @@ -195,3 +203,162 @@ nest::TargetTableDevices::get_connections( const size_t requested_source_node_id get_connections_from_devices_( requested_source_node_id, requested_target_node_id, tid, syn_id, synapse_label, conns ); } + +void +TargetTableDevices::add_connection_to_device( Node& source, + Node& target, + const size_t source_node_id, + const size_t tid, + const synindex syn_id, + const DictionaryDatum& p, + const double d, + const double w ) +{ + const size_t lid = kernel::manager< VPManager >.node_id_to_lid( source_node_id ); + assert( lid < target_to_devices_[ tid ].size() ); + assert( syn_id < target_to_devices_[ tid ][ lid ].size() ); + + kernel::manager< ModelManager >.get_connection_model( syn_id, tid ).add_connection( source, target, target_to_devices_[ tid ][ lid ], syn_id, p, d, w ); +} + +void +TargetTableDevices::add_connection_from_device( Node& source, + Node& target, + const size_t tid, + const synindex syn_id, + const DictionaryDatum& p, + const double d, + const double w ) +{ + const size_t ldid = source.get_local_device_id(); + assert( ldid != invalid_index ); + assert( ldid < target_from_devices_[ tid ].size() ); + assert( syn_id < target_from_devices_[ tid ][ ldid ].size() ); + + kernel::manager< ModelManager >.get_connection_model( syn_id, tid ).add_connection( source, target, target_from_devices_[ tid ][ ldid ], syn_id, p, d, w ); + + // store node ID of sending device + sending_devices_node_ids_[ tid ][ ldid ] = source.get_node_id(); +} + + +void +TargetTableDevices::get_synapse_status_from_device( const size_t tid, + const size_t ldid, + const synindex syn_id, + DictionaryDatum& dict, + const size_t lcid ) const +{ + target_from_devices_[ tid ][ ldid ][ syn_id ]->get_synapse_status( tid, lcid, dict ); +} + +void +TargetTableDevices::set_synapse_status_from_device( const size_t tid, + const size_t ldid, + const synindex syn_id, + ConnectorModel& cm, + const DictionaryDatum& dict, + const size_t lcid ) +{ + target_from_devices_[ tid ][ ldid ][ syn_id ]->set_synapse_status( lcid, dict, cm ); +} + +void +TargetTableDevices::send_from_device( const size_t tid, + const size_t ldid, + Event& e, + const std::vector< ConnectorModel* >& cm ) +{ + for ( std::vector< ConnectorBase* >::iterator it = target_from_devices_[ tid ][ ldid ].begin(); + it != target_from_devices_[ tid ][ ldid ].end(); + ++it ) + { + if ( *it ) + { + ( *it )->send_to_all( tid, cm, e ); + } + } +} + +bool +TargetTableDevices::is_device_connected( const size_t tid, const size_t lcid ) const +{ + for ( auto& synapse : target_from_devices_[ tid ][ lcid ] ) + { + if ( synapse ) + { + std::deque< ConnectionID > conns; + synapse->get_all_connections( lcid, 0, tid, UNLABELED_CONNECTION, conns ); + if ( not conns.empty() ) + { + return true; + } + } + } + return false; +} + +void +TargetTableDevices::send_to_device( const size_t tid, + const size_t source_node_id, + Event& e, + const std::vector< ConnectorModel* >& cm ) +{ + const size_t lid = kernel::manager< VPManager >.node_id_to_lid( source_node_id ); + for ( std::vector< ConnectorBase* >::iterator it = target_to_devices_[ tid ][ lid ].begin(); + it != target_to_devices_[ tid ][ lid ].end(); + ++it ) + { + if ( *it ) + { + ( *it )->send_to_all( tid, cm, e ); + } + } +} + +void +TargetTableDevices::send_to_device( const size_t tid, + const size_t source_node_id, + SecondaryEvent& e, + const std::vector< ConnectorModel* >& cm ) +{ + const size_t lid = kernel::manager< VPManager >.node_id_to_lid( source_node_id ); + for ( auto& synid : e.get_supported_syn_ids() ) + { + if ( target_to_devices_[ tid ][ lid ][ synid ] ) + { + target_to_devices_[ tid ][ lid ][ synid ]->send_to_all( tid, cm, e ); + } + } +} + +void +TargetTableDevices::get_synapse_status_to_device( const size_t tid, + const size_t source_node_id, + const synindex syn_id, + DictionaryDatum& dict, + const size_t lcid ) const +{ + const size_t lid = kernel::manager< VPManager >.node_id_to_lid( source_node_id ); + if ( target_to_devices_[ tid ][ lid ][ syn_id ] ) + { + target_to_devices_[ tid ][ lid ][ syn_id ]->get_synapse_status( tid, lcid, dict ); + } +} + +void +TargetTableDevices::set_synapse_status_to_device( const size_t tid, + const size_t source_node_id, + const synindex syn_id, + ConnectorModel& cm, + const DictionaryDatum& dict, + const size_t lcid ) +{ + const size_t lid = kernel::manager< VPManager >.node_id_to_lid( source_node_id ); + if ( target_to_devices_[ tid ][ lid ][ syn_id ] ) + { + target_to_devices_[ tid ][ lid ][ syn_id ]->set_synapse_status( lcid, dict, cm ); + } +} + +} diff --git a/nestkernel/target_table_devices.h b/nestkernel/target_table_devices.h index de6d31db3d..e8e8690c05 100644 --- a/nestkernel/target_table_devices.h +++ b/nestkernel/target_table_devices.h @@ -24,8 +24,6 @@ #define TARGET_TABLE_DEVICES_H // C++ includes: -#include -#include #include // Includes from nestkernel: @@ -35,7 +33,6 @@ #include "nest_types.h" // Includes from SLI: -#include "arraydatum.h" #include "dictdatum.h" namespace nest @@ -208,63 +205,6 @@ class TargetTableDevices bool is_device_connected( size_t tid, size_t lcid ) const; }; -inline void -TargetTableDevices::get_synapse_status_from_device( const size_t tid, - const size_t ldid, - const synindex syn_id, - DictionaryDatum& dict, - const size_t lcid ) const -{ - target_from_devices_[ tid ][ ldid ][ syn_id ]->get_synapse_status( tid, lcid, dict ); -} - -inline void -TargetTableDevices::set_synapse_status_from_device( const size_t tid, - const size_t ldid, - const synindex syn_id, - ConnectorModel& cm, - const DictionaryDatum& dict, - const size_t lcid ) -{ - target_from_devices_[ tid ][ ldid ][ syn_id ]->set_synapse_status( lcid, dict, cm ); -} - -inline void -TargetTableDevices::send_from_device( const size_t tid, - const size_t ldid, - Event& e, - const std::vector< ConnectorModel* >& cm ) -{ - for ( std::vector< ConnectorBase* >::iterator it = target_from_devices_[ tid ][ ldid ].begin(); - it != target_from_devices_[ tid ][ ldid ].end(); - ++it ) - { - if ( *it ) - { - ( *it )->send_to_all( tid, cm, e ); - } - } -} - -inline bool -TargetTableDevices::is_device_connected( const size_t tid, const size_t lcid ) const -{ - for ( auto& synapse : target_from_devices_[ tid ][ lcid ] ) - { - if ( synapse ) - { - std::deque< ConnectionID > conns; - synapse->get_all_connections( lcid, 0, tid, UNLABELED_CONNECTION, conns ); - if ( not conns.empty() ) - { - return true; - } - } - } - return false; -} - - } // namespace nest #endif diff --git a/nestkernel/target_table_devices_impl.h b/nestkernel/target_table_devices_impl.h deleted file mode 100644 index 26a4668fb1..0000000000 --- a/nestkernel/target_table_devices_impl.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * target_table_devices_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - */ - -#ifndef TARGET_TABLE_DEVICES_IMPL_H -#define TARGET_TABLE_DEVICES_IMPL_H - -// Includes from nestkernel: -#include "connector_base.h" -#include "kernel_manager.h" -#include "model_manager.h" -#include "node.h" -#include "target_table_devices.h" -#include "vp_manager_impl.h" - -inline void -nest::TargetTableDevices::add_connection_to_device( Node& source, - Node& target, - const size_t source_node_id, - const size_t tid, - const synindex syn_id, - const DictionaryDatum& p, - const double d, - const double w ) -{ - const size_t lid = kernel().vp_manager.node_id_to_lid( source_node_id ); - assert( lid < target_to_devices_[ tid ].size() ); - assert( syn_id < target_to_devices_[ tid ][ lid ].size() ); - - kernel() - .model_manager.get_connection_model( syn_id, tid ) - .add_connection( source, target, target_to_devices_[ tid ][ lid ], syn_id, p, d, w ); -} - -inline void -nest::TargetTableDevices::add_connection_from_device( Node& source, - Node& target, - const size_t tid, - const synindex syn_id, - const DictionaryDatum& p, - const double d, - const double w ) -{ - const size_t ldid = source.get_local_device_id(); - assert( ldid != invalid_index ); - assert( ldid < target_from_devices_[ tid ].size() ); - assert( syn_id < target_from_devices_[ tid ][ ldid ].size() ); - - kernel() - .model_manager.get_connection_model( syn_id, tid ) - .add_connection( source, target, target_from_devices_[ tid ][ ldid ], syn_id, p, d, w ); - - // store node ID of sending device - sending_devices_node_ids_[ tid ][ ldid ] = source.get_node_id(); -} - -inline void -nest::TargetTableDevices::send_to_device( const size_t tid, - const size_t source_node_id, - Event& e, - const std::vector< ConnectorModel* >& cm ) -{ - const size_t lid = kernel().vp_manager.node_id_to_lid( source_node_id ); - for ( std::vector< ConnectorBase* >::iterator it = target_to_devices_[ tid ][ lid ].begin(); - it != target_to_devices_[ tid ][ lid ].end(); - ++it ) - { - if ( *it ) - { - ( *it )->send_to_all( tid, cm, e ); - } - } -} - -inline void -nest::TargetTableDevices::send_to_device( const size_t tid, - const size_t source_node_id, - SecondaryEvent& e, - const std::vector< ConnectorModel* >& cm ) -{ - const size_t lid = kernel().vp_manager.node_id_to_lid( source_node_id ); - for ( auto& synid : e.get_supported_syn_ids() ) - { - if ( target_to_devices_[ tid ][ lid ][ synid ] ) - { - target_to_devices_[ tid ][ lid ][ synid ]->send_to_all( tid, cm, e ); - } - } -} - -inline void -nest::TargetTableDevices::get_synapse_status_to_device( const size_t tid, - const size_t source_node_id, - const synindex syn_id, - DictionaryDatum& dict, - const size_t lcid ) const -{ - const size_t lid = kernel().vp_manager.node_id_to_lid( source_node_id ); - if ( target_to_devices_[ tid ][ lid ][ syn_id ] ) - { - target_to_devices_[ tid ][ lid ][ syn_id ]->get_synapse_status( tid, lcid, dict ); - } -} - -inline void -nest::TargetTableDevices::set_synapse_status_to_device( const size_t tid, - const size_t source_node_id, - const synindex syn_id, - ConnectorModel& cm, - const DictionaryDatum& dict, - const size_t lcid ) -{ - const size_t lid = kernel().vp_manager.node_id_to_lid( source_node_id ); - if ( target_to_devices_[ tid ][ lid ][ syn_id ] ) - { - target_to_devices_[ tid ][ lid ][ syn_id ]->set_synapse_status( lcid, dict, cm ); - } -} - -#endif /* TARGET_TABLE_DEVICES_IMPL_H */ diff --git a/nestkernel/universal_data_logger.h b/nestkernel/universal_data_logger.h index cb51337b12..2edd9c83e7 100644 --- a/nestkernel/universal_data_logger.h +++ b/nestkernel/universal_data_logger.h @@ -29,8 +29,8 @@ // Includes from nestkernel: #include "event.h" +#include "event_delivery_manager.h" #include "nest_time.h" -#include "nest_types.h" #include "recordables_map.h" namespace nest @@ -84,27 +84,21 @@ namespace nest * * ... * - * nest::iaf_cond_alpha::Buffers_::Buffers_(iaf_cond_alpha& n) + * iaf_cond_alpha::Buffers_::Buffers_(iaf_cond_alpha& n) * : logger_(n), ... {} * - * nest::iaf_cond_alpha::Buffers_::Buffers_(const Buffers_&, iaf_cond_alpha& n) + * iaf_cond_alpha::Buffers_::Buffers_(const Buffers_&, iaf_cond_alpha& n) * : logger_(n), ... {} * - * nest::iaf_cond_alpha::iaf_cond_alpha() + * iaf_cond_alpha::iaf_cond_alpha() * : ..., B_(*this) {} * - * nest::iaf_cond_alpha::iaf_cond_alpha(const iaf_cond_alpha& n) + * iaf_cond_alpha::iaf_cond_alpha(const iaf_cond_alpha& n) * : ..., B_(n.B_, *this) {} * @code * * @todo Could HostNode be passed as const& to handle() and record_data()? * - * @note To avoid inclusion problems and code-bloat, the class - * interface is defined in this file, while most of the - * implementation is in the companion universal_data_logger_impl.h. - * As a consequence, calls to UniversalDataLogger members should - * only come from cpp files---do not inline them. - * * @addtogroup Devices */ @@ -231,83 +225,6 @@ class UniversalDataLogger UniversalDataLogger const& operator=( const UniversalDataLogger& ); }; -// must be defined in this file, since it is required by check_connection(), -// which typically is in h-files. -template < typename HostNode > -size_t -nest::UniversalDataLogger< HostNode >::connect_logging_device( const DataLoggingRequest& req, - const RecordablesMap< HostNode >& rmap ) -{ - // rports are assigned consecutively, the caller may not request specific - // rports. - if ( req.get_rport() != 0 ) - { - throw IllegalConnection( "Connections from multimeter to node must request rport 0." ); - } - - // ensure that we have not connected this multimeter before - const size_t mm_node_id = req.get_sender().get_node_id(); - - const auto item = std::find_if( data_loggers_.begin(), - data_loggers_.end(), - [ & ]( const DataLogger_& dl ) { return dl.get_mm_node_id() == mm_node_id; } ); - - if ( item != data_loggers_.end() ) - { - throw IllegalConnection( "Each multimeter can only be connected once to a given node." ); - } - - // we now know that we have no DataLogger_ for the given multimeter, so we - // create one and push it - data_loggers_.push_back( DataLogger_( req, rmap ) ); - - // rport is index plus one, i.e., size - return data_loggers_.size(); -} - -template < typename HostNode > -nest::UniversalDataLogger< HostNode >::DataLogger_::DataLogger_( const DataLoggingRequest& req, - const RecordablesMap< HostNode >& rmap ) - : multimeter_( req.get_sender().get_node_id() ) - , num_vars_( 0 ) - , recording_interval_( Time::neg_inf() ) - , recording_offset_( Time::ms( 0. ) ) - , rec_int_steps_( 0 ) - , next_rec_step_( -1 ) - , // flag as uninitialized - node_access_() - , data_() - , next_rec_( 2, 0 ) -{ - const std::vector< Name >& recvars = req.record_from(); - for ( size_t j = 0; j < recvars.size(); ++j ) - { - // .toString() required as work-around for #339, remove when #348 is solved. - typename RecordablesMap< HostNode >::const_iterator rec = rmap.find( recvars[ j ].toString() ); - - if ( rec == rmap.end() ) - { - // delete all access information again: the connect either succeeds - // for all entries in recvars, or it fails, leaving the logger untouched - node_access_.clear(); - throw IllegalConnection( "Cannot connect with unknown recordable " + recvars[ j ].toString() ); - } - - node_access_.push_back( rec->second ); - } - - num_vars_ = node_access_.size(); - - if ( num_vars_ > 0 and req.get_recording_interval() < Time::step( 1 ) ) - { - throw IllegalConnection( "Recording interval must be >= resolution." ); - } - - recording_interval_ = req.get_recording_interval(); - recording_offset_ = req.get_recording_offset(); -} - - /** * Dynamic Universal data-logging plug-in for multisynapse neuron models. * @@ -342,30 +259,24 @@ nest::UniversalDataLogger< HostNode >::DataLogger_::DataLogger_( const DataLoggi * * ... * - * nest::aeif_cond_beta_multisynapse::Buffers_::Buffers_(aeif_cond_beta_multisynapse& + * aeif_cond_beta_multisynapse::Buffers_::Buffers_(aeif_cond_beta_multisynapse& * n) * : logger_(n), ... {} * - * nest::aeif_cond_beta_multisynapse::Buffers_::Buffers_(const Buffers_&, + * aeif_cond_beta_multisynapse::Buffers_::Buffers_(const Buffers_&, * aeif_cond_beta_multisynapse& n) * : logger_(n), ... {} * - * nest::aeif_cond_beta_multisynapse::aeif_cond_beta_multisynapse() + * aeif_cond_beta_multisynapse::aeif_cond_beta_multisynapse() * : ..., B_(*this) {} * - * nest::aeif_cond_beta_multisynapse::aeif_cond_beta_multisynapse(const + * aeif_cond_beta_multisynapse::aeif_cond_beta_multisynapse(const * aeif_cond_beta_multisynapse& n) * : ..., B_(n.B_, *this) {} * @code * * @todo Could HostNode be passed as const& to handle() and record_data()? * - * @note To avoid inclusion problems and code-bloat, the class - * interface is defined in this file, while most of the - * implementation is in the companion universal_data_logger_impl.h. - * As a consequence, calls to UniversalDataLogger members should - * only come from cpp files---do not inline them. - * * @addtogroup Devices */ @@ -492,84 +403,6 @@ class DynamicUniversalDataLogger DynamicUniversalDataLogger const& operator=( const DynamicUniversalDataLogger& ); }; - -// must be defined in this file, since it is required by check_connection(), -// which typically is in h-files. -template < typename HostNode > -size_t -nest::DynamicUniversalDataLogger< HostNode >::connect_logging_device( const DataLoggingRequest& req, - const DynamicRecordablesMap< HostNode >& rmap ) -{ - // rports are assigned consecutively, the caller may not request specific - // rports. - if ( req.get_rport() != 0 ) - { - throw IllegalConnection( "Connections from multimeter to node must request rport 0." ); - } - - // ensure that we have not connected this multimeter before - const size_t mm_node_id = req.get_sender().get_node_id(); - const size_t n_loggers = data_loggers_.size(); - size_t j = 0; - while ( j < n_loggers and data_loggers_[ j ].get_mm_node_id() != mm_node_id ) - { - ++j; - } - if ( j < n_loggers ) - { - throw IllegalConnection( "Each multimeter can only be connected once to a given node." ); - } - - // we now know that we have no DataLogger_ for the given multimeter, so we - // create one and push it - data_loggers_.push_back( DataLogger_( req, rmap ) ); - - // rport is index plus one, i.e., size - return data_loggers_.size(); -} - -template < typename HostNode > -nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::DataLogger_( const DataLoggingRequest& req, - const DynamicRecordablesMap< HostNode >& rmap ) - : multimeter_( req.get_sender().get_node_id() ) - , num_vars_( 0 ) - , recording_interval_( Time::neg_inf() ) - , recording_offset_( Time::ms( 0. ) ) - , rec_int_steps_( 0 ) - , next_rec_step_( -1 ) - , // flag as uninitialized - node_access_() - , data_() - , next_rec_( 2, 0 ) -{ - const std::vector< Name >& recvars = req.record_from(); - for ( size_t j = 0; j < recvars.size(); ++j ) - { - // .toString() required as work-around for #339, remove when #348 is solved. - typename DynamicRecordablesMap< HostNode >::const_iterator rec = rmap.find( recvars[ j ].toString() ); - - if ( rec == rmap.end() ) - { - // delete all access information again: the connect either succeeds - // for all entries in recvars, or it fails, leaving the logger untouched - node_access_.clear(); - throw IllegalConnection( "Cannot connect with unknown recordable " + recvars[ j ].toString() ); - } - - node_access_.push_back( &( rec->second ) ); - } - - num_vars_ = node_access_.size(); - - if ( num_vars_ > 0 and req.get_recording_interval() < Time::step( 1 ) ) - { - throw IllegalConnection( "Recording interval must be >= resolution." ); - } - - recording_interval_ = req.get_recording_interval(); - recording_offset_ = req.get_recording_offset(); -} - } // namespace nest #endif /* #ifndef UNIVERSAL_DATA_LOGGER_H */ diff --git a/nestkernel/universal_data_logger_impl.h b/nestkernel/universal_data_logger_impl.h index 8b22da5872..33e8b9f241 100644 --- a/nestkernel/universal_data_logger_impl.h +++ b/nestkernel/universal_data_logger_impl.h @@ -23,16 +23,168 @@ #ifndef UNIVERSAL_DATA_LOGGER_IMPL_H #define UNIVERSAL_DATA_LOGGER_IMPL_H +#include "simulation_manager.h" #include "universal_data_logger.h" -// Includes from nestkernel: -#include "event_delivery_manager_impl.h" -#include "kernel_manager.h" -#include "nest_time.h" -#include "node.h" +namespace nest +{ + +// must be defined in this file, since it is required by check_connection(), +// which typically is in h-files. +template < typename HostNode > +size_t +UniversalDataLogger< HostNode >::connect_logging_device( const DataLoggingRequest& req, + const RecordablesMap< HostNode >& rmap ) +{ + // rports are assigned consecutively, the caller may not request specific + // rports. + if ( req.get_rport() != 0 ) + { + throw IllegalConnection( "Connections from multimeter to node must request rport 0." ); + } + + // ensure that we have not connected this multimeter before + const size_t mm_node_id = req.get_sender().get_node_id(); + + const auto item = std::find_if( data_loggers_.begin(), + data_loggers_.end(), + [ & ]( const DataLogger_& dl ) { return dl.get_mm_node_id() == mm_node_id; } ); + + if ( item != data_loggers_.end() ) + { + throw IllegalConnection( "Each multimeter can only be connected once to a given node." ); + } + + // we now know that we have no DataLogger_ for the given multimeter, so we + // create one and push it + data_loggers_.push_back( DataLogger_( req, rmap ) ); + + // rport is index plus one, i.e., size + return data_loggers_.size(); +} template < typename HostNode > -nest::DynamicUniversalDataLogger< HostNode >::DynamicUniversalDataLogger( HostNode& host ) +UniversalDataLogger< HostNode >::DataLogger_::DataLogger_( const DataLoggingRequest& req, + const RecordablesMap< HostNode >& rmap ) + : multimeter_( req.get_sender().get_node_id() ) + , num_vars_( 0 ) + , recording_interval_( Time::neg_inf() ) + , recording_offset_( Time::ms( 0. ) ) + , rec_int_steps_( 0 ) + , next_rec_step_( -1 ) + , // flag as uninitialized + node_access_() + , data_() + , next_rec_( 2, 0 ) +{ + const std::vector< Name >& recvars = req.record_from(); + for ( size_t j = 0; j < recvars.size(); ++j ) + { + // .toString() required as work-around for #339, remove when #348 is solved. + typename RecordablesMap< HostNode >::const_iterator rec = rmap.find( recvars[ j ].toString() ); + + if ( rec == rmap.end() ) + { + // delete all access information again: the connect either succeeds + // for all entries in recvars, or it fails, leaving the logger untouched + node_access_.clear(); + throw IllegalConnection( "Cannot connect with unknown recordable " + recvars[ j ].toString() ); + } + + node_access_.push_back( rec->second ); + } + + num_vars_ = node_access_.size(); + + if ( num_vars_ > 0 and req.get_recording_interval() < Time::step( 1 ) ) + { + throw IllegalConnection( "Recording interval must be >= resolution." ); + } + + recording_interval_ = req.get_recording_interval(); + recording_offset_ = req.get_recording_offset(); +} + + +// must be defined in this file, since it is required by check_connection(), +// which typically is in h-files. +template < typename HostNode > +size_t +DynamicUniversalDataLogger< HostNode >::connect_logging_device( const DataLoggingRequest& req, + const DynamicRecordablesMap< HostNode >& rmap ) +{ + // rports are assigned consecutively, the caller may not request specific + // rports. + if ( req.get_rport() != 0 ) + { + throw IllegalConnection( "Connections from multimeter to node must request rport 0." ); + } + + // ensure that we have not connected this multimeter before + const size_t mm_node_id = req.get_sender().get_node_id(); + const size_t n_loggers = data_loggers_.size(); + size_t j = 0; + while ( j < n_loggers and data_loggers_[ j ].get_mm_node_id() != mm_node_id ) + { + ++j; + } + if ( j < n_loggers ) + { + throw IllegalConnection( "Each multimeter can only be connected once to a given node." ); + } + + // we now know that we have no DataLogger_ for the given multimeter, so we + // create one and push it + data_loggers_.push_back( DataLogger_( req, rmap ) ); + + // rport is index plus one, i.e., size + return data_loggers_.size(); +} + +template < typename HostNode > +DynamicUniversalDataLogger< HostNode >::DataLogger_::DataLogger_( const DataLoggingRequest& req, + const DynamicRecordablesMap< HostNode >& rmap ) + : multimeter_( req.get_sender().get_node_id() ) + , num_vars_( 0 ) + , recording_interval_( Time::neg_inf() ) + , recording_offset_( Time::ms( 0. ) ) + , rec_int_steps_( 0 ) + , next_rec_step_( -1 ) + , // flag as uninitialized + node_access_() + , data_() + , next_rec_( 2, 0 ) +{ + const std::vector< Name >& recvars = req.record_from(); + for ( size_t j = 0; j < recvars.size(); ++j ) + { + // .toString() required as work-around for #339, remove when #348 is solved. + typename DynamicRecordablesMap< HostNode >::const_iterator rec = rmap.find( recvars[ j ].toString() ); + + if ( rec == rmap.end() ) + { + // delete all access information again: the connect either succeeds + // for all entries in recvars, or it fails, leaving the logger untouched + node_access_.clear(); + throw IllegalConnection( "Cannot connect with unknown recordable " + recvars[ j ].toString() ); + } + + node_access_.push_back( &( rec->second ) ); + } + + num_vars_ = node_access_.size(); + + if ( num_vars_ > 0 and req.get_recording_interval() < Time::step( 1 ) ) + { + throw IllegalConnection( "Recording interval must be >= resolution." ); + } + + recording_interval_ = req.get_recording_interval(); + recording_offset_ = req.get_recording_offset(); +} + +template < typename HostNode > +DynamicUniversalDataLogger< HostNode >::DynamicUniversalDataLogger( HostNode& host ) : host_( host ) , data_loggers_() { @@ -40,7 +192,7 @@ nest::DynamicUniversalDataLogger< HostNode >::DynamicUniversalDataLogger( HostNo template < typename HostNode > void -nest::DynamicUniversalDataLogger< HostNode >::reset() +DynamicUniversalDataLogger< HostNode >::reset() { for ( DLiter_ it = data_loggers_.begin(); it != data_loggers_.end(); ++it ) { @@ -50,7 +202,7 @@ nest::DynamicUniversalDataLogger< HostNode >::reset() template < typename HostNode > void -nest::DynamicUniversalDataLogger< HostNode >::init() +DynamicUniversalDataLogger< HostNode >::init() { for ( DLiter_ it = data_loggers_.begin(); it != data_loggers_.end(); ++it ) { @@ -60,7 +212,7 @@ nest::DynamicUniversalDataLogger< HostNode >::init() template < typename HostNode > void -nest::DynamicUniversalDataLogger< HostNode >::record_data( long step ) +DynamicUniversalDataLogger< HostNode >::record_data( long step ) { for ( DLiter_ it = data_loggers_.begin(); it != data_loggers_.end(); ++it ) { @@ -70,7 +222,7 @@ nest::DynamicUniversalDataLogger< HostNode >::record_data( long step ) template < typename HostNode > void -nest::DynamicUniversalDataLogger< HostNode >::handle( const DataLoggingRequest& dlr ) +DynamicUniversalDataLogger< HostNode >::handle( const DataLoggingRequest& dlr ) { const size_t rport = dlr.get_rport(); assert( rport >= 1 ); @@ -80,7 +232,7 @@ nest::DynamicUniversalDataLogger< HostNode >::handle( const DataLoggingRequest& template < typename HostNode > void -nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::reset() +DynamicUniversalDataLogger< HostNode >::DataLogger_::reset() { data_.clear(); next_rec_step_ = -1; // flag as uninitialized @@ -88,7 +240,7 @@ nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::reset() template < typename HostNode > void -nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::init() +DynamicUniversalDataLogger< HostNode >::DataLogger_::init() { if ( num_vars_ < 1 ) { @@ -97,7 +249,7 @@ nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::init() // Next recording step is in current slice or beyond, indicates that // buffer is properly initialized. - if ( next_rec_step_ >= kernel().simulation_manager.get_slice_origin().get_steps() ) + if ( next_rec_step_ >= kernel::manager< SimulationManager >.get_slice_origin().get_steps() ) { return; } @@ -114,14 +266,15 @@ nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::init() // left of update intervals, and we want time stamps at right end of // update interval to be multiples of recording interval. Need to add // +1 because the division result is rounded down. - next_rec_step_ = ( kernel().simulation_manager.get_time().get_steps() / rec_int_steps_ + 1 ) * rec_int_steps_ - 1; + next_rec_step_ = + ( kernel::manager< SimulationManager >.get_time().get_steps() / rec_int_steps_ + 1 ) * rec_int_steps_ - 1; // If offset is not 0, adjust next recording step to account for it by first setting next recording // step to be offset and then iterating until the variable is greater than current simulation time. if ( recording_offset_.get_steps() != 0 ) { next_rec_step_ = recording_offset_.get_steps() - 1; // shifted one to left - while ( next_rec_step_ <= kernel().simulation_manager.get_time().get_steps() ) + while ( next_rec_step_ <= kernel::manager< SimulationManager >.get_time().get_steps() ) { next_rec_step_ += rec_int_steps_; } @@ -129,7 +282,7 @@ nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::init() // number of data points per slice const long recs_per_slice = static_cast< long >( - std::ceil( kernel().connection_manager.get_min_delay() / static_cast< double >( rec_int_steps_ ) ) ); + std::ceil( kernel::manager< ConnectionManager >.get_min_delay() / static_cast< double >( rec_int_steps_ ) ) ); data_.resize( 2, DataLoggingReply::Container( recs_per_slice, DataLoggingReply::Item( num_vars_ ) ) ); @@ -139,14 +292,14 @@ nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::init() template < typename HostNode > void -nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::record_data( const HostNode&, long step ) +DynamicUniversalDataLogger< HostNode >::DataLogger_::record_data( const HostNode&, long step ) { if ( num_vars_ < 1 or step < next_rec_step_ ) { return; } - const size_t wt = kernel().event_delivery_manager.write_toggle(); + const size_t wt = kernel::manager< EventDeliveryManager >.write_toggle(); assert( wt < next_rec_.size() ); assert( wt < data_.size() ); @@ -181,7 +334,7 @@ nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::record_data( const Ho template < typename HostNode > void -nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::handle( HostNode& host, const DataLoggingRequest& request ) +DynamicUniversalDataLogger< HostNode >::DataLogger_::handle( HostNode& host, const DataLoggingRequest& request ) { if ( num_vars_ < 1 ) { @@ -194,13 +347,13 @@ nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::handle( HostNode& hos assert( data_.size() == 2 ); // get read toggle and start and end of slice - const size_t rt = kernel().event_delivery_manager.read_toggle(); + const size_t rt = kernel::manager< EventDeliveryManager >.read_toggle(); assert( not data_[ rt ].empty() ); // Check if we have valid data, i.e., data with time stamps within the // past time slice. This may not be the case if the node has been frozen. // In that case, we still reset the recording marker, to prepare for the next round. - if ( data_[ rt ][ 0 ].timestamp <= kernel().simulation_manager.get_previous_slice_origin() ) + if ( data_[ rt ][ 0 ].timestamp <= kernel::manager< SimulationManager >.get_previous_slice_origin() ) { next_rec_[ rt ] = 0; return; @@ -228,11 +381,11 @@ nest::DynamicUniversalDataLogger< HostNode >::DataLogger_::handle( HostNode& hos reply.set_port( request.get_port() ); // send it off - kernel().event_delivery_manager.send_to_node( reply ); + kernel::manager< EventDeliveryManager >.send_to_node( reply ); } template < typename HostNode > -nest::UniversalDataLogger< HostNode >::UniversalDataLogger( HostNode& host ) +UniversalDataLogger< HostNode >::UniversalDataLogger( HostNode& host ) : host_( host ) , data_loggers_() { @@ -240,7 +393,7 @@ nest::UniversalDataLogger< HostNode >::UniversalDataLogger( HostNode& host ) template < typename HostNode > void -nest::UniversalDataLogger< HostNode >::reset() +UniversalDataLogger< HostNode >::reset() { for ( DLiter_ it = data_loggers_.begin(); it != data_loggers_.end(); ++it ) { @@ -250,7 +403,7 @@ nest::UniversalDataLogger< HostNode >::reset() template < typename HostNode > void -nest::UniversalDataLogger< HostNode >::init() +UniversalDataLogger< HostNode >::init() { for ( DLiter_ it = data_loggers_.begin(); it != data_loggers_.end(); ++it ) { @@ -260,7 +413,7 @@ nest::UniversalDataLogger< HostNode >::init() template < typename HostNode > void -nest::UniversalDataLogger< HostNode >::record_data( long step ) +UniversalDataLogger< HostNode >::record_data( long step ) { for ( DLiter_ it = data_loggers_.begin(); it != data_loggers_.end(); ++it ) { @@ -270,7 +423,7 @@ nest::UniversalDataLogger< HostNode >::record_data( long step ) template < typename HostNode > void -nest::UniversalDataLogger< HostNode >::handle( const DataLoggingRequest& dlr ) +UniversalDataLogger< HostNode >::handle( const DataLoggingRequest& dlr ) { const size_t rport = dlr.get_rport(); assert( rport >= 1 ); @@ -280,7 +433,7 @@ nest::UniversalDataLogger< HostNode >::handle( const DataLoggingRequest& dlr ) template < typename HostNode > void -nest::UniversalDataLogger< HostNode >::DataLogger_::reset() +UniversalDataLogger< HostNode >::DataLogger_::reset() { data_.clear(); next_rec_step_ = -1; // flag as uninitialized @@ -288,7 +441,7 @@ nest::UniversalDataLogger< HostNode >::DataLogger_::reset() template < typename HostNode > void -nest::UniversalDataLogger< HostNode >::DataLogger_::init() +UniversalDataLogger< HostNode >::DataLogger_::init() { if ( num_vars_ < 1 ) { @@ -298,7 +451,7 @@ nest::UniversalDataLogger< HostNode >::DataLogger_::init() // Next recording step is in current slice or beyond, indicates that // buffer is properly initialized. - if ( next_rec_step_ >= kernel().simulation_manager.get_slice_origin().get_steps() ) + if ( next_rec_step_ >= kernel::manager< SimulationManager >.get_slice_origin().get_steps() ) { return; } @@ -315,14 +468,15 @@ nest::UniversalDataLogger< HostNode >::DataLogger_::init() // left of update intervals, and we want time stamps at right end of // update interval to be multiples of recording interval. Need to add // +1 because the division result is rounded down. - next_rec_step_ = ( kernel().simulation_manager.get_time().get_steps() / rec_int_steps_ + 1 ) * rec_int_steps_ - 1; + next_rec_step_ = + ( kernel::manager< SimulationManager >.get_time().get_steps() / rec_int_steps_ + 1 ) * rec_int_steps_ - 1; // If offset is not 0, adjust next recording step to account for it by first setting next recording // step to be offset and then iterating until the variable is greater than current simulation time. if ( recording_offset_.get_steps() != 0 ) { next_rec_step_ = recording_offset_.get_steps() - 1; // shifted one to left - while ( next_rec_step_ <= kernel().simulation_manager.get_time().get_steps() ) + while ( next_rec_step_ <= kernel::manager< SimulationManager >.get_time().get_steps() ) { next_rec_step_ += rec_int_steps_; } @@ -330,7 +484,7 @@ nest::UniversalDataLogger< HostNode >::DataLogger_::init() // number of data points per slice const long recs_per_slice = static_cast< long >( - std::ceil( kernel().connection_manager.get_min_delay() / static_cast< double >( rec_int_steps_ ) ) ); + std::ceil( kernel::manager< ConnectionManager >.get_min_delay() / static_cast< double >( rec_int_steps_ ) ) ); data_.resize( 2, DataLoggingReply::Container( recs_per_slice, DataLoggingReply::Item( num_vars_ ) ) ); @@ -340,14 +494,14 @@ nest::UniversalDataLogger< HostNode >::DataLogger_::init() template < typename HostNode > void -nest::UniversalDataLogger< HostNode >::DataLogger_::record_data( const HostNode& host, long step ) +UniversalDataLogger< HostNode >::DataLogger_::record_data( const HostNode& host, long step ) { if ( num_vars_ < 1 or step < next_rec_step_ ) { return; } - const size_t wt = kernel().event_delivery_manager.write_toggle(); + const size_t wt = kernel::manager< EventDeliveryManager >.write_toggle(); assert( wt < next_rec_.size() ); assert( wt < data_.size() ); @@ -382,7 +536,7 @@ nest::UniversalDataLogger< HostNode >::DataLogger_::record_data( const HostNode& template < typename HostNode > void -nest::UniversalDataLogger< HostNode >::DataLogger_::handle( HostNode& host, const DataLoggingRequest& request ) +UniversalDataLogger< HostNode >::DataLogger_::handle( HostNode& host, const DataLoggingRequest& request ) { if ( num_vars_ < 1 ) { @@ -396,13 +550,13 @@ nest::UniversalDataLogger< HostNode >::DataLogger_::handle( HostNode& host, cons assert( data_.size() == 2 ); // get read toggle and start and end of slice - const size_t rt = kernel().event_delivery_manager.read_toggle(); + const size_t rt = kernel::manager< EventDeliveryManager >.read_toggle(); assert( not data_[ rt ].empty() ); // Check if we have valid data, i.e., data with time stamps within the // past time slice. This may not be the case if the node has been frozen. // In that case, we still reset the recording marker, to prepare for the next round. - if ( data_[ rt ][ 0 ].timestamp <= kernel().simulation_manager.get_previous_slice_origin() ) + if ( data_[ rt ][ 0 ].timestamp <= kernel::manager< SimulationManager >.get_previous_slice_origin() ) { next_rec_[ rt ] = 0; return; @@ -430,7 +584,10 @@ nest::UniversalDataLogger< HostNode >::DataLogger_::handle( HostNode& host, cons reply.set_port( request.get_port() ); // send it off - kernel().event_delivery_manager.send_to_node( reply ); + kernel::manager< EventDeliveryManager >.send_to_node( reply ); } -#endif /* #ifndef UNIVERSAL_DATA_LOGGER_IMPL_H */ +} + + +#endif diff --git a/nestkernel/urbanczik_archiving_node.h b/nestkernel/urbanczik_archiving_node.h index a53e0f4ab7..0c81ed1556 100644 --- a/nestkernel/urbanczik_archiving_node.h +++ b/nestkernel/urbanczik_archiving_node.h @@ -108,41 +108,6 @@ class UrbanczikArchivingNode : public ArchivingNode std::deque< histentry_extended > urbanczik_history_[ urbanczik_parameters::NCOMP - 1 ]; }; -template < class urbanczik_parameters > -inline double -UrbanczikArchivingNode< urbanczik_parameters >::get_C_m( int comp ) -{ - return urbanczik_params->C_m[ comp ]; -} - -template < class urbanczik_parameters > -inline double -UrbanczikArchivingNode< urbanczik_parameters >::get_g_L( int comp ) -{ - return urbanczik_params->g_L[ comp ]; -} - -template < class urbanczik_parameters > -inline double -UrbanczikArchivingNode< urbanczik_parameters >::get_tau_L( int comp ) -{ - return urbanczik_params->C_m[ comp ] / urbanczik_params->g_L[ comp ]; -} - -template < class urbanczik_parameters > -inline double -UrbanczikArchivingNode< urbanczik_parameters >::get_tau_syn_ex( int comp ) -{ - return urbanczik_params->tau_syn_ex[ comp ]; -} - -template < class urbanczik_parameters > -inline double -UrbanczikArchivingNode< urbanczik_parameters >::get_tau_syn_in( int comp ) -{ - return urbanczik_params->tau_syn_in[ comp ]; -} - } // namespace nest #endif /* #ifndef URBANCZIK_ARCHIVING_NODE_H */ diff --git a/nestkernel/urbanczik_archiving_node_impl.h b/nestkernel/urbanczik_archiving_node_impl.h index 62c105fff2..d8f41b93a4 100644 --- a/nestkernel/urbanczik_archiving_node_impl.h +++ b/nestkernel/urbanczik_archiving_node_impl.h @@ -20,47 +20,78 @@ * */ +#ifndef URBANCZIK_ARCHIVING_NODE_IMPL_H +#define URBANCZIK_ARCHIVING_NODE_IMPL_H + #include "urbanczik_archiving_node.h" -// Includes from nestkernel: -#include "kernel_manager.h" +namespace nest +{ + +template < class urbanczik_parameters > +inline double +UrbanczikArchivingNode< urbanczik_parameters >::get_C_m( int comp ) +{ + return urbanczik_params->C_m[ comp ]; +} -// Includes from sli: -#include "dictutils.h" +template < class urbanczik_parameters > +inline double +UrbanczikArchivingNode< urbanczik_parameters >::get_g_L( int comp ) +{ + return urbanczik_params->g_L[ comp ]; +} -namespace nest +template < class urbanczik_parameters > +inline double +UrbanczikArchivingNode< urbanczik_parameters >::get_tau_L( int comp ) { + return urbanczik_params->C_m[ comp ] / urbanczik_params->g_L[ comp ]; +} + +template < class urbanczik_parameters > +inline double +UrbanczikArchivingNode< urbanczik_parameters >::get_tau_syn_ex( int comp ) +{ + return urbanczik_params->tau_syn_ex[ comp ]; +} + +template < class urbanczik_parameters > +inline double +UrbanczikArchivingNode< urbanczik_parameters >::get_tau_syn_in( int comp ) +{ + return urbanczik_params->tau_syn_in[ comp ]; +} -// member functions for UrbanczikArchivingNode template < class urbanczik_parameters > -nest::UrbanczikArchivingNode< urbanczik_parameters >::UrbanczikArchivingNode() +UrbanczikArchivingNode< urbanczik_parameters >::UrbanczikArchivingNode() : ArchivingNode() { } template < class urbanczik_parameters > -nest::UrbanczikArchivingNode< urbanczik_parameters >::UrbanczikArchivingNode( const UrbanczikArchivingNode& n ) +UrbanczikArchivingNode< urbanczik_parameters >::UrbanczikArchivingNode( const UrbanczikArchivingNode& n ) : ArchivingNode( n ) { } template < class urbanczik_parameters > void -nest::UrbanczikArchivingNode< urbanczik_parameters >::get_status( DictionaryDatum& d ) const +UrbanczikArchivingNode< urbanczik_parameters >::get_status( DictionaryDatum& d ) const { ArchivingNode::get_status( d ); } template < class urbanczik_parameters > void -nest::UrbanczikArchivingNode< urbanczik_parameters >::set_status( const DictionaryDatum& d ) +UrbanczikArchivingNode< urbanczik_parameters >::set_status( const DictionaryDatum& d ) { ArchivingNode::set_status( d ); } template < class urbanczik_parameters > void -nest::UrbanczikArchivingNode< urbanczik_parameters >::get_urbanczik_history( double t1, +UrbanczikArchivingNode< urbanczik_parameters >::get_urbanczik_history( double t1, double t2, std::deque< histentry_extended >::iterator* start, std::deque< histentry_extended >::iterator* finish, @@ -94,7 +125,7 @@ nest::UrbanczikArchivingNode< urbanczik_parameters >::get_urbanczik_history( dou template < class urbanczik_parameters > void -nest::UrbanczikArchivingNode< urbanczik_parameters >::write_urbanczik_history( Time const& t_sp, +UrbanczikArchivingNode< urbanczik_parameters >::write_urbanczik_history( Time const& t_sp, double V_W, int n_spikes, int comp ) @@ -128,4 +159,7 @@ nest::UrbanczikArchivingNode< urbanczik_parameters >::write_urbanczik_history( T } } -} // of namespace nest +} + + +#endif diff --git a/nestkernel/vp_manager.cpp b/nestkernel/vp_manager.cpp index 6ebf211e34..229bc0d49c 100644 --- a/nestkernel/vp_manager.cpp +++ b/nestkernel/vp_manager.cpp @@ -29,10 +29,15 @@ #include "logging.h" // Includes from nestkernel: +#include "connection_manager.h" #include "kernel_manager.h" +#include "logging_manager.h" +#include "model_manager.h" #include "mpi_manager.h" -#include "mpi_manager_impl.h" -#include "vp_manager_impl.h" +#include "node_manager.h" +#include "simulation_manager.h" +#include "sp_manager.h" + // Includes from sli: #include "dictutils.h" @@ -109,11 +114,11 @@ nest::VPManager::set_status( const DictionaryDatum& d ) { if ( not n_threads_updated ) { - n_threads = n_vps / kernel().mpi_manager.get_num_processes(); + n_threads = n_vps / kernel::manager< MPIManager >.get_num_processes(); } - const bool n_threads_conflict = n_vps / kernel().mpi_manager.get_num_processes() != n_threads; - const bool n_procs_conflict = n_vps % kernel().mpi_manager.get_num_processes() != 0; + const bool n_threads_conflict = n_vps / kernel::manager< MPIManager >.get_num_processes() != n_threads; + const bool n_procs_conflict = n_vps % kernel::manager< MPIManager >.get_num_processes() != 0; if ( n_threads_conflict or n_procs_conflict ) { throw BadProperty( @@ -130,23 +135,23 @@ nest::VPManager::set_status( const DictionaryDatum& d ) if ( n_threads_updated or n_vps_updated ) { std::vector< std::string > errors; - if ( kernel().node_manager.size() > 0 ) + if ( kernel::manager< NodeManager >.size() > 0 ) { errors.push_back( "Nodes exist" ); } - if ( kernel().connection_manager.get_user_set_delay_extrema() ) + if ( kernel::manager< ConnectionManager >.get_user_set_delay_extrema() ) { errors.push_back( "Delay extrema have been set" ); } - if ( kernel().simulation_manager.has_been_simulated() ) + if ( kernel::manager< SimulationManager >.has_been_simulated() ) { errors.push_back( "Network has been simulated" ); } - if ( kernel().model_manager.are_model_defaults_modified() ) + if ( kernel::manager< ModelManager >.are_model_defaults_modified() ) { errors.push_back( "Model defaults were modified" ); } - if ( kernel().sp_manager.is_structural_plasticity_enabled() and n_threads > 1 ) + if ( kernel::manager< SPManager >.is_structural_plasticity_enabled() and n_threads > 1 ) { errors.push_back( "Structural plasticity enabled: multithreading cannot be enabled" ); } @@ -172,7 +177,7 @@ nest::VPManager::set_status( const DictionaryDatum& d ) LOG( M_WARNING, "VPManager::set_status()", msg ); } - kernel().change_number_of_threads( n_threads ); + kernel::manager< KernelManager >.change_number_of_threads( n_threads ); } } @@ -186,10 +191,138 @@ nest::VPManager::get_status( DictionaryDatum& d ) void nest::VPManager::set_num_threads( size_t n_threads ) { - assert( not( kernel().sp_manager.is_structural_plasticity_enabled() and n_threads > 1 ) ); + assert( not( kernel::manager< SPManager >.is_structural_plasticity_enabled() and n_threads > 1 ) ); n_threads_ = n_threads; #ifdef _OPENMP omp_set_num_threads( n_threads_ ); #endif } + +size_t +nest::VPManager::get_thread_id() const +{ +#ifdef _OPENMP + return omp_get_thread_num(); +#else + return 0; +#endif +} + +size_t +nest::VPManager::get_num_threads() const +{ + return n_threads_; +} + +void +nest::VPManager::assert_single_threaded() const +{ +#ifdef _OPENMP + assert( omp_get_num_threads() == 1 ); +#endif +} + +void +nest::VPManager::assert_thread_parallel() const +{ +#ifdef _OPENMP + // omp_get_num_threads() returns int + assert( omp_get_num_threads() == static_cast< int >( n_threads_ ) ); +#endif +} + +size_t +nest::VPManager::get_vp() const +{ + return kernel::manager< MPIManager >.get_rank() + get_thread_id() * kernel::manager< MPIManager >.get_num_processes(); +} + +size_t +nest::VPManager::node_id_to_vp( const size_t node_id ) const +{ + return node_id % get_num_virtual_processes(); +} + +size_t +nest::VPManager::vp_to_thread( const size_t vp ) const +{ + return vp / kernel::manager< MPIManager >.get_num_processes(); +} + +size_t +nest::VPManager::get_num_virtual_processes() const +{ + return get_num_threads() * kernel::manager< MPIManager >.get_num_processes(); +} + +bool +nest::VPManager::is_local_vp( const size_t vp ) const +{ + return kernel::manager< MPIManager >.get_process_id_of_vp( vp ) == kernel::manager< MPIManager >.get_rank(); +} + +size_t +nest::VPManager::thread_to_vp( const size_t tid ) const +{ + return tid * kernel::manager< MPIManager >.get_num_processes() + kernel::manager< MPIManager >.get_rank(); +} + +bool +nest::VPManager::is_node_id_vp_local( const size_t node_id ) const +{ + return ( node_id % get_num_virtual_processes() == static_cast< size_t >( get_vp() ) ); +} + +size_t +nest::VPManager::node_id_to_lid( const size_t node_id ) const +{ + // starts at lid 0 for node_ids >= 1 (expected value for neurons, excl. node ID 0) + return std::ceil( static_cast< double >( node_id ) / get_num_virtual_processes() ) - 1; +} + +size_t +nest::VPManager::lid_to_node_id( const size_t lid ) const +{ + const size_t vp = get_vp(); + return ( lid + static_cast< size_t >( vp == 0 ) ) * get_num_virtual_processes() + vp; +} + +size_t +nest::VPManager::get_num_assigned_ranks_per_thread() const +{ + return std::ceil( static_cast< double >( kernel::manager< MPIManager >.get_num_processes() ) / n_threads_ ); +} + +size_t +nest::VPManager::get_start_rank_per_thread( const size_t tid ) const +{ + return tid * get_num_assigned_ranks_per_thread(); +} + +size_t +nest::VPManager::get_end_rank_per_thread( const size_t rank_start, const size_t num_assigned_ranks_per_thread ) const +{ + size_t rank_end = rank_start + num_assigned_ranks_per_thread; + + // if we have more threads than ranks, or if ranks can not be + // distributed evenly on threads, we need to make sure, that all + // threads care only about existing ranks + if ( rank_end > kernel::manager< MPIManager >.get_num_processes() ) + { + rank_end = std::max( rank_start, kernel::manager< MPIManager >.get_num_processes() ); + } + + return rank_end; +} + +nest::AssignedRanks +nest::VPManager::get_assigned_ranks( const size_t tid ) +{ + AssignedRanks assigned_ranks; + assigned_ranks.begin = get_start_rank_per_thread( tid ); + assigned_ranks.max_size = get_num_assigned_ranks_per_thread(); + assigned_ranks.end = get_end_rank_per_thread( assigned_ranks.begin, assigned_ranks.max_size ); + assigned_ranks.size = assigned_ranks.end - assigned_ranks.begin; + return assigned_ranks; +} diff --git a/nestkernel/vp_manager.h b/nestkernel/vp_manager.h index c0acc819a0..1e301fba77 100644 --- a/nestkernel/vp_manager.h +++ b/nestkernel/vp_manager.h @@ -26,12 +26,12 @@ // Includes from libnestutil: #include "manager_interface.h" -// Includes from nestkernel: -#include "nest_types.h" - // Includes from sli: #include "dictdatum.h" +#include "kernel_manager.h" +#include "mpi_manager.h" + #ifdef _OPENMP // C includes: #include @@ -173,40 +173,7 @@ class VPManager : public ManagerInterface const bool force_singlethreading_; size_t n_threads_; //!< Number of threads per process. }; -} - -inline size_t -nest::VPManager::get_thread_id() const -{ -#ifdef _OPENMP - return omp_get_thread_num(); -#else - return 0; -#endif -} - -inline size_t -nest::VPManager::get_num_threads() const -{ - return n_threads_; -} - -inline void -nest::VPManager::assert_single_threaded() const -{ -#ifdef _OPENMP - assert( omp_get_num_threads() == 1 ); -#endif -} - -inline void -nest::VPManager::assert_thread_parallel() const -{ -#ifdef _OPENMP - // omp_get_num_threads() returns int - assert( omp_get_num_threads() == static_cast< int >( n_threads_ ) ); -#endif -} +} // namespace nest #endif /* #ifndef VP_MANAGER_H */ diff --git a/nestkernel/vp_manager_impl.h b/nestkernel/vp_manager_impl.h deleted file mode 100644 index e7fa701d3a..0000000000 --- a/nestkernel/vp_manager_impl.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * vp_manager_impl.h - * - * This file is part of NEST. - * - * Copyright (C) 2004 The NEST Initiative - * - * NEST is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * NEST is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with NEST. If not, see . - * - */ - -#ifndef VP_MANAGER_IMPL_H -#define VP_MANAGER_IMPL_H - -#include "vp_manager.h" - -// Includes from nestkernel: -#include "kernel_manager.h" -#include "mpi_manager.h" -#include "mpi_manager_impl.h" - -namespace nest -{ - -inline size_t -VPManager::get_vp() const -{ - return kernel().mpi_manager.get_rank() + get_thread_id() * kernel().mpi_manager.get_num_processes(); -} - -inline size_t -VPManager::node_id_to_vp( const size_t node_id ) const -{ - return node_id % get_num_virtual_processes(); -} - -inline size_t -VPManager::vp_to_thread( const size_t vp ) const -{ - return vp / kernel().mpi_manager.get_num_processes(); -} - -inline size_t -VPManager::get_num_virtual_processes() const -{ - return get_num_threads() * kernel().mpi_manager.get_num_processes(); -} - -inline bool -VPManager::is_local_vp( const size_t vp ) const -{ - return kernel().mpi_manager.get_process_id_of_vp( vp ) == kernel().mpi_manager.get_rank(); -} - -inline size_t -VPManager::thread_to_vp( const size_t tid ) const -{ - return tid * kernel().mpi_manager.get_num_processes() + kernel().mpi_manager.get_rank(); -} - -inline bool -VPManager::is_node_id_vp_local( const size_t node_id ) const -{ - return ( node_id % get_num_virtual_processes() == static_cast< size_t >( get_vp() ) ); -} - -inline size_t -VPManager::node_id_to_lid( const size_t node_id ) const -{ - // starts at lid 0 for node_ids >= 1 (expected value for neurons, excl. node ID 0) - return std::ceil( static_cast< double >( node_id ) / get_num_virtual_processes() ) - 1; -} - -inline size_t -VPManager::lid_to_node_id( const size_t lid ) const -{ - const size_t vp = get_vp(); - return ( lid + static_cast< size_t >( vp == 0 ) ) * get_num_virtual_processes() + vp; -} - -inline size_t -VPManager::get_num_assigned_ranks_per_thread() const -{ - return std::ceil( static_cast< double >( kernel().mpi_manager.get_num_processes() ) / n_threads_ ); -} - -inline size_t -VPManager::get_start_rank_per_thread( const size_t tid ) const -{ - return tid * get_num_assigned_ranks_per_thread(); -} - -inline size_t -VPManager::get_end_rank_per_thread( const size_t rank_start, const size_t num_assigned_ranks_per_thread ) const -{ - size_t rank_end = rank_start + num_assigned_ranks_per_thread; - - // if we have more threads than ranks, or if ranks can not be - // distributed evenly on threads, we need to make sure, that all - // threads care only about existing ranks - if ( rank_end > kernel().mpi_manager.get_num_processes() ) - { - rank_end = std::max( rank_start, kernel().mpi_manager.get_num_processes() ); - } - - return rank_end; -} - -inline AssignedRanks -VPManager::get_assigned_ranks( const size_t tid ) -{ - AssignedRanks assigned_ranks; - assigned_ranks.begin = get_start_rank_per_thread( tid ); - assigned_ranks.max_size = get_num_assigned_ranks_per_thread(); - assigned_ranks.end = get_end_rank_per_thread( assigned_ranks.begin, assigned_ranks.max_size ); - assigned_ranks.size = assigned_ranks.end - assigned_ranks.begin; - return assigned_ranks; -} - -} // namespace nest - -#endif /* VP_MANAGER_IMPL_H */