diff --git a/CMakeLists.txt b/CMakeLists.txt index 6be2c202fb..f060a5c933 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,6 @@ set( with-modelset "full" CACHE STRING "The modelset to include. Sample configur set( with-models OFF CACHE STRING "The models to include as a semicolon-separated list of model headers (without the .h extension). This option is mutually exclusive with -Dwith-modelset. [default=OFF]." ) set( tics_per_ms "1000.0" CACHE STRING "Specify elementary unit of time [default=1000 tics per ms]." ) set( tics_per_step "100" CACHE STRING "Specify resolution [default=100 tics per step]." ) -set( external-modules OFF CACHE STRING "External NEST modules to be linked in, separated by ';', [default=OFF]." ) set( with-detailed-timers OFF CACHE STRING "Build with detailed internal time measurements [default=OFF]. Detailed timers can affect the performance." ) set( target-bits-split "standard" CACHE STRING "Split of the 64-bit target neuron identifier type [default='standard']. 'standard' is recommended for most users. If running on more than 262144 MPI processes or more than 512 threads, change to 'hpc'." ) @@ -136,7 +135,6 @@ nest_process_with_libraries() nest_process_with_includes() nest_process_with_defines() nest_process_static_libraries() -nest_process_external_modules() nest_process_tics_per_ms() nest_process_tics_per_step() nest_process_with_libltdl() diff --git a/cmake/ConfigureSummary.cmake b/cmake/ConfigureSummary.cmake index 2e78c6a7df..0e3eba6208 100644 --- a/cmake/ConfigureSummary.cmake +++ b/cmake/ConfigureSummary.cmake @@ -43,18 +43,6 @@ function( NEST_PRINT_CONFIG_SUMMARY ) message( "Built-in modelset : ${with-modelset}" ) endif () - message( "" ) - if ( external-modules ) - message( "User modules : ${external-modules}" ) - foreach ( mod ${external-modules} ) - message( " ${mod}:" ) - message( " Header : ${${mod}_EXT_MOD_INCLUDE}" ) - message( " Library : ${${mod}_EXT_MOD_LIBRARY}" ) - endforeach () - else () - message( "User modules : None" ) - endif () - message( "" ) if ( HAVE_PYTHON ) message( "Python bindings : Yes (Python ${Python_VERSION}: ${PYTHON})" ) diff --git a/cmake/ProcessOptions.cmake b/cmake/ProcessOptions.cmake index d380d98cef..485e94a55d 100644 --- a/cmake/ProcessOptions.cmake +++ b/cmake/ProcessOptions.cmake @@ -222,43 +222,6 @@ function( NEST_PROCESS_STATIC_LIBRARIES ) endif () endfunction() -function( NEST_PROCESS_EXTERNAL_MODULES ) - if ( external-modules ) - # headers from external modules will be installed here - include_directories( "${CMAKE_INSTALL_FULL_INCLUDEDIR}" ) - - # put all external libs into this variable - set( EXTERNAL_MODULE_LIBRARIES ) - # put all external headers into this variable - set( EXTERNAL_MODULE_INCLUDES ) - foreach ( mod ${external-modules} ) - # find module header - find_file( ${mod}_EXT_MOD_INCLUDE - NAMES ${mod}module.h - HINTS "${CMAKE_INSTALL_FULL_INCLUDEDIR}/${mod}module" - ) - if ( ${mod}_EXT_MOD_INCLUDE STREQUAL "${mod}_EXT_MOD_INCLUDE-NOTFOUND" ) - printError( "Cannot find header for external module '${mod}'. " - "Should be '${CMAKE_INSTALL_FULL_INCLUDEDIR}/${mod}module/${mod}module.h' ." ) - endif () - list( APPEND EXTERNAL_MODULE_INCLUDES ${${mod}_EXT_MOD_INCLUDE} ) - - # find module library - find_library( ${mod}_EXT_MOD_LIBRARY - NAMES ${mod}module - HINTS "${CMAKE_INSTALL_FULL_LIBDIR}/nest" - ) - if ( ${mod}_EXT_MOD_LIBRARY STREQUAL "${mod}_EXT_MOD_LIBRARY-NOTFOUND" ) - printError( "Cannot find library for external module '${mod}'." ) - endif () - list( APPEND EXTERNAL_MODULE_LIBRARIES "${${mod}_EXT_MOD_LIBRARY}" ) - endforeach () - - set( EXTERNAL_MODULE_LIBRARIES ${EXTERNAL_MODULE_LIBRARIES} PARENT_SCOPE ) - set( EXTERNAL_MODULE_INCLUDES ${EXTERNAL_MODULE_INCLUDES} PARENT_SCOPE ) - endif () -endfunction() - function( NEST_PROCESS_TICS_PER_MS ) # Set tics per ms / step if ( tics_per_ms ) @@ -280,7 +243,7 @@ function( NEST_PROCESS_WITH_LIBLTDL ) if ( with-ltdl AND NOT static-libraries ) if ( NOT ${with-ltdl} STREQUAL "ON" ) # a path is set - set( LTDL_ROOT_DIR "${with-ltdl}" ) + set( LTDL_ROOT "${with-ltdl}" ) endif () find_package( LTDL ) @@ -304,7 +267,7 @@ function( NEST_PROCESS_WITH_READLINE ) if ( with-readline ) if ( NOT ${with-readline} STREQUAL "ON" ) # a path is set - set( READLINE_ROOT_DIR "${with-readline}" ) + set( Readline_ROOT "${with-readline}" ) endif () find_package( Readline ) @@ -328,7 +291,7 @@ function( NEST_PROCESS_WITH_GSL ) if ( with-gsl ) if ( NOT ${with-gsl} STREQUAL "ON" ) # if set, use this prefix - set( GSL_ROOT_DIR "${with-gsl}" ) + set( GSL_ROOT "${with-gsl}" ) endif () find_package( GSL ) @@ -503,7 +466,7 @@ function( NEST_PROCESS_WITH_LIBNEUROSIM ) if ( with-libneurosim ) if ( NOT ${with-libneurosim} STREQUAL "ON" ) # a path is set - set( LIBNEUROSIM_ROOT ${with-libneurosim} ) + set( LibNeurosim_ROOT ${with-libneurosim} ) endif () find_package( LibNeurosim ) @@ -527,7 +490,7 @@ function( NEST_PROCESS_WITH_MUSIC ) if ( with-music ) if ( NOT ${with-music} STREQUAL "ON" ) # a path is set - set( MUSIC_ROOT_DIR "${with-music}" ) + set( Music_ROOT "${with-music}" ) endif () if ( NOT HAVE_MPI ) @@ -553,7 +516,7 @@ function( NEST_PROCESS_WITH_SIONLIB ) set( HAVE_SIONLIB OFF ) if ( with-sionlib ) if ( NOT ${with-sionlib} STREQUAL "ON" ) - set( SIONLIB_ROOT_DIR "${with-sionlib}" CACHE INTERNAL "sionlib" ) + set( SIONlib_ROOT "${with-sionlib}" CACHE INTERNAL "sionlib" ) endif() if ( NOT HAVE_MPI ) @@ -576,7 +539,7 @@ function( NEST_PROCESS_WITH_BOOST ) if ( with-boost ) if ( NOT ${with-boost} STREQUAL "ON" ) # a path is set - set( BOOST_ROOT "${with-boost}" ) + set( Boost_ROOT "${with-boost}" ) endif () set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs diff --git a/doc/htmldoc/installation/cmake_options.rst b/doc/htmldoc/installation/cmake_options.rst index d4b8bd0f56..55d3c64bbc 100644 --- a/doc/htmldoc/installation/cmake_options.rst +++ b/doc/htmldoc/installation/cmake_options.rst @@ -166,9 +166,6 @@ NEST properties +-----------------------------------------------+----------------------------------------------------------------+ | ``-Dtics_per_step=[number]`` | Specify resolution [default=100 tics per step]. | +-----------------------------------------------+----------------------------------------------------------------+ -| ``-Dexternal-modules=[OFF|]``| External NEST modules to be linked in, separated by ';', | -| | [default=OFF]. | -+-----------------------------------------------+----------------------------------------------------------------+ | ``-Dwith-detailed-timers=[OFF|ON]`` | Build with detailed internal time measurements [default=OFF]. | | | Detailed timers can affect the performance. | +-----------------------------------------------+----------------------------------------------------------------+ diff --git a/nest/CMakeLists.txt b/nest/CMakeLists.txt index e0a8e7413b..7a21c573c0 100644 --- a/nest/CMakeLists.txt +++ b/nest/CMakeLists.txt @@ -56,10 +56,10 @@ set_target_properties( nest_lib target_link_libraries( nest nestutil nestkernel sli_lib sli_readline models - ${EXTERNAL_MODULE_LIBRARIES} OpenMP::OpenMP_CXX ) + OpenMP::OpenMP_CXX ) target_link_libraries( nest_lib - nestutil nestkernel sli_lib models ${EXTERNAL_MODULE_LIBRARIES} + nestutil nestkernel sli_lib models OpenMP::OpenMP_CXX ) target_include_directories( nest PRIVATE @@ -88,7 +88,6 @@ target_include_directories( nest_lib PRIVATE ${Python_INCLUDE_DIRS} ) - if ( HAVE_PYTHON ) target_compile_definitions( nest_lib PRIVATE -D_IS_PYNEST diff --git a/nest/neststartup.cpp b/nest/neststartup.cpp index e515f62666..b27ba0abc5 100644 --- a/nest/neststartup.cpp +++ b/nest/neststartup.cpp @@ -30,7 +30,6 @@ #include "logging_event.h" // Includes from nestkernel: -#include "dynamicloader.h" #include "kernel_manager.h" #include "nest.h" #include "nestmodule.h" @@ -111,29 +110,6 @@ neststartup( int* argc, char*** argv, SLIInterpreter& engine, std::string module // NestModule extends SLI by commands for neuronal simulations addmodule< nest::NestModule >( engine ); -/* - * The following section concerns shared user modules and is thus only - * included if we built with libtool and libltdl. - * - * One may want to link user modules statically, but for convenience - * they still register themselves with the DyamicLoadModule during static - * initialization. At the same time, we need to create the DynamicLoaderModule, - * since the compiler might otherwise optimize DynamicLoaderModule::registerLinkedModule() away. - */ -#ifdef HAVE_LIBLTDL - // dynamic loader module for managing linked and dynamically loaded extension - // modules - nest::DynamicLoaderModule* pDynLoader = new nest::DynamicLoaderModule( engine ); - - // initialize all modules that were linked at compile time. - // These modules were registered via DynamicLoader::registerLinkedModule - // from their constructor - pDynLoader->initLinkedModules( engine ); - - // interpreter will delete module on destruction - engine.addmodule( pDynLoader ); -#endif - #ifdef _IS_PYNEST // add the init-script to the list of module initializers ArrayDatum* ad = dynamic_cast< ArrayDatum* >( engine.baselookup( engine.commandstring_name ).datum() ); diff --git a/nestkernel/CMakeLists.txt b/nestkernel/CMakeLists.txt index b354fb0791..50f99859f0 100644 --- a/nestkernel/CMakeLists.txt +++ b/nestkernel/CMakeLists.txt @@ -35,7 +35,7 @@ set ( nestkernel_sources deprecation_warning.h deprecation_warning.cpp device.h device.cpp device_node.h - dynamicloader.h dynamicloader.cpp + module_manager.h module_manager.cpp event.h event.cpp exceptions.h exceptions.cpp genericmodel.h genericmodel_impl.h @@ -116,6 +116,7 @@ set ( nestkernel_sources spatial.h spatial.cpp stimulation_backend.h buffer_resize_log.h buffer_resize_log.cpp + nest_extension_interface.h ) diff --git a/nestkernel/connection_manager.cpp b/nestkernel/connection_manager.cpp index 6fbfd04d07..b614e69d84 100644 --- a/nestkernel/connection_manager.cpp +++ b/nestkernel/connection_manager.cpp @@ -91,9 +91,9 @@ nest::ConnectionManager::~ConnectionManager() } void -nest::ConnectionManager::initialize( const bool reset_kernel ) +nest::ConnectionManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( reset_kernel ) + if ( not adjust_number_of_threads_or_rng_only ) { keep_source_table_ = true; connections_have_changed_ = false; diff --git a/nestkernel/dynamicloader.cpp b/nestkernel/dynamicloader.cpp deleted file mode 100644 index f8b0219971..0000000000 --- a/nestkernel/dynamicloader.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* - * dynamicloader.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 "dynamicloader.h" - -#ifdef HAVE_LIBLTDL - -// External includes: -#include - -// Includes from libnestutil: -#include "logging.h" - -// Includes from nestkernel: -#include "kernel_manager.h" -#include "model.h" - -// Includes from sli: -#include "integerdatum.h" -#include "interpret.h" -#include "stringdatum.h" - - -namespace nest -{ - -struct sDynModule -{ - std::string name; - lt_dlhandle handle; - SLIModule* pModule; - - bool - operator==( const sDynModule& rhs ) const - { - return name == rhs.name; - } - - // operator!= must be implemented explicitly, not all compilers - // generate it automatically from operator== - bool - operator!=( const sDynModule& rhs ) const - { - return not( *this == rhs ); - } -}; - -// static member initialization -Dictionary* DynamicLoaderModule::moduledict_ = new Dictionary(); - -vecLinkedModules& -DynamicLoaderModule::getLinkedModules() -{ - static vecLinkedModules lm; // initialized empty on first call - return lm; -} - - -DynamicLoaderModule::DynamicLoaderModule( SLIInterpreter& interpreter ) - : dyn_modules() - , loadmodule_function( dyn_modules ) -{ - interpreter.def( "moduledict", new DictionaryDatum( moduledict_ ) ); -} - -DynamicLoaderModule::~DynamicLoaderModule() -{ - // unload all loaded modules - for ( vecDynModules::iterator it = dyn_modules.begin(); it != dyn_modules.end(); ++it ) - { - if ( it->handle ) - { - lt_dlclose( it->handle ); - it->handle = nullptr; - } - } - - lt_dlexit(); -} - -// The following concerns the new module: ----------------------- - -const std::string -DynamicLoaderModule::name() const -{ - return std::string( "NEST-Dynamic Loader" ); // Return name of the module -} - -const std::string -DynamicLoaderModule::commandstring() const -{ - return std::string( "" ); // Run associated SLI startup script -} - - -// auxiliary function to check name of module via its pointer -// we cannot use a & for the second argument, as std::bind2nd() then -// becomes confused, at least with g++ 4.0.1. -bool -has_name( SLIModule const* const m, const std::string n ) -{ - return m->name() == n; -} - - -DynamicLoaderModule::LoadModuleFunction::LoadModuleFunction( vecDynModules& dyn_modules ) - : dyn_modules_( dyn_modules ) -{ -} - -void -DynamicLoaderModule::LoadModuleFunction::execute( SLIInterpreter* i ) const -{ - i->assert_stack_load( 1 ); - - sDynModule new_module; - - new_module.name = getValue< std::string >( i->OStack.top() ); - if ( new_module.name.empty() ) - { - throw DynamicModuleManagementError( "Module name must not be empty." ); - } - - // check if module already loaded - // this check can happen here, since we are comparing dynamically loaded - // modules based on the name given to the Install command - if ( std::find( dyn_modules_.begin(), dyn_modules_.end(), new_module ) != dyn_modules_.end() ) - { - throw DynamicModuleManagementError( "Module '" + new_module.name + "' is loaded already." ); - } - - // call lt_dlerror() to reset any error messages hanging around - lt_dlerror(); - // try to open the module - const lt_dlhandle hModule = lt_dlopenext( new_module.name.c_str() ); - - if ( not hModule ) - { - char* errstr = ( char* ) lt_dlerror(); - std::string msg = "Module '" + new_module.name + "' could not be opened."; - if ( errstr ) - { - msg += "\nThe dynamic loader returned the following error: '" + std::string( errstr ) + "'."; - } - msg += "\n\nPlease check LD_LIBRARY_PATH (OSX: DYLD_LIBRARY_PATH)!"; - throw DynamicModuleManagementError( msg ); - } - - // see if we can find the mod symbol in the module - SLIModule* pModule = ( SLIModule* ) lt_dlsym( hModule, "mod" ); - char* errstr = ( char* ) lt_dlerror(); - if ( errstr ) - { - lt_dlclose( hModule ); // close module again - lt_dlerror(); // remove any error caused by lt_dlclose() - throw DynamicModuleManagementError( - "Module '" + new_module.name + "' could not be loaded.\n" - "The dynamic loader returned the following error: '" - + std::string(errstr) + "'."); - } - - // check if module is linked in. This test is based on the module name - // returned by DynModule::name(), since we have no file names for linked - // modules. We can only perform it after we have loaded the module. - if ( std::find_if( DynamicLoaderModule::getLinkedModules().begin(), - DynamicLoaderModule::getLinkedModules().end(), - std::bind( has_name, std::placeholders::_1, pModule->name() ) ) - != DynamicLoaderModule::getLinkedModules().end() ) - { - lt_dlclose( hModule ); // close module again - lt_dlerror(); // remove any error caused by lt_dlclose() - throw DynamicModuleManagementError( - "Module '" + new_module.name + "' is linked into NEST.\n" - "You neither need nor may load it dynamically in addition."); - } - - // all is well an we can register the module with the interpreter - try - { - pModule->install( std::cerr, i ); - } - catch ( std::exception& e ) - { - // We should uninstall the partially installed module here, but - // this must wait for #152. - // For now, we just close the module file and rethrow the exception. - lt_dlclose( hModule ); - lt_dlerror(); // remove any error caused by lt_dlclose() - throw; // no arg re-throws entire exception, see Stroustrup 14.3.1 - } - - // add the handle to list of loaded modules - new_module.handle = hModule; - new_module.pModule = pModule; - dyn_modules_.push_back( new_module ); - - LOG( M_INFO, "Install", ( "loaded module " + pModule->name() ).c_str() ); - - // remove operand and operator from stack - i->OStack.pop(); - i->EStack.pop(); - - // put handle to module onto stack - int moduleid = dyn_modules_.size() - 1; - i->OStack.push( moduleid ); - ( *moduledict_ )[ new_module.name ] = moduleid; - - // now we can run the module initializer, after we have cleared the EStack - if ( not pModule->commandstring().empty() ) - { - Token t = new StringDatum( pModule->commandstring() ); - i->OStack.push_move( t ); - Token c = new NameDatum( "initialize_module" ); - i->EStack.push_move( c ); - } -} - -void -DynamicLoaderModule::init( SLIInterpreter* i ) -{ - // bind functions to terminal names - i->createcommand( "Install", &loadmodule_function ); - - // the ld_* functions return 0 on success and an int > 0 on failure - if ( lt_dlinit() ) - { - LOG( M_ERROR, "DynamicLoaderModule::init", "Could not initialize libltdl. No dynamic modules will be available." ); - } - - // To avoid problems due to string substitution in NEST binaries during - // Conda installation, we need to convert the literal to string, cstr and back, - // see #2237 and https://github.com/conda/conda-build/issues/1674#issuecomment-280378336 - const std::string module_dir = std::string( NEST_INSTALL_PREFIX ).c_str() + std::string( "/" NEST_INSTALL_LIBDIR ); - if ( lt_dladdsearchdir( module_dir.c_str() ) ) - { - LOG( M_ERROR, "DynamicLoaderModule::init", "Could not add dynamic module search directory." ); - } -} - - -int -DynamicLoaderModule::registerLinkedModule( SLIModule* pModule ) -{ - assert( pModule ); - getLinkedModules().push_back( pModule ); - return getLinkedModules().size(); -} - -void -DynamicLoaderModule::initLinkedModules( SLIInterpreter& interpreter ) -{ - - for ( vecLinkedModules::iterator it = getLinkedModules().begin(); it != getLinkedModules().end(); ++it ) - { - interpreter.message( SLIInterpreter::M_STATUS, "DynamicLoaderModule::initLinkedModules", "adding linked module" ); - interpreter.message( SLIInterpreter::M_STATUS, "DynamicLoaderModule::initLinkedModules", ( *it )->name().c_str() ); - interpreter.addlinkedusermodule( *it ); - } -} - - -} // namespace nest - -#endif /* HAVE_LIBLTDL */ diff --git a/nestkernel/dynamicloader.h b/nestkernel/dynamicloader.h deleted file mode 100644 index 50b9f051c0..0000000000 --- a/nestkernel/dynamicloader.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * dynamicloader.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 DYNAMICLOADER_H -#define DYNAMICLOADER_H - -// Generated includes: -#include "config.h" - -// DynamicLoaderModule defined only if libltdl is available - -#ifdef HAVE_LIBLTDL - -// C++ includes: -#include - -// Includes from sli: -#include "slifunction.h" -#include "slimodule.h" - -namespace nest -{ -struct sDynModule; // structure to store handles and pointers to modules - -typedef std::vector< sDynModule > vecDynModules; - -typedef std::vector< SLIModule* > vecLinkedModules; - - -/** - * SLI interface of the dynamic module loader. - * - * This class implements the SLI functions which allow for - * loading dynamic modules into the kernel to extend its functionality. - * - * At the time when DynamicLoaderModule is constructed, the SLI Interpreter - * and NestModule must be already constructed and initialized. - * DynamicLoaderModule relies on the presence of - * the following SLI datastructures: Name, Dictionary. - */ - -class DynamicLoaderModule : public SLIModule -{ -public: - explicit DynamicLoaderModule( SLIInterpreter& interpreter ); - ~DynamicLoaderModule() override; - - void init( SLIInterpreter* ) override; - - const std::string commandstring() const override; - const std::string name() const override; - - - /** - * This static member is called by the constructor of a loadable module that - * was linked at compile time into the application to circumvent dynamic - * loading problems. Typically, the constructor of the global - * instance of the module calls this method to register itself. - * Later, DynamicLoader will go through all registered modules and initialize - * them. - */ - static int registerLinkedModule( SLIModule* pModule ); - - void initLinkedModules( SLIInterpreter& ); - -private: - /** - * Provide access to the list of linked modules managed DynamicLoader. - * This function controls access to the list of linked modules managed - * by DynamicLoaderModule via a Meyers' Singleton (Alexandrescu, ch 6.4). - * The list is filled by calls to @c registerLinkedModule(). - */ - static vecLinkedModules& getLinkedModules(); - - //! Vector to store handles and pointers to dynamic modules - vecDynModules dyn_modules; - - //! Dictionary for dynamically loaded modules. - static Dictionary* moduledict_; - -public: - class LoadModuleFunction : public SLIFunction - { - public: - explicit LoadModuleFunction( vecDynModules& dyn_modules ); - - private: - void execute( SLIInterpreter* ) const override; - - private: - vecDynModules& dyn_modules_; - }; - - /** - * @BeginDocumentation - * Name: Install - Load a dynamic module to extend the functionality. - * - * Description: - * Load the specified dynamic module into NEST. The module has to be visible - * on the runtime linker's search path (i.e. LD_LIBRARY_PATH on Linux and - * DYLD_LIBRARY_PATH on macOS). - * - * Synopsis: (module_name) Install -> handle - */ - LoadModuleFunction loadmodule_function; -}; - -} // namespace - -#endif /* #ifdef HAVE_LIBLTDL */ - -#endif diff --git a/nestkernel/event_delivery_manager.cpp b/nestkernel/event_delivery_manager.cpp index cca5270577..1f3b94bee4 100644 --- a/nestkernel/event_delivery_manager.cpp +++ b/nestkernel/event_delivery_manager.cpp @@ -76,9 +76,9 @@ EventDeliveryManager::~EventDeliveryManager() } void -EventDeliveryManager::initialize( const bool reset_kernel ) +EventDeliveryManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( reset_kernel ) + if ( not adjust_number_of_threads_or_rng_only ) { init_moduli(); reset_timers_for_preparation(); diff --git a/nestkernel/io_manager.cpp b/nestkernel/io_manager.cpp index f4552a6c30..9f9647d48f 100644 --- a/nestkernel/io_manager.cpp +++ b/nestkernel/io_manager.cpp @@ -132,9 +132,9 @@ IOManager::set_data_path_prefix_( const DictionaryDatum& dict ) } void -IOManager::initialize( const bool reset_kernel ) +IOManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( reset_kernel ) + if ( not adjust_number_of_threads_or_rng_only ) { DictionaryDatum dict( new Dictionary ); // The properties data_path and data_prefix can be set via environment variables diff --git a/nestkernel/kernel_manager.cpp b/nestkernel/kernel_manager.cpp index 1a34248ef3..63b5937ada 100644 --- a/nestkernel/kernel_manager.cpp +++ b/nestkernel/kernel_manager.cpp @@ -50,6 +50,7 @@ nest::KernelManager::KernelManager() , logging_manager() , mpi_manager() , vp_manager() + , module_manager() , random_manager() , simulation_manager() , modelrange_manager() @@ -58,11 +59,12 @@ nest::KernelManager::KernelManager() , event_delivery_manager() , model_manager() , music_manager() - , node_manager() , io_manager() + , node_manager() , managers( { &logging_manager, &mpi_manager, &vp_manager, + &module_manager, &random_manager, &simulation_manager, &modelrange_manager, @@ -86,7 +88,7 @@ nest::KernelManager::initialize() { for ( auto& manager : managers ) { - manager->initialize(); + manager->initialize( /* adjust_number_of_threads_or_rng_only */ false ); } ++fingerprint_; @@ -120,7 +122,7 @@ nest::KernelManager::finalize() for ( auto&& m_it = managers.rbegin(); m_it != managers.rend(); ++m_it ) { - ( *m_it )->finalize(); + ( *m_it )->finalize( /* adjust_number_of_threads_or_rng_only */ false ); } initialized_ = false; } @@ -145,7 +147,7 @@ nest::KernelManager::change_number_of_threads( size_t new_num_threads ) // Finalize in reverse order of initialization with old thread number set for ( auto mgr_it = managers.rbegin(); mgr_it != managers.rend(); ++mgr_it ) { - ( *mgr_it )->finalize( /* reset_kernel */ false ); + ( *mgr_it )->finalize( /* adjust_number_of_threads_or_rng_only */ true ); } vp_manager.set_num_threads( new_num_threads ); @@ -153,8 +155,13 @@ nest::KernelManager::change_number_of_threads( size_t new_num_threads ) // Initialize in original order with new number of threads set for ( auto& manager : managers ) { - manager->initialize( /* reset_kernel */ false ); + manager->initialize( /* adjust_number_of_threads_or_rng_only */ true ); } + + // 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(); } void diff --git a/nestkernel/kernel_manager.h b/nestkernel/kernel_manager.h index 397f0cf986..78a31c52f3 100644 --- a/nestkernel/kernel_manager.h +++ b/nestkernel/kernel_manager.h @@ -33,6 +33,7 @@ #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" @@ -263,9 +264,18 @@ 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; @@ -274,11 +284,13 @@ class KernelManager EventDeliveryManager event_delivery_manager; ModelManager model_manager; MUSICManager music_manager; - NodeManager node_manager; IOManager io_manager; - + NodeManager node_manager; + /**@}*/ 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 }; diff --git a/nestkernel/logging_manager.cpp b/nestkernel/logging_manager.cpp index bbc99211e5..500290b54e 100644 --- a/nestkernel/logging_manager.cpp +++ b/nestkernel/logging_manager.cpp @@ -42,9 +42,9 @@ nest::LoggingManager::LoggingManager() } void -nest::LoggingManager::initialize( const bool reset_kernel ) +nest::LoggingManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( reset_kernel ) + if ( not adjust_number_of_threads_or_rng_only ) { dict_miss_is_error_ = true; } diff --git a/nestkernel/manager_interface.h b/nestkernel/manager_interface.h index 5dc04f8f7a..34d7eabb5c 100644 --- a/nestkernel/manager_interface.h +++ b/nestkernel/manager_interface.h @@ -68,11 +68,13 @@ class ManagerInterface * is responsible for calling the initialization routines on the * specific managers in correct order. * - * @param reset_kernel Pass false if calling from kernel_manager::change_number_of_threads() to limit operations + * @param adjust_number_of_threads_or_rng_only Pass true if calling from kernel_manager::change_number_of_threads() + * or RandomManager::get_status() to limit operations to those necessary for thread adjustment or switch or re-seeding + * of RNG. * * @see finalize() */ - virtual void initialize( const bool reset_kernel = true ) = 0; + virtual void initialize( const bool adjust_number_of_threads_or_rng_only ) = 0; /** * Take down manager after operation. @@ -87,11 +89,12 @@ class ManagerInterface * specific managers in correct order, i.e., the opposite order of * initialize() calls. * - * @param reset_kernel pass false if calling from kernel_manager::change_number_of_threads() to limit operations + * @param adjust_number_of_threads_or_rng_only Pass true if calling from kernel_manager::change_number_of_threads() + * to limit operations to those necessary for thread adjustment. * * @see initialize() */ - virtual void finalize( const bool reset_kernel = true ) = 0; + virtual void finalize( const bool adjust_number_of_threads_or_rng_only ) = 0; /** * Set the status of the manager diff --git a/nestkernel/model_manager.cpp b/nestkernel/model_manager.cpp index 506e83be3c..a656285f13 100644 --- a/nestkernel/model_manager.cpp +++ b/nestkernel/model_manager.cpp @@ -80,12 +80,17 @@ ModelManager::initialize( const bool ) // Make space for one vector of proxynodes for each thread proxy_nodes_.resize( num_threads ); + // We must re-register all models even if only changing the number of threads because + // the model-managing data structures depend on the number of threads. + // Models provided by extension modules will be re-registered by the ModulesManager. register_models(); } void ModelManager::finalize( const bool ) { + // We must clear all models even if only changing the number of threads because + // the model-managing data structures depend on the number of threads clear_node_models_(); clear_connection_models_(); } diff --git a/nestkernel/module_manager.cpp b/nestkernel/module_manager.cpp new file mode 100644 index 0000000000..57c668da9b --- /dev/null +++ b/nestkernel/module_manager.cpp @@ -0,0 +1,187 @@ +/* + * module_manager.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 "module_manager.h" + +#ifdef HAVE_LIBLTDL + +// Includes from libnestutil: +#include "logging.h" + +// Includes from nestkernel: +#include "kernel_manager.h" +#include "nest_extension_interface.h" + +// Includes from sli: +#include "arraydatum.h" + +// Includes from thirdparty: +#include "compose.hpp" + + +namespace nest +{ + +ModuleManager::ModuleManager() + : modules_() +{ + lt_dlinit(); + + // Add NEST lib install dir to ltdl search path + // To avoid problems due to string substitution in NEST binaries during + // Conda installation, we need to convert the literal to string, cstr and back, + // see #2237 and https://github.com/conda/conda-build/issues/1674#issuecomment-280378336 + const std::string module_dir = std::string( NEST_INSTALL_PREFIX ).c_str() + std::string( "/" NEST_INSTALL_LIBDIR ); + if ( lt_dladdsearchdir( module_dir.c_str() ) ) + { + LOG( M_ERROR, + "ModuleManager::ModuleManager", + String::compose( "Could not add dynamic module search directory '%1'.", module_dir ) ); + } +} + +ModuleManager::~ModuleManager() +{ + finalize( /* adjust_number_of_threads_or_rng_only */ false ); // closes dynamically loaded modules + lt_dlexit(); +} + +void +ModuleManager::initialize( const bool ) +{ +} + +void +ModuleManager::finalize( const bool adjust_number_of_threads_or_rng_only ) +{ + if ( adjust_number_of_threads_or_rng_only ) + { + return; + } + + // unload all loaded modules + for ( const auto& [ name, module_info ] : modules_ ) + { + lt_dlclose( module_info.handle ); + } + modules_.clear(); +} + +void +ModuleManager::reinitialize_dynamic_modules() +{ + for ( const auto& [ name, module_info ] : modules_ ) + { + module_info.extension->initialize(); + } +} + +void +ModuleManager::get_status( DictionaryDatum& d ) +{ + ArrayDatum loaded; + for ( const auto& [ name, module_info ] : modules_ ) + { + loaded.push_back( new LiteralDatum( name ) ); + } + ( *d )[ names::modules ] = loaded; +} + +void +ModuleManager::set_status( const DictionaryDatum& d ) +{ +} + +void +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 ) + { + throw KernelException( + "Network elements have been created, so external modules can no longer be imported. " + "Call ResetKernel() first." ); + } + + if ( name.empty() ) + { + throw DynamicModuleManagementError( "Module name must not be empty." ); + } + + if ( modules_.find( name ) != modules_.end() ) + { + throw DynamicModuleManagementError( "Module '" + name + "' is loaded already." ); + } + + // call lt_dlerror() to reset any error messages hanging around + lt_dlerror(); + + // try to open the module + const lt_dlhandle hModule = lt_dlopenext( name.c_str() ); + + if ( not hModule ) + { + char* errstr = ( char* ) lt_dlerror(); + std::string msg = "Module '" + name + "' could not be opened."; + if ( errstr ) + { + msg += "\nThe dynamic loader returned the following error: '" + std::string( errstr ) + "'."; + } + msg += "\n\nPlease check LD_LIBRARY_PATH (OSX: DYLD_LIBRARY_PATH)!"; + throw DynamicModuleManagementError( msg ); + } + + // see if we can find the "module" symbol in the module + NESTExtensionInterface* extension = reinterpret_cast< NESTExtensionInterface* >( lt_dlsym( hModule, "module" ) ); + char* errstr = ( char* ) lt_dlerror(); + if ( errstr ) + { + lt_dlclose( hModule ); // close module again + lt_dlerror(); // remove any error caused by lt_dlclose() + throw DynamicModuleManagementError( + "Module '" + name + "' could not be loaded.\n" + "The dynamic loader returned the following error: '" + + std::string(errstr) + "'."); + } + + // all is well and we can register module components + try + { + extension->initialize(); + } + catch ( std::exception& e ) + { + lt_dlclose( hModule ); + lt_dlerror(); // remove any error caused by lt_dlclose() + throw; // no arg re-throws entire exception, see Stroustrup 14.3.1 + } + + // add the handle to list of loaded modules + modules_[ name ] = ModuleMapEntry_( hModule, extension ); + + LOG( M_INFO, "Install", ( "loaded module " + name ).c_str() ); +} + +} // namespace nest + +#endif /* HAVE_LIBLTDL */ diff --git a/nestkernel/module_manager.h b/nestkernel/module_manager.h new file mode 100644 index 0000000000..107ed9ed65 --- /dev/null +++ b/nestkernel/module_manager.h @@ -0,0 +1,133 @@ +/* + * module_manager.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 MODULE_MANAGER_H +#define MODULE_MANAGER_H + +// Generated includes: +#include "config.h" + +// C++ includes: +#include +#include + +// Includes from nestkernel: +#include "manager_interface.h" + +// Includes from sli: +#include "dictutils.h" + +// DynamicLoaderModule defined only if libltdl is available +#ifdef HAVE_LIBLTDL +#include + +namespace nest +{ +class NESTExtensionInterface; + +class ModuleManager : public ManagerInterface +{ +public: + ModuleManager(); + ~ModuleManager() override; + + void initialize( const bool ) override; + + //! Unload modules but only on full ResetKernel(), not when just changing then number of threads + void finalize( const bool adjust_number_of_threads_or_rng_only ) override; + + //! To be called after change of number of threads to re-register components provided by modules + void reinitialize_dynamic_modules(); + + void get_status( DictionaryDatum& ) override; + void set_status( const DictionaryDatum& ) override; + + void install( const std::string& name ); + +private: + struct ModuleMapEntry_ + { + ModuleMapEntry_() = default; + ModuleMapEntry_( lt_dlhandle hndl, NESTExtensionInterface* ext ) + : handle( hndl ) + , extension( ext ) + { + } + + lt_dlhandle handle; //!< required for unloading + NESTExtensionInterface* extension; //!< required for re-initizliation(), avoid re-casting handle + }; + + std::map< std::string, ModuleMapEntry_ > modules_; +}; +} + +#else + +#include "exceptions.h" + +namespace nest +{ +class ModuleManager : public ManagerInterface +{ +public: + ModuleManager() + { + } + ~ModuleManager() override + { + } + + void + initialize( const bool ) override + { + } + void + finalize( const bool ) override + { + } + + void + reinitialize_dynamic_modules() + { + } + + void + get_status( DictionaryDatum& ) override + { + } + void + set_status( const DictionaryDatum& ) override + { + } + + void + install( const std::string& name ) + { + throw KernelException( "Dynamic modules not supported without libltdl." ); + } +}; +} + +#endif // HAVE_LIBLTDL + +#endif // #ifndef MODULE_MANAGER_H diff --git a/nestkernel/mpi_manager.cpp b/nestkernel/mpi_manager.cpp index 3492e33c20..b7a348322e 100644 --- a/nestkernel/mpi_manager.cpp +++ b/nestkernel/mpi_manager.cpp @@ -178,9 +178,9 @@ nest::MPIManager::init_mpi( int* argc, char** argv[] ) #endif /* #ifdef HAVE_MPI */ void -nest::MPIManager::initialize( const bool reset_kernel ) +nest::MPIManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( not reset_kernel ) + if ( adjust_number_of_threads_or_rng_only ) { return; } diff --git a/nestkernel/music_manager.cpp b/nestkernel/music_manager.cpp index 2aa652adb7..827bb7d61f 100644 --- a/nestkernel/music_manager.cpp +++ b/nestkernel/music_manager.cpp @@ -48,9 +48,9 @@ MUSICManager::MUSICManager() } void -MUSICManager::initialize( const bool reset_kernel ) +MUSICManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( not reset_kernel ) + if ( adjust_number_of_threads_or_rng_only ) { return; } diff --git a/nestkernel/nest_extension_interface.h b/nestkernel/nest_extension_interface.h new file mode 100644 index 0000000000..e185504bc8 --- /dev/null +++ b/nestkernel/nest_extension_interface.h @@ -0,0 +1,74 @@ +/* + * nest_extension_interface.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 NEST_EXTENSION_INTERFACE_H +#define NEST_EXTENSION_INTERFACE_H + +// 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 "target_identifier.h" + +// C++ includes +#include + +/** + * Interface for NEST Extenstion Modules. + * + * All NEST Extension Modules must be derived from this interface class. + * + * Method init() will be called after the module is loaded. + * + * The constructor should be empty. + */ + +namespace nest +{ + +class NESTExtensionInterface +{ +public: + virtual ~NESTExtensionInterface() + { + } + + /** + * Initialize module, register all components with kernel + */ + virtual void initialize() = 0; +}; + +} + +#endif // #ifndef NEST_EXTENSION_INTERFACE_H diff --git a/nestkernel/nest_names.cpp b/nestkernel/nest_names.cpp index 2d6b867aa7..df05a378a8 100644 --- a/nestkernel/nest_names.cpp +++ b/nestkernel/nest_names.cpp @@ -318,6 +318,7 @@ const Name min_update_time( "min_update_time" ); const Name minor_axis( "minor_axis" ); const Name model( "model" ); const Name model_id( "model_id" ); +const Name modules( "modules" ); const Name mpi_address( "mpi_address" ); const Name ms_per_tic( "ms_per_tic" ); const Name mu( "mu" ); diff --git a/nestkernel/nest_names.h b/nestkernel/nest_names.h index b07bda0cb7..21d03e4b3d 100644 --- a/nestkernel/nest_names.h +++ b/nestkernel/nest_names.h @@ -346,6 +346,7 @@ extern const Name min_update_time; extern const Name minor_axis; extern const Name model; extern const Name model_id; +extern const Name modules; extern const Name mpi_address; extern const Name ms_per_tic; extern const Name mu; diff --git a/nestkernel/nestmodule.cpp b/nestkernel/nestmodule.cpp index f6f206a5d8..bf0675f3d2 100644 --- a/nestkernel/nestmodule.cpp +++ b/nestkernel/nestmodule.cpp @@ -94,7 +94,7 @@ NestModule::~NestModule() const std::string NestModule::name() const { - return std::string( "NEST Kernel 2" ); // Return name of the module + return std::string( "NEST Kernel" ); // Return name of the module } const std::string @@ -567,6 +567,19 @@ NestModule::GetDefaults_lFunction::execute( SLIInterpreter* i ) const i->EStack.pop(); } +void +NestModule::Install_sFunction::execute( SLIInterpreter* i ) const +{ + i->assert_stack_load( 1 ); + + const std::string modulename = getValue< std::string >( i->OStack.pick( 0 ) ); + + kernel().module_manager.install( modulename ); + + i->OStack.pop(); + i->EStack.pop(); +} + void NestModule::GetConnections_DFunction::execute( SLIInterpreter* i ) const { @@ -2087,6 +2100,8 @@ NestModule::init( SLIInterpreter* i ) i->createcommand( "SetDefaults_l_D", &setdefaults_l_Dfunction ); i->createcommand( "GetDefaults_l", &getdefaults_lfunction ); + i->createcommand( "Install", &install_sfunction ); + i->createcommand( "Create_l_i", &create_l_ifunction ); i->createcommand( "GetNodes_D_b", &getnodes_D_bfunction ); diff --git a/nestkernel/nestmodule.h b/nestkernel/nestmodule.h index c028d2f17c..55df2bce23 100644 --- a/nestkernel/nestmodule.h +++ b/nestkernel/nestmodule.h @@ -389,6 +389,15 @@ class NestModule : public SLIModule void execute( SLIInterpreter* ) const override; } copymodel_l_l_Dfunction; + /** @BeginDocumentation + * Name: Install - install dynamically loaded module + */ + class Install_sFunction : public SLIFunction + { + public: + void execute( SLIInterpreter* ) const override; + } install_sfunction; + class GetConnections_DFunction : public SLIFunction { public: diff --git a/nestkernel/node_manager.cpp b/nestkernel/node_manager.cpp index 7c3ca760bc..5e984ca7fa 100644 --- a/nestkernel/node_manager.cpp +++ b/nestkernel/node_manager.cpp @@ -68,7 +68,7 @@ NodeManager::~NodeManager() } void -NodeManager::initialize( const bool reset_kernel ) +NodeManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { // explicitly force construction of wfr_nodes_vec_ to ensure consistent state wfr_network_size_ = 0; @@ -76,7 +76,7 @@ NodeManager::initialize( const bool reset_kernel ) num_thread_local_devices_.resize( kernel().vp_manager.get_num_threads(), 0 ); ensure_valid_thread_local_ids(); - if ( reset_kernel ) + if ( not adjust_number_of_threads_or_rng_only ) { sw_construction_create_.reset(); } diff --git a/nestkernel/random_manager.cpp b/nestkernel/random_manager.cpp index dd52f43b2a..db0a58fd65 100644 --- a/nestkernel/random_manager.cpp +++ b/nestkernel/random_manager.cpp @@ -60,9 +60,9 @@ nest::RandomManager::~RandomManager() } void -nest::RandomManager::initialize( const bool reset_kernel ) +nest::RandomManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( reset_kernel ) + if ( not adjust_number_of_threads_or_rng_only ) { register_rng_type< std::mt19937 >( "mt19937" ); register_rng_type< std::mt19937_64 >( "mt19937_64" ); @@ -97,7 +97,7 @@ nest::RandomManager::initialize( const bool reset_kernel ) } void -nest::RandomManager::finalize( const bool reset_kernel ) +nest::RandomManager::finalize( const bool adjust_number_of_threads_or_rng_only ) { // Delete existing RNGs auto delete_rngs = []( std::vector< RngPtr >& rng_vec ) @@ -114,7 +114,7 @@ nest::RandomManager::finalize( const bool reset_kernel ) vp_synced_rngs_.clear(); vp_specific_rngs_.clear(); - if ( reset_kernel ) + if ( not adjust_number_of_threads_or_rng_only ) { for ( auto& it : rng_types_ ) { @@ -171,8 +171,8 @@ nest::RandomManager::set_status( const DictionaryDatum& d ) if ( rng_seed_updated or rng_type_updated ) { - finalize( /* reset_kernel */ false ); - initialize( /* reset_kernel */ false ); + finalize( /* adjust_number_of_threads_or_rng_only */ true ); + initialize( /* adjust_number_of_threads_or_rng_only */ true ); } } diff --git a/nestkernel/simulation_manager.cpp b/nestkernel/simulation_manager.cpp index 2bcdf2802a..bad0b83e7c 100644 --- a/nestkernel/simulation_manager.cpp +++ b/nestkernel/simulation_manager.cpp @@ -69,9 +69,9 @@ nest::SimulationManager::SimulationManager() } void -nest::SimulationManager::initialize( const bool reset_kernel ) +nest::SimulationManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( not reset_kernel ) + if ( adjust_number_of_threads_or_rng_only ) { return; } diff --git a/nestkernel/sp_manager.cpp b/nestkernel/sp_manager.cpp index 345ac6b9c2..52e1f73d29 100644 --- a/nestkernel/sp_manager.cpp +++ b/nestkernel/sp_manager.cpp @@ -51,9 +51,9 @@ SPManager::~SPManager() } void -SPManager::initialize( const bool reset_kernel ) +SPManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( not reset_kernel ) + if ( adjust_number_of_threads_or_rng_only ) { return; } diff --git a/nestkernel/vp_manager.cpp b/nestkernel/vp_manager.cpp index 292f65239b..6ebf211e34 100644 --- a/nestkernel/vp_manager.cpp +++ b/nestkernel/vp_manager.cpp @@ -48,9 +48,9 @@ nest::VPManager::VPManager() } void -nest::VPManager::initialize( const bool reset_kernel ) +nest::VPManager::initialize( const bool adjust_number_of_threads_or_rng_only ) { - if ( not reset_kernel ) + if ( adjust_number_of_threads_or_rng_only ) { return; } diff --git a/pynest/CMakeLists.txt b/pynest/CMakeLists.txt index f679f39382..6d3129419d 100644 --- a/pynest/CMakeLists.txt +++ b/pynest/CMakeLists.txt @@ -54,7 +54,7 @@ if ( HAVE_PYTHON ) endif () target_link_libraries( pynestkernel - nest_lib nestutil nestkernel sli_lib models ${EXTERNAL_MODULE_LIBRARIES} + nest_lib nestutil nestkernel sli_lib models ) target_include_directories( pynestkernel PRIVATE diff --git a/sli/sliexceptions.h b/sli/sliexceptions.h index 23bc5ce6d8..2d0585450c 100644 --- a/sli/sliexceptions.h +++ b/sli/sliexceptions.h @@ -34,9 +34,6 @@ class SLIInterpreter; -#define UNKNOWN "unknown" -#define UNKNOWN_NUM -1 - /** * @addtogroup Exceptions Exception classes * Exception classes that are thrown to indicate